]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-aufs3.patch
- up to 3.9.6; vserver up to 3.9.5-vs2.3.6.5
[packages/kernel.git] / kernel-aufs3.patch
CommitLineData
a2a7ad62 1aufs3.8 kbuild patch
7f207e10
AM
2
3diff --git a/fs/Kconfig b/fs/Kconfig
1716fcea 4index 780725a..d460c05 100644
7f207e10
AM
5--- a/fs/Kconfig
6+++ b/fs/Kconfig
1716fcea 7@@ -211,6 +211,7 @@ source "fs/sysv/Kconfig"
7f207e10
AM
8 source "fs/ufs/Kconfig"
9 source "fs/exofs/Kconfig"
1716fcea 10 source "fs/f2fs/Kconfig"
7f207e10
AM
11+source "fs/aufs/Kconfig"
12
13 endif # MISC_FILESYSTEMS
14
15diff --git a/fs/Makefile b/fs/Makefile
1716fcea 16index 9d53192..e70f08f 100644
7f207e10
AM
17--- a/fs/Makefile
18+++ b/fs/Makefile
1716fcea 19@@ -127,3 +127,4 @@ obj-$(CONFIG_F2FS_FS) += f2fs/
9dbd164d 20 obj-y += exofs/ # Multiple modules
7f207e10 21 obj-$(CONFIG_CEPH_FS) += ceph/
bf0370f2 22 obj-$(CONFIG_PSTORE) += pstore/
2cbb1c4b 23+obj-$(CONFIG_AUFS_FS) += aufs/
a2a7ad62 24aufs3.8 base patch
7f207e10 25
537831f9 26diff --git a/fs/file_table.c b/fs/file_table.c
1716fcea 27index de9e965..e73287a 100644
537831f9
AM
28--- a/fs/file_table.c
29+++ b/fs/file_table.c
30@@ -36,7 +36,7 @@ struct files_stat_struct files_stat = {
31 .max_files = NR_FILE
32 };
33
34-DEFINE_STATIC_LGLOCK(files_lglock);
35+DEFINE_LGLOCK(files_lglock);
36
37 /* SLAB cache for file structures */
38 static struct kmem_cache *filp_cachep __read_mostly;
0c3ec466 39diff --git a/fs/inode.c b/fs/inode.c
1716fcea 40index 14084b7..ece87ed 100644
0c3ec466
AM
41--- a/fs/inode.c
42+++ b/fs/inode.c
7a9e40b8 43@@ -1503,7 +1503,7 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
0c3ec466
AM
44 * This does the actual work of updating an inodes time or version. Must have
45 * had called mnt_want_write() before calling this.
46 */
47-static int update_time(struct inode *inode, struct timespec *time, int flags)
48+int update_time(struct inode *inode, struct timespec *time, int flags)
49 {
50 if (inode->i_op->update_time)
51 return inode->i_op->update_time(inode, time, flags);
7f207e10 52diff --git a/fs/splice.c b/fs/splice.c
1716fcea 53index 6909d89..020c7bc 100644
7f207e10
AM
54--- a/fs/splice.c
55+++ b/fs/splice.c
1716fcea 56@@ -1092,8 +1092,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
7f207e10
AM
57 /*
58 * Attempt to initiate a splice from pipe to file.
59 */
60-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
61- loff_t *ppos, size_t len, unsigned int flags)
62+long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
63+ loff_t *ppos, size_t len, unsigned int flags)
64 {
65 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
66 loff_t *, size_t, unsigned int);
1716fcea 67@@ -1120,9 +1120,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
7f207e10
AM
68 /*
69 * Attempt to initiate a splice from a file to a pipe.
70 */
71-static long do_splice_to(struct file *in, loff_t *ppos,
72- struct pipe_inode_info *pipe, size_t len,
73- unsigned int flags)
74+long do_splice_to(struct file *in, loff_t *ppos,
75+ struct pipe_inode_info *pipe, size_t len,
76+ unsigned int flags)
77 {
78 ssize_t (*splice_read)(struct file *, loff_t *,
79 struct pipe_inode_info *, size_t, unsigned int);
0c3ec466 80diff --git a/include/linux/fs.h b/include/linux/fs.h
1716fcea 81index 7617ee0..1a39c33 100644
0c3ec466
AM
82--- a/include/linux/fs.h
83+++ b/include/linux/fs.h
1716fcea 84@@ -2551,6 +2551,7 @@ extern int inode_change_ok(const struct inode *, struct iattr *);
0c3ec466
AM
85 extern int inode_newsize_ok(const struct inode *, loff_t offset);
86 extern void setattr_copy(struct inode *inode, const struct iattr *attr);
87
88+extern int update_time(struct inode *, struct timespec *, int);
89 extern int file_update_time(struct file *file);
90
91 extern int generic_show_options(struct seq_file *m, struct dentry *root);
1e00d052 92diff --git a/include/linux/splice.h b/include/linux/splice.h
2dfbb274 93index 09a545a..1ac5727 100644
1e00d052
AM
94--- a/include/linux/splice.h
95+++ b/include/linux/splice.h
2dfbb274 96@@ -91,4 +91,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *);
4b3da204
AM
97 extern void spd_release_page(struct splice_pipe_desc *, unsigned int);
98
99 extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
1e00d052
AM
100+
101+extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
102+ loff_t *ppos, size_t len, unsigned int flags);
103+extern long do_splice_to(struct file *in, loff_t *ppos,
104+ struct pipe_inode_info *pipe, size_t len,
105+ unsigned int flags);
106 #endif
a2a7ad62 107aufs3.8 standalone patch
7f207e10
AM
108
109diff --git a/fs/file_table.c b/fs/file_table.c
1716fcea 110index e73287a..b33aebe 100644
7f207e10
AM
111--- a/fs/file_table.c
112+++ b/fs/file_table.c
b4510431 113@@ -37,6 +37,7 @@ struct files_stat_struct files_stat = {
0c3ec466
AM
114 };
115
116 DEFINE_LGLOCK(files_lglock);
117+EXPORT_SYMBOL(files_lglock);
118
119 /* SLAB cache for file structures */
120 static struct kmem_cache *filp_cachep __read_mostly;
537831f9 121@@ -403,6 +404,8 @@ void file_sb_list_del(struct file *file)
7f207e10
AM
122 }
123 }
124
125+EXPORT_SYMBOL(file_sb_list_del);
1facf9fc 126+
7f207e10
AM
127 #ifdef CONFIG_SMP
128
129 /*
1e00d052 130diff --git a/fs/inode.c b/fs/inode.c
1716fcea 131index ece87ed..38f7bc8 100644
1e00d052
AM
132--- a/fs/inode.c
133+++ b/fs/inode.c
92d182d2 134@@ -56,6 +56,7 @@ static struct hlist_head *inode_hashtable __read_mostly;
4b3da204 135 static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock);
2cbb1c4b
JR
136
137 __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock);
2cbb1c4b 138+EXPORT_SYMBOL(inode_sb_list_lock);
7f207e10
AM
139
140 /*
4b3da204 141 * Empty aops. Can be used for the cases where the user does not
7a9e40b8 142@@ -1519,6 +1520,7 @@ int update_time(struct inode *inode, struct timespec *time, int flags)
0c3ec466
AM
143 mark_inode_dirty_sync(inode);
144 return 0;
145 }
146+EXPORT_SYMBOL(update_time);
147
148 /**
149 * touch_atime - update the access time
7f207e10 150diff --git a/fs/namespace.c b/fs/namespace.c
1716fcea 151index 55605c5..aed7607 100644
7f207e10
AM
152--- a/fs/namespace.c
153+++ b/fs/namespace.c
1716fcea 154@@ -52,6 +52,7 @@ EXPORT_SYMBOL_GPL(fs_kobj);
0c3ec466
AM
155 * tree or hash is modified or when a vfsmount structure is modified.
156 */
157 DEFINE_BRLOCK(vfsmount_lock);
158+EXPORT_SYMBOL(vfsmount_lock);
159
160 static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
161 {
1716fcea 162@@ -1424,6 +1425,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
7f207e10
AM
163 }
164 return 0;
165 }
166+EXPORT_SYMBOL(iterate_mounts);
167
7eafdf33 168 static void cleanup_group_ids(struct mount *mnt, struct mount *end)
7f207e10
AM
169 {
170diff --git a/fs/notify/group.c b/fs/notify/group.c
1716fcea 171index bd2625b..2ff2a0f 100644
7f207e10
AM
172--- a/fs/notify/group.c
173+++ b/fs/notify/group.c
174@@ -22,6 +22,7 @@
175 #include <linux/srcu.h>
176 #include <linux/rculist.h>
177 #include <linux/wait.h>
178+#include <linux/module.h>
179
180 #include <linux/fsnotify_backend.h>
181 #include "fsnotify.h"
1716fcea
AM
182@@ -65,6 +66,7 @@ void fsnotify_get_group(struct fsnotify_group *group)
183 {
184 atomic_inc(&group->refcnt);
185 }
186+EXPORT_SYMBOL(fsnotify_get_group);
187
188 /*
189 * Drop a reference to a group. Free it if it's through.
190@@ -74,6 +76,7 @@ void fsnotify_put_group(struct fsnotify_group *group)
7f207e10 191 if (atomic_dec_and_test(&group->refcnt))
1716fcea 192 fsnotify_final_destroy_group(group);
7f207e10
AM
193 }
194+EXPORT_SYMBOL(fsnotify_put_group);
195
196 /*
197 * Create a new fsnotify_group and hold a reference for the group returned.
1716fcea 198@@ -102,6 +105,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
7f207e10
AM
199
200 return group;
201 }
202+EXPORT_SYMBOL(fsnotify_alloc_group);
1716fcea
AM
203
204 int fsnotify_fasync(int fd, struct file *file, int on)
205 {
7f207e10 206diff --git a/fs/notify/mark.c b/fs/notify/mark.c
1716fcea 207index fc6b49b..a6bb87d 100644
7f207e10
AM
208--- a/fs/notify/mark.c
209+++ b/fs/notify/mark.c
1716fcea 210@@ -115,6 +115,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
7f207e10 211 mark->free_mark(mark);
1716fcea 212 }
7f207e10
AM
213 }
214+EXPORT_SYMBOL(fsnotify_put_mark);
215
216 /*
217 * Any time a mark is getting freed we end up here.
1716fcea
AM
218@@ -197,6 +198,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark,
219 fsnotify_destroy_mark_locked(mark, group);
220 mutex_unlock(&group->mark_mutex);
7f207e10
AM
221 }
222+EXPORT_SYMBOL(fsnotify_destroy_mark);
223
224 void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask)
225 {
1716fcea 226@@ -281,6 +283,7 @@ err:
7f207e10
AM
227
228 return ret;
229 }
230+EXPORT_SYMBOL(fsnotify_add_mark);
231
1716fcea
AM
232 int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
233 struct inode *inode, struct vfsmount *mnt, int allow_dups)
234@@ -342,6 +345,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
7f207e10
AM
235 atomic_set(&mark->refcnt, 1);
236 mark->free_mark = free_mark;
237 }
238+EXPORT_SYMBOL(fsnotify_init_mark);
239
240 static int fsnotify_mark_destroy(void *ignored)
241 {
242diff --git a/fs/open.c b/fs/open.c
1716fcea 243index 9b33c0c..e3365035 100644
7f207e10
AM
244--- a/fs/open.c
245+++ b/fs/open.c
246@@ -60,6 +60,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
247 mutex_unlock(&dentry->d_inode->i_mutex);
248 return ret;
249 }
250+EXPORT_SYMBOL(do_truncate);
251
1716fcea 252 long vfs_truncate(struct path *path, loff_t length)
7f207e10
AM
253 {
254diff --git a/fs/splice.c b/fs/splice.c
1716fcea 255index 020c7bc..a622ade 100644
7f207e10
AM
256--- a/fs/splice.c
257+++ b/fs/splice.c
1716fcea 258@@ -1116,6 +1116,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
7f207e10
AM
259
260 return splice_write(pipe, out, ppos, len, flags);
261 }
262+EXPORT_SYMBOL(do_splice_from);
263
264 /*
265 * Attempt to initiate a splice from a file to a pipe.
1716fcea 266@@ -1142,6 +1143,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
7f207e10
AM
267
268 return splice_read(in, ppos, pipe, len, flags);
269 }
270+EXPORT_SYMBOL(do_splice_to);
271
272 /**
273 * splice_direct_to_actor - splices data directly between two non-pipes
274diff --git a/security/commoncap.c b/security/commoncap.c
1716fcea 275index 7ee08c7..176edf1 100644
7f207e10
AM
276--- a/security/commoncap.c
277+++ b/security/commoncap.c
1716fcea 278@@ -988,9 +988,11 @@ int cap_mmap_addr(unsigned long addr)
94337f0d 279 }
7f207e10
AM
280 return ret;
281 }
0c3ec466
AM
282+EXPORT_SYMBOL(cap_mmap_addr);
283
284 int cap_mmap_file(struct file *file, unsigned long reqprot,
285 unsigned long prot, unsigned long flags)
286 {
287 return 0;
288 }
289+EXPORT_SYMBOL(cap_mmap_file);
7f207e10 290diff --git a/security/device_cgroup.c b/security/device_cgroup.c
1716fcea 291index d794abc..a20f167 100644
7f207e10
AM
292--- a/security/device_cgroup.c
293+++ b/security/device_cgroup.c
f6c5ef8b
AM
294@@ -7,6 +7,7 @@
295 #include <linux/device_cgroup.h>
296 #include <linux/cgroup.h>
297 #include <linux/ctype.h>
298+#include <linux/export.h>
299 #include <linux/list.h>
300 #include <linux/uaccess.h>
301 #include <linux/seq_file.h>
1716fcea 302@@ -631,6 +632,7 @@ int __devcgroup_inode_permission(struct inode *inode, int mask)
537831f9
AM
303 return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
304 access);
7f207e10 305 }
2cbb1c4b 306+EXPORT_SYMBOL(__devcgroup_inode_permission);
7f207e10
AM
307
308 int devcgroup_inode_mknod(int mode, dev_t dev)
309 {
310diff --git a/security/security.c b/security/security.c
1716fcea 311index 7b88c6a..5d00a30 100644
7f207e10
AM
312--- a/security/security.c
313+++ b/security/security.c
537831f9 314@@ -396,6 +396,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry)
7f207e10
AM
315 return 0;
316 return security_ops->path_rmdir(dir, dentry);
317 }
318+EXPORT_SYMBOL(security_path_rmdir);
319
320 int security_path_unlink(struct path *dir, struct dentry *dentry)
321 {
537831f9 322@@ -412,6 +413,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry,
7f207e10
AM
323 return 0;
324 return security_ops->path_symlink(dir, dentry, old_name);
325 }
326+EXPORT_SYMBOL(security_path_symlink);
327
328 int security_path_link(struct dentry *old_dentry, struct path *new_dir,
329 struct dentry *new_dentry)
537831f9 330@@ -420,6 +422,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
7f207e10
AM
331 return 0;
332 return security_ops->path_link(old_dentry, new_dir, new_dentry);
333 }
334+EXPORT_SYMBOL(security_path_link);
335
336 int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
337 struct path *new_dir, struct dentry *new_dentry)
537831f9 338@@ -438,6 +441,7 @@ int security_path_truncate(struct path *path)
7f207e10
AM
339 return 0;
340 return security_ops->path_truncate(path);
341 }
342+EXPORT_SYMBOL(security_path_truncate);
343
7eafdf33
AM
344 int security_path_chmod(struct path *path, umode_t mode)
345 {
537831f9 346@@ -445,6 +449,7 @@ int security_path_chmod(struct path *path, umode_t mode)
7f207e10 347 return 0;
7eafdf33 348 return security_ops->path_chmod(path, mode);
7f207e10
AM
349 }
350+EXPORT_SYMBOL(security_path_chmod);
351
537831f9 352 int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
7f207e10 353 {
537831f9 354@@ -452,6 +457,7 @@ int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
7f207e10
AM
355 return 0;
356 return security_ops->path_chown(path, uid, gid);
357 }
358+EXPORT_SYMBOL(security_path_chown);
359
360 int security_path_chroot(struct path *path)
361 {
537831f9 362@@ -528,6 +534,7 @@ int security_inode_readlink(struct dentry *dentry)
7f207e10
AM
363 return 0;
364 return security_ops->inode_readlink(dentry);
365 }
366+EXPORT_SYMBOL(security_inode_readlink);
367
368 int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
369 {
537831f9 370@@ -542,6 +549,7 @@ int security_inode_permission(struct inode *inode, int mask)
7f207e10 371 return 0;
1e00d052 372 return security_ops->inode_permission(inode, mask);
7f207e10
AM
373 }
374+EXPORT_SYMBOL(security_inode_permission);
375
1e00d052 376 int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
7f207e10 377 {
537831f9 378@@ -663,6 +671,7 @@ int security_file_permission(struct file *file, int mask)
7f207e10
AM
379
380 return fsnotify_perm(file, mask);
381 }
382+EXPORT_SYMBOL(security_file_permission);
383
384 int security_file_alloc(struct file *file)
385 {
537831f9 386@@ -723,6 +732,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
7f207e10
AM
387 return ret;
388 return ima_file_mmap(file, prot);
389 }
0c3ec466 390+EXPORT_SYMBOL(security_mmap_file);
7f207e10 391
0c3ec466
AM
392 int security_mmap_addr(unsigned long addr)
393 {
7f207e10
AM
394diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs
395--- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100
7a9e40b8 396+++ linux/Documentation/ABI/testing/debugfs-aufs 2012-08-26 08:39:00.753841216 +0200
7f207e10
AM
397@@ -0,0 +1,37 @@
398+What: /debug/aufs/si_<id>/
399+Date: March 2009
400+Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
401+Description:
402+ Under /debug/aufs, a directory named si_<id> is created
403+ per aufs mount, where <id> is a unique id generated
404+ internally.
1facf9fc 405+
7f207e10
AM
406+What: /debug/aufs/si_<id>/xib
407+Date: March 2009
408+Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
409+Description:
410+ It shows the consumed blocks by xib (External Inode Number
411+ Bitmap), its block size and file size.
412+ When the aufs mount option 'noxino' is specified, it
413+ will be empty. About XINO files, see the aufs manual.
414+
415+What: /debug/aufs/si_<id>/xino0, xino1 ... xinoN
416+Date: March 2009
417+Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
418+Description:
419+ It shows the consumed blocks by xino (External Inode Number
420+ Translation Table), its link count, block size and file
421+ size.
422+ When the aufs mount option 'noxino' is specified, it
423+ will be empty. About XINO files, see the aufs manual.
424+
425+What: /debug/aufs/si_<id>/xigen
426+Date: March 2009
427+Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
428+Description:
429+ It shows the consumed blocks by xigen (External Inode
430+ Generation Table), its block size and file size.
431+ If CONFIG_AUFS_EXPORT is disabled, this entry will not
432+ be created.
433+ When the aufs mount option 'noxino' is specified, it
434+ will be empty. About XINO files, see the aufs manual.
435diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs
436--- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100
7a9e40b8 437+++ linux/Documentation/ABI/testing/sysfs-aufs 2012-08-26 08:39:00.753841216 +0200
7f207e10
AM
438@@ -0,0 +1,24 @@
439+What: /sys/fs/aufs/si_<id>/
440+Date: March 2009
441+Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
442+Description:
443+ Under /sys/fs/aufs, a directory named si_<id> is created
444+ per aufs mount, where <id> is a unique id generated
445+ internally.
446+
447+What: /sys/fs/aufs/si_<id>/br0, br1 ... brN
448+Date: March 2009
449+Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
450+Description:
451+ It shows the abolute path of a member directory (which
452+ is called branch) in aufs, and its permission.
453+
454+What: /sys/fs/aufs/si_<id>/xi_path
455+Date: March 2009
456+Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
457+Description:
458+ It shows the abolute path of XINO (External Inode Number
459+ Bitmap, Translation Table and Generation Table) file
460+ even if it is the default path.
461+ When the aufs mount option 'noxino' is specified, it
462+ will be empty. About XINO files, see the aufs manual.
53392da6
AM
463diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt
464--- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 01:00:00.000000000 +0100
1716fcea 465+++ linux/Documentation/filesystems/aufs/design/01intro.txt 2013-02-19 08:40:03.943559493 +0100
53392da6
AM
466@@ -0,0 +1,162 @@
467+
7a9e40b8 468+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
469+#
470+# This program is free software; you can redistribute it and/or modify
471+# it under the terms of the GNU General Public License as published by
472+# the Free Software Foundation; either version 2 of the License, or
473+# (at your option) any later version.
474+#
475+# This program is distributed in the hope that it will be useful,
476+# but WITHOUT ANY WARRANTY; without even the implied warranty of
477+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
478+# GNU General Public License for more details.
479+#
480+# You should have received a copy of the GNU General Public License
481+# along with this program; if not, write to the Free Software
482+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
483+
484+Introduction
485+----------------------------------------
486+
487+aufs [ei ju: ef es] | [a u f s]
488+1. abbrev. for "advanced multi-layered unification filesystem".
489+2. abbrev. for "another unionfs".
490+3. abbrev. for "auf das" in German which means "on the" in English.
491+ Ex. "Butter aufs Brot"(G) means "butter onto bread"(E).
492+ But "Filesystem aufs Filesystem" is hard to understand.
493+
494+AUFS is a filesystem with features:
495+- multi layered stackable unification filesystem, the member directory
496+ is called as a branch.
497+- branch permission and attribute, 'readonly', 'real-readonly',
498+ 'readwrite', 'whiteout-able', 'link-able whiteout' and their
499+ combination.
500+- internal "file copy-on-write".
501+- logical deletion, whiteout.
502+- dynamic branch manipulation, adding, deleting and changing permission.
503+- allow bypassing aufs, user's direct branch access.
504+- external inode number translation table and bitmap which maintains the
505+ persistent aufs inode number.
506+- seekable directory, including NFS readdir.
507+- file mapping, mmap and sharing pages.
508+- pseudo-link, hardlink over branches.
509+- loopback mounted filesystem as a branch.
510+- several policies to select one among multiple writable branches.
511+- revert a single systemcall when an error occurs in aufs.
512+- and more...
513+
514+
515+Multi Layered Stackable Unification Filesystem
516+----------------------------------------------------------------------
517+Most people already knows what it is.
518+It is a filesystem which unifies several directories and provides a
519+merged single directory. When users access a file, the access will be
520+passed/re-directed/converted (sorry, I am not sure which English word is
521+correct) to the real file on the member filesystem. The member
522+filesystem is called 'lower filesystem' or 'branch' and has a mode
523+'readonly' and 'readwrite.' And the deletion for a file on the lower
524+readonly branch is handled by creating 'whiteout' on the upper writable
525+branch.
526+
527+On LKML, there have been discussions about UnionMount (Jan Blunck,
528+Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took
529+different approaches to implement the merged-view.
530+The former tries putting it into VFS, and the latter implements as a
531+separate filesystem.
532+(If I misunderstand about these implementations, please let me know and
533+I shall correct it. Because it is a long time ago when I read their
534+source files last time).
535+
536+UnionMount's approach will be able to small, but may be hard to share
537+branches between several UnionMount since the whiteout in it is
538+implemented in the inode on branch filesystem and always
539+shared. According to Bharata's post, readdir does not seems to be
540+finished yet.
541+There are several missing features known in this implementations such as
542+- for users, the inode number may change silently. eg. copy-up.
543+- link(2) may break by copy-up.
544+- read(2) may get an obsoleted filedata (fstat(2) too).
545+- fcntl(F_SETLK) may be broken by copy-up.
546+- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
547+ open(O_RDWR).
548+
549+Unionfs has a longer history. When I started implementing a stacking filesystem
550+(Aug 2005), it already existed. It has virtual super_block, inode,
551+dentry and file objects and they have an array pointing lower same kind
552+objects. After contributing many patches for Unionfs, I re-started my
553+project AUFS (Jun 2006).
554+
555+In AUFS, the structure of filesystem resembles to Unionfs, but I
556+implemented my own ideas, approaches and enhancements and it became
557+totally different one.
558+
559+Comparing DM snapshot and fs based implementation
560+- the number of bytes to be copied between devices is much smaller.
561+- the type of filesystem must be one and only.
562+- the fs must be writable, no readonly fs, even for the lower original
563+ device. so the compression fs will not be usable. but if we use
564+ loopback mount, we may address this issue.
565+ for instance,
566+ mount /cdrom/squashfs.img /sq
567+ losetup /sq/ext2.img
568+ losetup /somewhere/cow
569+ dmsetup "snapshot /dev/loop0 /dev/loop1 ..."
570+- it will be difficult (or needs more operations) to extract the
571+ difference between the original device and COW.
572+- DM snapshot-merge may help a lot when users try merging. in the
573+ fs-layer union, users will use rsync(1).
574+
575+
576+Several characters/aspects of aufs
577+----------------------------------------------------------------------
578+
579+Aufs has several characters or aspects.
580+1. a filesystem, callee of VFS helper
581+2. sub-VFS, caller of VFS helper for branches
582+3. a virtual filesystem which maintains persistent inode number
583+4. reader/writer of files on branches such like an application
584+
585+1. Callee of VFS Helper
586+As an ordinary linux filesystem, aufs is a callee of VFS. For instance,
587+unlink(2) from an application reaches sys_unlink() kernel function and
588+then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it
589+calls filesystem specific unlink operation. Actually aufs implements the
590+unlink operation but it behaves like a redirector.
591+
592+2. Caller of VFS Helper for Branches
593+aufs_unlink() passes the unlink request to the branch filesystem as if
594+it were called from VFS. So the called unlink operation of the branch
595+filesystem acts as usual. As a caller of VFS helper, aufs should handle
596+every necessary pre/post operation for the branch filesystem.
597+- acquire the lock for the parent dir on a branch
598+- lookup in a branch
599+- revalidate dentry on a branch
600+- mnt_want_write() for a branch
601+- vfs_unlink() for a branch
602+- mnt_drop_write() for a branch
603+- release the lock on a branch
604+
605+3. Persistent Inode Number
606+One of the most important issue for a filesystem is to maintain inode
607+numbers. This is particularly important to support exporting a
608+filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
609+backend block device for its own. But some storage is necessary to
610+maintain inode number. It may be a large space and may not suit to keep
611+in memory. Aufs rents some space from its first writable branch
612+filesystem (by default) and creates file(s) on it. These files are
613+created by aufs internally and removed soon (currently) keeping opened.
614+Note: Because these files are removed, they are totally gone after
615+ unmounting aufs. It means the inode numbers are not persistent
616+ across unmount or reboot. I have a plan to make them really
617+ persistent which will be important for aufs on NFS server.
618+
619+4. Read/Write Files Internally (copy-on-write)
620+Because a branch can be readonly, when you write a file on it, aufs will
621+"copy-up" it to the upper writable branch internally. And then write the
622+originally requested thing to the file. Generally kernel doesn't
623+open/read/write file actively. In aufs, even a single write may cause a
624+internal "file copy". This behaviour is very similar to cp(1) command.
625+
626+Some people may think it is better to pass such work to user space
627+helper, instead of doing in kernel space. Actually I am still thinking
628+about it. But currently I have implemented it in kernel space.
629diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt linux/Documentation/filesystems/aufs/design/02struct.txt
630--- /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100
1716fcea 631+++ linux/Documentation/filesystems/aufs/design/02struct.txt 2013-02-19 08:40:03.943559493 +0100
53392da6
AM
632@@ -0,0 +1,226 @@
633+
7a9e40b8 634+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
635+#
636+# This program is free software; you can redistribute it and/or modify
637+# it under the terms of the GNU General Public License as published by
638+# the Free Software Foundation; either version 2 of the License, or
639+# (at your option) any later version.
640+#
641+# This program is distributed in the hope that it will be useful,
642+# but WITHOUT ANY WARRANTY; without even the implied warranty of
643+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
644+# GNU General Public License for more details.
645+#
646+# You should have received a copy of the GNU General Public License
647+# along with this program; if not, write to the Free Software
648+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
649+
650+Basic Aufs Internal Structure
651+
652+Superblock/Inode/Dentry/File Objects
653+----------------------------------------------------------------------
654+As like an ordinary filesystem, aufs has its own
655+superblock/inode/dentry/file objects. All these objects have a
656+dynamically allocated array and store the same kind of pointers to the
657+lower filesystem, branch.
658+For example, when you build a union with one readwrite branch and one
659+readonly, mounted /au, /rw and /ro respectively.
660+- /au = /rw + /ro
661+- /ro/fileA exists but /rw/fileA
662+
663+Aufs lookup operation finds /ro/fileA and gets dentry for that. These
664+pointers are stored in a aufs dentry. The array in aufs dentry will be,
665+- [0] = NULL
666+- [1] = /ro/fileA
667+
668+This style of an array is essentially same to the aufs
669+superblock/inode/dentry/file objects.
670+
671+Because aufs supports manipulating branches, ie. add/delete/change
672+dynamically, these objects has its own generation. When branches are
673+changed, the generation in aufs superblock is incremented. And a
674+generation in other object are compared when it is accessed.
675+When a generation in other objects are obsoleted, aufs refreshes the
676+internal array.
677+
678+
679+Superblock
680+----------------------------------------------------------------------
681+Additionally aufs superblock has some data for policies to select one
682+among multiple writable branches, XIB files, pseudo-links and kobject.
683+See below in detail.
684+About the policies which supports copy-down a directory, see policy.txt
685+too.
686+
687+
688+Branch and XINO(External Inode Number Translation Table)
689+----------------------------------------------------------------------
690+Every branch has its own xino (external inode number translation table)
691+file. The xino file is created and unlinked by aufs internally. When two
692+members of a union exist on the same filesystem, they share the single
693+xino file.
694+The struct of a xino file is simple, just a sequence of aufs inode
695+numbers which is indexed by the lower inode number.
696+In the above sample, assume the inode number of /ro/fileA is i111 and
697+aufs assigns the inode number i999 for fileA. Then aufs writes 999 as
698+4(8) bytes at 111 * 4(8) bytes offset in the xino file.
699+
700+When the inode numbers are not contiguous, the xino file will be sparse
701+which has a hole in it and doesn't consume as much disk space as it
702+might appear. If your branch filesystem consumes disk space for such
703+holes, then you should specify 'xino=' option at mounting aufs.
704+
705+Also a writable branch has three kinds of "whiteout bases". All these
706+are existed when the branch is joined to aufs and the names are
707+whiteout-ed doubly, so that users will never see their names in aufs
708+hierarchy.
709+1. a regular file which will be linked to all whiteouts.
710+2. a directory to store a pseudo-link.
711+3. a directory to store an "orphan-ed" file temporary.
712+
713+1. Whiteout Base
714+ When you remove a file on a readonly branch, aufs handles it as a
715+ logical deletion and creates a whiteout on the upper writable branch
716+ as a hardlink of this file in order not to consume inode on the
717+ writable branch.
718+2. Pseudo-link Dir
719+ See below, Pseudo-link.
720+3. Step-Parent Dir
721+ When "fileC" exists on the lower readonly branch only and it is
722+ opened and removed with its parent dir, and then user writes
723+ something into it, then aufs copies-up fileC to this
724+ directory. Because there is no other dir to store fileC. After
725+ creating a file under this dir, the file is unlinked.
726+
727+Because aufs supports manipulating branches, ie. add/delete/change
728+dynamically, a branch has its own id. When the branch order changes, aufs
729+finds the new index by searching the branch id.
730+
731+
732+Pseudo-link
733+----------------------------------------------------------------------
734+Assume "fileA" exists on the lower readonly branch only and it is
735+hardlinked to "fileB" on the branch. When you write something to fileA,
736+aufs copies-up it to the upper writable branch. Additionally aufs
737+creates a hardlink under the Pseudo-link Directory of the writable
738+branch. The inode of a pseudo-link is kept in aufs super_block as a
739+simple list. If fileB is read after unlinking fileA, aufs returns
740+filedata from the pseudo-link instead of the lower readonly
741+branch. Because the pseudo-link is based upon the inode, to keep the
742+inode number by xino (see above) is important.
743+
744+All the hardlinks under the Pseudo-link Directory of the writable branch
745+should be restored in a proper location later. Aufs provides a utility
746+to do this. The userspace helpers executed at remounting and unmounting
747+aufs by default.
748+During this utility is running, it puts aufs into the pseudo-link
749+maintenance mode. In this mode, only the process which began the
750+maintenance mode (and its child processes) is allowed to operate in
751+aufs. Some other processes which are not related to the pseudo-link will
752+be allowed to run too, but the rest have to return an error or wait
753+until the maintenance mode ends. If a process already acquires an inode
754+mutex (in VFS), it has to return an error.
755+
756+
757+XIB(external inode number bitmap)
758+----------------------------------------------------------------------
759+Addition to the xino file per a branch, aufs has an external inode number
760+bitmap in a superblock object. It is also a file such like a xino file.
761+It is a simple bitmap to mark whether the aufs inode number is in-use or
762+not.
763+To reduce the file I/O, aufs prepares a single memory page to cache xib.
764+
765+Aufs implements a feature to truncate/refresh both of xino and xib to
766+reduce the number of consumed disk blocks for these files.
767+
768+
769+Virtual or Vertical Dir, and Readdir in Userspace
770+----------------------------------------------------------------------
771+In order to support multiple layers (branches), aufs readdir operation
772+constructs a virtual dir block on memory. For readdir, aufs calls
773+vfs_readdir() internally for each dir on branches, merges their entries
774+with eliminating the whiteout-ed ones, and sets it to file (dir)
775+object. So the file object has its entry list until it is closed. The
776+entry list will be updated when the file position is zero and becomes
777+old. This decision is made in aufs automatically.
778+
779+The dynamically allocated memory block for the name of entries has a
780+unit of 512 bytes (by default) and stores the names contiguously (no
781+padding). Another block for each entry is handled by kmem_cache too.
782+During building dir blocks, aufs creates hash list and judging whether
783+the entry is whiteouted by its upper branch or already listed.
784+The merged result is cached in the corresponding inode object and
785+maintained by a customizable life-time option.
786+
787+Some people may call it can be a security hole or invite DoS attack
788+since the opened and once readdir-ed dir (file object) holds its entry
789+list and becomes a pressure for system memory. But I'd say it is similar
790+to files under /proc or /sys. The virtual files in them also holds a
791+memory page (generally) while they are opened. When an idea to reduce
792+memory for them is introduced, it will be applied to aufs too.
793+For those who really hate this situation, I've developed readdir(3)
794+library which operates this merging in userspace. You just need to set
795+LD_PRELOAD environment variable, and aufs will not consume no memory in
796+kernel space for readdir(3).
797+
798+
799+Workqueue
800+----------------------------------------------------------------------
801+Aufs sometimes requires privilege access to a branch. For instance,
802+in copy-up/down operation. When a user process is going to make changes
803+to a file which exists in the lower readonly branch only, and the mode
804+of one of ancestor directories may not be writable by a user
805+process. Here aufs copy-up the file with its ancestors and they may
806+require privilege to set its owner/group/mode/etc.
807+This is a typical case of a application character of aufs (see
808+Introduction).
809+
810+Aufs uses workqueue synchronously for this case. It creates its own
811+workqueue. The workqueue is a kernel thread and has privilege. Aufs
812+passes the request to call mkdir or write (for example), and wait for
813+its completion. This approach solves a problem of a signal handler
814+simply.
815+If aufs didn't adopt the workqueue and changed the privilege of the
816+process, and if the mkdir/write call arises SIGXFSZ or other signal,
817+then the user process might gain a privilege or the generated core file
818+was owned by a superuser.
819+
820+Also aufs uses the system global workqueue ("events" kernel thread) too
821+for asynchronous tasks, such like handling inotify/fsnotify, re-creating a
822+whiteout base and etc. This is unrelated to a privilege.
823+Most of aufs operation tries acquiring a rw_semaphore for aufs
824+superblock at the beginning, at the same time waits for the completion
825+of all queued asynchronous tasks.
826+
827+
828+Whiteout
829+----------------------------------------------------------------------
830+The whiteout in aufs is very similar to Unionfs's. That is represented
831+by its filename. UnionMount takes an approach of a file mode, but I am
832+afraid several utilities (find(1) or something) will have to support it.
833+
834+Basically the whiteout represents "logical deletion" which stops aufs to
835+lookup further, but also it represents "dir is opaque" which also stop
836+lookup.
837+
838+In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively.
839+In order to make several functions in a single systemcall to be
840+revertible, aufs adopts an approach to rename a directory to a temporary
841+unique whiteouted name.
842+For example, in rename(2) dir where the target dir already existed, aufs
843+renames the target dir to a temporary unique whiteouted name before the
844+actual rename on a branch and then handles other actions (make it opaque,
845+update the attributes, etc). If an error happens in these actions, aufs
846+simply renames the whiteouted name back and returns an error. If all are
847+succeeded, aufs registers a function to remove the whiteouted unique
848+temporary name completely and asynchronously to the system global
849+workqueue.
850+
851+
852+Copy-up
853+----------------------------------------------------------------------
854+It is a well-known feature or concept.
855+When user modifies a file on a readonly branch, aufs operate "copy-up"
856+internally and makes change to the new file on the upper writable branch.
857+When the trigger systemcall does not update the timestamps of the parent
858+dir, aufs reverts it after copy-up.
859diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt
860--- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100
1716fcea 861+++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2013-02-19 08:40:03.943559493 +0100
53392da6
AM
862@@ -0,0 +1,106 @@
863+
7a9e40b8 864+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
865+#
866+# This program is free software; you can redistribute it and/or modify
867+# it under the terms of the GNU General Public License as published by
868+# the Free Software Foundation; either version 2 of the License, or
869+# (at your option) any later version.
870+#
871+# This program is distributed in the hope that it will be useful,
872+# but WITHOUT ANY WARRANTY; without even the implied warranty of
873+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
874+# GNU General Public License for more details.
875+#
876+# You should have received a copy of the GNU General Public License
877+# along with this program; if not, write to the Free Software
878+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
879+
880+Lookup in a Branch
881+----------------------------------------------------------------------
882+Since aufs has a character of sub-VFS (see Introduction), it operates
883+lookup for branches as VFS does. It may be a heavy work. Generally
884+speaking struct nameidata is a bigger structure and includes many
885+information. But almost all lookup operation in aufs is the simplest
886+case, ie. lookup only an entry directly connected to its parent. Digging
887+down the directory hierarchy is unnecessary.
888+
889+VFS has a function lookup_one_len() for that use, but it is not usable
890+for a branch filesystem which requires struct nameidata. So aufs
891+implements a simple lookup wrapper function. When a branch filesystem
892+allows NULL as nameidata, it calls lookup_one_len(). Otherwise it builds
893+a simplest nameidata and calls lookup_hash().
894+Here aufs applies "a principle in NFSD", ie. if the filesystem supports
895+NFS-export, then it has to support NULL as a nameidata parameter for
896+->create(), ->lookup() and ->d_revalidate(). So the lookup wrapper in
897+aufs tests if ->s_export_op in the branch is NULL or not.
898+
899+When a branch is a remote filesystem, aufs basically trusts its
900+->d_revalidate(), also aufs forces the hardest revalidate tests for
901+them.
902+For d_revalidate, aufs implements three levels of revalidate tests. See
903+"Revalidate Dentry and UDBA" in detail.
904+
905+
906+Loopback Mount
907+----------------------------------------------------------------------
908+Basically aufs supports any type of filesystem and block device for a
909+branch (actually there are some exceptions). But it is prohibited to add
910+a loopback mounted one whose backend file exists in a filesystem which is
911+already added to aufs. The reason is to protect aufs from a recursive
912+lookup. If it was allowed, the aufs lookup operation might re-enter a
913+lookup for the loopback mounted branch in the same context, and will
914+cause a deadlock.
915+
916+
917+Revalidate Dentry and UDBA (User's Direct Branch Access)
918+----------------------------------------------------------------------
919+Generally VFS helpers re-validate a dentry as a part of lookup.
920+0. digging down the directory hierarchy.
921+1. lock the parent dir by its i_mutex.
922+2. lookup the final (child) entry.
923+3. revalidate it.
924+4. call the actual operation (create, unlink, etc.)
925+5. unlock the parent dir
926+
927+If the filesystem implements its ->d_revalidate() (step 3), then it is
928+called. Actually aufs implements it and checks the dentry on a branch is
929+still valid.
930+But it is not enough. Because aufs has to release the lock for the
931+parent dir on a branch at the end of ->lookup() (step 2) and
932+->d_revalidate() (step 3) while the i_mutex of the aufs dir is still
933+held by VFS.
934+If the file on a branch is changed directly, eg. bypassing aufs, after
935+aufs released the lock, then the subsequent operation may cause
936+something unpleasant result.
937+
938+This situation is a result of VFS architecture, ->lookup() and
939+->d_revalidate() is separated. But I never say it is wrong. It is a good
940+design from VFS's point of view. It is just not suitable for sub-VFS
941+character in aufs.
942+
943+Aufs supports such case by three level of revalidation which is
944+selectable by user.
945+1. Simple Revalidate
946+ Addition to the native flow in VFS's, confirm the child-parent
947+ relationship on the branch just after locking the parent dir on the
948+ branch in the "actual operation" (step 4). When this validation
949+ fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still
950+ checks the validation of the dentry on branches.
951+2. Monitor Changes Internally by Inotify/Fsnotify
952+ Addition to above, in the "actual operation" (step 4) aufs re-lookup
953+ the dentry on the branch, and returns EBUSY if it finds different
954+ dentry.
955+ Additionally, aufs sets the inotify/fsnotify watch for every dir on branches
956+ during it is in cache. When the event is notified, aufs registers a
957+ function to kernel 'events' thread by schedule_work(). And the
958+ function sets some special status to the cached aufs dentry and inode
959+ private data. If they are not cached, then aufs has nothing to
960+ do. When the same file is accessed through aufs (step 0-3) later,
961+ aufs will detect the status and refresh all necessary data.
962+ In this mode, aufs has to ignore the event which is fired by aufs
963+ itself.
964+3. No Extra Validation
965+ This is the simplest test and doesn't add any additional revalidation
966+ test, and skip therevalidatin in step 4. It is useful and improves
967+ aufs performance when system surely hide the aufs branches from user,
968+ by over-mounting something (or another method).
969diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt linux/Documentation/filesystems/aufs/design/04branch.txt
970--- /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100
1716fcea 971+++ linux/Documentation/filesystems/aufs/design/04branch.txt 2013-02-19 08:40:03.943559493 +0100
53392da6
AM
972@@ -0,0 +1,76 @@
973+
7a9e40b8 974+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
975+#
976+# This program is free software; you can redistribute it and/or modify
977+# it under the terms of the GNU General Public License as published by
978+# the Free Software Foundation; either version 2 of the License, or
979+# (at your option) any later version.
980+#
981+# This program is distributed in the hope that it will be useful,
982+# but WITHOUT ANY WARRANTY; without even the implied warranty of
983+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
984+# GNU General Public License for more details.
985+#
986+# You should have received a copy of the GNU General Public License
987+# along with this program; if not, write to the Free Software
988+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
989+
990+Branch Manipulation
991+
992+Since aufs supports dynamic branch manipulation, ie. add/remove a branch
993+and changing its permission/attribute, there are a lot of works to do.
994+
995+
996+Add a Branch
997+----------------------------------------------------------------------
998+o Confirm the adding dir exists outside of aufs, including loopback
999+ mount.
1000+- and other various attributes...
1001+o Initialize the xino file and whiteout bases if necessary.
1002+ See struct.txt.
1003+
1004+o Check the owner/group/mode of the directory
1005+ When the owner/group/mode of the adding directory differs from the
1006+ existing branch, aufs issues a warning because it may impose a
1007+ security risk.
1008+ For example, when a upper writable branch has a world writable empty
1009+ top directory, a malicious user can create any files on the writable
1010+ branch directly, like copy-up and modify manually. If something like
1011+ /etc/{passwd,shadow} exists on the lower readonly branch but the upper
1012+ writable branch, and the writable branch is world-writable, then a
1013+ malicious guy may create /etc/passwd on the writable branch directly
1014+ and the infected file will be valid in aufs.
1015+ I am afraid it can be a security issue, but nothing to do except
1016+ producing a warning.
1017+
1018+
1019+Delete a Branch
1020+----------------------------------------------------------------------
1021+o Confirm the deleting branch is not busy
1022+ To be general, there is one merit to adopt "remount" interface to
1023+ manipulate branches. It is to discard caches. At deleting a branch,
1024+ aufs checks the still cached (and connected) dentries and inodes. If
1025+ there are any, then they are all in-use. An inode without its
1026+ corresponding dentry can be alive alone (for example, inotify/fsnotify case).
1027+
1028+ For the cached one, aufs checks whether the same named entry exists on
1029+ other branches.
1030+ If the cached one is a directory, because aufs provides a merged view
1031+ to users, as long as one dir is left on any branch aufs can show the
1032+ dir to users. In this case, the branch can be removed from aufs.
1033+ Otherwise aufs rejects deleting the branch.
1034+
1035+ If any file on the deleting branch is opened by aufs, then aufs
1036+ rejects deleting.
1037+
1038+
1039+Modify the Permission of a Branch
1040+----------------------------------------------------------------------
1041+o Re-initialize or remove the xino file and whiteout bases if necessary.
1042+ See struct.txt.
1043+
1044+o rw --> ro: Confirm the modifying branch is not busy
1045+ Aufs rejects the request if any of these conditions are true.
1046+ - a file on the branch is mmap-ed.
1047+ - a regular file on the branch is opened for write and there is no
1048+ same named entry on the upper branch.
1049diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt linux/Documentation/filesystems/aufs/design/05wbr_policy.txt
1050--- /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 01:00:00.000000000 +0100
1716fcea 1051+++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2013-02-19 08:40:03.943559493 +0100
53392da6
AM
1052@@ -0,0 +1,65 @@
1053+
7a9e40b8 1054+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
1055+#
1056+# This program is free software; you can redistribute it and/or modify
1057+# it under the terms of the GNU General Public License as published by
1058+# the Free Software Foundation; either version 2 of the License, or
1059+# (at your option) any later version.
1060+#
1061+# This program is distributed in the hope that it will be useful,
1062+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1063+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1064+# GNU General Public License for more details.
1065+#
1066+# You should have received a copy of the GNU General Public License
1067+# along with this program; if not, write to the Free Software
1068+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1069+
1070+Policies to Select One among Multiple Writable Branches
1071+----------------------------------------------------------------------
1072+When the number of writable branch is more than one, aufs has to decide
1073+the target branch for file creation or copy-up. By default, the highest
1074+writable branch which has the parent (or ancestor) dir of the target
1075+file is chosen (top-down-parent policy).
1076+By user's request, aufs implements some other policies to select the
1077+writable branch, for file creation two policies, round-robin and
1078+most-free-space policies. For copy-up three policies, top-down-parent,
1079+bottom-up-parent and bottom-up policies.
1080+
1081+As expected, the round-robin policy selects the branch in circular. When
1082+you have two writable branches and creates 10 new files, 5 files will be
1083+created for each branch. mkdir(2) systemcall is an exception. When you
1084+create 10 new directories, all will be created on the same branch.
1085+And the most-free-space policy selects the one which has most free
1086+space among the writable branches. The amount of free space will be
1087+checked by aufs internally, and users can specify its time interval.
1088+
1089+The policies for copy-up is more simple,
1090+top-down-parent is equivalent to the same named on in create policy,
1091+bottom-up-parent selects the writable branch where the parent dir
1092+exists and the nearest upper one from the copyup-source,
1093+bottom-up selects the nearest upper writable branch from the
1094+copyup-source, regardless the existence of the parent dir.
1095+
1096+There are some rules or exceptions to apply these policies.
1097+- If there is a readonly branch above the policy-selected branch and
1098+ the parent dir is marked as opaque (a variation of whiteout), or the
1099+ target (creating) file is whiteout-ed on the upper readonly branch,
1100+ then the result of the policy is ignored and the target file will be
1101+ created on the nearest upper writable branch than the readonly branch.
1102+- If there is a writable branch above the policy-selected branch and
1103+ the parent dir is marked as opaque or the target file is whiteouted
1104+ on the branch, then the result of the policy is ignored and the target
1105+ file will be created on the highest one among the upper writable
1106+ branches who has diropq or whiteout. In case of whiteout, aufs removes
1107+ it as usual.
1108+- link(2) and rename(2) systemcalls are exceptions in every policy.
1109+ They try selecting the branch where the source exists as possible
1110+ since copyup a large file will take long time. If it can't be,
1111+ ie. the branch where the source exists is readonly, then they will
1112+ follow the copyup policy.
1113+- There is an exception for rename(2) when the target exists.
1114+ If the rename target exists, aufs compares the index of the branches
1115+ where the source and the target exists and selects the higher
1116+ one. If the selected branch is readonly, then aufs follows the
1117+ copyup policy.
1118diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt
1119--- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 01:00:00.000000000 +0100
1716fcea 1120+++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2013-02-19 08:40:03.943559493 +0100
53392da6
AM
1121@@ -0,0 +1,47 @@
1122+
7a9e40b8 1123+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
1124+#
1125+# This program is free software; you can redistribute it and/or modify
1126+# it under the terms of the GNU General Public License as published by
1127+# the Free Software Foundation; either version 2 of the License, or
1128+# (at your option) any later version.
1129+#
1130+# This program is distributed in the hope that it will be useful,
1131+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1132+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1133+# GNU General Public License for more details.
1134+#
1135+# You should have received a copy of the GNU General Public License
1136+# along with this program; if not, write to the Free Software
1137+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1138+
1139+mmap(2) -- File Memory Mapping
1140+----------------------------------------------------------------------
1141+In aufs, the file-mapped pages are handled by a branch fs directly, no
1142+interaction with aufs. It means aufs_mmap() calls the branch fs's
1143+->mmap().
1144+This approach is simple and good, but there is one problem.
1145+Under /proc, several entries show the mmap-ped files by its path (with
1146+device and inode number), and the printed path will be the path on the
1147+branch fs's instead of virtual aufs's.
1148+This is not a problem in most cases, but some utilities lsof(1) (and its
1149+user) may expect the path on aufs.
1150+
1151+To address this issue, aufs adds a new member called vm_prfile in struct
1152+vm_area_struct (and struct vm_region). The original vm_file points to
1153+the file on the branch fs in order to handle everything correctly as
1154+usual. The new vm_prfile points to a virtual file in aufs, and the
1155+show-functions in procfs refers to vm_prfile if it is set.
1156+Also we need to maintain several other places where touching vm_file
1157+such like
1158+- fork()/clone() copies vma and the reference count of vm_file is
1159+ incremented.
1160+- merging vma maintains the ref count too.
1161+
1162+This is not a good approach. It just faking the printed path. But it
1163+leaves all behaviour around f_mapping unchanged. This is surely an
1164+advantage.
1165+Actually aufs had adopted another complicated approach which calls
1166+generic_file_mmap() and handles struct vm_operations_struct. In this
1167+approach, aufs met a hard problem and I could not solve it without
1168+switching the approach.
1169diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt
1170--- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100
1716fcea 1171+++ linux/Documentation/filesystems/aufs/design/07export.txt 2013-02-19 08:40:03.943559493 +0100
53392da6
AM
1172@@ -0,0 +1,59 @@
1173+
7a9e40b8 1174+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
1175+#
1176+# This program is free software; you can redistribute it and/or modify
1177+# it under the terms of the GNU General Public License as published by
1178+# the Free Software Foundation; either version 2 of the License, or
1179+# (at your option) any later version.
1180+#
1181+# This program is distributed in the hope that it will be useful,
1182+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1183+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1184+# GNU General Public License for more details.
1185+#
1186+# You should have received a copy of the GNU General Public License
1187+# along with this program; if not, write to the Free Software
1188+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1189+
1190+Export Aufs via NFS
1191+----------------------------------------------------------------------
1192+Here is an approach.
1193+- like xino/xib, add a new file 'xigen' which stores aufs inode
1194+ generation.
1195+- iget_locked(): initialize aufs inode generation for a new inode, and
1196+ store it in xigen file.
1197+- destroy_inode(): increment aufs inode generation and store it in xigen
1198+ file. it is necessary even if it is not unlinked, because any data of
1199+ inode may be changed by UDBA.
1200+- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise
1201+ build file handle by
1202+ + branch id (4 bytes)
1203+ + superblock generation (4 bytes)
1204+ + inode number (4 or 8 bytes)
1205+ + parent dir inode number (4 or 8 bytes)
1206+ + inode generation (4 bytes))
1207+ + return value of exportfs_encode_fh() for the parent on a branch (4
1208+ bytes)
1209+ + file handle for a branch (by exportfs_encode_fh())
1210+- fh_to_dentry():
1211+ + find the index of a branch from its id in handle, and check it is
1212+ still exist in aufs.
1213+ + 1st level: get the inode number from handle and search it in cache.
1214+ + 2nd level: if not found, get the parent inode number from handle and
1215+ search it in cache. and then open the parent dir, find the matching
1216+ inode number by vfs_readdir() and get its name, and call
1217+ lookup_one_len() for the target dentry.
1218+ + 3rd level: if the parent dir is not cached, call
1219+ exportfs_decode_fh() for a branch and get the parent on a branch,
1220+ build a pathname of it, convert it a pathname in aufs, call
1221+ path_lookup(). now aufs gets a parent dir dentry, then handle it as
1222+ the 2nd level.
1223+ + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount
1224+ for every branch, but not itself. to get this, (currently) aufs
1225+ searches in current->nsproxy->mnt_ns list. it may not be a good
1226+ idea, but I didn't get other approach.
1227+ + test the generation of the gotten inode.
1228+- every inode operation: they may get EBUSY due to UDBA. in this case,
1229+ convert it into ESTALE for NFSD.
1230+- readdir(): call lockdep_on/off() because filldir in NFSD calls
1231+ lookup_one_len(), vfs_getattr(), encode_fh() and others.
1232diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linux/Documentation/filesystems/aufs/design/08shwh.txt
1233--- /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 01:00:00.000000000 +0100
1716fcea 1234+++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2013-02-19 08:40:03.943559493 +0100
53392da6
AM
1235@@ -0,0 +1,53 @@
1236+
7a9e40b8 1237+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
1238+#
1239+# This program is free software; you can redistribute it and/or modify
1240+# it under the terms of the GNU General Public License as published by
1241+# the Free Software Foundation; either version 2 of the License, or
1242+# (at your option) any later version.
1243+#
1244+# This program is distributed in the hope that it will be useful,
1245+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1246+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1247+# GNU General Public License for more details.
1248+#
1249+# You should have received a copy of the GNU General Public License
1250+# along with this program; if not, write to the Free Software
1251+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1252+
1253+Show Whiteout Mode (shwh)
1254+----------------------------------------------------------------------
1255+Generally aufs hides the name of whiteouts. But in some cases, to show
1256+them is very useful for users. For instance, creating a new middle layer
1257+(branch) by merging existing layers.
1258+
1259+(borrowing aufs1 HOW-TO from a user, Michael Towers)
1260+When you have three branches,
1261+- Bottom: 'system', squashfs (underlying base system), read-only
1262+- Middle: 'mods', squashfs, read-only
1263+- Top: 'overlay', ram (tmpfs), read-write
1264+
1265+The top layer is loaded at boot time and saved at shutdown, to preserve
1266+the changes made to the system during the session.
1267+When larger changes have been made, or smaller changes have accumulated,
1268+the size of the saved top layer data grows. At this point, it would be
1269+nice to be able to merge the two overlay branches ('mods' and 'overlay')
1270+and rewrite the 'mods' squashfs, clearing the top layer and thus
1271+restoring save and load speed.
1272+
1273+This merging is simplified by the use of another aufs mount, of just the
1274+two overlay branches using the 'shwh' option.
1275+# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \
1276+ aufs /livesys/merge_union
1277+
1278+A merged view of these two branches is then available at
1279+/livesys/merge_union, and the new feature is that the whiteouts are
1280+visible!
1281+Note that in 'shwh' mode the aufs mount must be 'ro', which will disable
1282+writing to all branches. Also the default mode for all branches is 'ro'.
1283+It is now possible to save the combined contents of the two overlay
1284+branches to a new squashfs, e.g.:
1285+# mksquashfs /livesys/merge_union /path/to/newmods.squash
1286+
1287+This new squashfs archive can be stored on the boot device and the
1288+initramfs will use it to replace the old one at the next boot.
1289diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt linux/Documentation/filesystems/aufs/design/10dynop.txt
1290--- /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 01:00:00.000000000 +0100
1716fcea 1291+++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2013-02-19 08:40:03.943559493 +0100
53392da6
AM
1292@@ -0,0 +1,47 @@
1293+
7a9e40b8 1294+# Copyright (C) 2010-2013 Junjiro R. Okajima
53392da6
AM
1295+#
1296+# This program is free software; you can redistribute it and/or modify
1297+# it under the terms of the GNU General Public License as published by
1298+# the Free Software Foundation; either version 2 of the License, or
1299+# (at your option) any later version.
1300+#
1301+# This program is distributed in the hope that it will be useful,
1302+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1303+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1304+# GNU General Public License for more details.
1305+#
1306+# You should have received a copy of the GNU General Public License
1307+# along with this program; if not, write to the Free Software
1308+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1309+
1310+Dynamically customizable FS operations
1311+----------------------------------------------------------------------
1312+Generally FS operations (struct inode_operations, struct
1313+address_space_operations, struct file_operations, etc.) are defined as
1314+"static const", but it never means that FS have only one set of
1315+operation. Some FS have multiple sets of them. For instance, ext2 has
1316+three sets, one for XIP, for NOBH, and for normal.
1317+Since aufs overrides and redirects these operations, sometimes aufs has
1318+to change its behaviour according to the branch FS type. More imporantly
1319+VFS acts differently if a function (member in the struct) is set or
1320+not. It means aufs should have several sets of operations and select one
1321+among them according to the branch FS definition.
1322+
1323+In order to solve this problem and not to affect the behavour of VFS,
1324+aufs defines these operations dynamically. For instance, aufs defines
1325+aio_read function for struct file_operations, but it may not be set to
1326+the file_operations. When the branch FS doesn't have it, aufs doesn't
1327+set it to its file_operations while the function definition itself is
1328+still alive. So the behaviour of io_submit(2) will not change, and it
1329+will return an error when aio_read is not defined.
1330+
1331+The lifetime of these dynamically generated operation object is
1332+maintained by aufs branch object. When the branch is removed from aufs,
1333+the reference counter of the object is decremented. When it reaches
1334+zero, the dynamically generated operation object will be freed.
1335+
1336+This approach is designed to support AIO (io_submit), Direcit I/O and
1337+XIP mainly.
1338+Currently this approach is applied to file_operations and
1339+vm_operations_struct for regular files only.
1340diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt linux/Documentation/filesystems/aufs/design/99plan.txt
1341--- /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt 1970-01-01 01:00:00.000000000 +0100
1716fcea 1342+++ linux/Documentation/filesystems/aufs/design/99plan.txt 2013-02-19 08:40:03.943559493 +0100
53392da6
AM
1343@@ -0,0 +1,96 @@
1344+
7a9e40b8 1345+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
1346+#
1347+# This program is free software; you can redistribute it and/or modify
1348+# it under the terms of the GNU General Public License as published by
1349+# the Free Software Foundation; either version 2 of the License, or
1350+# (at your option) any later version.
1351+#
1352+# This program is distributed in the hope that it will be useful,
1353+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1354+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1355+# GNU General Public License for more details.
1356+#
1357+# You should have received a copy of the GNU General Public License
1358+# along with this program; if not, write to the Free Software
1359+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1360+
1361+Plan
1362+
1363+Restoring some features which was implemented in aufs1.
1364+They were dropped in aufs2 in order to make source files simpler and
1365+easier to be reviewed.
1366+
1367+
1368+Test Only the Highest One for the Directory Permission (dirperm1 option)
1369+----------------------------------------------------------------------
1370+Let's try case study.
1371+- aufs has two branches, upper readwrite and lower readonly.
1372+ /au = /rw + /ro
1373+- "dirA" exists under /ro, but /rw. and its mode is 0700.
1374+- user invoked "chmod a+rx /au/dirA"
1375+- then "dirA" becomes world readable?
1376+
1377+In this case, /ro/dirA is still 0700 since it exists in readonly branch,
1378+or it may be a natively readonly filesystem. If aufs respects the lower
1379+branch, it should not respond readdir request from other users. But user
1380+allowed it by chmod. Should really aufs rejects showing the entries
1381+under /ro/dirA?
1382+
1383+To be honest, I don't have a best solution for this case. So I
1384+implemented 'dirperm1' and 'nodirperm1' option in aufs1, and leave it to
1385+users.
1386+When dirperm1 is specified, aufs checks only the highest one for the
1387+directory permission, and shows the entries. Otherwise, as usual, checks
1388+every dir existing on all branches and rejects the request.
1389+
1390+As a side effect, dirperm1 option improves the performance of aufs
1391+because the number of permission check is reduced.
1392+
1393+
1394+Being Another Aufs's Readonly Branch (robr)
1395+----------------------------------------------------------------------
1396+Aufs1 allows aufs to be another aufs's readonly branch.
1397+This feature was developed by a user's request. But it may not be used
1398+currecnly.
1399+
1400+
1401+Copy-up on Open (coo=)
1402+----------------------------------------------------------------------
1403+By default the internal copy-up is executed when it is really necessary.
1404+It is not done when a file is opened for writing, but when write(2) is
1405+done. Users who have many (over 100) branches want to know and analyse
1406+when and what file is copied-up. To insert a new upper branch which
1407+contains such files only may improve the performance of aufs.
1408+
1409+Aufs1 implemented "coo=none | leaf | all" option.
1410+
1411+
1412+Refresh the Opened File (refrof)
1413+----------------------------------------------------------------------
1414+This option is implemented in aufs1 but incomplete.
1415+
1416+When user reads from a file, he expects to get its latest filedata
1417+generally. If the file is removed and a new same named file is created,
1418+the content he gets is unchanged, ie. the unlinked filedata.
1419+
1420+Let's try case study again.
1421+- aufs has two branches.
1422+ /au = /rw + /ro
1423+- "fileA" exists under /ro, but /rw.
1424+- user opened "/au/fileA".
1425+- he or someone else inserts a branch (/new) between /rw and /ro.
1426+ /au = /rw + /new + /ro
1427+- the new branch has "fileA".
1428+- user reads from the opened "fileA"
1429+- which filedata should aufs return, from /ro or /new?
1430+
1431+Some people says it has to be "from /ro" and it is a semantics of Unix.
1432+The others say it should be "from /new" because the file is not removed
1433+and it is equivalent to the case of someone else modifies the file.
1434+
1435+Here again I don't have a best and final answer. I got an idea to
1436+implement 'refrof' and 'norefrof' option. When 'refrof' (REFResh the
1437+Opened File) is specified (by default), aufs returns the filedata from
1438+/new.
1439+Otherwise from /new.
1440diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README
1441--- /usr/share/empty/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100
a2a7ad62 1442+++ linux/Documentation/filesystems/aufs/README 2013-03-14 20:07:40.574775374 +0100
537831f9 1443@@ -0,0 +1,333 @@
53392da6
AM
1444+
1445+Aufs3 -- advanced multi layered unification filesystem version 3.x
1446+http://aufs.sf.net
1447+Junjiro R. Okajima
1448+
1449+
1450+0. Introduction
1451+----------------------------------------
1452+In the early days, aufs was entirely re-designed and re-implemented
1453+Unionfs Version 1.x series. After many original ideas, approaches,
1454+improvements and implementations, it becomes totally different from
1455+Unionfs while keeping the basic features.
1456+Recently, Unionfs Version 2.x series begin taking some of the same
1457+approaches to aufs1's.
1458+Unionfs is being developed by Professor Erez Zadok at Stony Brook
1459+University and his team.
1460+
1461+Aufs3 supports linux-3.0 and later.
1462+If you want older kernel version support, try aufs2-2.6.git or
1463+aufs2-standalone.git repository, aufs1 from CVS on SourceForge.
1464+
1465+Note: it becomes clear that "Aufs was rejected. Let's give it up."
1466+According to Christoph Hellwig, linux rejects all union-type filesystems
1467+but UnionMount.
1468+<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
1469+
1470+
1471+1. Features
1472+----------------------------------------
1473+- unite several directories into a single virtual filesystem. The member
1474+ directory is called as a branch.
1475+- you can specify the permission flags to the branch, which are 'readonly',
1476+ 'readwrite' and 'whiteout-able.'
1477+- by upper writable branch, internal copyup and whiteout, files/dirs on
1478+ readonly branch are modifiable logically.
1479+- dynamic branch manipulation, add, del.
1480+- etc...
1481+
1482+Also there are many enhancements in aufs1, such as:
1483+- readdir(3) in userspace.
1484+- keep inode number by external inode number table
1485+- keep the timestamps of file/dir in internal copyup operation
1486+- seekable directory, supporting NFS readdir.
1487+- whiteout is hardlinked in order to reduce the consumption of inodes
1488+ on branch
1489+- do not copyup, nor create a whiteout when it is unnecessary
1490+- revert a single systemcall when an error occurs in aufs
1491+- remount interface instead of ioctl
1492+- maintain /etc/mtab by an external command, /sbin/mount.aufs.
1493+- loopback mounted filesystem as a branch
1494+- kernel thread for removing the dir who has a plenty of whiteouts
1495+- support copyup sparse file (a file which has a 'hole' in it)
1496+- default permission flags for branches
1497+- selectable permission flags for ro branch, whether whiteout can
1498+ exist or not
1499+- export via NFS.
1500+- support <sysfs>/fs/aufs and <debugfs>/aufs.
1501+- support multiple writable branches, some policies to select one
1502+ among multiple writable branches.
1503+- a new semantics for link(2) and rename(2) to support multiple
1504+ writable branches.
1505+- no glibc changes are required.
1506+- pseudo hardlink (hardlink over branches)
1507+- allow a direct access manually to a file on branch, e.g. bypassing aufs.
1508+ including NFS or remote filesystem branch.
1509+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
1510+- and more...
1511+
1512+Currently these features are dropped temporary from aufs3.
1513+See design/08plan.txt in detail.
1514+- test only the highest one for the directory permission (dirperm1)
1515+- copyup on open (coo=)
1516+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
1517+ (robr)
1518+- statistics of aufs thread (/sys/fs/aufs/stat)
1519+- delegation mode (dlgt)
1520+ a delegation of the internal branch access to support task I/O
1521+ accounting, which also supports Linux Security Modules (LSM) mainly
1522+ for Suse AppArmor.
1523+- intent.open/create (file open in a single lookup)
1524+
1525+Features or just an idea in the future (see also design/*.txt),
1526+- reorder the branch index without del/re-add.
1527+- permanent xino files for NFSD
1528+- an option for refreshing the opened files after add/del branches
1529+- 'move' policy for copy-up between two writable branches, after
1530+ checking free space.
1531+- light version, without branch manipulation. (unnecessary?)
1532+- copyup in userspace
1533+- inotify in userspace
1534+- readv/writev
1535+- xattr, acl
1536+
1537+
1538+2. Download
1539+----------------------------------------
1e00d052
AM
1540+There were three GIT trees for aufs3, aufs3-linux.git,
1541+aufs3-standalone.git, and aufs-util.git. Note that there is no "3" in
1542+"aufs-util.git."
1543+While the aufs-util is always necessary, you need either of aufs3-linux
1544+or aufs3-standalone.
1545+
1546+The aufs3-linux tree includes the whole linux mainline GIT tree,
1547+git://git.kernel.org/.../torvalds/linux.git.
1548+And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
b4510431 1549+build aufs3 as an external kernel module.
1e00d052
AM
1550+
1551+On the other hand, the aufs3-standalone tree has only aufs source files
53392da6
AM
1552+and necessary patches, and you can select CONFIG_AUFS_FS=m.
1553+
1554+You will find GIT branches whose name is in form of "aufs3.x" where "x"
1555+represents the linux kernel version, "linux-3.x". For instance,
1e00d052
AM
1556+"aufs3.0" is for linux-3.0. For latest "linux-3.x-rcN", use
1557+"aufs3.x-rcN" branch.
1558+
1559+o aufs3-linux tree
1560+$ git clone --reference /your/linux/git/tree \
1561+ git://aufs.git.sourceforge.net/gitroot/aufs/aufs3-linux.git \
1562+ aufs3-linux.git
1563+- if you don't have linux GIT tree, then remove "--reference ..."
1564+$ cd aufs3-linux.git
1565+$ git checkout origin/aufs3.0
53392da6
AM
1566+
1567+o aufs3-standalone tree
1568+$ git clone git://aufs.git.sourceforge.net/gitroot/aufs/aufs3-standalone.git \
1569+ aufs3-standalone.git
1570+$ cd aufs3-standalone.git
1571+$ git checkout origin/aufs3.0
1572+
1573+o aufs-util tree
1574+$ git clone git://aufs.git.sourceforge.net/gitroot/aufs/aufs-util.git \
1575+ aufs-util.git
1576+$ cd aufs-util.git
1577+$ git checkout origin/aufs3.0
1578+
9dbd164d
AM
1579+Note: The 3.x-rcN branch is to be used with `rc' kernel versions ONLY.
1580+The minor version number, 'x' in '3.x', of aufs may not always
1581+follow the minor version number of the kernel.
1582+Because changes in the kernel that cause the use of a new
1583+minor version number do not always require changes to aufs-util.
1584+
1585+Since aufs-util has its own minor version number, you may not be
1586+able to find a GIT branch in aufs-util for your kernel's
1587+exact minor version number.
1588+In this case, you should git-checkout the branch for the
53392da6 1589+nearest lower number.
9dbd164d
AM
1590+
1591+For (an unreleased) example:
1592+If you are using "linux-3.10" and the "aufs3.10" branch
7eafdf33 1593+does not exist in aufs-util repository, then "aufs3.9", "aufs3.8"
9dbd164d
AM
1594+or something numerically smaller is the branch for your kernel.
1595+
53392da6
AM
1596+Also you can view all branches by
1597+ $ git branch -a
1598+
1599+
1600+3. Configuration and Compilation
1601+----------------------------------------
1602+Make sure you have git-checkout'ed the correct branch.
1603+
1e00d052
AM
1604+For aufs3-linux tree,
1605+- enable CONFIG_EXPERIMENTAL and CONFIG_AUFS_FS.
1606+- set other aufs configurations if necessary.
1607+
53392da6
AM
1608+For aufs3-standalone tree,
1609+There are several ways to build.
1610+
1611+1.
1612+- apply ./aufs3-kbuild.patch to your kernel source files.
1613+- apply ./aufs3-base.patch too.
1614+- apply ./aufs3-proc_map.patch too, if you want to make /proc/PID/maps (and
1615+ others including lsof(1)) show the file path on aufs instead of the
1616+ path on the branch fs.
1617+- apply ./aufs3-standalone.patch too, if you have a plan to set
1618+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs3-standalone.patch.
537831f9
AM
1619+- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
1620+ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
53392da6
AM
1621+- enable CONFIG_EXPERIMENTAL and CONFIG_AUFS_FS, you can select either
1622+ =m or =y.
1623+- and build your kernel as usual.
1624+- install the built kernel.
7eafdf33
AM
1625+- install the header files too by "make headers_install" to the
1626+ directory where you specify. By default, it is $PWD/usr.
b4510431 1627+ "make help" shows a brief note for headers_install.
53392da6
AM
1628+- and reboot your system.
1629+
1630+2.
1631+- module only (CONFIG_AUFS_FS=m).
1632+- apply ./aufs3-base.patch to your kernel source files.
1633+- apply ./aufs3-proc_map.patch too to your kernel source files,
1634+ if you want to make /proc/PID/maps (and others including lsof(1)) show
1635+ the file path on aufs instead of the path on the branch fs.
1636+- apply ./aufs3-standalone.patch too.
1637+- build your kernel, don't forget "make headers_install", and reboot.
1638+- edit ./config.mk and set other aufs configurations if necessary.
b4510431 1639+ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
53392da6
AM
1640+ every aufs configurations.
1641+- build the module by simple "make".
1642+- you can specify ${KDIR} make variable which points to your kernel
1643+ source tree.
1644+- install the files
1645+ + run "make install" to install the aufs module, or copy the built
b4510431
AM
1646+ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply).
1647+ + run "make install_headers" (instead of headers_install) to install
1648+ the modified aufs header file (you can specify DESTDIR which is
1649+ available in aufs standalone version's Makefile only), or copy
1650+ $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever
1651+ you like manually. By default, the target directory is $PWD/usr.
53392da6
AM
1652+- no need to apply aufs3-kbuild.patch, nor copying source files to your
1653+ kernel source tree.
1654+
b4510431 1655+Note: The header file aufs_type.h is necessary to build aufs-util
53392da6
AM
1656+ as well as "make headers_install" in the kernel source tree.
1657+ headers_install is subject to be forgotten, but it is essentially
1658+ necessary, not only for building aufs-util.
1659+ You may not meet problems without headers_install in some older
1660+ version though.
1661+
1662+And then,
1663+- read README in aufs-util, build and install it
9dbd164d
AM
1664+- note that your distribution may contain an obsoleted version of
1665+ aufs_type.h in /usr/include/linux or something. When you build aufs
1666+ utilities, make sure that your compiler refers the correct aufs header
1667+ file which is built by "make headers_install."
53392da6
AM
1668+- if you want to use readdir(3) in userspace or pathconf(3) wrapper,
1669+ then run "make install_ulib" too. And refer to the aufs manual in
1670+ detail.
1671+
1672+
1673+4. Usage
1674+----------------------------------------
1675+At first, make sure aufs-util are installed, and please read the aufs
1676+manual, aufs.5 in aufs-util.git tree.
1677+$ man -l aufs.5
1678+
1679+And then,
1680+$ mkdir /tmp/rw /tmp/aufs
1681+# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs
1682+
1683+Here is another example. The result is equivalent.
1684+# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
1685+ Or
1686+# mount -t aufs -o br:/tmp/rw none /tmp/aufs
1687+# mount -o remount,append:${HOME} /tmp/aufs
1688+
1689+Then, you can see whole tree of your home dir through /tmp/aufs. If
1690+you modify a file under /tmp/aufs, the one on your home directory is
1691+not affected, instead the same named file will be newly created under
1692+/tmp/rw. And all of your modification to a file will be applied to
1693+the one under /tmp/rw. This is called the file based Copy on Write
1694+(COW) method.
1695+Aufs mount options are described in aufs.5.
1696+If you run chroot or something and make your aufs as a root directory,
1697+then you need to customize the shutdown script. See the aufs manual in
1698+detail.
1699+
1700+Additionally, there are some sample usages of aufs which are a
1701+diskless system with network booting, and LiveCD over NFS.
1702+See sample dir in CVS tree on SourceForge.
1703+
1704+
1705+5. Contact
1706+----------------------------------------
1707+When you have any problems or strange behaviour in aufs, please let me
1708+know with:
1709+- /proc/mounts (instead of the output of mount(8))
1710+- /sys/module/aufs/*
1711+- /sys/fs/aufs/* (if you have them)
1712+- /debug/aufs/* (if you have them)
1713+- linux kernel version
1714+ if your kernel is not plain, for example modified by distributor,
1715+ the url where i can download its source is necessary too.
1716+- aufs version which was printed at loading the module or booting the
1717+ system, instead of the date you downloaded.
1718+- configuration (define/undefine CONFIG_AUFS_xxx)
1719+- kernel configuration or /proc/config.gz (if you have it)
1720+- behaviour which you think to be incorrect
1721+- actual operation, reproducible one is better
1722+- mailto: aufs-users at lists.sourceforge.net
1723+
1724+Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches,
1725+and Feature Requests) on SourceForge. Please join and write to
1726+aufs-users ML.
1727+
1728+
1729+6. Acknowledgements
1730+----------------------------------------
1731+Thanks to everyone who have tried and are using aufs, whoever
1732+have reported a bug or any feedback.
1733+
1734+Especially donators:
1735+Tomas Matejicek(slax.org) made a donation (much more than once).
1736+ Since Apr 2010, Tomas M (the author of Slax and Linux Live
1737+ scripts) is making "doubling" donations.
1738+ Unfortunately I cannot list all of the donators, but I really
b4510431 1739+ appreciate.
53392da6
AM
1740+ It ends Aug 2010, but the ordinary donation URL is still available.
1741+ <http://sourceforge.net/donate/index.php?group_id=167503>
1742+Dai Itasaka made a donation (2007/8).
1743+Chuck Smith made a donation (2008/4, 10 and 12).
1744+Henk Schoneveld made a donation (2008/9).
1745+Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10).
1746+Francois Dupoux made a donation (2008/11).
1747+Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public
1748+ aufs2 GIT tree (2009/2).
1749+William Grant made a donation (2009/3).
1750+Patrick Lane made a donation (2009/4).
1751+The Mail Archive (mail-archive.com) made donations (2009/5).
1752+Nippy Networks (Ed Wildgoose) made a donation (2009/7).
1753+New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11).
1754+Pavel Pronskiy made a donation (2011/2).
1755+Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy
1756+ Networks (Ed Wildgoose) made a donation for hardware (2011/3).
537831f9
AM
1757+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
1758+11).
1e00d052 1759+Sam Liddicott made a donation (2011/9).
53392da6
AM
1760+
1761+Thank you very much.
1762+Donations are always, including future donations, very important and
1763+helpful for me to keep on developing aufs.
1764+
1765+
1766+7.
1767+----------------------------------------
1768+If you are an experienced user, no explanation is needed. Aufs is
1769+just a linux filesystem.
1770+
1771+
1772+Enjoy!
1773+
1774+# Local variables: ;
1775+# mode: text;
1776+# End: ;
7f207e10
AM
1777diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
1778--- /usr/share/empty/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100
1716fcea 1779+++ linux/fs/aufs/aufs.h 2013-02-19 08:40:03.946892891 +0100
2cbb1c4b 1780@@ -0,0 +1,60 @@
7f207e10 1781+/*
7a9e40b8 1782+ * Copyright (C) 2005-2013 Junjiro R. Okajima
7f207e10
AM
1783+ *
1784+ * This program, aufs is free software; you can redistribute it and/or modify
1785+ * it under the terms of the GNU General Public License as published by
1786+ * the Free Software Foundation; either version 2 of the License, or
1787+ * (at your option) any later version.
1788+ *
1789+ * This program is distributed in the hope that it will be useful,
1790+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1791+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1792+ * GNU General Public License for more details.
1793+ *
1794+ * You should have received a copy of the GNU General Public License
1795+ * along with this program; if not, write to the Free Software
1796+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1797+ */
1798+
1799+/*
1800+ * all header files
1801+ */
1802+
1803+#ifndef __AUFS_H__
1804+#define __AUFS_H__
1805+
1806+#ifdef __KERNEL__
1807+
1808+#define AuStub(type, name, body, ...) \
1809+ static inline type name(__VA_ARGS__) { body; }
1810+
1811+#define AuStubVoid(name, ...) \
1812+ AuStub(void, name, , __VA_ARGS__)
1813+#define AuStubInt0(name, ...) \
1814+ AuStub(int, name, return 0, __VA_ARGS__)
1815+
1816+#include "debug.h"
1817+
1818+#include "branch.h"
1819+#include "cpup.h"
1820+#include "dcsub.h"
1821+#include "dbgaufs.h"
1822+#include "dentry.h"
1823+#include "dir.h"
1824+#include "dynop.h"
1825+#include "file.h"
1826+#include "fstype.h"
1827+#include "inode.h"
1828+#include "loop.h"
1829+#include "module.h"
7f207e10
AM
1830+#include "opts.h"
1831+#include "rwsem.h"
1832+#include "spl.h"
1833+#include "super.h"
1834+#include "sysaufs.h"
1835+#include "vfsub.h"
1836+#include "whout.h"
1837+#include "wkq.h"
1838+
1839+#endif /* __KERNEL__ */
1840+#endif /* __AUFS_H__ */
1841diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
1842--- /usr/share/empty/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100
a2a7ad62 1843+++ linux/fs/aufs/branch.c 2013-03-14 20:07:41.038119650 +0100
537831f9 1844@@ -0,0 +1,1172 @@
7f207e10 1845+/*
7a9e40b8 1846+ * Copyright (C) 2005-2013 Junjiro R. Okajima
7f207e10
AM
1847+ *
1848+ * This program, aufs is free software; you can redistribute it and/or modify
1849+ * it under the terms of the GNU General Public License as published by
1850+ * the Free Software Foundation; either version 2 of the License, or
1851+ * (at your option) any later version.
1852+ *
1853+ * This program is distributed in the hope that it will be useful,
1854+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1855+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1856+ * GNU General Public License for more details.
1857+ *
1858+ * You should have received a copy of the GNU General Public License
1859+ * along with this program; if not, write to the Free Software
1860+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1861+ */
1862+
1863+/*
1864+ * branch management
1865+ */
1866+
027c5e7a 1867+#include <linux/compat.h>
7f207e10
AM
1868+#include <linux/statfs.h>
1869+#include "aufs.h"
1870+
1871+/*
1872+ * free a single branch
1facf9fc 1873+ */
1874+static void au_br_do_free(struct au_branch *br)
1875+{
1876+ int i;
1877+ struct au_wbr *wbr;
4a4d8108 1878+ struct au_dykey **key;
1facf9fc 1879+
027c5e7a
AM
1880+ au_hnotify_fin_br(br);
1881+
1facf9fc 1882+ if (br->br_xino.xi_file)
1883+ fput(br->br_xino.xi_file);
1884+ mutex_destroy(&br->br_xino.xi_nondir_mtx);
1885+
1886+ AuDebugOn(atomic_read(&br->br_count));
1887+
1888+ wbr = br->br_wbr;
1889+ if (wbr) {
1890+ for (i = 0; i < AuBrWh_Last; i++)
1891+ dput(wbr->wbr_wh[i]);
1892+ AuDebugOn(atomic_read(&wbr->wbr_wh_running));
dece6358 1893+ AuRwDestroy(&wbr->wbr_wh_rwsem);
1facf9fc 1894+ }
1895+
4a4d8108
AM
1896+ key = br->br_dykey;
1897+ for (i = 0; i < AuBrDynOp; i++, key++)
1898+ if (*key)
1899+ au_dy_put(*key);
1900+ else
1901+ break;
1902+
537831f9
AM
1903+ /* recursive lock, s_umount of branch's */
1904+ lockdep_off();
1facf9fc 1905+ mntput(br->br_mnt);
537831f9 1906+ lockdep_on();
1facf9fc 1907+ kfree(wbr);
1908+ kfree(br);
1909+}
1910+
1911+/*
1912+ * frees all branches
1913+ */
1914+void au_br_free(struct au_sbinfo *sbinfo)
1915+{
1916+ aufs_bindex_t bmax;
1917+ struct au_branch **br;
1918+
dece6358
AM
1919+ AuRwMustWriteLock(&sbinfo->si_rwsem);
1920+
1facf9fc 1921+ bmax = sbinfo->si_bend + 1;
1922+ br = sbinfo->si_branch;
1923+ while (bmax--)
1924+ au_br_do_free(*br++);
1925+}
1926+
1927+/*
1928+ * find the index of a branch which is specified by @br_id.
1929+ */
1930+int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
1931+{
1932+ aufs_bindex_t bindex, bend;
1933+
1934+ bend = au_sbend(sb);
1935+ for (bindex = 0; bindex <= bend; bindex++)
1936+ if (au_sbr_id(sb, bindex) == br_id)
1937+ return bindex;
1938+ return -1;
1939+}
1940+
1941+/* ---------------------------------------------------------------------- */
1942+
1943+/*
1944+ * add a branch
1945+ */
1946+
b752ccd1
AM
1947+static int test_overlap(struct super_block *sb, struct dentry *h_adding,
1948+ struct dentry *h_root)
1facf9fc 1949+{
b752ccd1
AM
1950+ if (unlikely(h_adding == h_root
1951+ || au_test_loopback_overlap(sb, h_adding)))
1facf9fc 1952+ return 1;
b752ccd1
AM
1953+ if (h_adding->d_sb != h_root->d_sb)
1954+ return 0;
1955+ return au_test_subdir(h_adding, h_root)
1956+ || au_test_subdir(h_root, h_adding);
1facf9fc 1957+}
1958+
1959+/*
1960+ * returns a newly allocated branch. @new_nbranch is a number of branches
1961+ * after adding a branch.
1962+ */
1963+static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
1964+ int perm)
1965+{
1966+ struct au_branch *add_branch;
1967+ struct dentry *root;
4a4d8108 1968+ int err;
1facf9fc 1969+
4a4d8108 1970+ err = -ENOMEM;
1facf9fc 1971+ root = sb->s_root;
1972+ add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS);
1973+ if (unlikely(!add_branch))
1974+ goto out;
1975+
027c5e7a
AM
1976+ err = au_hnotify_init_br(add_branch, perm);
1977+ if (unlikely(err))
1978+ goto out_br;
1979+
1facf9fc 1980+ add_branch->br_wbr = NULL;
1981+ if (au_br_writable(perm)) {
1982+ /* may be freed separately at changing the branch permission */
1983+ add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr),
1984+ GFP_NOFS);
1985+ if (unlikely(!add_branch->br_wbr))
027c5e7a 1986+ goto out_hnotify;
1facf9fc 1987+ }
1988+
4a4d8108
AM
1989+ err = au_sbr_realloc(au_sbi(sb), new_nbranch);
1990+ if (!err)
1991+ err = au_di_realloc(au_di(root), new_nbranch);
1992+ if (!err)
1993+ err = au_ii_realloc(au_ii(root->d_inode), new_nbranch);
1994+ if (!err)
1995+ return add_branch; /* success */
1facf9fc 1996+
1facf9fc 1997+ kfree(add_branch->br_wbr);
4a4d8108 1998+
027c5e7a
AM
1999+out_hnotify:
2000+ au_hnotify_fin_br(add_branch);
4f0767ce 2001+out_br:
1facf9fc 2002+ kfree(add_branch);
4f0767ce 2003+out:
4a4d8108 2004+ return ERR_PTR(err);
1facf9fc 2005+}
2006+
2007+/*
2008+ * test if the branch permission is legal or not.
2009+ */
2010+static int test_br(struct inode *inode, int brperm, char *path)
2011+{
2012+ int err;
2013+
4a4d8108
AM
2014+ err = (au_br_writable(brperm) && IS_RDONLY(inode));
2015+ if (!err)
2016+ goto out;
1facf9fc 2017+
4a4d8108
AM
2018+ err = -EINVAL;
2019+ pr_err("write permission for readonly mount or inode, %s\n", path);
2020+
4f0767ce 2021+out:
1facf9fc 2022+ return err;
2023+}
2024+
2025+/*
2026+ * returns:
2027+ * 0: success, the caller will add it
2028+ * plus: success, it is already unified, the caller should ignore it
2029+ * minus: error
2030+ */
2031+static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
2032+{
2033+ int err;
2034+ aufs_bindex_t bend, bindex;
2035+ struct dentry *root;
2036+ struct inode *inode, *h_inode;
2037+
2038+ root = sb->s_root;
2039+ bend = au_sbend(sb);
2040+ if (unlikely(bend >= 0
2041+ && au_find_dbindex(root, add->path.dentry) >= 0)) {
2042+ err = 1;
2043+ if (!remount) {
2044+ err = -EINVAL;
4a4d8108 2045+ pr_err("%s duplicated\n", add->pathname);
1facf9fc 2046+ }
2047+ goto out;
2048+ }
2049+
2050+ err = -ENOSPC; /* -E2BIG; */
2051+ if (unlikely(AUFS_BRANCH_MAX <= add->bindex
2052+ || AUFS_BRANCH_MAX - 1 <= bend)) {
4a4d8108 2053+ pr_err("number of branches exceeded %s\n", add->pathname);
1facf9fc 2054+ goto out;
2055+ }
2056+
2057+ err = -EDOM;
2058+ if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) {
4a4d8108 2059+ pr_err("bad index %d\n", add->bindex);
1facf9fc 2060+ goto out;
2061+ }
2062+
2063+ inode = add->path.dentry->d_inode;
2064+ err = -ENOENT;
2065+ if (unlikely(!inode->i_nlink)) {
4a4d8108 2066+ pr_err("no existence %s\n", add->pathname);
1facf9fc 2067+ goto out;
2068+ }
2069+
2070+ err = -EINVAL;
2071+ if (unlikely(inode->i_sb == sb)) {
4a4d8108 2072+ pr_err("%s must be outside\n", add->pathname);
1facf9fc 2073+ goto out;
2074+ }
2075+
2076+ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
4a4d8108
AM
2077+ pr_err("unsupported filesystem, %s (%s)\n",
2078+ add->pathname, au_sbtype(inode->i_sb));
1facf9fc 2079+ goto out;
2080+ }
2081+
2082+ err = test_br(add->path.dentry->d_inode, add->perm, add->pathname);
2083+ if (unlikely(err))
2084+ goto out;
2085+
2086+ if (bend < 0)
2087+ return 0; /* success */
2088+
2089+ err = -EINVAL;
2090+ for (bindex = 0; bindex <= bend; bindex++)
2091+ if (unlikely(test_overlap(sb, add->path.dentry,
2092+ au_h_dptr(root, bindex)))) {
4a4d8108 2093+ pr_err("%s is overlapped\n", add->pathname);
1facf9fc 2094+ goto out;
2095+ }
2096+
2097+ err = 0;
2098+ if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
2099+ h_inode = au_h_dptr(root, 0)->d_inode;
2100+ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
0c3ec466
AM
2101+ || !uid_eq(h_inode->i_uid, inode->i_uid)
2102+ || !gid_eq(h_inode->i_gid, inode->i_gid))
2103+ pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
2104+ add->pathname,
2105+ i_uid_read(inode), i_gid_read(inode),
2106+ (inode->i_mode & S_IALLUGO),
2107+ i_uid_read(h_inode), i_gid_read(h_inode),
2108+ (h_inode->i_mode & S_IALLUGO));
1facf9fc 2109+ }
2110+
4f0767ce 2111+out:
1facf9fc 2112+ return err;
2113+}
2114+
2115+/*
2116+ * initialize or clean the whiteouts for an adding branch
2117+ */
2118+static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
2119+ int new_perm, struct dentry *h_root)
2120+{
2121+ int err, old_perm;
2122+ aufs_bindex_t bindex;
2123+ struct mutex *h_mtx;
2124+ struct au_wbr *wbr;
2125+ struct au_hinode *hdir;
2126+
2127+ wbr = br->br_wbr;
2128+ old_perm = br->br_perm;
2129+ br->br_perm = new_perm;
2130+ hdir = NULL;
2131+ h_mtx = NULL;
2132+ bindex = au_br_index(sb, br->br_id);
2133+ if (0 <= bindex) {
2134+ hdir = au_hi(sb->s_root->d_inode, bindex);
4a4d8108 2135+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 2136+ } else {
2137+ h_mtx = &h_root->d_inode->i_mutex;
2138+ mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
2139+ }
2140+ if (!wbr)
2141+ err = au_wh_init(h_root, br, sb);
2142+ else {
2143+ wbr_wh_write_lock(wbr);
2144+ err = au_wh_init(h_root, br, sb);
2145+ wbr_wh_write_unlock(wbr);
2146+ }
2147+ if (hdir)
4a4d8108 2148+ au_hn_imtx_unlock(hdir);
1facf9fc 2149+ else
2150+ mutex_unlock(h_mtx);
2151+ br->br_perm = old_perm;
2152+
2153+ if (!err && wbr && !au_br_writable(new_perm)) {
2154+ kfree(wbr);
2155+ br->br_wbr = NULL;
2156+ }
2157+
2158+ return err;
2159+}
2160+
2161+static int au_wbr_init(struct au_branch *br, struct super_block *sb,
2162+ int perm, struct path *path)
2163+{
2164+ int err;
4a4d8108 2165+ struct kstatfs kst;
1facf9fc 2166+ struct au_wbr *wbr;
4a4d8108 2167+ struct dentry *h_dentry;
1facf9fc 2168+
2169+ wbr = br->br_wbr;
dece6358 2170+ au_rw_init(&wbr->wbr_wh_rwsem);
1facf9fc 2171+ memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh));
2172+ atomic_set(&wbr->wbr_wh_running, 0);
2173+ wbr->wbr_bytes = 0;
2174+
4a4d8108
AM
2175+ /*
2176+ * a limit for rmdir/rename a dir
2177+ * cf. AUFS_MAX_NAMELEN in include/linux/aufs_type.h
2178+ */
7f207e10 2179+ err = vfs_statfs(path, &kst);
4a4d8108
AM
2180+ if (unlikely(err))
2181+ goto out;
2182+ err = -EINVAL;
7f207e10 2183+ h_dentry = path->dentry;
4a4d8108
AM
2184+ if (kst.f_namelen >= NAME_MAX)
2185+ err = au_br_init_wh(sb, br, perm, h_dentry);
2186+ else
2187+ pr_err("%.*s(%s), unsupported namelen %ld\n",
2188+ AuDLNPair(h_dentry), au_sbtype(h_dentry->d_sb),
2189+ kst.f_namelen);
1facf9fc 2190+
4f0767ce 2191+out:
1facf9fc 2192+ return err;
2193+}
2194+
2195+/* intialize a new branch */
2196+static int au_br_init(struct au_branch *br, struct super_block *sb,
2197+ struct au_opt_add *add)
2198+{
2199+ int err;
2200+
2201+ err = 0;
2202+ memset(&br->br_xino, 0, sizeof(br->br_xino));
2203+ mutex_init(&br->br_xino.xi_nondir_mtx);
2204+ br->br_perm = add->perm;
2205+ br->br_mnt = add->path.mnt; /* set first, mntget() later */
4a4d8108
AM
2206+ spin_lock_init(&br->br_dykey_lock);
2207+ memset(br->br_dykey, 0, sizeof(br->br_dykey));
1facf9fc 2208+ atomic_set(&br->br_count, 0);
2209+ br->br_xino_upper = AUFS_XINO_TRUNC_INIT;
2210+ atomic_set(&br->br_xino_running, 0);
2211+ br->br_id = au_new_br_id(sb);
7f207e10 2212+ AuDebugOn(br->br_id < 0);
1facf9fc 2213+
2214+ if (au_br_writable(add->perm)) {
2215+ err = au_wbr_init(br, sb, add->perm, &add->path);
2216+ if (unlikely(err))
b752ccd1 2217+ goto out_err;
1facf9fc 2218+ }
2219+
2220+ if (au_opt_test(au_mntflags(sb), XINO)) {
2221+ err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino,
2222+ au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
2223+ if (unlikely(err)) {
2224+ AuDebugOn(br->br_xino.xi_file);
b752ccd1 2225+ goto out_err;
1facf9fc 2226+ }
2227+ }
2228+
2229+ sysaufs_br_init(br);
2230+ mntget(add->path.mnt);
b752ccd1 2231+ goto out; /* success */
1facf9fc 2232+
4f0767ce 2233+out_err:
b752ccd1 2234+ br->br_mnt = NULL;
4f0767ce 2235+out:
1facf9fc 2236+ return err;
2237+}
2238+
2239+static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
2240+ struct au_branch *br, aufs_bindex_t bend,
2241+ aufs_bindex_t amount)
2242+{
2243+ struct au_branch **brp;
2244+
dece6358
AM
2245+ AuRwMustWriteLock(&sbinfo->si_rwsem);
2246+
1facf9fc 2247+ brp = sbinfo->si_branch + bindex;
2248+ memmove(brp + 1, brp, sizeof(*brp) * amount);
2249+ *brp = br;
2250+ sbinfo->si_bend++;
2251+ if (unlikely(bend < 0))
2252+ sbinfo->si_bend = 0;
2253+}
2254+
2255+static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
2256+ aufs_bindex_t bend, aufs_bindex_t amount)
2257+{
2258+ struct au_hdentry *hdp;
2259+
1308ab2a 2260+ AuRwMustWriteLock(&dinfo->di_rwsem);
2261+
1facf9fc 2262+ hdp = dinfo->di_hdentry + bindex;
2263+ memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
2264+ au_h_dentry_init(hdp);
2265+ dinfo->di_bend++;
2266+ if (unlikely(bend < 0))
2267+ dinfo->di_bstart = 0;
2268+}
2269+
2270+static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
2271+ aufs_bindex_t bend, aufs_bindex_t amount)
2272+{
2273+ struct au_hinode *hip;
2274+
1308ab2a 2275+ AuRwMustWriteLock(&iinfo->ii_rwsem);
2276+
1facf9fc 2277+ hip = iinfo->ii_hinode + bindex;
2278+ memmove(hip + 1, hip, sizeof(*hip) * amount);
2279+ hip->hi_inode = NULL;
4a4d8108 2280+ au_hn_init(hip);
1facf9fc 2281+ iinfo->ii_bend++;
2282+ if (unlikely(bend < 0))
2283+ iinfo->ii_bstart = 0;
2284+}
2285+
2286+static void au_br_do_add(struct super_block *sb, struct dentry *h_dentry,
2287+ struct au_branch *br, aufs_bindex_t bindex)
2288+{
2289+ struct dentry *root;
2290+ struct inode *root_inode;
2291+ aufs_bindex_t bend, amount;
2292+
2293+ root = sb->s_root;
2294+ root_inode = root->d_inode;
1facf9fc 2295+ bend = au_sbend(sb);
2296+ amount = bend + 1 - bindex;
53392da6 2297+ au_sbilist_lock();
1facf9fc 2298+ au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount);
2299+ au_br_do_add_hdp(au_di(root), bindex, bend, amount);
2300+ au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount);
2301+ au_set_h_dptr(root, bindex, dget(h_dentry));
2302+ au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode),
2303+ /*flags*/0);
53392da6 2304+ au_sbilist_unlock();
1facf9fc 2305+}
2306+
2307+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
2308+{
2309+ int err;
1facf9fc 2310+ aufs_bindex_t bend, add_bindex;
2311+ struct dentry *root, *h_dentry;
2312+ struct inode *root_inode;
2313+ struct au_branch *add_branch;
2314+
2315+ root = sb->s_root;
2316+ root_inode = root->d_inode;
2317+ IMustLock(root_inode);
2318+ err = test_add(sb, add, remount);
2319+ if (unlikely(err < 0))
2320+ goto out;
2321+ if (err) {
2322+ err = 0;
2323+ goto out; /* success */
2324+ }
2325+
2326+ bend = au_sbend(sb);
2327+ add_branch = au_br_alloc(sb, bend + 2, add->perm);
2328+ err = PTR_ERR(add_branch);
2329+ if (IS_ERR(add_branch))
2330+ goto out;
2331+
2332+ err = au_br_init(add_branch, sb, add);
2333+ if (unlikely(err)) {
2334+ au_br_do_free(add_branch);
2335+ goto out;
2336+ }
2337+
2338+ add_bindex = add->bindex;
2339+ h_dentry = add->path.dentry;
2340+ if (!remount)
2341+ au_br_do_add(sb, h_dentry, add_branch, add_bindex);
2342+ else {
2343+ sysaufs_brs_del(sb, add_bindex);
2344+ au_br_do_add(sb, h_dentry, add_branch, add_bindex);
2345+ sysaufs_brs_add(sb, add_bindex);
2346+ }
2347+
1308ab2a 2348+ if (!add_bindex) {
1facf9fc 2349+ au_cpup_attr_all(root_inode, /*force*/1);
1308ab2a 2350+ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
2351+ } else
1facf9fc 2352+ au_add_nlink(root_inode, h_dentry->d_inode);
1facf9fc 2353+
2354+ /*
4a4d8108 2355+ * this test/set prevents aufs from handling unnecesary notify events
027c5e7a 2356+ * of xino files, in case of re-adding a writable branch which was
1facf9fc 2357+ * once detached from aufs.
2358+ */
2359+ if (au_xino_brid(sb) < 0
2360+ && au_br_writable(add_branch->br_perm)
2361+ && !au_test_fs_bad_xino(h_dentry->d_sb)
2362+ && add_branch->br_xino.xi_file
2363+ && add_branch->br_xino.xi_file->f_dentry->d_parent == h_dentry)
2364+ au_xino_brid_set(sb, add_branch->br_id);
2365+
4f0767ce 2366+out:
1facf9fc 2367+ return err;
2368+}
2369+
2370+/* ---------------------------------------------------------------------- */
2371+
2372+/*
2373+ * delete a branch
2374+ */
2375+
2376+/* to show the line number, do not make it inlined function */
4a4d8108 2377+#define AuVerbose(do_info, fmt, ...) do { \
1facf9fc 2378+ if (do_info) \
4a4d8108 2379+ pr_info(fmt, ##__VA_ARGS__); \
1facf9fc 2380+} while (0)
2381+
027c5e7a
AM
2382+static int au_test_ibusy(struct inode *inode, aufs_bindex_t bstart,
2383+ aufs_bindex_t bend)
2384+{
2385+ return (inode && !S_ISDIR(inode->i_mode)) || bstart == bend;
2386+}
2387+
2388+static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t bstart,
2389+ aufs_bindex_t bend)
2390+{
2391+ return au_test_ibusy(dentry->d_inode, bstart, bend);
2392+}
2393+
1facf9fc 2394+/*
2395+ * test if the branch is deletable or not.
2396+ */
2397+static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
b752ccd1 2398+ unsigned int sigen, const unsigned int verbose)
1facf9fc 2399+{
2400+ int err, i, j, ndentry;
2401+ aufs_bindex_t bstart, bend;
1facf9fc 2402+ struct au_dcsub_pages dpages;
2403+ struct au_dpage *dpage;
2404+ struct dentry *d;
1facf9fc 2405+
2406+ err = au_dpages_init(&dpages, GFP_NOFS);
2407+ if (unlikely(err))
2408+ goto out;
2409+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
2410+ if (unlikely(err))
2411+ goto out_dpages;
2412+
1facf9fc 2413+ for (i = 0; !err && i < dpages.ndpage; i++) {
2414+ dpage = dpages.dpages + i;
2415+ ndentry = dpage->ndentry;
2416+ for (j = 0; !err && j < ndentry; j++) {
2417+ d = dpage->dentries[j];
027c5e7a
AM
2418+ AuDebugOn(!d->d_count);
2419+ if (!au_digen_test(d, sigen)) {
1facf9fc 2420+ di_read_lock_child(d, AuLock_IR);
027c5e7a
AM
2421+ if (unlikely(au_dbrange_test(d))) {
2422+ di_read_unlock(d, AuLock_IR);
2423+ continue;
2424+ }
2425+ } else {
1facf9fc 2426+ di_write_lock_child(d);
027c5e7a
AM
2427+ if (unlikely(au_dbrange_test(d))) {
2428+ di_write_unlock(d);
2429+ continue;
2430+ }
1facf9fc 2431+ err = au_reval_dpath(d, sigen);
2432+ if (!err)
2433+ di_downgrade_lock(d, AuLock_IR);
2434+ else {
2435+ di_write_unlock(d);
2436+ break;
2437+ }
2438+ }
2439+
027c5e7a 2440+ /* AuDbgDentry(d); */
1facf9fc 2441+ bstart = au_dbstart(d);
2442+ bend = au_dbend(d);
2443+ if (bstart <= bindex
2444+ && bindex <= bend
2445+ && au_h_dptr(d, bindex)
027c5e7a 2446+ && au_test_dbusy(d, bstart, bend)) {
1facf9fc 2447+ err = -EBUSY;
2448+ AuVerbose(verbose, "busy %.*s\n", AuDLNPair(d));
027c5e7a 2449+ AuDbgDentry(d);
1facf9fc 2450+ }
2451+ di_read_unlock(d, AuLock_IR);
2452+ }
2453+ }
2454+
4f0767ce 2455+out_dpages:
1facf9fc 2456+ au_dpages_free(&dpages);
4f0767ce 2457+out:
1facf9fc 2458+ return err;
2459+}
2460+
2461+static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
b752ccd1 2462+ unsigned int sigen, const unsigned int verbose)
1facf9fc 2463+{
2464+ int err;
7f207e10
AM
2465+ unsigned long long max, ull;
2466+ struct inode *i, **array;
1facf9fc 2467+ aufs_bindex_t bstart, bend;
1facf9fc 2468+
7f207e10
AM
2469+ array = au_iarray_alloc(sb, &max);
2470+ err = PTR_ERR(array);
2471+ if (IS_ERR(array))
2472+ goto out;
2473+
1facf9fc 2474+ err = 0;
7f207e10
AM
2475+ AuDbg("b%d\n", bindex);
2476+ for (ull = 0; !err && ull < max; ull++) {
2477+ i = array[ull];
2478+ if (i->i_ino == AUFS_ROOT_INO)
1facf9fc 2479+ continue;
2480+
7f207e10 2481+ /* AuDbgInode(i); */
537831f9 2482+ if (au_iigen(i, NULL) == sigen)
1facf9fc 2483+ ii_read_lock_child(i);
2484+ else {
2485+ ii_write_lock_child(i);
027c5e7a
AM
2486+ err = au_refresh_hinode_self(i);
2487+ au_iigen_dec(i);
1facf9fc 2488+ if (!err)
2489+ ii_downgrade_lock(i);
2490+ else {
2491+ ii_write_unlock(i);
2492+ break;
2493+ }
2494+ }
2495+
2496+ bstart = au_ibstart(i);
2497+ bend = au_ibend(i);
2498+ if (bstart <= bindex
2499+ && bindex <= bend
2500+ && au_h_iptr(i, bindex)
027c5e7a 2501+ && au_test_ibusy(i, bstart, bend)) {
1facf9fc 2502+ err = -EBUSY;
2503+ AuVerbose(verbose, "busy i%lu\n", i->i_ino);
7f207e10 2504+ AuDbgInode(i);
1facf9fc 2505+ }
2506+ ii_read_unlock(i);
2507+ }
7f207e10 2508+ au_iarray_free(array, max);
1facf9fc 2509+
7f207e10 2510+out:
1facf9fc 2511+ return err;
2512+}
2513+
b752ccd1
AM
2514+static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
2515+ const unsigned int verbose)
1facf9fc 2516+{
2517+ int err;
2518+ unsigned int sigen;
2519+
2520+ sigen = au_sigen(root->d_sb);
2521+ DiMustNoWaiters(root);
2522+ IiMustNoWaiters(root->d_inode);
2523+ di_write_unlock(root);
b752ccd1 2524+ err = test_dentry_busy(root, bindex, sigen, verbose);
1facf9fc 2525+ if (!err)
b752ccd1 2526+ err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
1facf9fc 2527+ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
2528+
2529+ return err;
2530+}
2531+
2532+static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
2533+ const aufs_bindex_t bindex,
2534+ const aufs_bindex_t bend)
2535+{
2536+ struct au_branch **brp, **p;
2537+
dece6358
AM
2538+ AuRwMustWriteLock(&sbinfo->si_rwsem);
2539+
1facf9fc 2540+ brp = sbinfo->si_branch + bindex;
2541+ if (bindex < bend)
2542+ memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex));
2543+ sbinfo->si_branch[0 + bend] = NULL;
2544+ sbinfo->si_bend--;
2545+
53392da6 2546+ p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 2547+ if (p)
2548+ sbinfo->si_branch = p;
4a4d8108 2549+ /* harmless error */
1facf9fc 2550+}
2551+
2552+static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
2553+ const aufs_bindex_t bend)
2554+{
2555+ struct au_hdentry *hdp, *p;
2556+
1308ab2a 2557+ AuRwMustWriteLock(&dinfo->di_rwsem);
2558+
4a4d8108 2559+ hdp = dinfo->di_hdentry;
1facf9fc 2560+ if (bindex < bend)
4a4d8108
AM
2561+ memmove(hdp + bindex, hdp + bindex + 1,
2562+ sizeof(*hdp) * (bend - bindex));
2563+ hdp[0 + bend].hd_dentry = NULL;
1facf9fc 2564+ dinfo->di_bend--;
2565+
53392da6 2566+ p = krealloc(hdp, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 2567+ if (p)
2568+ dinfo->di_hdentry = p;
4a4d8108 2569+ /* harmless error */
1facf9fc 2570+}
2571+
2572+static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
2573+ const aufs_bindex_t bend)
2574+{
2575+ struct au_hinode *hip, *p;
2576+
1308ab2a 2577+ AuRwMustWriteLock(&iinfo->ii_rwsem);
2578+
1facf9fc 2579+ hip = iinfo->ii_hinode + bindex;
2580+ if (bindex < bend)
2581+ memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex));
2582+ iinfo->ii_hinode[0 + bend].hi_inode = NULL;
4a4d8108 2583+ au_hn_init(iinfo->ii_hinode + bend);
1facf9fc 2584+ iinfo->ii_bend--;
2585+
53392da6 2586+ p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 2587+ if (p)
2588+ iinfo->ii_hinode = p;
4a4d8108 2589+ /* harmless error */
1facf9fc 2590+}
2591+
2592+static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
2593+ struct au_branch *br)
2594+{
2595+ aufs_bindex_t bend;
2596+ struct au_sbinfo *sbinfo;
53392da6
AM
2597+ struct dentry *root, *h_root;
2598+ struct inode *inode, *h_inode;
2599+ struct au_hinode *hinode;
1facf9fc 2600+
dece6358
AM
2601+ SiMustWriteLock(sb);
2602+
1facf9fc 2603+ root = sb->s_root;
2604+ inode = root->d_inode;
1facf9fc 2605+ sbinfo = au_sbi(sb);
2606+ bend = sbinfo->si_bend;
2607+
53392da6
AM
2608+ h_root = au_h_dptr(root, bindex);
2609+ hinode = au_hi(inode, bindex);
2610+ h_inode = au_igrab(hinode->hi_inode);
2611+ au_hiput(hinode);
1facf9fc 2612+
53392da6 2613+ au_sbilist_lock();
1facf9fc 2614+ au_br_do_del_brp(sbinfo, bindex, bend);
2615+ au_br_do_del_hdp(au_di(root), bindex, bend);
2616+ au_br_do_del_hip(au_ii(inode), bindex, bend);
53392da6
AM
2617+ au_sbilist_unlock();
2618+
2619+ dput(h_root);
2620+ iput(h_inode);
2621+ au_br_do_free(br);
1facf9fc 2622+}
2623+
2624+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
2625+{
2626+ int err, rerr, i;
2627+ unsigned int mnt_flags;
2628+ aufs_bindex_t bindex, bend, br_id;
2629+ unsigned char do_wh, verbose;
2630+ struct au_branch *br;
2631+ struct au_wbr *wbr;
2632+
2633+ err = 0;
2634+ bindex = au_find_dbindex(sb->s_root, del->h_path.dentry);
2635+ if (bindex < 0) {
2636+ if (remount)
2637+ goto out; /* success */
2638+ err = -ENOENT;
4a4d8108 2639+ pr_err("%s no such branch\n", del->pathname);
1facf9fc 2640+ goto out;
2641+ }
2642+ AuDbg("bindex b%d\n", bindex);
2643+
2644+ err = -EBUSY;
2645+ mnt_flags = au_mntflags(sb);
2646+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
2647+ bend = au_sbend(sb);
2648+ if (unlikely(!bend)) {
2649+ AuVerbose(verbose, "no more branches left\n");
2650+ goto out;
2651+ }
2652+ br = au_sbr(sb, bindex);
2653+ i = atomic_read(&br->br_count);
2654+ if (unlikely(i)) {
2655+ AuVerbose(verbose, "%d file(s) opened\n", i);
e49829fe 2656+ goto out;
1facf9fc 2657+ }
2658+
2659+ wbr = br->br_wbr;
2660+ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
2661+ if (do_wh) {
1308ab2a 2662+ /* instead of WbrWhMustWriteLock(wbr) */
2663+ SiMustWriteLock(sb);
1facf9fc 2664+ for (i = 0; i < AuBrWh_Last; i++) {
2665+ dput(wbr->wbr_wh[i]);
2666+ wbr->wbr_wh[i] = NULL;
2667+ }
2668+ }
2669+
b752ccd1 2670+ err = test_children_busy(sb->s_root, bindex, verbose);
1facf9fc 2671+ if (unlikely(err)) {
2672+ if (do_wh)
2673+ goto out_wh;
2674+ goto out;
2675+ }
2676+
2677+ err = 0;
2678+ br_id = br->br_id;
2679+ if (!remount)
2680+ au_br_do_del(sb, bindex, br);
2681+ else {
2682+ sysaufs_brs_del(sb, bindex);
2683+ au_br_do_del(sb, bindex, br);
2684+ sysaufs_brs_add(sb, bindex);
2685+ }
2686+
1308ab2a 2687+ if (!bindex) {
1facf9fc 2688+ au_cpup_attr_all(sb->s_root->d_inode, /*force*/1);
1308ab2a 2689+ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
2690+ } else
1facf9fc 2691+ au_sub_nlink(sb->s_root->d_inode, del->h_path.dentry->d_inode);
2692+ if (au_opt_test(mnt_flags, PLINK))
2693+ au_plink_half_refresh(sb, br_id);
2694+
b752ccd1 2695+ if (au_xino_brid(sb) == br_id)
1facf9fc 2696+ au_xino_brid_set(sb, -1);
2697+ goto out; /* success */
2698+
4f0767ce 2699+out_wh:
1facf9fc 2700+ /* revert */
2701+ rerr = au_br_init_wh(sb, br, br->br_perm, del->h_path.dentry);
2702+ if (rerr)
0c3ec466
AM
2703+ pr_warn("failed re-creating base whiteout, %s. (%d)\n",
2704+ del->pathname, rerr);
4f0767ce 2705+out:
1facf9fc 2706+ return err;
2707+}
2708+
2709+/* ---------------------------------------------------------------------- */
2710+
027c5e7a
AM
2711+static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg)
2712+{
2713+ int err;
2714+ aufs_bindex_t bstart, bend;
2715+ struct aufs_ibusy ibusy;
2716+ struct inode *inode, *h_inode;
2717+
2718+ err = -EPERM;
2719+ if (unlikely(!capable(CAP_SYS_ADMIN)))
2720+ goto out;
2721+
2722+ err = copy_from_user(&ibusy, arg, sizeof(ibusy));
2723+ if (!err)
2724+ err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino));
2725+ if (unlikely(err)) {
2726+ err = -EFAULT;
2727+ AuTraceErr(err);
2728+ goto out;
2729+ }
2730+
2731+ err = -EINVAL;
2732+ si_read_lock(sb, AuLock_FLUSH);
2733+ if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbend(sb)))
2734+ goto out_unlock;
2735+
2736+ err = 0;
2737+ ibusy.h_ino = 0; /* invalid */
2738+ inode = ilookup(sb, ibusy.ino);
2739+ if (!inode
2740+ || inode->i_ino == AUFS_ROOT_INO
2741+ || is_bad_inode(inode))
2742+ goto out_unlock;
2743+
2744+ ii_read_lock_child(inode);
2745+ bstart = au_ibstart(inode);
2746+ bend = au_ibend(inode);
2747+ if (bstart <= ibusy.bindex && ibusy.bindex <= bend) {
2748+ h_inode = au_h_iptr(inode, ibusy.bindex);
2749+ if (h_inode && au_test_ibusy(inode, bstart, bend))
2750+ ibusy.h_ino = h_inode->i_ino;
2751+ }
2752+ ii_read_unlock(inode);
2753+ iput(inode);
2754+
2755+out_unlock:
2756+ si_read_unlock(sb);
2757+ if (!err) {
2758+ err = __put_user(ibusy.h_ino, &arg->h_ino);
2759+ if (unlikely(err)) {
2760+ err = -EFAULT;
2761+ AuTraceErr(err);
2762+ }
2763+ }
2764+out:
2765+ return err;
2766+}
2767+
2768+long au_ibusy_ioctl(struct file *file, unsigned long arg)
2769+{
2770+ return au_ibusy(file->f_dentry->d_sb, (void __user *)arg);
2771+}
2772+
2773+#ifdef CONFIG_COMPAT
2774+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg)
2775+{
2776+ return au_ibusy(file->f_dentry->d_sb, compat_ptr(arg));
2777+}
2778+#endif
2779+
2780+/* ---------------------------------------------------------------------- */
2781+
1facf9fc 2782+/*
2783+ * change a branch permission
2784+ */
2785+
dece6358
AM
2786+static void au_warn_ima(void)
2787+{
2788+#ifdef CONFIG_IMA
1308ab2a 2789+ /* since it doesn't support mark_files_ro() */
027c5e7a 2790+ AuWarn1("RW -> RO makes IMA to produce wrong message\n");
dece6358
AM
2791+#endif
2792+}
2793+
1facf9fc 2794+static int do_need_sigen_inc(int a, int b)
2795+{
2796+ return au_br_whable(a) && !au_br_whable(b);
2797+}
2798+
2799+static int need_sigen_inc(int old, int new)
2800+{
2801+ return do_need_sigen_inc(old, new)
2802+ || do_need_sigen_inc(new, old);
2803+}
2804+
7f207e10
AM
2805+static unsigned long long au_farray_cb(void *a,
2806+ unsigned long long max __maybe_unused,
2807+ void *arg)
2808+{
2809+ unsigned long long n;
2810+ struct file **p, *f;
2811+ struct super_block *sb = arg;
2812+
2813+ n = 0;
2814+ p = a;
0c3ec466 2815+ lg_global_lock(&files_lglock);
7f207e10
AM
2816+ do_file_list_for_each_entry(sb, f) {
2817+ if (au_fi(f)
027c5e7a 2818+ && file_count(f)
7f207e10
AM
2819+ && !special_file(f->f_dentry->d_inode->i_mode)) {
2820+ get_file(f);
2821+ *p++ = f;
2822+ n++;
2823+ AuDebugOn(n > max);
2824+ }
2825+ } while_file_list_for_each_entry;
0c3ec466 2826+ lg_global_unlock(&files_lglock);
7f207e10
AM
2827+
2828+ return n;
2829+}
2830+
2831+static struct file **au_farray_alloc(struct super_block *sb,
2832+ unsigned long long *max)
2833+{
2834+ *max = atomic_long_read(&au_sbi(sb)->si_nfiles);
2835+ return au_array_alloc(max, au_farray_cb, sb);
2836+}
2837+
2838+static void au_farray_free(struct file **a, unsigned long long max)
2839+{
2840+ unsigned long long ull;
2841+
2842+ for (ull = 0; ull < max; ull++)
2843+ if (a[ull])
2844+ fput(a[ull]);
2845+ au_array_free(a);
2846+}
2847+
1facf9fc 2848+static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
2849+{
7f207e10 2850+ int err, do_warn;
027c5e7a 2851+ unsigned int mnt_flags;
7f207e10 2852+ unsigned long long ull, max;
e49829fe 2853+ aufs_bindex_t br_id;
027c5e7a 2854+ unsigned char verbose;
7f207e10 2855+ struct file *file, *hf, **array;
e49829fe
JR
2856+ struct inode *inode;
2857+ struct au_hfile *hfile;
1facf9fc 2858+
027c5e7a
AM
2859+ mnt_flags = au_mntflags(sb);
2860+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
2861+
7f207e10
AM
2862+ array = au_farray_alloc(sb, &max);
2863+ err = PTR_ERR(array);
2864+ if (IS_ERR(array))
1facf9fc 2865+ goto out;
2866+
7f207e10 2867+ do_warn = 0;
e49829fe 2868+ br_id = au_sbr_id(sb, bindex);
7f207e10
AM
2869+ for (ull = 0; ull < max; ull++) {
2870+ file = array[ull];
1facf9fc 2871+
7f207e10 2872+ /* AuDbg("%.*s\n", AuDLNPair(file->f_dentry)); */
1facf9fc 2873+ fi_read_lock(file);
2874+ if (unlikely(au_test_mmapped(file))) {
2875+ err = -EBUSY;
027c5e7a
AM
2876+ AuVerbose(verbose, "mmapped %.*s\n",
2877+ AuDLNPair(file->f_dentry));
7f207e10 2878+ AuDbgFile(file);
1facf9fc 2879+ FiMustNoWaiters(file);
2880+ fi_read_unlock(file);
7f207e10 2881+ goto out_array;
1facf9fc 2882+ }
2883+
027c5e7a 2884+ inode = file->f_dentry->d_inode;
e49829fe
JR
2885+ hfile = &au_fi(file)->fi_htop;
2886+ hf = hfile->hf_file;
2887+ if (!S_ISREG(inode->i_mode)
1facf9fc 2888+ || !(file->f_mode & FMODE_WRITE)
e49829fe 2889+ || hfile->hf_br->br_id != br_id
7f207e10
AM
2890+ || !(hf->f_mode & FMODE_WRITE))
2891+ array[ull] = NULL;
2892+ else {
2893+ do_warn = 1;
2894+ get_file(file);
1facf9fc 2895+ }
2896+
1facf9fc 2897+ FiMustNoWaiters(file);
2898+ fi_read_unlock(file);
7f207e10
AM
2899+ fput(file);
2900+ }
1facf9fc 2901+
2902+ err = 0;
7f207e10 2903+ if (do_warn)
dece6358 2904+ au_warn_ima();
7f207e10
AM
2905+
2906+ for (ull = 0; ull < max; ull++) {
2907+ file = array[ull];
2908+ if (!file)
2909+ continue;
2910+
1facf9fc 2911+ /* todo: already flushed? */
2912+ /* cf. fs/super.c:mark_files_ro() */
7f207e10
AM
2913+ /* fi_read_lock(file); */
2914+ hfile = &au_fi(file)->fi_htop;
2915+ hf = hfile->hf_file;
2916+ /* fi_read_unlock(file); */
027c5e7a 2917+ spin_lock(&hf->f_lock);
1facf9fc 2918+ hf->f_mode &= ~FMODE_WRITE;
027c5e7a 2919+ spin_unlock(&hf->f_lock);
1facf9fc 2920+ if (!file_check_writeable(hf)) {
2921+ file_release_write(hf);
b4510431 2922+ vfsub_mnt_drop_write(hf->f_vfsmnt);
1facf9fc 2923+ }
2924+ }
2925+
7f207e10
AM
2926+out_array:
2927+ au_farray_free(array, max);
4f0767ce 2928+out:
7f207e10 2929+ AuTraceErr(err);
1facf9fc 2930+ return err;
2931+}
2932+
2933+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 2934+ int *do_refresh)
1facf9fc 2935+{
2936+ int err, rerr;
2937+ aufs_bindex_t bindex;
1308ab2a 2938+ struct path path;
1facf9fc 2939+ struct dentry *root;
2940+ struct au_branch *br;
2941+
2942+ root = sb->s_root;
1facf9fc 2943+ bindex = au_find_dbindex(root, mod->h_root);
2944+ if (bindex < 0) {
2945+ if (remount)
2946+ return 0; /* success */
2947+ err = -ENOENT;
4a4d8108 2948+ pr_err("%s no such branch\n", mod->path);
1facf9fc 2949+ goto out;
2950+ }
2951+ AuDbg("bindex b%d\n", bindex);
2952+
2953+ err = test_br(mod->h_root->d_inode, mod->perm, mod->path);
2954+ if (unlikely(err))
2955+ goto out;
2956+
2957+ br = au_sbr(sb, bindex);
2958+ if (br->br_perm == mod->perm)
2959+ return 0; /* success */
2960+
2961+ if (au_br_writable(br->br_perm)) {
2962+ /* remove whiteout base */
2963+ err = au_br_init_wh(sb, br, mod->perm, mod->h_root);
2964+ if (unlikely(err))
2965+ goto out;
2966+
2967+ if (!au_br_writable(mod->perm)) {
2968+ /* rw --> ro, file might be mmapped */
2969+ DiMustNoWaiters(root);
2970+ IiMustNoWaiters(root->d_inode);
2971+ di_write_unlock(root);
2972+ err = au_br_mod_files_ro(sb, bindex);
2973+ /* aufs_write_lock() calls ..._child() */
2974+ di_write_lock_child(root);
2975+
2976+ if (unlikely(err)) {
2977+ rerr = -ENOMEM;
2978+ br->br_wbr = kmalloc(sizeof(*br->br_wbr),
2979+ GFP_NOFS);
1308ab2a 2980+ if (br->br_wbr) {
2981+ path.mnt = br->br_mnt;
2982+ path.dentry = mod->h_root;
2983+ rerr = au_wbr_init(br, sb, br->br_perm,
2984+ &path);
2985+ }
1facf9fc 2986+ if (unlikely(rerr)) {
2987+ AuIOErr("nested error %d (%d)\n",
2988+ rerr, err);
2989+ br->br_perm = mod->perm;
2990+ }
2991+ }
2992+ }
2993+ } else if (au_br_writable(mod->perm)) {
2994+ /* ro --> rw */
2995+ err = -ENOMEM;
2996+ br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS);
2997+ if (br->br_wbr) {
1308ab2a 2998+ path.mnt = br->br_mnt;
2999+ path.dentry = mod->h_root;
1facf9fc 3000+ err = au_wbr_init(br, sb, mod->perm, &path);
3001+ if (unlikely(err)) {
3002+ kfree(br->br_wbr);
3003+ br->br_wbr = NULL;
3004+ }
3005+ }
3006+ }
3007+
3008+ if (!err) {
7f207e10 3009+ *do_refresh |= need_sigen_inc(br->br_perm, mod->perm);
1facf9fc 3010+ br->br_perm = mod->perm;
3011+ }
3012+
4f0767ce 3013+out:
7f207e10 3014+ AuTraceErr(err);
1facf9fc 3015+ return err;
3016+}
7f207e10
AM
3017diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
3018--- /usr/share/empty/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100
1716fcea
AM
3019+++ linux/fs/aufs/branch.h 2013-02-19 08:40:03.946892891 +0100
3020@@ -0,0 +1,236 @@
1facf9fc 3021+/*
7a9e40b8 3022+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 3023+ *
3024+ * This program, aufs is free software; you can redistribute it and/or modify
3025+ * it under the terms of the GNU General Public License as published by
3026+ * the Free Software Foundation; either version 2 of the License, or
3027+ * (at your option) any later version.
dece6358
AM
3028+ *
3029+ * This program is distributed in the hope that it will be useful,
3030+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3031+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3032+ * GNU General Public License for more details.
3033+ *
3034+ * You should have received a copy of the GNU General Public License
3035+ * along with this program; if not, write to the Free Software
3036+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 3037+ */
3038+
3039+/*
3040+ * branch filesystems and xino for them
3041+ */
3042+
3043+#ifndef __AUFS_BRANCH_H__
3044+#define __AUFS_BRANCH_H__
3045+
3046+#ifdef __KERNEL__
3047+
1facf9fc 3048+#include <linux/mount.h>
4a4d8108 3049+#include "dynop.h"
1facf9fc 3050+#include "rwsem.h"
3051+#include "super.h"
3052+
3053+/* ---------------------------------------------------------------------- */
3054+
3055+/* a xino file */
3056+struct au_xino_file {
3057+ struct file *xi_file;
3058+ struct mutex xi_nondir_mtx;
3059+
3060+ /* todo: make xino files an array to support huge inode number */
3061+
3062+#ifdef CONFIG_DEBUG_FS
3063+ struct dentry *xi_dbgaufs;
3064+#endif
3065+};
3066+
3067+/* members for writable branch only */
3068+enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
3069+struct au_wbr {
dece6358 3070+ struct au_rwsem wbr_wh_rwsem;
1facf9fc 3071+ struct dentry *wbr_wh[AuBrWh_Last];
4a4d8108 3072+ atomic_t wbr_wh_running;
1facf9fc 3073+#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
3074+#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
3075+#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
3076+
3077+ /* mfs mode */
3078+ unsigned long long wbr_bytes;
3079+};
3080+
4a4d8108
AM
3081+/* ext2 has 3 types of operations at least, ext3 has 4 */
3082+#define AuBrDynOp (AuDyLast * 4)
3083+
1716fcea
AM
3084+#ifdef CONFIG_AUFS_HFSNOTIFY
3085+/* support for asynchronous destruction */
3086+struct au_br_hfsnotify {
3087+ struct fsnotify_group *hfsn_group;
3088+};
3089+#endif
3090+
1facf9fc 3091+/* protected by superblock rwsem */
3092+struct au_branch {
3093+ struct au_xino_file br_xino;
3094+
3095+ aufs_bindex_t br_id;
3096+
3097+ int br_perm;
3098+ struct vfsmount *br_mnt;
4a4d8108
AM
3099+ spinlock_t br_dykey_lock;
3100+ struct au_dykey *br_dykey[AuBrDynOp];
1facf9fc 3101+ atomic_t br_count;
3102+
3103+ struct au_wbr *br_wbr;
3104+
3105+ /* xino truncation */
3106+ blkcnt_t br_xino_upper; /* watermark in blocks */
3107+ atomic_t br_xino_running;
3108+
027c5e7a 3109+#ifdef CONFIG_AUFS_HFSNOTIFY
1716fcea 3110+ struct au_br_hfsnotify *br_hfsn;
027c5e7a
AM
3111+#endif
3112+
1facf9fc 3113+#ifdef CONFIG_SYSFS
3114+ /* an entry under sysfs per mount-point */
3115+ char br_name[8];
3116+ struct attribute br_attr;
3117+#endif
3118+};
3119+
3120+/* ---------------------------------------------------------------------- */
3121+
1e00d052
AM
3122+/* branch permissions and attributes */
3123+#define AuBrPerm_RW 1 /* writable, hardlinkable wh */
3124+#define AuBrPerm_RO (1 << 1) /* readonly */
3125+#define AuBrPerm_RR (1 << 2) /* natively readonly */
3126+#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
1facf9fc 3127+
1e00d052 3128+#define AuBrRAttr_WH (1 << 3) /* whiteout-able */
1facf9fc 3129+
1e00d052 3130+#define AuBrWAttr_NoLinkWH (1 << 4) /* un-hardlinkable whiteouts */
1facf9fc 3131+
3132+static inline int au_br_writable(int brperm)
3133+{
1e00d052 3134+ return brperm & AuBrPerm_RW;
1facf9fc 3135+}
3136+
3137+static inline int au_br_whable(int brperm)
3138+{
1e00d052
AM
3139+ return brperm & (AuBrPerm_RW | AuBrRAttr_WH);
3140+}
3141+
3142+static inline int au_br_wh_linkable(int brperm)
3143+{
3144+ return !(brperm & AuBrWAttr_NoLinkWH);
1facf9fc 3145+}
3146+
3147+static inline int au_br_rdonly(struct au_branch *br)
3148+{
3149+ return ((br->br_mnt->mnt_sb->s_flags & MS_RDONLY)
3150+ || !au_br_writable(br->br_perm))
3151+ ? -EROFS : 0;
3152+}
3153+
4a4d8108 3154+static inline int au_br_hnotifyable(int brperm __maybe_unused)
1facf9fc 3155+{
4a4d8108 3156+#ifdef CONFIG_AUFS_HNOTIFY
1e00d052 3157+ return !(brperm & AuBrPerm_RR);
1facf9fc 3158+#else
3159+ return 0;
3160+#endif
3161+}
3162+
3163+/* ---------------------------------------------------------------------- */
3164+
3165+/* branch.c */
3166+struct au_sbinfo;
3167+void au_br_free(struct au_sbinfo *sinfo);
3168+int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
3169+struct au_opt_add;
3170+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
3171+struct au_opt_del;
3172+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
027c5e7a
AM
3173+long au_ibusy_ioctl(struct file *file, unsigned long arg);
3174+#ifdef CONFIG_COMPAT
3175+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
3176+#endif
1facf9fc 3177+struct au_opt_mod;
3178+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 3179+ int *do_refresh);
1facf9fc 3180+
3181+/* xino.c */
3182+static const loff_t au_loff_max = LLONG_MAX;
3183+
3184+int au_xib_trunc(struct super_block *sb);
3185+ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size,
3186+ loff_t *pos);
3187+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
3188+ loff_t *pos);
3189+struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
3190+struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
3191+ino_t au_xino_new_ino(struct super_block *sb);
b752ccd1 3192+void au_xino_delete_inode(struct inode *inode, const int unlinked);
1facf9fc 3193+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
3194+ ino_t ino);
3195+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
3196+ ino_t *ino);
3197+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
3198+ struct file *base_file, int do_test);
3199+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
3200+
3201+struct au_opt_xino;
3202+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
3203+void au_xino_clr(struct super_block *sb);
3204+struct file *au_xino_def(struct super_block *sb);
3205+int au_xino_path(struct seq_file *seq, struct file *file);
3206+
3207+/* ---------------------------------------------------------------------- */
3208+
3209+/* Superblock to branch */
3210+static inline
3211+aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
3212+{
3213+ return au_sbr(sb, bindex)->br_id;
3214+}
3215+
3216+static inline
3217+struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
3218+{
3219+ return au_sbr(sb, bindex)->br_mnt;
3220+}
3221+
3222+static inline
3223+struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
3224+{
3225+ return au_sbr_mnt(sb, bindex)->mnt_sb;
3226+}
3227+
3228+static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
3229+{
e49829fe 3230+ atomic_dec(&au_sbr(sb, bindex)->br_count);
1facf9fc 3231+}
3232+
3233+static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
3234+{
3235+ return au_sbr(sb, bindex)->br_perm;
3236+}
3237+
3238+static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
3239+{
3240+ return au_br_whable(au_sbr_perm(sb, bindex));
3241+}
3242+
3243+/* ---------------------------------------------------------------------- */
3244+
3245+/*
3246+ * wbr_wh_read_lock, wbr_wh_write_lock
3247+ * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
3248+ */
3249+AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
3250+
dece6358
AM
3251+#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
3252+#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
3253+#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
3254+
1facf9fc 3255+#endif /* __KERNEL__ */
3256+#endif /* __AUFS_BRANCH_H__ */
7f207e10
AM
3257diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
3258--- /usr/share/empty/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100
7a9e40b8 3259+++ linux/fs/aufs/conf.mk 2012-08-26 08:39:00.757174634 +0200
2cbb1c4b 3260@@ -0,0 +1,38 @@
4a4d8108
AM
3261+
3262+AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
3263+
3264+define AuConf
3265+ifdef ${1}
3266+AuConfStr += ${1}=${${1}}
3267+endif
3268+endef
3269+
b752ccd1 3270+AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
e49829fe 3271+ SBILIST \
7f207e10 3272+ HNOTIFY HFSNOTIFY \
4a4d8108
AM
3273+ EXPORT INO_T_64 \
3274+ RDU \
2cbb1c4b 3275+ PROC_MAP \
4a4d8108
AM
3276+ SP_IATTR \
3277+ SHWH \
3278+ BR_RAMFS \
3279+ BR_FUSE POLL \
3280+ BR_HFSPLUS \
3281+ BDEV_LOOP \
b752ccd1
AM
3282+ DEBUG MAGIC_SYSRQ
3283+$(foreach i, ${AuConfAll}, \
4a4d8108
AM
3284+ $(eval $(call AuConf,CONFIG_AUFS_${i})))
3285+
3286+AuConfName = ${obj}/conf.str
3287+${AuConfName}.tmp: FORCE
3288+ @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
3289+${AuConfName}: ${AuConfName}.tmp
3290+ @diff -q $< $@ > /dev/null 2>&1 || { \
3291+ echo ' GEN ' $@; \
3292+ cp -p $< $@; \
3293+ }
3294+FORCE:
3295+clean-files += ${AuConfName} ${AuConfName}.tmp
3296+${obj}/sysfs.o: ${AuConfName}
b752ccd1
AM
3297+
3298+-include ${srctree}/${src}/conf_priv.mk
7f207e10
AM
3299diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
3300--- /usr/share/empty/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
a2a7ad62 3301+++ linux/fs/aufs/cpup.c 2013-03-14 20:07:41.038119650 +0100
b4510431 3302@@ -0,0 +1,1085 @@
1facf9fc 3303+/*
7a9e40b8 3304+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 3305+ *
3306+ * This program, aufs is free software; you can redistribute it and/or modify
3307+ * it under the terms of the GNU General Public License as published by
3308+ * the Free Software Foundation; either version 2 of the License, or
3309+ * (at your option) any later version.
dece6358
AM
3310+ *
3311+ * This program is distributed in the hope that it will be useful,
3312+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3313+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3314+ * GNU General Public License for more details.
3315+ *
3316+ * You should have received a copy of the GNU General Public License
3317+ * along with this program; if not, write to the Free Software
3318+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 3319+ */
3320+
3321+/*
3322+ * copy-up functions, see wbr_policy.c for copy-down
3323+ */
3324+
3325+#include <linux/fs_stack.h>
dece6358 3326+#include <linux/mm.h>
1facf9fc 3327+#include "aufs.h"
3328+
3329+void au_cpup_attr_flags(struct inode *dst, struct inode *src)
3330+{
3331+ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
3332+ | S_NOATIME | S_NOCMTIME;
3333+
3334+ dst->i_flags |= src->i_flags & ~mask;
3335+ if (au_test_fs_notime(dst->i_sb))
3336+ dst->i_flags |= S_NOATIME | S_NOCMTIME;
3337+}
3338+
3339+void au_cpup_attr_timesizes(struct inode *inode)
3340+{
3341+ struct inode *h_inode;
3342+
3343+ h_inode = au_h_iptr(inode, au_ibstart(inode));
3344+ fsstack_copy_attr_times(inode, h_inode);
4a4d8108 3345+ fsstack_copy_inode_size(inode, h_inode);
1facf9fc 3346+}
3347+
3348+void au_cpup_attr_nlink(struct inode *inode, int force)
3349+{
3350+ struct inode *h_inode;
3351+ struct super_block *sb;
3352+ aufs_bindex_t bindex, bend;
3353+
3354+ sb = inode->i_sb;
3355+ bindex = au_ibstart(inode);
3356+ h_inode = au_h_iptr(inode, bindex);
3357+ if (!force
3358+ && !S_ISDIR(h_inode->i_mode)
3359+ && au_opt_test(au_mntflags(sb), PLINK)
3360+ && au_plink_test(inode))
3361+ return;
3362+
7eafdf33
AM
3363+ /*
3364+ * 0 can happen in revalidating.
3365+ * h_inode->i_mutex is not held, but it is harmless since once i_nlink
3366+ * reaches 0, it will never become positive.
3367+ */
92d182d2 3368+ set_nlink(inode, h_inode->i_nlink);
1facf9fc 3369+
3370+ /*
3371+ * fewer nlink makes find(1) noisy, but larger nlink doesn't.
3372+ * it may includes whplink directory.
3373+ */
3374+ if (S_ISDIR(h_inode->i_mode)) {
3375+ bend = au_ibend(inode);
3376+ for (bindex++; bindex <= bend; bindex++) {
3377+ h_inode = au_h_iptr(inode, bindex);
3378+ if (h_inode)
3379+ au_add_nlink(inode, h_inode);
3380+ }
3381+ }
3382+}
3383+
3384+void au_cpup_attr_changeable(struct inode *inode)
3385+{
3386+ struct inode *h_inode;
3387+
3388+ h_inode = au_h_iptr(inode, au_ibstart(inode));
3389+ inode->i_mode = h_inode->i_mode;
3390+ inode->i_uid = h_inode->i_uid;
3391+ inode->i_gid = h_inode->i_gid;
3392+ au_cpup_attr_timesizes(inode);
3393+ au_cpup_attr_flags(inode, h_inode);
3394+}
3395+
3396+void au_cpup_igen(struct inode *inode, struct inode *h_inode)
3397+{
3398+ struct au_iinfo *iinfo = au_ii(inode);
3399+
1308ab2a 3400+ IiMustWriteLock(inode);
3401+
1facf9fc 3402+ iinfo->ii_higen = h_inode->i_generation;
3403+ iinfo->ii_hsb1 = h_inode->i_sb;
3404+}
3405+
3406+void au_cpup_attr_all(struct inode *inode, int force)
3407+{
3408+ struct inode *h_inode;
3409+
3410+ h_inode = au_h_iptr(inode, au_ibstart(inode));
3411+ au_cpup_attr_changeable(inode);
3412+ if (inode->i_nlink > 0)
3413+ au_cpup_attr_nlink(inode, force);
3414+ inode->i_rdev = h_inode->i_rdev;
3415+ inode->i_blkbits = h_inode->i_blkbits;
3416+ au_cpup_igen(inode, h_inode);
3417+}
3418+
3419+/* ---------------------------------------------------------------------- */
3420+
3421+/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
3422+
3423+/* keep the timestamps of the parent dir when cpup */
3424+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
3425+ struct path *h_path)
3426+{
3427+ struct inode *h_inode;
3428+
3429+ dt->dt_dentry = dentry;
3430+ dt->dt_h_path = *h_path;
3431+ h_inode = h_path->dentry->d_inode;
3432+ dt->dt_atime = h_inode->i_atime;
3433+ dt->dt_mtime = h_inode->i_mtime;
3434+ /* smp_mb(); */
3435+}
3436+
3437+void au_dtime_revert(struct au_dtime *dt)
3438+{
3439+ struct iattr attr;
3440+ int err;
3441+
3442+ attr.ia_atime = dt->dt_atime;
3443+ attr.ia_mtime = dt->dt_mtime;
3444+ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
3445+ | ATTR_ATIME | ATTR_ATIME_SET;
3446+
3447+ err = vfsub_notify_change(&dt->dt_h_path, &attr);
3448+ if (unlikely(err))
0c3ec466 3449+ pr_warn("restoring timestamps failed(%d). ignored\n", err);
1facf9fc 3450+}
3451+
3452+/* ---------------------------------------------------------------------- */
3453+
3454+static noinline_for_stack
3455+int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src)
3456+{
3457+ int err, sbits;
3458+ struct iattr ia;
3459+ struct path h_path;
1308ab2a 3460+ struct inode *h_isrc, *h_idst;
1facf9fc 3461+
3462+ h_path.dentry = au_h_dptr(dst, bindex);
1308ab2a 3463+ h_idst = h_path.dentry->d_inode;
1facf9fc 3464+ h_path.mnt = au_sbr_mnt(dst->d_sb, bindex);
3465+ h_isrc = h_src->d_inode;
1308ab2a 3466+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
1facf9fc 3467+ | ATTR_ATIME | ATTR_MTIME
3468+ | ATTR_ATIME_SET | ATTR_MTIME_SET;
1facf9fc 3469+ ia.ia_uid = h_isrc->i_uid;
3470+ ia.ia_gid = h_isrc->i_gid;
3471+ ia.ia_atime = h_isrc->i_atime;
3472+ ia.ia_mtime = h_isrc->i_mtime;
1308ab2a 3473+ if (h_idst->i_mode != h_isrc->i_mode
3474+ && !S_ISLNK(h_idst->i_mode)) {
3475+ ia.ia_valid |= ATTR_MODE;
3476+ ia.ia_mode = h_isrc->i_mode;
3477+ }
3478+ sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
3479+ au_cpup_attr_flags(h_idst, h_isrc);
1facf9fc 3480+ err = vfsub_notify_change(&h_path, &ia);
3481+
3482+ /* is this nfs only? */
3483+ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
3484+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
3485+ ia.ia_mode = h_isrc->i_mode;
3486+ err = vfsub_notify_change(&h_path, &ia);
3487+ }
3488+
3489+ return err;
3490+}
3491+
3492+/* ---------------------------------------------------------------------- */
3493+
3494+static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
3495+ char *buf, unsigned long blksize)
3496+{
3497+ int err;
3498+ size_t sz, rbytes, wbytes;
3499+ unsigned char all_zero;
3500+ char *p, *zp;
3501+ struct mutex *h_mtx;
3502+ /* reduce stack usage */
3503+ struct iattr *ia;
3504+
3505+ zp = page_address(ZERO_PAGE(0));
3506+ if (unlikely(!zp))
3507+ return -ENOMEM; /* possible? */
3508+
3509+ err = 0;
3510+ all_zero = 0;
3511+ while (len) {
3512+ AuDbg("len %lld\n", len);
3513+ sz = blksize;
3514+ if (len < blksize)
3515+ sz = len;
3516+
3517+ rbytes = 0;
3518+ /* todo: signal_pending? */
3519+ while (!rbytes || err == -EAGAIN || err == -EINTR) {
3520+ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
3521+ err = rbytes;
3522+ }
3523+ if (unlikely(err < 0))
3524+ break;
3525+
3526+ all_zero = 0;
3527+ if (len >= rbytes && rbytes == blksize)
3528+ all_zero = !memcmp(buf, zp, rbytes);
3529+ if (!all_zero) {
3530+ wbytes = rbytes;
3531+ p = buf;
3532+ while (wbytes) {
3533+ size_t b;
3534+
3535+ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
3536+ err = b;
3537+ /* todo: signal_pending? */
3538+ if (unlikely(err == -EAGAIN || err == -EINTR))
3539+ continue;
3540+ if (unlikely(err < 0))
3541+ break;
3542+ wbytes -= b;
3543+ p += b;
3544+ }
3545+ } else {
3546+ loff_t res;
3547+
3548+ AuLabel(hole);
3549+ res = vfsub_llseek(dst, rbytes, SEEK_CUR);
3550+ err = res;
3551+ if (unlikely(res < 0))
3552+ break;
3553+ }
3554+ len -= rbytes;
3555+ err = 0;
3556+ }
3557+
3558+ /* the last block may be a hole */
3559+ if (!err && all_zero) {
3560+ AuLabel(last hole);
3561+
3562+ err = 1;
3563+ if (au_test_nfs(dst->f_dentry->d_sb)) {
3564+ /* nfs requires this step to make last hole */
3565+ /* is this only nfs? */
3566+ do {
3567+ /* todo: signal_pending? */
3568+ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
3569+ } while (err == -EAGAIN || err == -EINTR);
3570+ if (err == 1)
3571+ dst->f_pos--;
3572+ }
3573+
3574+ if (err == 1) {
3575+ ia = (void *)buf;
3576+ ia->ia_size = dst->f_pos;
3577+ ia->ia_valid = ATTR_SIZE | ATTR_FILE;
3578+ ia->ia_file = dst;
3579+ h_mtx = &dst->f_dentry->d_inode->i_mutex;
3580+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
3581+ err = vfsub_notify_change(&dst->f_path, ia);
3582+ mutex_unlock(h_mtx);
3583+ }
3584+ }
3585+
3586+ return err;
3587+}
3588+
3589+int au_copy_file(struct file *dst, struct file *src, loff_t len)
3590+{
3591+ int err;
3592+ unsigned long blksize;
3593+ unsigned char do_kfree;
3594+ char *buf;
3595+
3596+ err = -ENOMEM;
3597+ blksize = dst->f_dentry->d_sb->s_blocksize;
3598+ if (!blksize || PAGE_SIZE < blksize)
3599+ blksize = PAGE_SIZE;
3600+ AuDbg("blksize %lu\n", blksize);
3601+ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
3602+ if (do_kfree)
3603+ buf = kmalloc(blksize, GFP_NOFS);
3604+ else
3605+ buf = (void *)__get_free_page(GFP_NOFS);
3606+ if (unlikely(!buf))
3607+ goto out;
3608+
3609+ if (len > (1 << 22))
3610+ AuDbg("copying a large file %lld\n", (long long)len);
3611+
3612+ src->f_pos = 0;
3613+ dst->f_pos = 0;
3614+ err = au_do_copy_file(dst, src, len, buf, blksize);
3615+ if (do_kfree)
3616+ kfree(buf);
3617+ else
3618+ free_page((unsigned long)buf);
3619+
4f0767ce 3620+out:
1facf9fc 3621+ return err;
3622+}
3623+
3624+/*
3625+ * to support a sparse file which is opened with O_APPEND,
3626+ * we need to close the file.
3627+ */
3628+static int au_cp_regular(struct dentry *dentry, aufs_bindex_t bdst,
4a4d8108 3629+ aufs_bindex_t bsrc, loff_t len)
1facf9fc 3630+{
3631+ int err, i;
3632+ enum { SRC, DST };
3633+ struct {
3634+ aufs_bindex_t bindex;
3635+ unsigned int flags;
3636+ struct dentry *dentry;
3637+ struct file *file;
3638+ void *label, *label_file;
3639+ } *f, file[] = {
3640+ {
3641+ .bindex = bsrc,
3642+ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
3643+ .file = NULL,
3644+ .label = &&out,
3645+ .label_file = &&out_src
3646+ },
3647+ {
3648+ .bindex = bdst,
3649+ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
3650+ .file = NULL,
3651+ .label = &&out_src,
3652+ .label_file = &&out_dst
3653+ }
3654+ };
3655+ struct super_block *sb;
3656+
3657+ /* bsrc branch can be ro/rw. */
3658+ sb = dentry->d_sb;
3659+ f = file;
3660+ for (i = 0; i < 2; i++, f++) {
3661+ f->dentry = au_h_dptr(dentry, f->bindex);
3662+ f->file = au_h_open(dentry, f->bindex, f->flags, /*file*/NULL);
3663+ err = PTR_ERR(f->file);
3664+ if (IS_ERR(f->file))
3665+ goto *f->label;
3666+ err = -EINVAL;
3667+ if (unlikely(!f->file->f_op))
3668+ goto *f->label_file;
3669+ }
3670+
3671+ /* try stopping to update while we copyup */
3672+ IMustLock(file[SRC].dentry->d_inode);
3673+ err = au_copy_file(file[DST].file, file[SRC].file, len);
3674+
4f0767ce 3675+out_dst:
1facf9fc 3676+ fput(file[DST].file);
3677+ au_sbr_put(sb, file[DST].bindex);
4f0767ce 3678+out_src:
1facf9fc 3679+ fput(file[SRC].file);
3680+ au_sbr_put(sb, file[SRC].bindex);
4f0767ce 3681+out:
1facf9fc 3682+ return err;
3683+}
3684+
3685+static int au_do_cpup_regular(struct dentry *dentry, aufs_bindex_t bdst,
3686+ aufs_bindex_t bsrc, loff_t len,
3687+ struct inode *h_dir, struct path *h_path)
3688+{
3689+ int err, rerr;
3690+ loff_t l;
3691+
3692+ err = 0;
3693+ l = i_size_read(au_h_iptr(dentry->d_inode, bsrc));
3694+ if (len == -1 || l < len)
3695+ len = l;
3696+ if (len)
3697+ err = au_cp_regular(dentry, bdst, bsrc, len);
3698+ if (!err)
3699+ goto out; /* success */
3700+
3701+ rerr = vfsub_unlink(h_dir, h_path, /*force*/0);
3702+ if (rerr) {
3703+ AuIOErr("failed unlinking cpup-ed %.*s(%d, %d)\n",
3704+ AuDLNPair(h_path->dentry), err, rerr);
3705+ err = -EIO;
3706+ }
3707+
4f0767ce 3708+out:
1facf9fc 3709+ return err;
3710+}
3711+
3712+static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
3713+ struct inode *h_dir)
3714+{
3715+ int err, symlen;
3716+ mm_segment_t old_fs;
b752ccd1
AM
3717+ union {
3718+ char *k;
3719+ char __user *u;
3720+ } sym;
1facf9fc 3721+
3722+ err = -ENOSYS;
3723+ if (unlikely(!h_src->d_inode->i_op->readlink))
3724+ goto out;
3725+
3726+ err = -ENOMEM;
537831f9 3727+ sym.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 3728+ if (unlikely(!sym.k))
1facf9fc 3729+ goto out;
3730+
9dbd164d 3731+ /* unnecessary to support mmap_sem since symlink is not mmap-able */
1facf9fc 3732+ old_fs = get_fs();
3733+ set_fs(KERNEL_DS);
b752ccd1 3734+ symlen = h_src->d_inode->i_op->readlink(h_src, sym.u, PATH_MAX);
1facf9fc 3735+ err = symlen;
3736+ set_fs(old_fs);
3737+
3738+ if (symlen > 0) {
b752ccd1
AM
3739+ sym.k[symlen] = 0;
3740+ err = vfsub_symlink(h_dir, h_path, sym.k);
1facf9fc 3741+ }
537831f9 3742+ free_page((unsigned long)sym.k);
1facf9fc 3743+
4f0767ce 3744+out:
1facf9fc 3745+ return err;
3746+}
3747+
3748+/* return with the lower dst inode is locked */
3749+static noinline_for_stack
3750+int cpup_entry(struct dentry *dentry, aufs_bindex_t bdst,
3751+ aufs_bindex_t bsrc, loff_t len, unsigned int flags,
3752+ struct dentry *dst_parent)
3753+{
3754+ int err;
3755+ umode_t mode;
3756+ unsigned int mnt_flags;
3757+ unsigned char isdir;
3758+ const unsigned char do_dt = !!au_ftest_cpup(flags, DTIME);
3759+ struct au_dtime dt;
3760+ struct path h_path;
3761+ struct dentry *h_src, *h_dst, *h_parent;
3762+ struct inode *h_inode, *h_dir;
3763+ struct super_block *sb;
3764+
3765+ /* bsrc branch can be ro/rw. */
3766+ h_src = au_h_dptr(dentry, bsrc);
3767+ h_inode = h_src->d_inode;
3768+ AuDebugOn(h_inode != au_h_iptr(dentry->d_inode, bsrc));
3769+
3770+ /* try stopping to be referenced while we are creating */
3771+ h_dst = au_h_dptr(dentry, bdst);
3772+ h_parent = h_dst->d_parent; /* dir inode is locked */
3773+ h_dir = h_parent->d_inode;
3774+ IMustLock(h_dir);
3775+ AuDebugOn(h_parent != h_dst->d_parent);
3776+
3777+ sb = dentry->d_sb;
3778+ h_path.mnt = au_sbr_mnt(sb, bdst);
3779+ if (do_dt) {
3780+ h_path.dentry = h_parent;
3781+ au_dtime_store(&dt, dst_parent, &h_path);
3782+ }
3783+ h_path.dentry = h_dst;
3784+
3785+ isdir = 0;
3786+ mode = h_inode->i_mode;
3787+ switch (mode & S_IFMT) {
3788+ case S_IFREG:
3789+ /* try stopping to update while we are referencing */
3790+ IMustLock(h_inode);
b4510431
AM
3791+ err = vfsub_create(h_dir, &h_path, mode | S_IWUSR,
3792+ /*want_excl*/true);
1facf9fc 3793+ if (!err)
3794+ err = au_do_cpup_regular
3795+ (dentry, bdst, bsrc, len,
3796+ au_h_iptr(dst_parent->d_inode, bdst), &h_path);
3797+ break;
3798+ case S_IFDIR:
3799+ isdir = 1;
3800+ err = vfsub_mkdir(h_dir, &h_path, mode);
3801+ if (!err) {
3802+ /*
3803+ * strange behaviour from the users view,
3804+ * particularry setattr case
3805+ */
3806+ if (au_ibstart(dst_parent->d_inode) == bdst)
3807+ au_cpup_attr_nlink(dst_parent->d_inode,
3808+ /*force*/1);
3809+ au_cpup_attr_nlink(dentry->d_inode, /*force*/1);
3810+ }
3811+ break;
3812+ case S_IFLNK:
3813+ err = au_do_cpup_symlink(&h_path, h_src, h_dir);
3814+ break;
3815+ case S_IFCHR:
3816+ case S_IFBLK:
3817+ AuDebugOn(!capable(CAP_MKNOD));
3818+ /*FALLTHROUGH*/
3819+ case S_IFIFO:
3820+ case S_IFSOCK:
3821+ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
3822+ break;
3823+ default:
3824+ AuIOErr("Unknown inode type 0%o\n", mode);
3825+ err = -EIO;
3826+ }
3827+
3828+ mnt_flags = au_mntflags(sb);
3829+ if (!au_opt_test(mnt_flags, UDBA_NONE)
3830+ && !isdir
3831+ && au_opt_test(mnt_flags, XINO)
3832+ && h_inode->i_nlink == 1
3833+ /* todo: unnecessary? */
3834+ /* && dentry->d_inode->i_nlink == 1 */
3835+ && bdst < bsrc
3836+ && !au_ftest_cpup(flags, KEEPLINO))
1308ab2a 3837+ au_xino_write(sb, bsrc, h_inode->i_ino, /*ino*/0);
1facf9fc 3838+ /* ignore this error */
3839+
3840+ if (do_dt)
3841+ au_dtime_revert(&dt);
3842+ return err;
3843+}
3844+
3845+/*
3846+ * copyup the @dentry from @bsrc to @bdst.
3847+ * the caller must set the both of lower dentries.
3848+ * @len is for truncating when it is -1 copyup the entire file.
3849+ * in link/rename cases, @dst_parent may be different from the real one.
3850+ */
3851+static int au_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
3852+ aufs_bindex_t bsrc, loff_t len, unsigned int flags,
3853+ struct dentry *dst_parent)
3854+{
3855+ int err, rerr;
3856+ aufs_bindex_t old_ibstart;
3857+ unsigned char isdir, plink;
3858+ struct au_dtime dt;
3859+ struct path h_path;
3860+ struct dentry *h_src, *h_dst, *h_parent;
3861+ struct inode *dst_inode, *h_dir, *inode;
3862+ struct super_block *sb;
3863+
3864+ AuDebugOn(bsrc <= bdst);
3865+
3866+ sb = dentry->d_sb;
3867+ h_path.mnt = au_sbr_mnt(sb, bdst);
3868+ h_dst = au_h_dptr(dentry, bdst);
3869+ h_parent = h_dst->d_parent; /* dir inode is locked */
3870+ h_dir = h_parent->d_inode;
3871+ IMustLock(h_dir);
3872+
3873+ h_src = au_h_dptr(dentry, bsrc);
3874+ inode = dentry->d_inode;
3875+
3876+ if (!dst_parent)
3877+ dst_parent = dget_parent(dentry);
3878+ else
3879+ dget(dst_parent);
3880+
3881+ plink = !!au_opt_test(au_mntflags(sb), PLINK);
3882+ dst_inode = au_h_iptr(inode, bdst);
3883+ if (dst_inode) {
3884+ if (unlikely(!plink)) {
3885+ err = -EIO;
027c5e7a
AM
3886+ AuIOErr("hi%lu(i%lu) exists on b%d "
3887+ "but plink is disabled\n",
3888+ dst_inode->i_ino, inode->i_ino, bdst);
1facf9fc 3889+ goto out;
3890+ }
3891+
3892+ if (dst_inode->i_nlink) {
3893+ const int do_dt = au_ftest_cpup(flags, DTIME);
3894+
3895+ h_src = au_plink_lkup(inode, bdst);
3896+ err = PTR_ERR(h_src);
3897+ if (IS_ERR(h_src))
3898+ goto out;
3899+ if (unlikely(!h_src->d_inode)) {
3900+ err = -EIO;
3901+ AuIOErr("i%lu exists on a upper branch "
027c5e7a
AM
3902+ "but not pseudo-linked\n",
3903+ inode->i_ino);
1facf9fc 3904+ dput(h_src);
3905+ goto out;
3906+ }
3907+
3908+ if (do_dt) {
3909+ h_path.dentry = h_parent;
3910+ au_dtime_store(&dt, dst_parent, &h_path);
3911+ }
3912+ h_path.dentry = h_dst;
3913+ err = vfsub_link(h_src, h_dir, &h_path);
3914+ if (do_dt)
3915+ au_dtime_revert(&dt);
3916+ dput(h_src);
3917+ goto out;
3918+ } else
3919+ /* todo: cpup_wh_file? */
3920+ /* udba work */
4a4d8108 3921+ au_update_ibrange(inode, /*do_put_zero*/1);
1facf9fc 3922+ }
3923+
3924+ old_ibstart = au_ibstart(inode);
3925+ err = cpup_entry(dentry, bdst, bsrc, len, flags, dst_parent);
3926+ if (unlikely(err))
3927+ goto out;
3928+ dst_inode = h_dst->d_inode;
3929+ mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
3930+
3931+ err = cpup_iattr(dentry, bdst, h_src);
3932+ isdir = S_ISDIR(dst_inode->i_mode);
3933+ if (!err) {
4a4d8108
AM
3934+ if (bdst < old_ibstart) {
3935+ if (S_ISREG(inode->i_mode)) {
3936+ err = au_dy_iaop(inode, bdst, dst_inode);
3937+ if (unlikely(err))
3938+ goto out_rev;
3939+ }
1facf9fc 3940+ au_set_ibstart(inode, bdst);
4a4d8108 3941+ }
1facf9fc 3942+ au_set_h_iptr(inode, bdst, au_igrab(dst_inode),
3943+ au_hi_flags(inode, isdir));
3944+ mutex_unlock(&dst_inode->i_mutex);
3945+ if (!isdir
3946+ && h_src->d_inode->i_nlink > 1
3947+ && plink)
3948+ au_plink_append(inode, bdst, h_dst);
3949+ goto out; /* success */
3950+ }
3951+
3952+ /* revert */
4a4d8108 3953+out_rev:
1facf9fc 3954+ h_path.dentry = h_parent;
3955+ mutex_unlock(&dst_inode->i_mutex);
3956+ au_dtime_store(&dt, dst_parent, &h_path);
3957+ h_path.dentry = h_dst;
3958+ if (!isdir)
3959+ rerr = vfsub_unlink(h_dir, &h_path, /*force*/0);
3960+ else
3961+ rerr = vfsub_rmdir(h_dir, &h_path);
3962+ au_dtime_revert(&dt);
3963+ if (rerr) {
3964+ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
3965+ err = -EIO;
3966+ }
3967+
4f0767ce 3968+out:
1facf9fc 3969+ dput(dst_parent);
3970+ return err;
3971+}
3972+
3973+struct au_cpup_single_args {
3974+ int *errp;
3975+ struct dentry *dentry;
3976+ aufs_bindex_t bdst, bsrc;
3977+ loff_t len;
3978+ unsigned int flags;
3979+ struct dentry *dst_parent;
3980+};
3981+
3982+static void au_call_cpup_single(void *args)
3983+{
3984+ struct au_cpup_single_args *a = args;
3985+ *a->errp = au_cpup_single(a->dentry, a->bdst, a->bsrc, a->len,
3986+ a->flags, a->dst_parent);
3987+}
3988+
53392da6
AM
3989+/*
3990+ * prevent SIGXFSZ in copy-up.
3991+ * testing CAP_MKNOD is for generic fs,
3992+ * but CAP_FSETID is for xfs only, currently.
3993+ */
3994+static int au_cpup_sio_test(struct super_block *sb, umode_t mode)
3995+{
3996+ int do_sio;
3997+
3998+ do_sio = 0;
3999+ if (!au_wkq_test()
4000+ && (!au_sbi(sb)->si_plink_maint_pid
4001+ || au_plink_maint(sb, AuLock_NOPLM))) {
4002+ switch (mode & S_IFMT) {
4003+ case S_IFREG:
4004+ /* no condition about RLIMIT_FSIZE and the file size */
4005+ do_sio = 1;
4006+ break;
4007+ case S_IFCHR:
4008+ case S_IFBLK:
4009+ do_sio = !capable(CAP_MKNOD);
4010+ break;
4011+ }
4012+ if (!do_sio)
4013+ do_sio = ((mode & (S_ISUID | S_ISGID))
4014+ && !capable(CAP_FSETID));
4015+ }
4016+
4017+ return do_sio;
4018+}
4019+
1facf9fc 4020+int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
4021+ aufs_bindex_t bsrc, loff_t len, unsigned int flags,
4022+ struct dentry *dst_parent)
4023+{
4024+ int err, wkq_err;
1facf9fc 4025+ struct dentry *h_dentry;
4026+
4027+ h_dentry = au_h_dptr(dentry, bsrc);
53392da6 4028+ if (!au_cpup_sio_test(dentry->d_sb, h_dentry->d_inode->i_mode))
1facf9fc 4029+ err = au_cpup_single(dentry, bdst, bsrc, len, flags,
4030+ dst_parent);
4031+ else {
4032+ struct au_cpup_single_args args = {
4033+ .errp = &err,
4034+ .dentry = dentry,
4035+ .bdst = bdst,
4036+ .bsrc = bsrc,
4037+ .len = len,
4038+ .flags = flags,
4039+ .dst_parent = dst_parent
4040+ };
4041+ wkq_err = au_wkq_wait(au_call_cpup_single, &args);
4042+ if (unlikely(wkq_err))
4043+ err = wkq_err;
4044+ }
4045+
4046+ return err;
4047+}
4048+
4049+/*
4050+ * copyup the @dentry from the first active lower branch to @bdst,
4051+ * using au_cpup_single().
4052+ */
4053+static int au_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4054+ unsigned int flags)
4055+{
4056+ int err;
4057+ aufs_bindex_t bsrc, bend;
4058+
4059+ bend = au_dbend(dentry);
4060+ for (bsrc = bdst + 1; bsrc <= bend; bsrc++)
4061+ if (au_h_dptr(dentry, bsrc))
4062+ break;
4063+
4064+ err = au_lkup_neg(dentry, bdst);
4065+ if (!err) {
4066+ err = au_cpup_single(dentry, bdst, bsrc, len, flags, NULL);
4067+ if (!err)
4068+ return 0; /* success */
4069+
4070+ /* revert */
4071+ au_set_h_dptr(dentry, bdst, NULL);
4072+ au_set_dbstart(dentry, bsrc);
4073+ }
4074+
4075+ return err;
4076+}
4077+
4078+struct au_cpup_simple_args {
4079+ int *errp;
4080+ struct dentry *dentry;
4081+ aufs_bindex_t bdst;
4082+ loff_t len;
4083+ unsigned int flags;
4084+};
4085+
4086+static void au_call_cpup_simple(void *args)
4087+{
4088+ struct au_cpup_simple_args *a = args;
4089+ *a->errp = au_cpup_simple(a->dentry, a->bdst, a->len, a->flags);
4090+}
4091+
4092+int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4093+ unsigned int flags)
4094+{
4095+ int err, wkq_err;
1facf9fc 4096+ struct dentry *parent;
4097+ struct inode *h_dir;
4098+
4099+ parent = dget_parent(dentry);
4100+ h_dir = au_h_iptr(parent->d_inode, bdst);
53392da6
AM
4101+ if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
4102+ && !au_cpup_sio_test(dentry->d_sb, dentry->d_inode->i_mode))
1facf9fc 4103+ err = au_cpup_simple(dentry, bdst, len, flags);
4104+ else {
4105+ struct au_cpup_simple_args args = {
4106+ .errp = &err,
4107+ .dentry = dentry,
4108+ .bdst = bdst,
4109+ .len = len,
4110+ .flags = flags
4111+ };
4112+ wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
4113+ if (unlikely(wkq_err))
4114+ err = wkq_err;
4115+ }
4116+
4117+ dput(parent);
4118+ return err;
4119+}
4120+
4121+/* ---------------------------------------------------------------------- */
4122+
4123+/*
4124+ * copyup the deleted file for writing.
4125+ */
4126+static int au_do_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst,
4127+ struct dentry *wh_dentry, struct file *file,
4128+ loff_t len)
4129+{
4130+ int err;
4131+ aufs_bindex_t bstart;
4132+ struct au_dinfo *dinfo;
4133+ struct dentry *h_d_dst, *h_d_start;
4a4d8108 4134+ struct au_hdentry *hdp;
1facf9fc 4135+
4136+ dinfo = au_di(dentry);
1308ab2a 4137+ AuRwMustWriteLock(&dinfo->di_rwsem);
4138+
1facf9fc 4139+ bstart = dinfo->di_bstart;
4a4d8108
AM
4140+ hdp = dinfo->di_hdentry;
4141+ h_d_dst = hdp[0 + bdst].hd_dentry;
1facf9fc 4142+ dinfo->di_bstart = bdst;
4a4d8108 4143+ hdp[0 + bdst].hd_dentry = wh_dentry;
027c5e7a
AM
4144+ if (file) {
4145+ h_d_start = hdp[0 + bstart].hd_dentry;
4a4d8108 4146+ hdp[0 + bstart].hd_dentry = au_hf_top(file)->f_dentry;
027c5e7a 4147+ }
1facf9fc 4148+ err = au_cpup_single(dentry, bdst, bstart, len, !AuCpup_DTIME,
4149+ /*h_parent*/NULL);
027c5e7a
AM
4150+ if (file) {
4151+ if (!err)
4152+ err = au_reopen_nondir(file);
4a4d8108 4153+ hdp[0 + bstart].hd_dentry = h_d_start;
1facf9fc 4154+ }
4a4d8108 4155+ hdp[0 + bdst].hd_dentry = h_d_dst;
1facf9fc 4156+ dinfo->di_bstart = bstart;
4157+
4158+ return err;
4159+}
4160+
4161+static int au_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4162+ struct file *file)
4163+{
4164+ int err;
4165+ struct au_dtime dt;
4166+ struct dentry *parent, *h_parent, *wh_dentry;
4167+ struct au_branch *br;
4168+ struct path h_path;
4169+
4170+ br = au_sbr(dentry->d_sb, bdst);
4171+ parent = dget_parent(dentry);
4172+ h_parent = au_h_dptr(parent, bdst);
4173+ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
4174+ err = PTR_ERR(wh_dentry);
4175+ if (IS_ERR(wh_dentry))
4176+ goto out;
4177+
4178+ h_path.dentry = h_parent;
4179+ h_path.mnt = br->br_mnt;
4180+ au_dtime_store(&dt, parent, &h_path);
4181+ err = au_do_cpup_wh(dentry, bdst, wh_dentry, file, len);
4182+ if (unlikely(err))
4183+ goto out_wh;
4184+
4185+ dget(wh_dentry);
4186+ h_path.dentry = wh_dentry;
4a4d8108
AM
4187+ if (!S_ISDIR(wh_dentry->d_inode->i_mode))
4188+ err = vfsub_unlink(h_parent->d_inode, &h_path, /*force*/0);
4189+ else
4190+ err = vfsub_rmdir(h_parent->d_inode, &h_path);
1facf9fc 4191+ if (unlikely(err)) {
4192+ AuIOErr("failed remove copied-up tmp file %.*s(%d)\n",
4193+ AuDLNPair(wh_dentry), err);
4194+ err = -EIO;
4195+ }
4196+ au_dtime_revert(&dt);
4197+ au_set_hi_wh(dentry->d_inode, bdst, wh_dentry);
4198+
4f0767ce 4199+out_wh:
1facf9fc 4200+ dput(wh_dentry);
4f0767ce 4201+out:
1facf9fc 4202+ dput(parent);
4203+ return err;
4204+}
4205+
4206+struct au_cpup_wh_args {
4207+ int *errp;
4208+ struct dentry *dentry;
4209+ aufs_bindex_t bdst;
4210+ loff_t len;
4211+ struct file *file;
4212+};
4213+
4214+static void au_call_cpup_wh(void *args)
4215+{
4216+ struct au_cpup_wh_args *a = args;
4217+ *a->errp = au_cpup_wh(a->dentry, a->bdst, a->len, a->file);
4218+}
4219+
4220+int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4221+ struct file *file)
4222+{
4223+ int err, wkq_err;
4224+ struct dentry *parent, *h_orph, *h_parent, *h_dentry;
4225+ struct inode *dir, *h_dir, *h_tmpdir, *h_inode;
4226+ struct au_wbr *wbr;
4227+
4228+ parent = dget_parent(dentry);
4229+ dir = parent->d_inode;
4230+ h_orph = NULL;
4231+ h_parent = NULL;
4232+ h_dir = au_igrab(au_h_iptr(dir, bdst));
4233+ h_tmpdir = h_dir;
4234+ if (!h_dir->i_nlink) {
4235+ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
4236+ h_orph = wbr->wbr_orph;
4237+
4238+ h_parent = dget(au_h_dptr(parent, bdst));
1facf9fc 4239+ au_set_h_dptr(parent, bdst, dget(h_orph));
4240+ h_tmpdir = h_orph->d_inode;
1facf9fc 4241+ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
4242+
4243+ /* this temporary unlock is safe */
4244+ if (file)
4a4d8108 4245+ h_dentry = au_hf_top(file)->f_dentry;
1facf9fc 4246+ else
4247+ h_dentry = au_h_dptr(dentry, au_dbstart(dentry));
4248+ h_inode = h_dentry->d_inode;
4249+ IMustLock(h_inode);
4250+ mutex_unlock(&h_inode->i_mutex);
dece6358 4251+ mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
1facf9fc 4252+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
4a4d8108 4253+ /* todo: au_h_open_pre()? */
1facf9fc 4254+ }
4255+
53392da6
AM
4256+ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
4257+ && !au_cpup_sio_test(dentry->d_sb, dentry->d_inode->i_mode))
1facf9fc 4258+ err = au_cpup_wh(dentry, bdst, len, file);
4259+ else {
4260+ struct au_cpup_wh_args args = {
4261+ .errp = &err,
4262+ .dentry = dentry,
4263+ .bdst = bdst,
4264+ .len = len,
4265+ .file = file
4266+ };
4267+ wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
4268+ if (unlikely(wkq_err))
4269+ err = wkq_err;
4270+ }
4271+
4272+ if (h_orph) {
4273+ mutex_unlock(&h_tmpdir->i_mutex);
4a4d8108 4274+ /* todo: au_h_open_post()? */
1facf9fc 4275+ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
1facf9fc 4276+ au_set_h_dptr(parent, bdst, h_parent);
4277+ }
4278+ iput(h_dir);
4279+ dput(parent);
4280+
4281+ return err;
4282+}
4283+
4284+/* ---------------------------------------------------------------------- */
4285+
4286+/*
4287+ * generic routine for both of copy-up and copy-down.
4288+ */
4289+/* cf. revalidate function in file.c */
4290+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
4291+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
4292+ struct dentry *h_parent, void *arg),
4293+ void *arg)
4294+{
4295+ int err;
4296+ struct au_pin pin;
4297+ struct dentry *d, *parent, *h_parent, *real_parent;
4298+
4299+ err = 0;
4300+ parent = dget_parent(dentry);
4301+ if (IS_ROOT(parent))
4302+ goto out;
4303+
4304+ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
4305+ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
4306+
4307+ /* do not use au_dpage */
4308+ real_parent = parent;
4309+ while (1) {
4310+ dput(parent);
4311+ parent = dget_parent(dentry);
4312+ h_parent = au_h_dptr(parent, bdst);
4313+ if (h_parent)
4314+ goto out; /* success */
4315+
4316+ /* find top dir which is necessary to cpup */
4317+ do {
4318+ d = parent;
4319+ dput(parent);
4320+ parent = dget_parent(d);
4321+ di_read_lock_parent3(parent, !AuLock_IR);
4322+ h_parent = au_h_dptr(parent, bdst);
4323+ di_read_unlock(parent, !AuLock_IR);
4324+ } while (!h_parent);
4325+
4326+ if (d != real_parent)
4327+ di_write_lock_child3(d);
4328+
4329+ /* somebody else might create while we were sleeping */
4330+ if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) {
4331+ if (au_h_dptr(d, bdst))
4332+ au_update_dbstart(d);
4333+
4334+ au_pin_set_dentry(&pin, d);
4335+ err = au_do_pin(&pin);
4336+ if (!err) {
4337+ err = cp(d, bdst, h_parent, arg);
4338+ au_unpin(&pin);
4339+ }
4340+ }
4341+
4342+ if (d != real_parent)
4343+ di_write_unlock(d);
4344+ if (unlikely(err))
4345+ break;
4346+ }
4347+
4f0767ce 4348+out:
1facf9fc 4349+ dput(parent);
4350+ return err;
4351+}
4352+
4353+static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
4354+ struct dentry *h_parent __maybe_unused ,
4355+ void *arg __maybe_unused)
4356+{
4357+ return au_sio_cpup_simple(dentry, bdst, -1, AuCpup_DTIME);
4358+}
4359+
4360+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
4361+{
4362+ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
4363+}
4364+
4365+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
4366+{
4367+ int err;
4368+ struct dentry *parent;
4369+ struct inode *dir;
4370+
4371+ parent = dget_parent(dentry);
4372+ dir = parent->d_inode;
4373+ err = 0;
4374+ if (au_h_iptr(dir, bdst))
4375+ goto out;
4376+
4377+ di_read_unlock(parent, AuLock_IR);
4378+ di_write_lock_parent(parent);
4379+ /* someone else might change our inode while we were sleeping */
4380+ if (!au_h_iptr(dir, bdst))
4381+ err = au_cpup_dirs(dentry, bdst);
4382+ di_downgrade_lock(parent, AuLock_IR);
4383+
4f0767ce 4384+out:
1facf9fc 4385+ dput(parent);
4386+ return err;
4387+}
7f207e10
AM
4388diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
4389--- /usr/share/empty/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100
1716fcea 4390+++ linux/fs/aufs/cpup.h 2013-02-19 08:40:03.946892891 +0100
f6c5ef8b 4391@@ -0,0 +1,81 @@
1facf9fc 4392+/*
7a9e40b8 4393+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 4394+ *
4395+ * This program, aufs is free software; you can redistribute it and/or modify
4396+ * it under the terms of the GNU General Public License as published by
4397+ * the Free Software Foundation; either version 2 of the License, or
4398+ * (at your option) any later version.
dece6358
AM
4399+ *
4400+ * This program is distributed in the hope that it will be useful,
4401+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4402+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4403+ * GNU General Public License for more details.
4404+ *
4405+ * You should have received a copy of the GNU General Public License
4406+ * along with this program; if not, write to the Free Software
4407+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 4408+ */
4409+
4410+/*
4411+ * copy-up/down functions
4412+ */
4413+
4414+#ifndef __AUFS_CPUP_H__
4415+#define __AUFS_CPUP_H__
4416+
4417+#ifdef __KERNEL__
4418+
dece6358 4419+#include <linux/path.h>
1facf9fc 4420+
dece6358
AM
4421+struct inode;
4422+struct file;
4423+
1facf9fc 4424+void au_cpup_attr_flags(struct inode *dst, struct inode *src);
4425+void au_cpup_attr_timesizes(struct inode *inode);
4426+void au_cpup_attr_nlink(struct inode *inode, int force);
4427+void au_cpup_attr_changeable(struct inode *inode);
4428+void au_cpup_igen(struct inode *inode, struct inode *h_inode);
4429+void au_cpup_attr_all(struct inode *inode, int force);
4430+
4431+/* ---------------------------------------------------------------------- */
4432+
4433+/* cpup flags */
4434+#define AuCpup_DTIME 1 /* do dtime_store/revert */
4435+#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino,
4436+ for link(2) */
4437+#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name)
7f207e10
AM
4438+#define au_fset_cpup(flags, name) \
4439+ do { (flags) |= AuCpup_##name; } while (0)
4440+#define au_fclr_cpup(flags, name) \
4441+ do { (flags) &= ~AuCpup_##name; } while (0)
1facf9fc 4442+
4443+int au_copy_file(struct file *dst, struct file *src, loff_t len);
4444+int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
4445+ aufs_bindex_t bsrc, loff_t len, unsigned int flags,
4446+ struct dentry *dst_parent);
4447+int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4448+ unsigned int flags);
4449+int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4450+ struct file *file);
4451+
4452+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
4453+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
4454+ struct dentry *h_parent, void *arg),
4455+ void *arg);
4456+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
4457+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
4458+
4459+/* ---------------------------------------------------------------------- */
4460+
4461+/* keep timestamps when copyup */
4462+struct au_dtime {
4463+ struct dentry *dt_dentry;
4464+ struct path dt_h_path;
4465+ struct timespec dt_atime, dt_mtime;
4466+};
4467+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
4468+ struct path *h_path);
4469+void au_dtime_revert(struct au_dtime *dt);
4470+
4471+#endif /* __KERNEL__ */
4472+#endif /* __AUFS_CPUP_H__ */
7f207e10
AM
4473diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
4474--- /usr/share/empty/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
a2a7ad62 4475+++ linux/fs/aufs/dbgaufs.c 2013-03-14 20:07:41.038119650 +0100
4a4d8108 4476@@ -0,0 +1,334 @@
1facf9fc 4477+/*
7a9e40b8 4478+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 4479+ *
4480+ * This program, aufs is free software; you can redistribute it and/or modify
4481+ * it under the terms of the GNU General Public License as published by
4482+ * the Free Software Foundation; either version 2 of the License, or
4483+ * (at your option) any later version.
dece6358
AM
4484+ *
4485+ * This program is distributed in the hope that it will be useful,
4486+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4487+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4488+ * GNU General Public License for more details.
4489+ *
4490+ * You should have received a copy of the GNU General Public License
4491+ * along with this program; if not, write to the Free Software
4492+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 4493+ */
4494+
4495+/*
4496+ * debugfs interface
4497+ */
4498+
4499+#include <linux/debugfs.h>
4500+#include "aufs.h"
4501+
4502+#ifndef CONFIG_SYSFS
4503+#error DEBUG_FS depends upon SYSFS
4504+#endif
4505+
4506+static struct dentry *dbgaufs;
4507+static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
4508+
4509+/* 20 is max digits length of ulong 64 */
4510+struct dbgaufs_arg {
4511+ int n;
4512+ char a[20 * 4];
4513+};
4514+
4515+/*
4516+ * common function for all XINO files
4517+ */
4518+static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
4519+ struct file *file)
4520+{
4521+ kfree(file->private_data);
4522+ return 0;
4523+}
4524+
4525+static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
4526+{
4527+ int err;
4528+ struct kstat st;
4529+ struct dbgaufs_arg *p;
4530+
4531+ err = -ENOMEM;
4532+ p = kmalloc(sizeof(*p), GFP_NOFS);
4533+ if (unlikely(!p))
4534+ goto out;
4535+
4536+ err = 0;
4537+ p->n = 0;
4538+ file->private_data = p;
4539+ if (!xf)
4540+ goto out;
4541+
4542+ err = vfs_getattr(xf->f_vfsmnt, xf->f_dentry, &st);
4543+ if (!err) {
4544+ if (do_fcnt)
4545+ p->n = snprintf
4546+ (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n",
4547+ (long)file_count(xf), st.blocks, st.blksize,
4548+ (long long)st.size);
4549+ else
4550+ p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n",
4551+ st.blocks, st.blksize,
4552+ (long long)st.size);
4553+ AuDebugOn(p->n >= sizeof(p->a));
4554+ } else {
4555+ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
4556+ err = 0;
4557+ }
4558+
4f0767ce 4559+out:
1facf9fc 4560+ return err;
4561+
4562+}
4563+
4564+static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
4565+ size_t count, loff_t *ppos)
4566+{
4567+ struct dbgaufs_arg *p;
4568+
4569+ p = file->private_data;
4570+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
4571+}
4572+
4573+/* ---------------------------------------------------------------------- */
4574+
4575+static int dbgaufs_xib_open(struct inode *inode, struct file *file)
4576+{
4577+ int err;
4578+ struct au_sbinfo *sbinfo;
4579+ struct super_block *sb;
4580+
4581+ sbinfo = inode->i_private;
4582+ sb = sbinfo->si_sb;
4583+ si_noflush_read_lock(sb);
4584+ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0);
4585+ si_read_unlock(sb);
4586+ return err;
4587+}
4588+
4589+static const struct file_operations dbgaufs_xib_fop = {
4a4d8108 4590+ .owner = THIS_MODULE,
1facf9fc 4591+ .open = dbgaufs_xib_open,
4592+ .release = dbgaufs_xi_release,
4593+ .read = dbgaufs_xi_read
4594+};
4595+
4596+/* ---------------------------------------------------------------------- */
4597+
4598+#define DbgaufsXi_PREFIX "xi"
4599+
4600+static int dbgaufs_xino_open(struct inode *inode, struct file *file)
4601+{
4602+ int err;
4603+ long l;
4604+ struct au_sbinfo *sbinfo;
4605+ struct super_block *sb;
4606+ struct file *xf;
4607+ struct qstr *name;
4608+
4609+ err = -ENOENT;
4610+ xf = NULL;
4611+ name = &file->f_dentry->d_name;
4612+ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
4613+ || memcmp(name->name, DbgaufsXi_PREFIX,
4614+ sizeof(DbgaufsXi_PREFIX) - 1)))
4615+ goto out;
9dbd164d 4616+ err = kstrtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
1facf9fc 4617+ if (unlikely(err))
4618+ goto out;
4619+
4620+ sbinfo = inode->i_private;
4621+ sb = sbinfo->si_sb;
4622+ si_noflush_read_lock(sb);
4623+ if (l <= au_sbend(sb)) {
4624+ xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file;
4625+ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1);
4626+ } else
4627+ err = -ENOENT;
4628+ si_read_unlock(sb);
4629+
4f0767ce 4630+out:
1facf9fc 4631+ return err;
4632+}
4633+
4634+static const struct file_operations dbgaufs_xino_fop = {
4a4d8108 4635+ .owner = THIS_MODULE,
1facf9fc 4636+ .open = dbgaufs_xino_open,
4637+ .release = dbgaufs_xi_release,
4638+ .read = dbgaufs_xi_read
4639+};
4640+
4641+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
4642+{
4643+ aufs_bindex_t bend;
4644+ struct au_branch *br;
4645+ struct au_xino_file *xi;
4646+
4647+ if (!au_sbi(sb)->si_dbgaufs)
4648+ return;
4649+
4650+ bend = au_sbend(sb);
4651+ for (; bindex <= bend; bindex++) {
4652+ br = au_sbr(sb, bindex);
4653+ xi = &br->br_xino;
4654+ if (xi->xi_dbgaufs) {
4655+ debugfs_remove(xi->xi_dbgaufs);
4656+ xi->xi_dbgaufs = NULL;
4657+ }
4658+ }
4659+}
4660+
4661+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
4662+{
4663+ struct au_sbinfo *sbinfo;
4664+ struct dentry *parent;
4665+ struct au_branch *br;
4666+ struct au_xino_file *xi;
4667+ aufs_bindex_t bend;
4668+ char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */
4669+
4670+ sbinfo = au_sbi(sb);
4671+ parent = sbinfo->si_dbgaufs;
4672+ if (!parent)
4673+ return;
4674+
4675+ bend = au_sbend(sb);
4676+ for (; bindex <= bend; bindex++) {
4677+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
4678+ br = au_sbr(sb, bindex);
4679+ xi = &br->br_xino;
4680+ AuDebugOn(xi->xi_dbgaufs);
4681+ xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
4682+ sbinfo, &dbgaufs_xino_fop);
4683+ /* ignore an error */
4684+ if (unlikely(!xi->xi_dbgaufs))
4685+ AuWarn1("failed %s under debugfs\n", name);
4686+ }
4687+}
4688+
4689+/* ---------------------------------------------------------------------- */
4690+
4691+#ifdef CONFIG_AUFS_EXPORT
4692+static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
4693+{
4694+ int err;
4695+ struct au_sbinfo *sbinfo;
4696+ struct super_block *sb;
4697+
4698+ sbinfo = inode->i_private;
4699+ sb = sbinfo->si_sb;
4700+ si_noflush_read_lock(sb);
4701+ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0);
4702+ si_read_unlock(sb);
4703+ return err;
4704+}
4705+
4706+static const struct file_operations dbgaufs_xigen_fop = {
4a4d8108 4707+ .owner = THIS_MODULE,
1facf9fc 4708+ .open = dbgaufs_xigen_open,
4709+ .release = dbgaufs_xi_release,
4710+ .read = dbgaufs_xi_read
4711+};
4712+
4713+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
4714+{
4715+ int err;
4716+
dece6358
AM
4717+ /*
4718+ * This function is a dynamic '__init' fucntion actually,
4719+ * so the tiny check for si_rwsem is unnecessary.
4720+ */
4721+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
4722+
1facf9fc 4723+ err = -EIO;
4724+ sbinfo->si_dbgaufs_xigen = debugfs_create_file
4725+ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
4726+ &dbgaufs_xigen_fop);
4727+ if (sbinfo->si_dbgaufs_xigen)
4728+ err = 0;
4729+
4730+ return err;
4731+}
4732+#else
4733+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
4734+{
4735+ return 0;
4736+}
4737+#endif /* CONFIG_AUFS_EXPORT */
4738+
4739+/* ---------------------------------------------------------------------- */
4740+
4741+void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
4742+{
dece6358
AM
4743+ /*
4744+ * This function is a dynamic '__init' fucntion actually,
4745+ * so the tiny check for si_rwsem is unnecessary.
4746+ */
4747+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
4748+
1facf9fc 4749+ debugfs_remove_recursive(sbinfo->si_dbgaufs);
4750+ sbinfo->si_dbgaufs = NULL;
4751+ kobject_put(&sbinfo->si_kobj);
4752+}
4753+
4754+int dbgaufs_si_init(struct au_sbinfo *sbinfo)
4755+{
4756+ int err;
4757+ char name[SysaufsSiNameLen];
4758+
dece6358
AM
4759+ /*
4760+ * This function is a dynamic '__init' fucntion actually,
4761+ * so the tiny check for si_rwsem is unnecessary.
4762+ */
4763+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
4764+
1facf9fc 4765+ err = -ENOENT;
4766+ if (!dbgaufs) {
4767+ AuErr1("/debug/aufs is uninitialized\n");
4768+ goto out;
4769+ }
4770+
4771+ err = -EIO;
4772+ sysaufs_name(sbinfo, name);
4773+ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
4774+ if (unlikely(!sbinfo->si_dbgaufs))
4775+ goto out;
4776+ kobject_get(&sbinfo->si_kobj);
4777+
4778+ sbinfo->si_dbgaufs_xib = debugfs_create_file
4779+ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
4780+ &dbgaufs_xib_fop);
4781+ if (unlikely(!sbinfo->si_dbgaufs_xib))
4782+ goto out_dir;
4783+
4784+ err = dbgaufs_xigen_init(sbinfo);
4785+ if (!err)
4786+ goto out; /* success */
4787+
4f0767ce 4788+out_dir:
1facf9fc 4789+ dbgaufs_si_fin(sbinfo);
4f0767ce 4790+out:
1facf9fc 4791+ return err;
4792+}
4793+
4794+/* ---------------------------------------------------------------------- */
4795+
4796+void dbgaufs_fin(void)
4797+{
4798+ debugfs_remove(dbgaufs);
4799+}
4800+
4801+int __init dbgaufs_init(void)
4802+{
4803+ int err;
4804+
4805+ err = -EIO;
4806+ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
4807+ if (dbgaufs)
4808+ err = 0;
4809+ return err;
4810+}
7f207e10
AM
4811diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
4812--- /usr/share/empty/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
1716fcea 4813+++ linux/fs/aufs/dbgaufs.h 2013-02-19 08:40:03.946892891 +0100
f6c5ef8b 4814@@ -0,0 +1,49 @@
1facf9fc 4815+/*
7a9e40b8 4816+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 4817+ *
4818+ * This program, aufs is free software; you can redistribute it and/or modify
4819+ * it under the terms of the GNU General Public License as published by
4820+ * the Free Software Foundation; either version 2 of the License, or
4821+ * (at your option) any later version.
dece6358
AM
4822+ *
4823+ * This program is distributed in the hope that it will be useful,
4824+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4825+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4826+ * GNU General Public License for more details.
4827+ *
4828+ * You should have received a copy of the GNU General Public License
4829+ * along with this program; if not, write to the Free Software
4830+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 4831+ */
4832+
4833+/*
4834+ * debugfs interface
4835+ */
4836+
4837+#ifndef __DBGAUFS_H__
4838+#define __DBGAUFS_H__
4839+
4840+#ifdef __KERNEL__
4841+
dece6358 4842+struct super_block;
1facf9fc 4843+struct au_sbinfo;
dece6358 4844+
1facf9fc 4845+#ifdef CONFIG_DEBUG_FS
4846+/* dbgaufs.c */
4847+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
4848+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
4849+void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
4850+int dbgaufs_si_init(struct au_sbinfo *sbinfo);
4851+void dbgaufs_fin(void);
4852+int __init dbgaufs_init(void);
1facf9fc 4853+#else
4a4d8108
AM
4854+AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
4855+AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
4856+AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
4857+AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
4858+AuStubVoid(dbgaufs_fin, void)
4859+AuStubInt0(__init dbgaufs_init, void)
1facf9fc 4860+#endif /* CONFIG_DEBUG_FS */
4861+
4862+#endif /* __KERNEL__ */
4863+#endif /* __DBGAUFS_H__ */
7f207e10
AM
4864diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
4865--- /usr/share/empty/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100
1716fcea 4866+++ linux/fs/aufs/dcsub.c 2013-02-19 08:40:03.946892891 +0100
027c5e7a 4867@@ -0,0 +1,243 @@
1facf9fc 4868+/*
7a9e40b8 4869+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 4870+ *
4871+ * This program, aufs is free software; you can redistribute it and/or modify
4872+ * it under the terms of the GNU General Public License as published by
4873+ * the Free Software Foundation; either version 2 of the License, or
4874+ * (at your option) any later version.
dece6358
AM
4875+ *
4876+ * This program is distributed in the hope that it will be useful,
4877+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4878+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4879+ * GNU General Public License for more details.
4880+ *
4881+ * You should have received a copy of the GNU General Public License
4882+ * along with this program; if not, write to the Free Software
4883+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 4884+ */
4885+
4886+/*
4887+ * sub-routines for dentry cache
4888+ */
4889+
4890+#include "aufs.h"
4891+
4892+static void au_dpage_free(struct au_dpage *dpage)
4893+{
4894+ int i;
4895+ struct dentry **p;
4896+
4897+ p = dpage->dentries;
4898+ for (i = 0; i < dpage->ndentry; i++)
4899+ dput(*p++);
4900+ free_page((unsigned long)dpage->dentries);
4901+}
4902+
4903+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
4904+{
4905+ int err;
4906+ void *p;
4907+
4908+ err = -ENOMEM;
4909+ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
4910+ if (unlikely(!dpages->dpages))
4911+ goto out;
4912+
4913+ p = (void *)__get_free_page(gfp);
4914+ if (unlikely(!p))
4915+ goto out_dpages;
4916+
4917+ dpages->dpages[0].ndentry = 0;
4918+ dpages->dpages[0].dentries = p;
4919+ dpages->ndpage = 1;
4920+ return 0; /* success */
4921+
4f0767ce 4922+out_dpages:
1facf9fc 4923+ kfree(dpages->dpages);
4f0767ce 4924+out:
1facf9fc 4925+ return err;
4926+}
4927+
4928+void au_dpages_free(struct au_dcsub_pages *dpages)
4929+{
4930+ int i;
4931+ struct au_dpage *p;
4932+
4933+ p = dpages->dpages;
4934+ for (i = 0; i < dpages->ndpage; i++)
4935+ au_dpage_free(p++);
4936+ kfree(dpages->dpages);
4937+}
4938+
4939+static int au_dpages_append(struct au_dcsub_pages *dpages,
4940+ struct dentry *dentry, gfp_t gfp)
4941+{
4942+ int err, sz;
4943+ struct au_dpage *dpage;
4944+ void *p;
4945+
4946+ dpage = dpages->dpages + dpages->ndpage - 1;
4947+ sz = PAGE_SIZE / sizeof(dentry);
4948+ if (unlikely(dpage->ndentry >= sz)) {
4949+ AuLabel(new dpage);
4950+ err = -ENOMEM;
4951+ sz = dpages->ndpage * sizeof(*dpages->dpages);
4952+ p = au_kzrealloc(dpages->dpages, sz,
4953+ sz + sizeof(*dpages->dpages), gfp);
4954+ if (unlikely(!p))
4955+ goto out;
4956+
4957+ dpages->dpages = p;
4958+ dpage = dpages->dpages + dpages->ndpage;
4959+ p = (void *)__get_free_page(gfp);
4960+ if (unlikely(!p))
4961+ goto out;
4962+
4963+ dpage->ndentry = 0;
4964+ dpage->dentries = p;
4965+ dpages->ndpage++;
4966+ }
4967+
027c5e7a
AM
4968+ AuDebugOn(!dentry->d_count);
4969+ dpage->dentries[dpage->ndentry++] = dget_dlock(dentry);
1facf9fc 4970+ return 0; /* success */
4971+
4f0767ce 4972+out:
1facf9fc 4973+ return err;
4974+}
4975+
4976+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
4977+ au_dpages_test test, void *arg)
4978+{
4979+ int err;
027c5e7a 4980+ struct dentry *this_parent;
1facf9fc 4981+ struct list_head *next;
4982+ struct super_block *sb = root->d_sb;
4983+
4984+ err = 0;
027c5e7a
AM
4985+ write_seqlock(&rename_lock);
4986+ this_parent = root;
4987+ spin_lock(&this_parent->d_lock);
4f0767ce 4988+repeat:
1facf9fc 4989+ next = this_parent->d_subdirs.next;
4f0767ce 4990+resume:
1facf9fc 4991+ if (this_parent->d_sb == sb
4992+ && !IS_ROOT(this_parent)
027c5e7a
AM
4993+ && au_di(this_parent)
4994+ && this_parent->d_count
1facf9fc 4995+ && (!test || test(this_parent, arg))) {
4996+ err = au_dpages_append(dpages, this_parent, GFP_ATOMIC);
4997+ if (unlikely(err))
4998+ goto out;
4999+ }
5000+
5001+ while (next != &this_parent->d_subdirs) {
5002+ struct list_head *tmp = next;
5003+ struct dentry *dentry = list_entry(tmp, struct dentry,
5004+ d_u.d_child);
027c5e7a 5005+
1facf9fc 5006+ next = tmp->next;
027c5e7a
AM
5007+ spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
5008+ if (dentry->d_count) {
5009+ if (!list_empty(&dentry->d_subdirs)) {
5010+ spin_unlock(&this_parent->d_lock);
5011+ spin_release(&dentry->d_lock.dep_map, 1,
5012+ _RET_IP_);
5013+ this_parent = dentry;
5014+ spin_acquire(&this_parent->d_lock.dep_map, 0, 1,
5015+ _RET_IP_);
5016+ goto repeat;
5017+ }
5018+ if (dentry->d_sb == sb
5019+ && au_di(dentry)
5020+ && (!test || test(dentry, arg)))
5021+ err = au_dpages_append(dpages, dentry,
5022+ GFP_ATOMIC);
1facf9fc 5023+ }
027c5e7a
AM
5024+ spin_unlock(&dentry->d_lock);
5025+ if (unlikely(err))
5026+ goto out;
1facf9fc 5027+ }
5028+
5029+ if (this_parent != root) {
027c5e7a
AM
5030+ struct dentry *tmp;
5031+ struct dentry *child;
5032+
5033+ tmp = this_parent->d_parent;
5034+ rcu_read_lock();
5035+ spin_unlock(&this_parent->d_lock);
5036+ child = this_parent;
5037+ this_parent = tmp;
5038+ spin_lock(&this_parent->d_lock);
5039+ rcu_read_unlock();
5040+ next = child->d_u.d_child.next;
1facf9fc 5041+ goto resume;
5042+ }
027c5e7a 5043+
4f0767ce 5044+out:
027c5e7a
AM
5045+ spin_unlock(&this_parent->d_lock);
5046+ write_sequnlock(&rename_lock);
1facf9fc 5047+ return err;
5048+}
5049+
5050+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
5051+ int do_include, au_dpages_test test, void *arg)
5052+{
5053+ int err;
5054+
5055+ err = 0;
027c5e7a
AM
5056+ write_seqlock(&rename_lock);
5057+ spin_lock(&dentry->d_lock);
5058+ if (do_include
5059+ && dentry->d_count
5060+ && (!test || test(dentry, arg)))
1facf9fc 5061+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
5062+ spin_unlock(&dentry->d_lock);
5063+ if (unlikely(err))
5064+ goto out;
5065+
5066+ /*
5067+ * vfsmount_lock is unnecessary since this is a traverse in a single
5068+ * mount
5069+ */
1facf9fc 5070+ while (!IS_ROOT(dentry)) {
027c5e7a
AM
5071+ dentry = dentry->d_parent; /* rename_lock is locked */
5072+ spin_lock(&dentry->d_lock);
5073+ if (dentry->d_count
5074+ && (!test || test(dentry, arg)))
1facf9fc 5075+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
5076+ spin_unlock(&dentry->d_lock);
5077+ if (unlikely(err))
5078+ break;
1facf9fc 5079+ }
5080+
4f0767ce 5081+out:
027c5e7a 5082+ write_sequnlock(&rename_lock);
1facf9fc 5083+ return err;
5084+}
5085+
027c5e7a
AM
5086+static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg)
5087+{
5088+ return au_di(dentry) && dentry->d_sb == arg;
5089+}
5090+
5091+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
5092+ struct dentry *dentry, int do_include)
5093+{
5094+ return au_dcsub_pages_rev(dpages, dentry, do_include,
5095+ au_dcsub_dpages_aufs, dentry->d_sb);
5096+}
5097+
4a4d8108 5098+int au_test_subdir(struct dentry *d1, struct dentry *d2)
1facf9fc 5099+{
4a4d8108
AM
5100+ struct path path[2] = {
5101+ {
5102+ .dentry = d1
5103+ },
5104+ {
5105+ .dentry = d2
5106+ }
5107+ };
1facf9fc 5108+
4a4d8108 5109+ return path_is_under(path + 0, path + 1);
1facf9fc 5110+}
7f207e10
AM
5111diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
5112--- /usr/share/empty/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100
1716fcea 5113+++ linux/fs/aufs/dcsub.h 2013-02-19 08:40:03.946892891 +0100
f6c5ef8b 5114@@ -0,0 +1,94 @@
1facf9fc 5115+/*
7a9e40b8 5116+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 5117+ *
5118+ * This program, aufs is free software; you can redistribute it and/or modify
5119+ * it under the terms of the GNU General Public License as published by
5120+ * the Free Software Foundation; either version 2 of the License, or
5121+ * (at your option) any later version.
dece6358
AM
5122+ *
5123+ * This program is distributed in the hope that it will be useful,
5124+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5125+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5126+ * GNU General Public License for more details.
5127+ *
5128+ * You should have received a copy of the GNU General Public License
5129+ * along with this program; if not, write to the Free Software
5130+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 5131+ */
5132+
5133+/*
5134+ * sub-routines for dentry cache
5135+ */
5136+
5137+#ifndef __AUFS_DCSUB_H__
5138+#define __AUFS_DCSUB_H__
5139+
5140+#ifdef __KERNEL__
5141+
7f207e10 5142+#include <linux/dcache.h>
027c5e7a 5143+#include <linux/fs.h>
dece6358
AM
5144+
5145+struct dentry;
1facf9fc 5146+
5147+struct au_dpage {
5148+ int ndentry;
5149+ struct dentry **dentries;
5150+};
5151+
5152+struct au_dcsub_pages {
5153+ int ndpage;
5154+ struct au_dpage *dpages;
5155+};
5156+
5157+/* ---------------------------------------------------------------------- */
5158+
7f207e10 5159+/* dcsub.c */
1facf9fc 5160+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
5161+void au_dpages_free(struct au_dcsub_pages *dpages);
5162+typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
5163+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
5164+ au_dpages_test test, void *arg);
5165+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
5166+ int do_include, au_dpages_test test, void *arg);
027c5e7a
AM
5167+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
5168+ struct dentry *dentry, int do_include);
4a4d8108 5169+int au_test_subdir(struct dentry *d1, struct dentry *d2);
1facf9fc 5170+
7f207e10
AM
5171+/* ---------------------------------------------------------------------- */
5172+
027c5e7a
AM
5173+static inline int au_d_hashed_positive(struct dentry *d)
5174+{
5175+ int err;
5176+ struct inode *inode = d->d_inode;
5177+ err = 0;
5178+ if (unlikely(d_unhashed(d) || !inode || !inode->i_nlink))
5179+ err = -ENOENT;
5180+ return err;
5181+}
5182+
5183+static inline int au_d_alive(struct dentry *d)
5184+{
5185+ int err;
5186+ struct inode *inode;
5187+ err = 0;
5188+ if (!IS_ROOT(d))
5189+ err = au_d_hashed_positive(d);
5190+ else {
5191+ inode = d->d_inode;
5192+ if (unlikely(d_unlinked(d) || !inode || !inode->i_nlink))
5193+ err = -ENOENT;
5194+ }
5195+ return err;
5196+}
5197+
5198+static inline int au_alive_dir(struct dentry *d)
7f207e10 5199+{
027c5e7a
AM
5200+ int err;
5201+ err = au_d_alive(d);
5202+ if (unlikely(err || IS_DEADDIR(d->d_inode)))
5203+ err = -ENOENT;
5204+ return err;
7f207e10
AM
5205+}
5206+
1facf9fc 5207+#endif /* __KERNEL__ */
5208+#endif /* __AUFS_DCSUB_H__ */
7f207e10
AM
5209diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
5210--- /usr/share/empty/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
a2a7ad62 5211+++ linux/fs/aufs/debug.c 2013-03-14 20:07:41.038119650 +0100
b4510431 5212@@ -0,0 +1,490 @@
1facf9fc 5213+/*
7a9e40b8 5214+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 5215+ *
5216+ * This program, aufs is free software; you can redistribute it and/or modify
5217+ * it under the terms of the GNU General Public License as published by
5218+ * the Free Software Foundation; either version 2 of the License, or
5219+ * (at your option) any later version.
dece6358
AM
5220+ *
5221+ * This program is distributed in the hope that it will be useful,
5222+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5223+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5224+ * GNU General Public License for more details.
5225+ *
5226+ * You should have received a copy of the GNU General Public License
5227+ * along with this program; if not, write to the Free Software
5228+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 5229+ */
5230+
5231+/*
5232+ * debug print functions
5233+ */
5234+
7f207e10 5235+#include <linux/vt_kern.h>
1facf9fc 5236+#include "aufs.h"
5237+
5238+int aufs_debug;
5239+MODULE_PARM_DESC(debug, "debug print");
5240+module_param_named(debug, aufs_debug, int, S_IRUGO | S_IWUSR | S_IWGRP);
5241+
5242+char *au_plevel = KERN_DEBUG;
e49829fe
JR
5243+#define dpri(fmt, ...) do { \
5244+ if ((au_plevel \
5245+ && strcmp(au_plevel, KERN_DEBUG)) \
5246+ || au_debug_test()) \
5247+ printk("%s" fmt, au_plevel, ##__VA_ARGS__); \
1facf9fc 5248+} while (0)
5249+
5250+/* ---------------------------------------------------------------------- */
5251+
5252+void au_dpri_whlist(struct au_nhash *whlist)
5253+{
5254+ unsigned long ul, n;
5255+ struct hlist_head *head;
5256+ struct au_vdir_wh *tpos;
5257+ struct hlist_node *pos;
5258+
5259+ n = whlist->nh_num;
5260+ head = whlist->nh_head;
5261+ for (ul = 0; ul < n; ul++) {
5262+ hlist_for_each_entry(tpos, pos, head, wh_hash)
5263+ dpri("b%d, %.*s, %d\n",
5264+ tpos->wh_bindex,
5265+ tpos->wh_str.len, tpos->wh_str.name,
5266+ tpos->wh_str.len);
5267+ head++;
5268+ }
5269+}
5270+
5271+void au_dpri_vdir(struct au_vdir *vdir)
5272+{
5273+ unsigned long ul;
5274+ union au_vdir_deblk_p p;
5275+ unsigned char *o;
5276+
5277+ if (!vdir || IS_ERR(vdir)) {
5278+ dpri("err %ld\n", PTR_ERR(vdir));
5279+ return;
5280+ }
5281+
5282+ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n",
5283+ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
5284+ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
5285+ for (ul = 0; ul < vdir->vd_nblk; ul++) {
5286+ p.deblk = vdir->vd_deblk[ul];
5287+ o = p.deblk;
5288+ dpri("[%lu]: %p\n", ul, o);
5289+ }
5290+}
5291+
53392da6 5292+static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn,
1facf9fc 5293+ struct dentry *wh)
5294+{
5295+ char *n = NULL;
5296+ int l = 0;
5297+
5298+ if (!inode || IS_ERR(inode)) {
5299+ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
5300+ return -1;
5301+ }
5302+
5303+ /* the type of i_blocks depends upon CONFIG_LSF */
5304+ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
5305+ && sizeof(inode->i_blocks) != sizeof(u64));
5306+ if (wh) {
5307+ n = (void *)wh->d_name.name;
5308+ l = wh->d_name.len;
5309+ }
5310+
53392da6
AM
5311+ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
5312+ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
5313+ bindex, inode,
1facf9fc 5314+ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
5315+ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
5316+ i_size_read(inode), (unsigned long long)inode->i_blocks,
53392da6 5317+ hn, (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
1facf9fc 5318+ inode->i_mapping ? inode->i_mapping->nrpages : 0,
b752ccd1
AM
5319+ inode->i_state, inode->i_flags, inode->i_version,
5320+ inode->i_generation,
1facf9fc 5321+ l ? ", wh " : "", l, n);
5322+ return 0;
5323+}
5324+
5325+void au_dpri_inode(struct inode *inode)
5326+{
5327+ struct au_iinfo *iinfo;
5328+ aufs_bindex_t bindex;
53392da6 5329+ int err, hn;
1facf9fc 5330+
53392da6 5331+ err = do_pri_inode(-1, inode, -1, NULL);
1facf9fc 5332+ if (err || !au_test_aufs(inode->i_sb))
5333+ return;
5334+
5335+ iinfo = au_ii(inode);
5336+ if (!iinfo)
5337+ return;
5338+ dpri("i-1: bstart %d, bend %d, gen %d\n",
537831f9 5339+ iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode, NULL));
1facf9fc 5340+ if (iinfo->ii_bstart < 0)
5341+ return;
53392da6
AM
5342+ hn = 0;
5343+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++) {
5344+ hn = !!au_hn(iinfo->ii_hinode + bindex);
5345+ do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode, hn,
1facf9fc 5346+ iinfo->ii_hinode[0 + bindex].hi_whdentry);
53392da6 5347+ }
1facf9fc 5348+}
5349+
2cbb1c4b
JR
5350+void au_dpri_dalias(struct inode *inode)
5351+{
5352+ struct dentry *d;
b4510431 5353+ struct hlist_node *p;
2cbb1c4b
JR
5354+
5355+ spin_lock(&inode->i_lock);
b4510431 5356+ hlist_for_each_entry(d, p, &inode->i_dentry, d_alias)
2cbb1c4b
JR
5357+ au_dpri_dentry(d);
5358+ spin_unlock(&inode->i_lock);
5359+}
5360+
1facf9fc 5361+static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
5362+{
5363+ struct dentry *wh = NULL;
53392da6 5364+ int hn;
1facf9fc 5365+
5366+ if (!dentry || IS_ERR(dentry)) {
5367+ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
5368+ return -1;
5369+ }
5370+ /* do not call dget_parent() here */
027c5e7a 5371+ /* note: access d_xxx without d_lock */
1facf9fc 5372+ dpri("d%d: %.*s?/%.*s, %s, cnt %d, flags 0x%x\n",
5373+ bindex,
5374+ AuDLNPair(dentry->d_parent), AuDLNPair(dentry),
5375+ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
027c5e7a 5376+ dentry->d_count, dentry->d_flags);
53392da6 5377+ hn = -1;
1facf9fc 5378+ if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) {
5379+ struct au_iinfo *iinfo = au_ii(dentry->d_inode);
53392da6
AM
5380+ if (iinfo) {
5381+ hn = !!au_hn(iinfo->ii_hinode + bindex);
1facf9fc 5382+ wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
53392da6 5383+ }
1facf9fc 5384+ }
53392da6 5385+ do_pri_inode(bindex, dentry->d_inode, hn, wh);
1facf9fc 5386+ return 0;
5387+}
5388+
5389+void au_dpri_dentry(struct dentry *dentry)
5390+{
5391+ struct au_dinfo *dinfo;
5392+ aufs_bindex_t bindex;
5393+ int err;
4a4d8108 5394+ struct au_hdentry *hdp;
1facf9fc 5395+
5396+ err = do_pri_dentry(-1, dentry);
5397+ if (err || !au_test_aufs(dentry->d_sb))
5398+ return;
5399+
5400+ dinfo = au_di(dentry);
5401+ if (!dinfo)
5402+ return;
5403+ dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d\n",
5404+ dinfo->di_bstart, dinfo->di_bend,
5405+ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry));
5406+ if (dinfo->di_bstart < 0)
5407+ return;
4a4d8108 5408+ hdp = dinfo->di_hdentry;
1facf9fc 5409+ for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++)
4a4d8108 5410+ do_pri_dentry(bindex, hdp[0 + bindex].hd_dentry);
1facf9fc 5411+}
5412+
5413+static int do_pri_file(aufs_bindex_t bindex, struct file *file)
5414+{
5415+ char a[32];
5416+
5417+ if (!file || IS_ERR(file)) {
5418+ dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
5419+ return -1;
5420+ }
5421+ a[0] = 0;
5422+ if (bindex < 0
5423+ && file->f_dentry
5424+ && au_test_aufs(file->f_dentry->d_sb)
5425+ && au_fi(file))
e49829fe 5426+ snprintf(a, sizeof(a), ", gen %d, mmapped %d",
2cbb1c4b 5427+ au_figen(file), atomic_read(&au_fi(file)->fi_mmapped));
b752ccd1 5428+ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
1facf9fc 5429+ bindex, file->f_mode, file->f_flags, (long)file_count(file),
b752ccd1 5430+ file->f_version, file->f_pos, a);
1facf9fc 5431+ if (file->f_dentry)
5432+ do_pri_dentry(bindex, file->f_dentry);
5433+ return 0;
5434+}
5435+
5436+void au_dpri_file(struct file *file)
5437+{
5438+ struct au_finfo *finfo;
4a4d8108
AM
5439+ struct au_fidir *fidir;
5440+ struct au_hfile *hfile;
1facf9fc 5441+ aufs_bindex_t bindex;
5442+ int err;
5443+
5444+ err = do_pri_file(-1, file);
5445+ if (err || !file->f_dentry || !au_test_aufs(file->f_dentry->d_sb))
5446+ return;
5447+
5448+ finfo = au_fi(file);
5449+ if (!finfo)
5450+ return;
4a4d8108 5451+ if (finfo->fi_btop < 0)
1facf9fc 5452+ return;
4a4d8108
AM
5453+ fidir = finfo->fi_hdir;
5454+ if (!fidir)
5455+ do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
5456+ else
e49829fe
JR
5457+ for (bindex = finfo->fi_btop;
5458+ bindex >= 0 && bindex <= fidir->fd_bbot;
4a4d8108
AM
5459+ bindex++) {
5460+ hfile = fidir->fd_hfile + bindex;
5461+ do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
5462+ }
1facf9fc 5463+}
5464+
5465+static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
5466+{
5467+ struct vfsmount *mnt;
5468+ struct super_block *sb;
5469+
5470+ if (!br || IS_ERR(br))
5471+ goto out;
5472+ mnt = br->br_mnt;
5473+ if (!mnt || IS_ERR(mnt))
5474+ goto out;
5475+ sb = mnt->mnt_sb;
5476+ if (!sb || IS_ERR(sb))
5477+ goto out;
5478+
1e00d052 5479+ dpri("s%d: {perm 0x%x, id %d, cnt %d, wbr %p}, "
b752ccd1 5480+ "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
1facf9fc 5481+ "xino %d\n",
1e00d052
AM
5482+ bindex, br->br_perm, br->br_id, atomic_read(&br->br_count),
5483+ br->br_wbr, au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
b752ccd1 5484+ sb->s_flags, sb->s_count,
1facf9fc 5485+ atomic_read(&sb->s_active), !!br->br_xino.xi_file);
5486+ return 0;
5487+
4f0767ce 5488+out:
1facf9fc 5489+ dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
5490+ return -1;
5491+}
5492+
5493+void au_dpri_sb(struct super_block *sb)
5494+{
5495+ struct au_sbinfo *sbinfo;
5496+ aufs_bindex_t bindex;
5497+ int err;
5498+ /* to reuduce stack size */
5499+ struct {
5500+ struct vfsmount mnt;
5501+ struct au_branch fake;
5502+ } *a;
5503+
5504+ /* this function can be called from magic sysrq */
5505+ a = kzalloc(sizeof(*a), GFP_ATOMIC);
5506+ if (unlikely(!a)) {
5507+ dpri("no memory\n");
5508+ return;
5509+ }
5510+
5511+ a->mnt.mnt_sb = sb;
5512+ a->fake.br_perm = 0;
5513+ a->fake.br_mnt = &a->mnt;
5514+ a->fake.br_xino.xi_file = NULL;
5515+ atomic_set(&a->fake.br_count, 0);
5516+ smp_mb(); /* atomic_set */
5517+ err = do_pri_br(-1, &a->fake);
5518+ kfree(a);
5519+ dpri("dev 0x%x\n", sb->s_dev);
5520+ if (err || !au_test_aufs(sb))
5521+ return;
5522+
5523+ sbinfo = au_sbi(sb);
5524+ if (!sbinfo)
5525+ return;
5526+ dpri("nw %d, gen %u, kobj %d\n",
5527+ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
5528+ atomic_read(&sbinfo->si_kobj.kref.refcount));
5529+ for (bindex = 0; bindex <= sbinfo->si_bend; bindex++)
5530+ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
5531+}
5532+
5533+/* ---------------------------------------------------------------------- */
5534+
5535+void au_dbg_sleep_jiffy(int jiffy)
5536+{
5537+ while (jiffy)
5538+ jiffy = schedule_timeout_uninterruptible(jiffy);
5539+}
5540+
5541+void au_dbg_iattr(struct iattr *ia)
5542+{
5543+#define AuBit(name) if (ia->ia_valid & ATTR_ ## name) \
5544+ dpri(#name "\n")
5545+ AuBit(MODE);
5546+ AuBit(UID);
5547+ AuBit(GID);
5548+ AuBit(SIZE);
5549+ AuBit(ATIME);
5550+ AuBit(MTIME);
5551+ AuBit(CTIME);
5552+ AuBit(ATIME_SET);
5553+ AuBit(MTIME_SET);
5554+ AuBit(FORCE);
5555+ AuBit(ATTR_FLAG);
5556+ AuBit(KILL_SUID);
5557+ AuBit(KILL_SGID);
5558+ AuBit(FILE);
5559+ AuBit(KILL_PRIV);
5560+ AuBit(OPEN);
5561+ AuBit(TIMES_SET);
5562+#undef AuBit
5563+ dpri("ia_file %p\n", ia->ia_file);
5564+}
5565+
5566+/* ---------------------------------------------------------------------- */
5567+
027c5e7a
AM
5568+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
5569+{
5570+ struct inode *h_inode, *inode = dentry->d_inode;
5571+ struct dentry *h_dentry;
5572+ aufs_bindex_t bindex, bend, bi;
5573+
5574+ if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */)
5575+ return;
5576+
5577+ bend = au_dbend(dentry);
5578+ bi = au_ibend(inode);
5579+ if (bi < bend)
5580+ bend = bi;
5581+ bindex = au_dbstart(dentry);
5582+ bi = au_ibstart(inode);
5583+ if (bi > bindex)
5584+ bindex = bi;
5585+
5586+ for (; bindex <= bend; bindex++) {
5587+ h_dentry = au_h_dptr(dentry, bindex);
5588+ if (!h_dentry)
5589+ continue;
5590+ h_inode = au_h_iptr(inode, bindex);
5591+ if (unlikely(h_inode != h_dentry->d_inode)) {
5592+ int old = au_debug_test();
5593+ if (!old)
5594+ au_debug(1);
5595+ AuDbg("b%d, %s:%d\n", bindex, func, line);
5596+ AuDbgDentry(dentry);
5597+ AuDbgInode(inode);
5598+ if (!old)
5599+ au_debug(0);
5600+ BUG();
5601+ }
5602+ }
5603+}
5604+
1facf9fc 5605+void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen)
5606+{
5607+ struct dentry *parent;
5608+
5609+ parent = dget_parent(dentry);
027c5e7a
AM
5610+ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
5611+ AuDebugOn(IS_ROOT(dentry));
5612+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 5613+ dput(parent);
5614+}
5615+
5616+void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen)
5617+{
5618+ struct dentry *parent;
027c5e7a 5619+ struct inode *inode;
1facf9fc 5620+
5621+ parent = dget_parent(dentry);
027c5e7a
AM
5622+ inode = dentry->d_inode;
5623+ AuDebugOn(inode && S_ISDIR(dentry->d_inode->i_mode));
5624+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 5625+ dput(parent);
5626+}
5627+
5628+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
5629+{
5630+ int err, i, j;
5631+ struct au_dcsub_pages dpages;
5632+ struct au_dpage *dpage;
5633+ struct dentry **dentries;
5634+
5635+ err = au_dpages_init(&dpages, GFP_NOFS);
5636+ AuDebugOn(err);
027c5e7a 5637+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
1facf9fc 5638+ AuDebugOn(err);
5639+ for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
5640+ dpage = dpages.dpages + i;
5641+ dentries = dpage->dentries;
5642+ for (j = dpage->ndentry - 1; !err && j >= 0; j--)
027c5e7a 5643+ AuDebugOn(au_digen_test(dentries[j], sigen));
1facf9fc 5644+ }
5645+ au_dpages_free(&dpages);
5646+}
5647+
1facf9fc 5648+void au_dbg_verify_kthread(void)
5649+{
53392da6 5650+ if (au_wkq_test()) {
1facf9fc 5651+ au_dbg_blocked();
1e00d052
AM
5652+ /*
5653+ * It may be recursive, but udba=notify between two aufs mounts,
5654+ * where a single ro branch is shared, is not a problem.
5655+ */
5656+ /* WARN_ON(1); */
1facf9fc 5657+ }
5658+}
5659+
5660+/* ---------------------------------------------------------------------- */
5661+
5662+void au_debug_sbinfo_init(struct au_sbinfo *sbinfo __maybe_unused)
5663+{
5664+#ifdef AuForceNoPlink
5665+ au_opt_clr(sbinfo->si_mntflags, PLINK);
5666+#endif
5667+#ifdef AuForceNoXino
5668+ au_opt_clr(sbinfo->si_mntflags, XINO);
5669+#endif
5670+#ifdef AuForceNoRefrof
5671+ au_opt_clr(sbinfo->si_mntflags, REFROF);
5672+#endif
4a4d8108
AM
5673+#ifdef AuForceHnotify
5674+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_HNOTIFY);
1facf9fc 5675+#endif
1308ab2a 5676+#ifdef AuForceRd0
5677+ sbinfo->si_rdblk = 0;
5678+ sbinfo->si_rdhash = 0;
5679+#endif
1facf9fc 5680+}
5681+
5682+int __init au_debug_init(void)
5683+{
5684+ aufs_bindex_t bindex;
5685+ struct au_vdir_destr destr;
5686+
5687+ bindex = -1;
5688+ AuDebugOn(bindex >= 0);
5689+
5690+ destr.len = -1;
5691+ AuDebugOn(destr.len < NAME_MAX);
5692+
5693+#ifdef CONFIG_4KSTACKS
0c3ec466 5694+ pr_warn("CONFIG_4KSTACKS is defined.\n");
1facf9fc 5695+#endif
5696+
5697+#ifdef AuForceNoBrs
5698+ sysaufs_brs = 0;
5699+#endif
5700+
5701+ return 0;
5702+}
7f207e10
AM
5703diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
5704--- /usr/share/empty/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100
1716fcea 5705+++ linux/fs/aufs/debug.h 2013-02-19 08:40:03.946892891 +0100
92d182d2 5706@@ -0,0 +1,242 @@
1facf9fc 5707+/*
7a9e40b8 5708+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 5709+ *
5710+ * This program, aufs is free software; you can redistribute it and/or modify
5711+ * it under the terms of the GNU General Public License as published by
5712+ * the Free Software Foundation; either version 2 of the License, or
5713+ * (at your option) any later version.
dece6358
AM
5714+ *
5715+ * This program is distributed in the hope that it will be useful,
5716+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5717+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5718+ * GNU General Public License for more details.
5719+ *
5720+ * You should have received a copy of the GNU General Public License
5721+ * along with this program; if not, write to the Free Software
5722+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 5723+ */
5724+
5725+/*
5726+ * debug print functions
5727+ */
5728+
5729+#ifndef __AUFS_DEBUG_H__
5730+#define __AUFS_DEBUG_H__
5731+
5732+#ifdef __KERNEL__
5733+
4a4d8108
AM
5734+#include <linux/module.h>
5735+#include <linux/kallsyms.h>
1facf9fc 5736+#include <linux/sysrq.h>
4a4d8108 5737+
1facf9fc 5738+#ifdef CONFIG_AUFS_DEBUG
5739+#define AuDebugOn(a) BUG_ON(a)
5740+
5741+/* module parameter */
5742+extern int aufs_debug;
5743+static inline void au_debug(int n)
5744+{
5745+ aufs_debug = n;
5746+ smp_mb();
5747+}
5748+
5749+static inline int au_debug_test(void)
5750+{
5751+ return aufs_debug;
5752+}
5753+#else
5754+#define AuDebugOn(a) do {} while (0)
4a4d8108
AM
5755+AuStubVoid(au_debug, int n)
5756+AuStubInt0(au_debug_test, void)
1facf9fc 5757+#endif /* CONFIG_AUFS_DEBUG */
5758+
5759+/* ---------------------------------------------------------------------- */
5760+
5761+/* debug print */
5762+
4a4d8108 5763+#define AuDbg(fmt, ...) do { \
1facf9fc 5764+ if (au_debug_test()) \
4a4d8108 5765+ pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
1facf9fc 5766+} while (0)
4a4d8108
AM
5767+#define AuLabel(l) AuDbg(#l "\n")
5768+#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__)
5769+#define AuWarn1(fmt, ...) do { \
1facf9fc 5770+ static unsigned char _c; \
5771+ if (!_c++) \
0c3ec466 5772+ pr_warn(fmt, ##__VA_ARGS__); \
1facf9fc 5773+} while (0)
5774+
4a4d8108 5775+#define AuErr1(fmt, ...) do { \
1facf9fc 5776+ static unsigned char _c; \
5777+ if (!_c++) \
4a4d8108 5778+ pr_err(fmt, ##__VA_ARGS__); \
1facf9fc 5779+} while (0)
5780+
4a4d8108 5781+#define AuIOErr1(fmt, ...) do { \
1facf9fc 5782+ static unsigned char _c; \
5783+ if (!_c++) \
4a4d8108 5784+ AuIOErr(fmt, ##__VA_ARGS__); \
1facf9fc 5785+} while (0)
5786+
5787+#define AuUnsupportMsg "This operation is not supported." \
5788+ " Please report this application to aufs-users ML."
4a4d8108
AM
5789+#define AuUnsupport(fmt, ...) do { \
5790+ pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
1facf9fc 5791+ dump_stack(); \
5792+} while (0)
5793+
5794+#define AuTraceErr(e) do { \
5795+ if (unlikely((e) < 0)) \
5796+ AuDbg("err %d\n", (int)(e)); \
5797+} while (0)
5798+
5799+#define AuTraceErrPtr(p) do { \
5800+ if (IS_ERR(p)) \
5801+ AuDbg("err %ld\n", PTR_ERR(p)); \
5802+} while (0)
5803+
5804+/* dirty macros for debug print, use with "%.*s" and caution */
5805+#define AuLNPair(qstr) (qstr)->len, (qstr)->name
5806+#define AuDLNPair(d) AuLNPair(&(d)->d_name)
5807+
5808+/* ---------------------------------------------------------------------- */
5809+
5810+struct au_sbinfo;
5811+struct au_finfo;
dece6358 5812+struct dentry;
1facf9fc 5813+#ifdef CONFIG_AUFS_DEBUG
5814+extern char *au_plevel;
5815+struct au_nhash;
5816+void au_dpri_whlist(struct au_nhash *whlist);
5817+struct au_vdir;
5818+void au_dpri_vdir(struct au_vdir *vdir);
dece6358 5819+struct inode;
1facf9fc 5820+void au_dpri_inode(struct inode *inode);
2cbb1c4b 5821+void au_dpri_dalias(struct inode *inode);
1facf9fc 5822+void au_dpri_dentry(struct dentry *dentry);
dece6358 5823+struct file;
1facf9fc 5824+void au_dpri_file(struct file *filp);
dece6358 5825+struct super_block;
1facf9fc 5826+void au_dpri_sb(struct super_block *sb);
5827+
5828+void au_dbg_sleep_jiffy(int jiffy);
dece6358 5829+struct iattr;
1facf9fc 5830+void au_dbg_iattr(struct iattr *ia);
5831+
027c5e7a
AM
5832+#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__)
5833+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line);
1facf9fc 5834+void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen);
5835+void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen);
5836+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
1facf9fc 5837+void au_dbg_verify_kthread(void);
5838+
5839+int __init au_debug_init(void);
5840+void au_debug_sbinfo_init(struct au_sbinfo *sbinfo);
5841+#define AuDbgWhlist(w) do { \
5842+ AuDbg(#w "\n"); \
5843+ au_dpri_whlist(w); \
5844+} while (0)
5845+
5846+#define AuDbgVdir(v) do { \
5847+ AuDbg(#v "\n"); \
5848+ au_dpri_vdir(v); \
5849+} while (0)
5850+
5851+#define AuDbgInode(i) do { \
5852+ AuDbg(#i "\n"); \
5853+ au_dpri_inode(i); \
5854+} while (0)
5855+
2cbb1c4b
JR
5856+#define AuDbgDAlias(i) do { \
5857+ AuDbg(#i "\n"); \
5858+ au_dpri_dalias(i); \
5859+} while (0)
5860+
1facf9fc 5861+#define AuDbgDentry(d) do { \
5862+ AuDbg(#d "\n"); \
5863+ au_dpri_dentry(d); \
5864+} while (0)
5865+
5866+#define AuDbgFile(f) do { \
5867+ AuDbg(#f "\n"); \
5868+ au_dpri_file(f); \
5869+} while (0)
5870+
5871+#define AuDbgSb(sb) do { \
5872+ AuDbg(#sb "\n"); \
5873+ au_dpri_sb(sb); \
5874+} while (0)
5875+
5876+#define AuDbgSleep(sec) do { \
5877+ AuDbg("sleep %d sec\n", sec); \
5878+ ssleep(sec); \
5879+} while (0)
5880+
5881+#define AuDbgSleepJiffy(jiffy) do { \
5882+ AuDbg("sleep %d jiffies\n", jiffy); \
5883+ au_dbg_sleep_jiffy(jiffy); \
5884+} while (0)
5885+
5886+#define AuDbgIAttr(ia) do { \
5887+ AuDbg("ia_valid 0x%x\n", (ia)->ia_valid); \
5888+ au_dbg_iattr(ia); \
5889+} while (0)
4a4d8108
AM
5890+
5891+#define AuDbgSym(addr) do { \
5892+ char sym[KSYM_SYMBOL_LEN]; \
5893+ sprint_symbol(sym, (unsigned long)addr); \
5894+ AuDbg("%s\n", sym); \
5895+} while (0)
5896+
5897+#define AuInfoSym(addr) do { \
5898+ char sym[KSYM_SYMBOL_LEN]; \
5899+ sprint_symbol(sym, (unsigned long)addr); \
5900+ AuInfo("%s\n", sym); \
5901+} while (0)
1facf9fc 5902+#else
027c5e7a 5903+AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
4a4d8108
AM
5904+AuStubVoid(au_dbg_verify_dir_parent, struct dentry *dentry, unsigned int sigen)
5905+AuStubVoid(au_dbg_verify_nondir_parent, struct dentry *dentry,
5906+ unsigned int sigen)
5907+AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
5908+AuStubVoid(au_dbg_verify_kthread, void)
5909+AuStubInt0(__init au_debug_init, void)
5910+AuStubVoid(au_debug_sbinfo_init, struct au_sbinfo *sbinfo)
1facf9fc 5911+
1facf9fc 5912+#define AuDbgWhlist(w) do {} while (0)
5913+#define AuDbgVdir(v) do {} while (0)
5914+#define AuDbgInode(i) do {} while (0)
2cbb1c4b 5915+#define AuDbgDAlias(i) do {} while (0)
1facf9fc 5916+#define AuDbgDentry(d) do {} while (0)
5917+#define AuDbgFile(f) do {} while (0)
5918+#define AuDbgSb(sb) do {} while (0)
5919+#define AuDbgSleep(sec) do {} while (0)
5920+#define AuDbgSleepJiffy(jiffy) do {} while (0)
5921+#define AuDbgIAttr(ia) do {} while (0)
4a4d8108
AM
5922+#define AuDbgSym(addr) do {} while (0)
5923+#define AuInfoSym(addr) do {} while (0)
1facf9fc 5924+#endif /* CONFIG_AUFS_DEBUG */
5925+
5926+/* ---------------------------------------------------------------------- */
5927+
5928+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
5929+int __init au_sysrq_init(void);
5930+void au_sysrq_fin(void);
5931+
5932+#ifdef CONFIG_HW_CONSOLE
5933+#define au_dbg_blocked() do { \
5934+ WARN_ON(1); \
0c5527e5 5935+ handle_sysrq('w'); \
1facf9fc 5936+} while (0)
5937+#else
4a4d8108 5938+AuStubVoid(au_dbg_blocked, void)
1facf9fc 5939+#endif
5940+
5941+#else
4a4d8108
AM
5942+AuStubInt0(__init au_sysrq_init, void)
5943+AuStubVoid(au_sysrq_fin, void)
5944+AuStubVoid(au_dbg_blocked, void)
1facf9fc 5945+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
5946+
5947+#endif /* __KERNEL__ */
5948+#endif /* __AUFS_DEBUG_H__ */
7f207e10
AM
5949diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
5950--- /usr/share/empty/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100
a2a7ad62 5951+++ linux/fs/aufs/dentry.c 2013-03-14 20:07:41.038119650 +0100
537831f9 5952@@ -0,0 +1,1060 @@
1facf9fc 5953+/*
7a9e40b8 5954+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 5955+ *
5956+ * This program, aufs is free software; you can redistribute it and/or modify
5957+ * it under the terms of the GNU General Public License as published by
5958+ * the Free Software Foundation; either version 2 of the License, or
5959+ * (at your option) any later version.
dece6358
AM
5960+ *
5961+ * This program is distributed in the hope that it will be useful,
5962+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5963+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5964+ * GNU General Public License for more details.
5965+ *
5966+ * You should have received a copy of the GNU General Public License
5967+ * along with this program; if not, write to the Free Software
5968+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 5969+ */
5970+
5971+/*
5972+ * lookup and dentry operations
5973+ */
5974+
dece6358 5975+#include <linux/namei.h>
1facf9fc 5976+#include "aufs.h"
5977+
1facf9fc 5978+#define AuLkup_ALLOW_NEG 1
5979+#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name)
7f207e10
AM
5980+#define au_fset_lkup(flags, name) \
5981+ do { (flags) |= AuLkup_##name; } while (0)
5982+#define au_fclr_lkup(flags, name) \
5983+ do { (flags) &= ~AuLkup_##name; } while (0)
1facf9fc 5984+
5985+struct au_do_lookup_args {
5986+ unsigned int flags;
5987+ mode_t type;
1facf9fc 5988+};
5989+
5990+/*
5991+ * returns positive/negative dentry, NULL or an error.
5992+ * NULL means whiteout-ed or not-found.
5993+ */
5994+static struct dentry*
5995+au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
5996+ aufs_bindex_t bindex, struct qstr *wh_name,
5997+ struct au_do_lookup_args *args)
5998+{
5999+ struct dentry *h_dentry;
6000+ struct inode *h_inode, *inode;
1facf9fc 6001+ struct au_branch *br;
6002+ int wh_found, opq;
6003+ unsigned char wh_able;
6004+ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
6005+
1facf9fc 6006+ wh_found = 0;
6007+ br = au_sbr(dentry->d_sb, bindex);
6008+ wh_able = !!au_br_whable(br->br_perm);
6009+ if (wh_able)
6010+ wh_found = au_wh_test(h_parent, wh_name, br, /*try_sio*/0);
6011+ h_dentry = ERR_PTR(wh_found);
6012+ if (!wh_found)
6013+ goto real_lookup;
6014+ if (unlikely(wh_found < 0))
6015+ goto out;
6016+
6017+ /* We found a whiteout */
6018+ /* au_set_dbend(dentry, bindex); */
6019+ au_set_dbwh(dentry, bindex);
6020+ if (!allow_neg)
6021+ return NULL; /* success */
6022+
4f0767ce 6023+real_lookup:
b4510431 6024+ h_dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
1facf9fc 6025+ if (IS_ERR(h_dentry))
6026+ goto out;
6027+
6028+ h_inode = h_dentry->d_inode;
6029+ if (!h_inode) {
6030+ if (!allow_neg)
6031+ goto out_neg;
6032+ } else if (wh_found
6033+ || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
6034+ goto out_neg;
6035+
6036+ if (au_dbend(dentry) <= bindex)
6037+ au_set_dbend(dentry, bindex);
6038+ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
6039+ au_set_dbstart(dentry, bindex);
6040+ au_set_h_dptr(dentry, bindex, h_dentry);
6041+
6042+ inode = dentry->d_inode;
6043+ if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able
6044+ || (inode && !S_ISDIR(inode->i_mode)))
6045+ goto out; /* success */
6046+
6047+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
6048+ opq = au_diropq_test(h_dentry, br);
6049+ mutex_unlock(&h_inode->i_mutex);
6050+ if (opq > 0)
6051+ au_set_dbdiropq(dentry, bindex);
6052+ else if (unlikely(opq < 0)) {
6053+ au_set_h_dptr(dentry, bindex, NULL);
6054+ h_dentry = ERR_PTR(opq);
6055+ }
6056+ goto out;
6057+
4f0767ce 6058+out_neg:
1facf9fc 6059+ dput(h_dentry);
6060+ h_dentry = NULL;
4f0767ce 6061+out:
1facf9fc 6062+ return h_dentry;
6063+}
6064+
dece6358
AM
6065+static int au_test_shwh(struct super_block *sb, const struct qstr *name)
6066+{
6067+ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
6068+ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
6069+ return -EPERM;
6070+ return 0;
6071+}
6072+
1facf9fc 6073+/*
6074+ * returns the number of lower positive dentries,
6075+ * otherwise an error.
6076+ * can be called at unlinking with @type is zero.
6077+ */
537831f9 6078+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type)
1facf9fc 6079+{
6080+ int npositive, err;
6081+ aufs_bindex_t bindex, btail, bdiropq;
6082+ unsigned char isdir;
6083+ struct qstr whname;
6084+ struct au_do_lookup_args args = {
b4510431 6085+ .flags = 0,
537831f9 6086+ .type = type
1facf9fc 6087+ };
6088+ const struct qstr *name = &dentry->d_name;
6089+ struct dentry *parent;
6090+ struct inode *inode;
6091+
dece6358
AM
6092+ err = au_test_shwh(dentry->d_sb, name);
6093+ if (unlikely(err))
1facf9fc 6094+ goto out;
6095+
6096+ err = au_wh_name_alloc(&whname, name);
6097+ if (unlikely(err))
6098+ goto out;
6099+
6100+ inode = dentry->d_inode;
6101+ isdir = !!(inode && S_ISDIR(inode->i_mode));
6102+ if (!type)
6103+ au_fset_lkup(args.flags, ALLOW_NEG);
6104+
6105+ npositive = 0;
4a4d8108 6106+ parent = dget_parent(dentry);
1facf9fc 6107+ btail = au_dbtaildir(parent);
6108+ for (bindex = bstart; bindex <= btail; bindex++) {
6109+ struct dentry *h_parent, *h_dentry;
6110+ struct inode *h_inode, *h_dir;
6111+
6112+ h_dentry = au_h_dptr(dentry, bindex);
6113+ if (h_dentry) {
6114+ if (h_dentry->d_inode)
6115+ npositive++;
6116+ if (type != S_IFDIR)
6117+ break;
6118+ continue;
6119+ }
6120+ h_parent = au_h_dptr(parent, bindex);
6121+ if (!h_parent)
6122+ continue;
6123+ h_dir = h_parent->d_inode;
6124+ if (!h_dir || !S_ISDIR(h_dir->i_mode))
6125+ continue;
6126+
6127+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
6128+ h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
6129+ &args);
6130+ mutex_unlock(&h_dir->i_mutex);
6131+ err = PTR_ERR(h_dentry);
6132+ if (IS_ERR(h_dentry))
4a4d8108 6133+ goto out_parent;
1facf9fc 6134+ au_fclr_lkup(args.flags, ALLOW_NEG);
6135+
6136+ if (au_dbwh(dentry) >= 0)
6137+ break;
6138+ if (!h_dentry)
6139+ continue;
6140+ h_inode = h_dentry->d_inode;
6141+ if (!h_inode)
6142+ continue;
6143+ npositive++;
6144+ if (!args.type)
6145+ args.type = h_inode->i_mode & S_IFMT;
6146+ if (args.type != S_IFDIR)
6147+ break;
6148+ else if (isdir) {
6149+ /* the type of lower may be different */
6150+ bdiropq = au_dbdiropq(dentry);
6151+ if (bdiropq >= 0 && bdiropq <= bindex)
6152+ break;
6153+ }
6154+ }
6155+
6156+ if (npositive) {
6157+ AuLabel(positive);
6158+ au_update_dbstart(dentry);
6159+ }
6160+ err = npositive;
6161+ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
027c5e7a 6162+ && au_dbstart(dentry) < 0)) {
1facf9fc 6163+ err = -EIO;
027c5e7a
AM
6164+ AuIOErr("both of real entry and whiteout found, %.*s, err %d\n",
6165+ AuDLNPair(dentry), err);
6166+ }
1facf9fc 6167+
4f0767ce 6168+out_parent:
4a4d8108 6169+ dput(parent);
1facf9fc 6170+ kfree(whname.name);
4f0767ce 6171+out:
1facf9fc 6172+ return err;
6173+}
6174+
6175+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
6176+ struct au_branch *br)
6177+{
6178+ struct dentry *dentry;
6179+ int wkq_err;
6180+
6181+ if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC))
b4510431 6182+ dentry = vfsub_lkup_one(name, parent);
1facf9fc 6183+ else {
b4510431
AM
6184+ struct vfsub_lkup_one_args args = {
6185+ .errp = &dentry,
6186+ .name = name,
6187+ .parent = parent
1facf9fc 6188+ };
6189+
b4510431 6190+ wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args);
1facf9fc 6191+ if (unlikely(wkq_err))
6192+ dentry = ERR_PTR(wkq_err);
6193+ }
6194+
6195+ return dentry;
6196+}
6197+
6198+/*
6199+ * lookup @dentry on @bindex which should be negative.
6200+ */
6201+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex)
6202+{
6203+ int err;
6204+ struct dentry *parent, *h_parent, *h_dentry;
1facf9fc 6205+
1facf9fc 6206+ parent = dget_parent(dentry);
6207+ h_parent = au_h_dptr(parent, bindex);
4a4d8108 6208+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent,
1facf9fc 6209+ au_sbr(dentry->d_sb, bindex));
6210+ err = PTR_ERR(h_dentry);
6211+ if (IS_ERR(h_dentry))
6212+ goto out;
6213+ if (unlikely(h_dentry->d_inode)) {
6214+ err = -EIO;
027c5e7a
AM
6215+ AuIOErr("%.*s should be negative on b%d.\n",
6216+ AuDLNPair(h_dentry), bindex);
1facf9fc 6217+ dput(h_dentry);
6218+ goto out;
6219+ }
6220+
4a4d8108 6221+ err = 0;
1facf9fc 6222+ if (bindex < au_dbstart(dentry))
6223+ au_set_dbstart(dentry, bindex);
6224+ if (au_dbend(dentry) < bindex)
6225+ au_set_dbend(dentry, bindex);
6226+ au_set_h_dptr(dentry, bindex, h_dentry);
1facf9fc 6227+
4f0767ce 6228+out:
1facf9fc 6229+ dput(parent);
6230+ return err;
6231+}
6232+
6233+/* ---------------------------------------------------------------------- */
6234+
6235+/* subset of struct inode */
6236+struct au_iattr {
6237+ unsigned long i_ino;
6238+ /* unsigned int i_nlink; */
0c3ec466
AM
6239+ kuid_t i_uid;
6240+ kgid_t i_gid;
1facf9fc 6241+ u64 i_version;
6242+/*
6243+ loff_t i_size;
6244+ blkcnt_t i_blocks;
6245+*/
6246+ umode_t i_mode;
6247+};
6248+
6249+static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
6250+{
6251+ ia->i_ino = h_inode->i_ino;
6252+ /* ia->i_nlink = h_inode->i_nlink; */
6253+ ia->i_uid = h_inode->i_uid;
6254+ ia->i_gid = h_inode->i_gid;
6255+ ia->i_version = h_inode->i_version;
6256+/*
6257+ ia->i_size = h_inode->i_size;
6258+ ia->i_blocks = h_inode->i_blocks;
6259+*/
6260+ ia->i_mode = (h_inode->i_mode & S_IFMT);
6261+}
6262+
6263+static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
6264+{
6265+ return ia->i_ino != h_inode->i_ino
6266+ /* || ia->i_nlink != h_inode->i_nlink */
0c3ec466 6267+ || !uid_eq(ia->i_uid, h_inode->i_uid)
2dfbb274 6268+ || !gid_eq(ia->i_gid, h_inode->i_gid)
1facf9fc 6269+ || ia->i_version != h_inode->i_version
6270+/*
6271+ || ia->i_size != h_inode->i_size
6272+ || ia->i_blocks != h_inode->i_blocks
6273+*/
6274+ || ia->i_mode != (h_inode->i_mode & S_IFMT);
6275+}
6276+
6277+static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
6278+ struct au_branch *br)
6279+{
6280+ int err;
6281+ struct au_iattr ia;
6282+ struct inode *h_inode;
6283+ struct dentry *h_d;
6284+ struct super_block *h_sb;
6285+
6286+ err = 0;
6287+ memset(&ia, -1, sizeof(ia));
6288+ h_sb = h_dentry->d_sb;
6289+ h_inode = h_dentry->d_inode;
6290+ if (h_inode)
6291+ au_iattr_save(&ia, h_inode);
6292+ else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
6293+ /* nfs d_revalidate may return 0 for negative dentry */
6294+ /* fuse d_revalidate always return 0 for negative dentry */
6295+ goto out;
6296+
6297+ /* main purpose is namei.c:cached_lookup() and d_revalidate */
b4510431 6298+ h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent);
1facf9fc 6299+ err = PTR_ERR(h_d);
6300+ if (IS_ERR(h_d))
6301+ goto out;
6302+
6303+ err = 0;
6304+ if (unlikely(h_d != h_dentry
6305+ || h_d->d_inode != h_inode
6306+ || (h_inode && au_iattr_test(&ia, h_inode))))
6307+ err = au_busy_or_stale();
6308+ dput(h_d);
6309+
4f0767ce 6310+out:
1facf9fc 6311+ AuTraceErr(err);
6312+ return err;
6313+}
6314+
6315+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
6316+ struct dentry *h_parent, struct au_branch *br)
6317+{
6318+ int err;
6319+
6320+ err = 0;
027c5e7a
AM
6321+ if (udba == AuOpt_UDBA_REVAL
6322+ && !au_test_fs_remote(h_dentry->d_sb)) {
1facf9fc 6323+ IMustLock(h_dir);
6324+ err = (h_dentry->d_parent->d_inode != h_dir);
027c5e7a 6325+ } else if (udba != AuOpt_UDBA_NONE)
1facf9fc 6326+ err = au_h_verify_dentry(h_dentry, h_parent, br);
6327+
6328+ return err;
6329+}
6330+
6331+/* ---------------------------------------------------------------------- */
6332+
027c5e7a 6333+static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
1facf9fc 6334+{
027c5e7a 6335+ int err;
1facf9fc 6336+ aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq;
027c5e7a
AM
6337+ struct au_hdentry tmp, *p, *q;
6338+ struct au_dinfo *dinfo;
6339+ struct super_block *sb;
1facf9fc 6340+
027c5e7a 6341+ DiMustWriteLock(dentry);
1308ab2a 6342+
027c5e7a
AM
6343+ sb = dentry->d_sb;
6344+ dinfo = au_di(dentry);
1facf9fc 6345+ bend = dinfo->di_bend;
6346+ bwh = dinfo->di_bwh;
6347+ bdiropq = dinfo->di_bdiropq;
027c5e7a 6348+ p = dinfo->di_hdentry + dinfo->di_bstart;
1facf9fc 6349+ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
027c5e7a 6350+ if (!p->hd_dentry)
1facf9fc 6351+ continue;
6352+
027c5e7a
AM
6353+ new_bindex = au_br_index(sb, p->hd_id);
6354+ if (new_bindex == bindex)
1facf9fc 6355+ continue;
1facf9fc 6356+
1facf9fc 6357+ if (dinfo->di_bwh == bindex)
6358+ bwh = new_bindex;
6359+ if (dinfo->di_bdiropq == bindex)
6360+ bdiropq = new_bindex;
6361+ if (new_bindex < 0) {
6362+ au_hdput(p);
6363+ p->hd_dentry = NULL;
6364+ continue;
6365+ }
6366+
6367+ /* swap two lower dentries, and loop again */
6368+ q = dinfo->di_hdentry + new_bindex;
6369+ tmp = *q;
6370+ *q = *p;
6371+ *p = tmp;
6372+ if (tmp.hd_dentry) {
6373+ bindex--;
6374+ p--;
6375+ }
6376+ }
6377+
1facf9fc 6378+ dinfo->di_bwh = -1;
6379+ if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))
6380+ dinfo->di_bwh = bwh;
6381+
6382+ dinfo->di_bdiropq = -1;
6383+ if (bdiropq >= 0
6384+ && bdiropq <= au_sbend(sb)
6385+ && au_sbr_whable(sb, bdiropq))
6386+ dinfo->di_bdiropq = bdiropq;
6387+
027c5e7a
AM
6388+ err = -EIO;
6389+ dinfo->di_bstart = -1;
6390+ dinfo->di_bend = -1;
1facf9fc 6391+ bend = au_dbend(parent);
6392+ p = dinfo->di_hdentry;
6393+ for (bindex = 0; bindex <= bend; bindex++, p++)
6394+ if (p->hd_dentry) {
6395+ dinfo->di_bstart = bindex;
6396+ break;
6397+ }
6398+
027c5e7a
AM
6399+ if (dinfo->di_bstart >= 0) {
6400+ p = dinfo->di_hdentry + bend;
6401+ for (bindex = bend; bindex >= 0; bindex--, p--)
6402+ if (p->hd_dentry) {
6403+ dinfo->di_bend = bindex;
6404+ err = 0;
6405+ break;
6406+ }
6407+ }
6408+
6409+ return err;
1facf9fc 6410+}
6411+
027c5e7a 6412+static void au_do_hide(struct dentry *dentry)
1facf9fc 6413+{
027c5e7a 6414+ struct inode *inode;
1facf9fc 6415+
027c5e7a
AM
6416+ inode = dentry->d_inode;
6417+ if (inode) {
6418+ if (!S_ISDIR(inode->i_mode)) {
6419+ if (inode->i_nlink && !d_unhashed(dentry))
6420+ drop_nlink(inode);
6421+ } else {
6422+ clear_nlink(inode);
6423+ /* stop next lookup */
6424+ inode->i_flags |= S_DEAD;
6425+ }
6426+ smp_mb(); /* necessary? */
6427+ }
6428+ d_drop(dentry);
6429+}
1308ab2a 6430+
027c5e7a
AM
6431+static int au_hide_children(struct dentry *parent)
6432+{
6433+ int err, i, j, ndentry;
6434+ struct au_dcsub_pages dpages;
6435+ struct au_dpage *dpage;
6436+ struct dentry *dentry;
1facf9fc 6437+
027c5e7a 6438+ err = au_dpages_init(&dpages, GFP_NOFS);
1facf9fc 6439+ if (unlikely(err))
6440+ goto out;
027c5e7a
AM
6441+ err = au_dcsub_pages(&dpages, parent, NULL, NULL);
6442+ if (unlikely(err))
6443+ goto out_dpages;
1facf9fc 6444+
027c5e7a
AM
6445+ /* in reverse order */
6446+ for (i = dpages.ndpage - 1; i >= 0; i--) {
6447+ dpage = dpages.dpages + i;
6448+ ndentry = dpage->ndentry;
6449+ for (j = ndentry - 1; j >= 0; j--) {
6450+ dentry = dpage->dentries[j];
6451+ if (dentry != parent)
6452+ au_do_hide(dentry);
6453+ }
6454+ }
1facf9fc 6455+
027c5e7a
AM
6456+out_dpages:
6457+ au_dpages_free(&dpages);
4f0767ce 6458+out:
027c5e7a 6459+ return err;
1facf9fc 6460+}
6461+
027c5e7a 6462+static void au_hide(struct dentry *dentry)
1facf9fc 6463+{
027c5e7a
AM
6464+ int err;
6465+ struct inode *inode;
1facf9fc 6466+
027c5e7a
AM
6467+ AuDbgDentry(dentry);
6468+ inode = dentry->d_inode;
6469+ if (inode && S_ISDIR(inode->i_mode)) {
6470+ /* shrink_dcache_parent(dentry); */
6471+ err = au_hide_children(dentry);
6472+ if (unlikely(err))
6473+ AuIOErr("%.*s, failed hiding children, ignored %d\n",
6474+ AuDLNPair(dentry), err);
6475+ }
6476+ au_do_hide(dentry);
6477+}
1facf9fc 6478+
027c5e7a
AM
6479+/*
6480+ * By adding a dirty branch, a cached dentry may be affected in various ways.
6481+ *
6482+ * a dirty branch is added
6483+ * - on the top of layers
6484+ * - in the middle of layers
6485+ * - to the bottom of layers
6486+ *
6487+ * on the added branch there exists
6488+ * - a whiteout
6489+ * - a diropq
6490+ * - a same named entry
6491+ * + exist
6492+ * * negative --> positive
6493+ * * positive --> positive
6494+ * - type is unchanged
6495+ * - type is changed
6496+ * + doesn't exist
6497+ * * negative --> negative
6498+ * * positive --> negative (rejected by au_br_del() for non-dir case)
6499+ * - none
6500+ */
6501+static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
6502+ struct au_dinfo *tmp)
6503+{
6504+ int err;
6505+ aufs_bindex_t bindex, bend;
6506+ struct {
6507+ struct dentry *dentry;
6508+ struct inode *inode;
6509+ mode_t mode;
6510+ } orig_h, tmp_h;
6511+ struct au_hdentry *hd;
6512+ struct inode *inode, *h_inode;
6513+ struct dentry *h_dentry;
6514+
6515+ err = 0;
6516+ AuDebugOn(dinfo->di_bstart < 0);
6517+ orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry;
6518+ orig_h.inode = orig_h.dentry->d_inode;
6519+ orig_h.mode = 0;
6520+ if (orig_h.inode)
6521+ orig_h.mode = orig_h.inode->i_mode & S_IFMT;
6522+ memset(&tmp_h, 0, sizeof(tmp_h));
6523+ if (tmp->di_bstart >= 0) {
6524+ tmp_h.dentry = tmp->di_hdentry[tmp->di_bstart].hd_dentry;
6525+ tmp_h.inode = tmp_h.dentry->d_inode;
6526+ if (tmp_h.inode)
6527+ tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
6528+ }
6529+
6530+ inode = dentry->d_inode;
6531+ if (!orig_h.inode) {
6532+ AuDbg("nagative originally\n");
6533+ if (inode) {
6534+ au_hide(dentry);
6535+ goto out;
6536+ }
6537+ AuDebugOn(inode);
6538+ AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
6539+ AuDebugOn(dinfo->di_bdiropq != -1);
6540+
6541+ if (!tmp_h.inode) {
6542+ AuDbg("negative --> negative\n");
6543+ /* should have only one negative lower */
6544+ if (tmp->di_bstart >= 0
6545+ && tmp->di_bstart < dinfo->di_bstart) {
6546+ AuDebugOn(tmp->di_bstart != tmp->di_bend);
6547+ AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
6548+ au_set_h_dptr(dentry, dinfo->di_bstart, NULL);
6549+ au_di_cp(dinfo, tmp);
6550+ hd = tmp->di_hdentry + tmp->di_bstart;
6551+ au_set_h_dptr(dentry, tmp->di_bstart,
6552+ dget(hd->hd_dentry));
6553+ }
6554+ au_dbg_verify_dinode(dentry);
6555+ } else {
6556+ AuDbg("negative --> positive\n");
6557+ /*
6558+ * similar to the behaviour of creating with bypassing
6559+ * aufs.
6560+ * unhash it in order to force an error in the
6561+ * succeeding create operation.
6562+ * we should not set S_DEAD here.
6563+ */
6564+ d_drop(dentry);
6565+ /* au_di_swap(tmp, dinfo); */
6566+ au_dbg_verify_dinode(dentry);
6567+ }
6568+ } else {
6569+ AuDbg("positive originally\n");
6570+ /* inode may be NULL */
6571+ AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode);
6572+ if (!tmp_h.inode) {
6573+ AuDbg("positive --> negative\n");
6574+ /* or bypassing aufs */
6575+ au_hide(dentry);
6576+ if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_bstart)
6577+ dinfo->di_bwh = tmp->di_bwh;
6578+ if (inode)
6579+ err = au_refresh_hinode_self(inode);
6580+ au_dbg_verify_dinode(dentry);
6581+ } else if (orig_h.mode == tmp_h.mode) {
6582+ AuDbg("positive --> positive, same type\n");
6583+ if (!S_ISDIR(orig_h.mode)
6584+ && dinfo->di_bstart > tmp->di_bstart) {
6585+ /*
6586+ * similar to the behaviour of removing and
6587+ * creating.
6588+ */
6589+ au_hide(dentry);
6590+ if (inode)
6591+ err = au_refresh_hinode_self(inode);
6592+ au_dbg_verify_dinode(dentry);
6593+ } else {
6594+ /* fill empty slots */
6595+ if (dinfo->di_bstart > tmp->di_bstart)
6596+ dinfo->di_bstart = tmp->di_bstart;
6597+ if (dinfo->di_bend < tmp->di_bend)
6598+ dinfo->di_bend = tmp->di_bend;
6599+ dinfo->di_bwh = tmp->di_bwh;
6600+ dinfo->di_bdiropq = tmp->di_bdiropq;
6601+ hd = tmp->di_hdentry;
6602+ bend = dinfo->di_bend;
6603+ for (bindex = tmp->di_bstart; bindex <= bend;
6604+ bindex++) {
6605+ if (au_h_dptr(dentry, bindex))
6606+ continue;
6607+ h_dentry = hd[bindex].hd_dentry;
6608+ if (!h_dentry)
6609+ continue;
6610+ h_inode = h_dentry->d_inode;
6611+ AuDebugOn(!h_inode);
6612+ AuDebugOn(orig_h.mode
6613+ != (h_inode->i_mode
6614+ & S_IFMT));
6615+ au_set_h_dptr(dentry, bindex,
6616+ dget(h_dentry));
6617+ }
6618+ err = au_refresh_hinode(inode, dentry);
6619+ au_dbg_verify_dinode(dentry);
6620+ }
6621+ } else {
6622+ AuDbg("positive --> positive, different type\n");
6623+ /* similar to the behaviour of removing and creating */
6624+ au_hide(dentry);
6625+ if (inode)
6626+ err = au_refresh_hinode_self(inode);
6627+ au_dbg_verify_dinode(dentry);
6628+ }
6629+ }
6630+
6631+out:
6632+ return err;
6633+}
6634+
6635+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
6636+{
6637+ int err, ebrange;
6638+ unsigned int sigen;
6639+ struct au_dinfo *dinfo, *tmp;
6640+ struct super_block *sb;
6641+ struct inode *inode;
6642+
6643+ DiMustWriteLock(dentry);
6644+ AuDebugOn(IS_ROOT(dentry));
6645+ AuDebugOn(!parent->d_inode);
6646+
6647+ sb = dentry->d_sb;
6648+ inode = dentry->d_inode;
6649+ sigen = au_sigen(sb);
6650+ err = au_digen_test(parent, sigen);
6651+ if (unlikely(err))
6652+ goto out;
6653+
6654+ dinfo = au_di(dentry);
6655+ err = au_di_realloc(dinfo, au_sbend(sb) + 1);
6656+ if (unlikely(err))
6657+ goto out;
6658+ ebrange = au_dbrange_test(dentry);
6659+ if (!ebrange)
6660+ ebrange = au_do_refresh_hdentry(dentry, parent);
6661+
6662+ if (d_unhashed(dentry) || ebrange) {
6663+ AuDebugOn(au_dbstart(dentry) < 0 && au_dbend(dentry) >= 0);
6664+ if (inode)
6665+ err = au_refresh_hinode_self(inode);
6666+ au_dbg_verify_dinode(dentry);
6667+ if (!err)
6668+ goto out_dgen; /* success */
6669+ goto out;
6670+ }
6671+
6672+ /* temporary dinfo */
6673+ AuDbgDentry(dentry);
6674+ err = -ENOMEM;
6675+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
6676+ if (unlikely(!tmp))
6677+ goto out;
6678+ au_di_swap(tmp, dinfo);
6679+ /* returns the number of positive dentries */
6680+ /*
6681+ * if current working dir is removed, it returns an error.
6682+ * but the dentry is legal.
6683+ */
537831f9 6684+ err = au_lkup_dentry(dentry, /*bstart*/0, /*type*/0);
027c5e7a
AM
6685+ AuDbgDentry(dentry);
6686+ au_di_swap(tmp, dinfo);
6687+ if (err == -ENOENT)
6688+ err = 0;
6689+ if (err >= 0) {
6690+ /* compare/refresh by dinfo */
6691+ AuDbgDentry(dentry);
6692+ err = au_refresh_by_dinfo(dentry, dinfo, tmp);
6693+ au_dbg_verify_dinode(dentry);
6694+ AuTraceErr(err);
6695+ }
6696+ au_rw_write_unlock(&tmp->di_rwsem);
6697+ au_di_free(tmp);
6698+ if (unlikely(err))
6699+ goto out;
6700+
6701+out_dgen:
6702+ au_update_digen(dentry);
6703+out:
6704+ if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) {
6705+ AuIOErr("failed refreshing %.*s, %d\n",
6706+ AuDLNPair(dentry), err);
6707+ AuDbgDentry(dentry);
6708+ }
6709+ AuTraceErr(err);
6710+ return err;
6711+}
6712+
b4510431
AM
6713+static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags,
6714+ struct dentry *dentry, aufs_bindex_t bindex)
027c5e7a
AM
6715+{
6716+ int err, valid;
027c5e7a
AM
6717+
6718+ err = 0;
6719+ if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE))
6720+ goto out;
027c5e7a
AM
6721+
6722+ AuDbg("b%d\n", bindex);
b4510431
AM
6723+ /*
6724+ * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
6725+ * due to whiteout and branch permission.
6726+ */
6727+ flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
6728+ | LOOKUP_FOLLOW | LOOKUP_EXCL);
6729+ /* it may return tri-state */
6730+ valid = h_dentry->d_op->d_revalidate(h_dentry, flags);
1facf9fc 6731+
6732+ if (unlikely(valid < 0))
6733+ err = valid;
6734+ else if (!valid)
6735+ err = -EINVAL;
6736+
4f0767ce 6737+out:
1facf9fc 6738+ AuTraceErr(err);
6739+ return err;
6740+}
6741+
6742+/* todo: remove this */
6743+static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
b4510431 6744+ unsigned int flags, int do_udba)
1facf9fc 6745+{
6746+ int err;
6747+ umode_t mode, h_mode;
6748+ aufs_bindex_t bindex, btail, bstart, ibs, ibe;
6749+ unsigned char plus, unhashed, is_root, h_plus;
4a4d8108 6750+ struct inode *h_inode, *h_cached_inode;
1facf9fc 6751+ struct dentry *h_dentry;
6752+ struct qstr *name, *h_name;
6753+
6754+ err = 0;
6755+ plus = 0;
6756+ mode = 0;
1facf9fc 6757+ ibs = -1;
6758+ ibe = -1;
6759+ unhashed = !!d_unhashed(dentry);
6760+ is_root = !!IS_ROOT(dentry);
6761+ name = &dentry->d_name;
6762+
6763+ /*
7f207e10
AM
6764+ * Theoretically, REVAL test should be unnecessary in case of
6765+ * {FS,I}NOTIFY.
6766+ * But {fs,i}notify doesn't fire some necessary events,
1facf9fc 6767+ * IN_ATTRIB for atime/nlink/pageio
6768+ * IN_DELETE for NFS dentry
6769+ * Let's do REVAL test too.
6770+ */
6771+ if (do_udba && inode) {
6772+ mode = (inode->i_mode & S_IFMT);
6773+ plus = (inode->i_nlink > 0);
1facf9fc 6774+ ibs = au_ibstart(inode);
6775+ ibe = au_ibend(inode);
6776+ }
6777+
6778+ bstart = au_dbstart(dentry);
6779+ btail = bstart;
6780+ if (inode && S_ISDIR(inode->i_mode))
6781+ btail = au_dbtaildir(dentry);
6782+ for (bindex = bstart; bindex <= btail; bindex++) {
6783+ h_dentry = au_h_dptr(dentry, bindex);
6784+ if (!h_dentry)
6785+ continue;
6786+
6787+ AuDbg("b%d, %.*s\n", bindex, AuDLNPair(h_dentry));
027c5e7a 6788+ spin_lock(&h_dentry->d_lock);
1facf9fc 6789+ h_name = &h_dentry->d_name;
6790+ if (unlikely(do_udba
6791+ && !is_root
6792+ && (unhashed != !!d_unhashed(h_dentry)
6793+ || name->len != h_name->len
6794+ || memcmp(name->name, h_name->name, name->len))
6795+ )) {
6796+ AuDbg("unhash 0x%x 0x%x, %.*s %.*s\n",
6797+ unhashed, d_unhashed(h_dentry),
6798+ AuDLNPair(dentry), AuDLNPair(h_dentry));
027c5e7a 6799+ spin_unlock(&h_dentry->d_lock);
1facf9fc 6800+ goto err;
6801+ }
027c5e7a 6802+ spin_unlock(&h_dentry->d_lock);
1facf9fc 6803+
b4510431 6804+ err = au_do_h_d_reval(h_dentry, flags, dentry, bindex);
1facf9fc 6805+ if (unlikely(err))
6806+ /* do not goto err, to keep the errno */
6807+ break;
6808+
6809+ /* todo: plink too? */
6810+ if (!do_udba)
6811+ continue;
6812+
6813+ /* UDBA tests */
6814+ h_inode = h_dentry->d_inode;
6815+ if (unlikely(!!inode != !!h_inode))
6816+ goto err;
6817+
6818+ h_plus = plus;
6819+ h_mode = mode;
6820+ h_cached_inode = h_inode;
6821+ if (h_inode) {
6822+ h_mode = (h_inode->i_mode & S_IFMT);
6823+ h_plus = (h_inode->i_nlink > 0);
6824+ }
6825+ if (inode && ibs <= bindex && bindex <= ibe)
6826+ h_cached_inode = au_h_iptr(inode, bindex);
6827+
6828+ if (unlikely(plus != h_plus
6829+ || mode != h_mode
6830+ || h_cached_inode != h_inode))
6831+ goto err;
6832+ continue;
6833+
6834+ err:
6835+ err = -EINVAL;
6836+ break;
6837+ }
6838+
6839+ return err;
6840+}
6841+
027c5e7a 6842+/* todo: consolidate with do_refresh() and au_reval_for_attr() */
1facf9fc 6843+static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
6844+{
6845+ int err;
6846+ struct dentry *parent;
1facf9fc 6847+
027c5e7a 6848+ if (!au_digen_test(dentry, sigen))
1facf9fc 6849+ return 0;
6850+
6851+ parent = dget_parent(dentry);
6852+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 6853+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 6854+ au_dbg_verify_gen(parent, sigen);
027c5e7a 6855+ err = au_refresh_dentry(dentry, parent);
1facf9fc 6856+ di_read_unlock(parent, AuLock_IR);
6857+ dput(parent);
027c5e7a 6858+ AuTraceErr(err);
1facf9fc 6859+ return err;
6860+}
6861+
6862+int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
6863+{
6864+ int err;
6865+ struct dentry *d, *parent;
6866+ struct inode *inode;
6867+
027c5e7a 6868+ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
1facf9fc 6869+ return simple_reval_dpath(dentry, sigen);
6870+
6871+ /* slow loop, keep it simple and stupid */
6872+ /* cf: au_cpup_dirs() */
6873+ err = 0;
6874+ parent = NULL;
027c5e7a 6875+ while (au_digen_test(dentry, sigen)) {
1facf9fc 6876+ d = dentry;
6877+ while (1) {
6878+ dput(parent);
6879+ parent = dget_parent(d);
027c5e7a 6880+ if (!au_digen_test(parent, sigen))
1facf9fc 6881+ break;
6882+ d = parent;
6883+ }
6884+
6885+ inode = d->d_inode;
6886+ if (d != dentry)
027c5e7a 6887+ di_write_lock_child2(d);
1facf9fc 6888+
6889+ /* someone might update our dentry while we were sleeping */
027c5e7a
AM
6890+ if (au_digen_test(d, sigen)) {
6891+ /*
6892+ * todo: consolidate with simple_reval_dpath(),
6893+ * do_refresh() and au_reval_for_attr().
6894+ */
1facf9fc 6895+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 6896+ err = au_refresh_dentry(d, parent);
1facf9fc 6897+ di_read_unlock(parent, AuLock_IR);
6898+ }
6899+
6900+ if (d != dentry)
6901+ di_write_unlock(d);
6902+ dput(parent);
6903+ if (unlikely(err))
6904+ break;
6905+ }
6906+
6907+ return err;
6908+}
6909+
6910+/*
6911+ * if valid returns 1, otherwise 0.
6912+ */
b4510431 6913+static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags)
1facf9fc 6914+{
6915+ int valid, err;
6916+ unsigned int sigen;
6917+ unsigned char do_udba;
6918+ struct super_block *sb;
6919+ struct inode *inode;
6920+
027c5e7a 6921+ /* todo: support rcu-walk? */
b4510431 6922+ if (flags & LOOKUP_RCU)
027c5e7a
AM
6923+ return -ECHILD;
6924+
6925+ valid = 0;
6926+ if (unlikely(!au_di(dentry)))
6927+ goto out;
6928+
6929+ inode = dentry->d_inode;
6930+ if (inode && is_bad_inode(inode))
6931+ goto out;
6932+
e49829fe 6933+ valid = 1;
1facf9fc 6934+ sb = dentry->d_sb;
e49829fe
JR
6935+ /*
6936+ * todo: very ugly
6937+ * i_mutex of parent dir may be held,
6938+ * but we should not return 'invalid' due to busy.
6939+ */
6940+ err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM);
6941+ if (unlikely(err)) {
6942+ valid = err;
027c5e7a 6943+ AuTraceErr(err);
e49829fe
JR
6944+ goto out;
6945+ }
027c5e7a
AM
6946+ if (unlikely(au_dbrange_test(dentry))) {
6947+ err = -EINVAL;
6948+ AuTraceErr(err);
6949+ goto out_dgrade;
1facf9fc 6950+ }
027c5e7a
AM
6951+
6952+ sigen = au_sigen(sb);
6953+ if (au_digen_test(dentry, sigen)) {
1facf9fc 6954+ AuDebugOn(IS_ROOT(dentry));
027c5e7a
AM
6955+ err = au_reval_dpath(dentry, sigen);
6956+ if (unlikely(err)) {
6957+ AuTraceErr(err);
1facf9fc 6958+ goto out_dgrade;
027c5e7a 6959+ }
1facf9fc 6960+ }
6961+ di_downgrade_lock(dentry, AuLock_IR);
6962+
1facf9fc 6963+ err = -EINVAL;
027c5e7a
AM
6964+ if (inode && (IS_DEADDIR(inode) || !inode->i_nlink))
6965+ goto out_inval;
6966+
1facf9fc 6967+ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
6968+ if (do_udba && inode) {
6969+ aufs_bindex_t bstart = au_ibstart(inode);
027c5e7a 6970+ struct inode *h_inode;
1facf9fc 6971+
027c5e7a
AM
6972+ if (bstart >= 0) {
6973+ h_inode = au_h_iptr(inode, bstart);
6974+ if (h_inode && au_test_higen(inode, h_inode))
6975+ goto out_inval;
6976+ }
1facf9fc 6977+ }
6978+
b4510431 6979+ err = h_d_revalidate(dentry, inode, flags, do_udba);
027c5e7a 6980+ if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) {
1facf9fc 6981+ err = -EIO;
027c5e7a
AM
6982+ AuDbg("both of real entry and whiteout found, %.*s, err %d\n",
6983+ AuDLNPair(dentry), err);
6984+ }
e49829fe 6985+ goto out_inval;
1facf9fc 6986+
4f0767ce 6987+out_dgrade:
1facf9fc 6988+ di_downgrade_lock(dentry, AuLock_IR);
e49829fe 6989+out_inval:
1facf9fc 6990+ aufs_read_unlock(dentry, AuLock_IR);
6991+ AuTraceErr(err);
6992+ valid = !err;
e49829fe 6993+out:
027c5e7a 6994+ if (!valid) {
e49829fe 6995+ AuDbg("%.*s invalid, %d\n", AuDLNPair(dentry), valid);
027c5e7a
AM
6996+ d_drop(dentry);
6997+ }
1facf9fc 6998+ return valid;
6999+}
7000+
7001+static void aufs_d_release(struct dentry *dentry)
7002+{
027c5e7a 7003+ if (au_di(dentry)) {
4a4d8108
AM
7004+ au_di_fin(dentry);
7005+ au_hn_di_reinit(dentry);
1facf9fc 7006+ }
1facf9fc 7007+}
7008+
4a4d8108 7009+const struct dentry_operations aufs_dop = {
1facf9fc 7010+ .d_revalidate = aufs_d_revalidate,
7011+ .d_release = aufs_d_release
7012+};
7f207e10
AM
7013diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
7014--- /usr/share/empty/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
1716fcea 7015+++ linux/fs/aufs/dentry.h 2013-02-19 08:40:03.946892891 +0100
537831f9 7016@@ -0,0 +1,234 @@
1facf9fc 7017+/*
7a9e40b8 7018+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 7019+ *
7020+ * This program, aufs is free software; you can redistribute it and/or modify
7021+ * it under the terms of the GNU General Public License as published by
7022+ * the Free Software Foundation; either version 2 of the License, or
7023+ * (at your option) any later version.
dece6358
AM
7024+ *
7025+ * This program is distributed in the hope that it will be useful,
7026+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7027+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7028+ * GNU General Public License for more details.
7029+ *
7030+ * You should have received a copy of the GNU General Public License
7031+ * along with this program; if not, write to the Free Software
7032+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 7033+ */
7034+
7035+/*
7036+ * lookup and dentry operations
7037+ */
7038+
7039+#ifndef __AUFS_DENTRY_H__
7040+#define __AUFS_DENTRY_H__
7041+
7042+#ifdef __KERNEL__
7043+
dece6358 7044+#include <linux/dcache.h>
1facf9fc 7045+#include "rwsem.h"
7046+
1facf9fc 7047+struct au_hdentry {
7048+ struct dentry *hd_dentry;
027c5e7a 7049+ aufs_bindex_t hd_id;
1facf9fc 7050+};
7051+
7052+struct au_dinfo {
7053+ atomic_t di_generation;
7054+
dece6358 7055+ struct au_rwsem di_rwsem;
1facf9fc 7056+ aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq;
7057+ struct au_hdentry *di_hdentry;
4a4d8108 7058+} ____cacheline_aligned_in_smp;
1facf9fc 7059+
7060+/* ---------------------------------------------------------------------- */
7061+
7062+/* dentry.c */
4a4d8108 7063+extern const struct dentry_operations aufs_dop;
1facf9fc 7064+struct au_branch;
1facf9fc 7065+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
7066+ struct au_branch *br);
7067+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
7068+ struct dentry *h_parent, struct au_branch *br);
7069+
537831f9 7070+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type);
1facf9fc 7071+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex);
027c5e7a 7072+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
1facf9fc 7073+int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
7074+
7075+/* dinfo.c */
4a4d8108 7076+void au_di_init_once(void *_di);
027c5e7a
AM
7077+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
7078+void au_di_free(struct au_dinfo *dinfo);
7079+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
7080+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
4a4d8108
AM
7081+int au_di_init(struct dentry *dentry);
7082+void au_di_fin(struct dentry *dentry);
1facf9fc 7083+int au_di_realloc(struct au_dinfo *dinfo, int nbr);
7084+
7085+void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
7086+void di_read_unlock(struct dentry *d, int flags);
7087+void di_downgrade_lock(struct dentry *d, int flags);
7088+void di_write_lock(struct dentry *d, unsigned int lsc);
7089+void di_write_unlock(struct dentry *d);
7090+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
7091+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
7092+void di_write_unlock2(struct dentry *d1, struct dentry *d2);
7093+
7094+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
2cbb1c4b 7095+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
1facf9fc 7096+aufs_bindex_t au_dbtail(struct dentry *dentry);
7097+aufs_bindex_t au_dbtaildir(struct dentry *dentry);
7098+
7099+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
7100+ struct dentry *h_dentry);
027c5e7a
AM
7101+int au_digen_test(struct dentry *dentry, unsigned int sigen);
7102+int au_dbrange_test(struct dentry *dentry);
1facf9fc 7103+void au_update_digen(struct dentry *dentry);
7104+void au_update_dbrange(struct dentry *dentry, int do_put_zero);
7105+void au_update_dbstart(struct dentry *dentry);
7106+void au_update_dbend(struct dentry *dentry);
7107+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
7108+
7109+/* ---------------------------------------------------------------------- */
7110+
7111+static inline struct au_dinfo *au_di(struct dentry *dentry)
7112+{
7113+ return dentry->d_fsdata;
7114+}
7115+
7116+/* ---------------------------------------------------------------------- */
7117+
7118+/* lock subclass for dinfo */
7119+enum {
7120+ AuLsc_DI_CHILD, /* child first */
4a4d8108 7121+ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */
1facf9fc 7122+ AuLsc_DI_CHILD3, /* copyup dirs */
7123+ AuLsc_DI_PARENT,
7124+ AuLsc_DI_PARENT2,
027c5e7a
AM
7125+ AuLsc_DI_PARENT3,
7126+ AuLsc_DI_TMP /* temp for replacing dinfo */
1facf9fc 7127+};
7128+
7129+/*
7130+ * di_read_lock_child, di_write_lock_child,
7131+ * di_read_lock_child2, di_write_lock_child2,
7132+ * di_read_lock_child3, di_write_lock_child3,
7133+ * di_read_lock_parent, di_write_lock_parent,
7134+ * di_read_lock_parent2, di_write_lock_parent2,
7135+ * di_read_lock_parent3, di_write_lock_parent3,
7136+ */
7137+#define AuReadLockFunc(name, lsc) \
7138+static inline void di_read_lock_##name(struct dentry *d, int flags) \
7139+{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
7140+
7141+#define AuWriteLockFunc(name, lsc) \
7142+static inline void di_write_lock_##name(struct dentry *d) \
7143+{ di_write_lock(d, AuLsc_DI_##lsc); }
7144+
7145+#define AuRWLockFuncs(name, lsc) \
7146+ AuReadLockFunc(name, lsc) \
7147+ AuWriteLockFunc(name, lsc)
7148+
7149+AuRWLockFuncs(child, CHILD);
7150+AuRWLockFuncs(child2, CHILD2);
7151+AuRWLockFuncs(child3, CHILD3);
7152+AuRWLockFuncs(parent, PARENT);
7153+AuRWLockFuncs(parent2, PARENT2);
7154+AuRWLockFuncs(parent3, PARENT3);
7155+
7156+#undef AuReadLockFunc
7157+#undef AuWriteLockFunc
7158+#undef AuRWLockFuncs
7159+
7160+#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
dece6358
AM
7161+#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
7162+#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
1facf9fc 7163+
7164+/* ---------------------------------------------------------------------- */
7165+
7166+/* todo: memory barrier? */
7167+static inline unsigned int au_digen(struct dentry *d)
7168+{
7169+ return atomic_read(&au_di(d)->di_generation);
7170+}
7171+
7172+static inline void au_h_dentry_init(struct au_hdentry *hdentry)
7173+{
7174+ hdentry->hd_dentry = NULL;
7175+}
7176+
7177+static inline void au_hdput(struct au_hdentry *hd)
7178+{
4a4d8108
AM
7179+ if (hd)
7180+ dput(hd->hd_dentry);
1facf9fc 7181+}
7182+
7183+static inline aufs_bindex_t au_dbstart(struct dentry *dentry)
7184+{
1308ab2a 7185+ DiMustAnyLock(dentry);
1facf9fc 7186+ return au_di(dentry)->di_bstart;
7187+}
7188+
7189+static inline aufs_bindex_t au_dbend(struct dentry *dentry)
7190+{
1308ab2a 7191+ DiMustAnyLock(dentry);
1facf9fc 7192+ return au_di(dentry)->di_bend;
7193+}
7194+
7195+static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
7196+{
1308ab2a 7197+ DiMustAnyLock(dentry);
1facf9fc 7198+ return au_di(dentry)->di_bwh;
7199+}
7200+
7201+static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
7202+{
1308ab2a 7203+ DiMustAnyLock(dentry);
1facf9fc 7204+ return au_di(dentry)->di_bdiropq;
7205+}
7206+
7207+/* todo: hard/soft set? */
7208+static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex)
7209+{
1308ab2a 7210+ DiMustWriteLock(dentry);
1facf9fc 7211+ au_di(dentry)->di_bstart = bindex;
7212+}
7213+
7214+static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex)
7215+{
1308ab2a 7216+ DiMustWriteLock(dentry);
1facf9fc 7217+ au_di(dentry)->di_bend = bindex;
7218+}
7219+
7220+static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
7221+{
1308ab2a 7222+ DiMustWriteLock(dentry);
1facf9fc 7223+ /* dbwh can be outside of bstart - bend range */
7224+ au_di(dentry)->di_bwh = bindex;
7225+}
7226+
7227+static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
7228+{
1308ab2a 7229+ DiMustWriteLock(dentry);
1facf9fc 7230+ au_di(dentry)->di_bdiropq = bindex;
7231+}
7232+
7233+/* ---------------------------------------------------------------------- */
7234+
4a4d8108 7235+#ifdef CONFIG_AUFS_HNOTIFY
1facf9fc 7236+static inline void au_digen_dec(struct dentry *d)
7237+{
e49829fe 7238+ atomic_dec(&au_di(d)->di_generation);
1facf9fc 7239+}
7240+
4a4d8108 7241+static inline void au_hn_di_reinit(struct dentry *dentry)
1facf9fc 7242+{
7243+ dentry->d_fsdata = NULL;
7244+}
7245+#else
4a4d8108
AM
7246+AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
7247+#endif /* CONFIG_AUFS_HNOTIFY */
1facf9fc 7248+
7249+#endif /* __KERNEL__ */
7250+#endif /* __AUFS_DENTRY_H__ */
7f207e10
AM
7251diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
7252--- /usr/share/empty/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100
1716fcea 7253+++ linux/fs/aufs/dinfo.c 2013-02-19 08:40:03.946892891 +0100
2cbb1c4b 7254@@ -0,0 +1,543 @@
1facf9fc 7255+/*
7a9e40b8 7256+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 7257+ *
7258+ * This program, aufs is free software; you can redistribute it and/or modify
7259+ * it under the terms of the GNU General Public License as published by
7260+ * the Free Software Foundation; either version 2 of the License, or
7261+ * (at your option) any later version.
dece6358
AM
7262+ *
7263+ * This program is distributed in the hope that it will be useful,
7264+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7265+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7266+ * GNU General Public License for more details.
7267+ *
7268+ * You should have received a copy of the GNU General Public License
7269+ * along with this program; if not, write to the Free Software
7270+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 7271+ */
7272+
7273+/*
7274+ * dentry private data
7275+ */
7276+
7277+#include "aufs.h"
7278+
e49829fe 7279+void au_di_init_once(void *_dinfo)
4a4d8108 7280+{
e49829fe
JR
7281+ struct au_dinfo *dinfo = _dinfo;
7282+ static struct lock_class_key aufs_di;
4a4d8108 7283+
e49829fe
JR
7284+ au_rw_init(&dinfo->di_rwsem);
7285+ au_rw_class(&dinfo->di_rwsem, &aufs_di);
4a4d8108
AM
7286+}
7287+
027c5e7a 7288+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
1facf9fc 7289+{
7290+ struct au_dinfo *dinfo;
027c5e7a 7291+ int nbr, i;
1facf9fc 7292+
7293+ dinfo = au_cache_alloc_dinfo();
7294+ if (unlikely(!dinfo))
7295+ goto out;
7296+
1facf9fc 7297+ nbr = au_sbend(sb) + 1;
7298+ if (nbr <= 0)
7299+ nbr = 1;
7300+ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
027c5e7a
AM
7301+ if (dinfo->di_hdentry) {
7302+ au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
7303+ dinfo->di_bstart = -1;
7304+ dinfo->di_bend = -1;
7305+ dinfo->di_bwh = -1;
7306+ dinfo->di_bdiropq = -1;
7307+ for (i = 0; i < nbr; i++)
7308+ dinfo->di_hdentry[i].hd_id = -1;
7309+ goto out;
7310+ }
1facf9fc 7311+
1facf9fc 7312+ au_cache_free_dinfo(dinfo);
027c5e7a
AM
7313+ dinfo = NULL;
7314+
4f0767ce 7315+out:
027c5e7a 7316+ return dinfo;
1facf9fc 7317+}
7318+
027c5e7a 7319+void au_di_free(struct au_dinfo *dinfo)
4a4d8108 7320+{
4a4d8108
AM
7321+ struct au_hdentry *p;
7322+ aufs_bindex_t bend, bindex;
7323+
7324+ /* dentry may not be revalidated */
027c5e7a 7325+ bindex = dinfo->di_bstart;
4a4d8108 7326+ if (bindex >= 0) {
027c5e7a
AM
7327+ bend = dinfo->di_bend;
7328+ p = dinfo->di_hdentry + bindex;
4a4d8108
AM
7329+ while (bindex++ <= bend)
7330+ au_hdput(p++);
7331+ }
027c5e7a
AM
7332+ kfree(dinfo->di_hdentry);
7333+ au_cache_free_dinfo(dinfo);
7334+}
7335+
7336+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
7337+{
7338+ struct au_hdentry *p;
7339+ aufs_bindex_t bi;
7340+
7341+ AuRwMustWriteLock(&a->di_rwsem);
7342+ AuRwMustWriteLock(&b->di_rwsem);
7343+
7344+#define DiSwap(v, name) \
7345+ do { \
7346+ v = a->di_##name; \
7347+ a->di_##name = b->di_##name; \
7348+ b->di_##name = v; \
7349+ } while (0)
7350+
7351+ DiSwap(p, hdentry);
7352+ DiSwap(bi, bstart);
7353+ DiSwap(bi, bend);
7354+ DiSwap(bi, bwh);
7355+ DiSwap(bi, bdiropq);
7356+ /* smp_mb(); */
7357+
7358+#undef DiSwap
7359+}
7360+
7361+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
7362+{
7363+ AuRwMustWriteLock(&dst->di_rwsem);
7364+ AuRwMustWriteLock(&src->di_rwsem);
7365+
7366+ dst->di_bstart = src->di_bstart;
7367+ dst->di_bend = src->di_bend;
7368+ dst->di_bwh = src->di_bwh;
7369+ dst->di_bdiropq = src->di_bdiropq;
7370+ /* smp_mb(); */
7371+}
7372+
7373+int au_di_init(struct dentry *dentry)
7374+{
7375+ int err;
7376+ struct super_block *sb;
7377+ struct au_dinfo *dinfo;
7378+
7379+ err = 0;
7380+ sb = dentry->d_sb;
7381+ dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
7382+ if (dinfo) {
7383+ atomic_set(&dinfo->di_generation, au_sigen(sb));
7384+ /* smp_mb(); */ /* atomic_set */
7385+ dentry->d_fsdata = dinfo;
7386+ } else
7387+ err = -ENOMEM;
7388+
7389+ return err;
7390+}
7391+
7392+void au_di_fin(struct dentry *dentry)
7393+{
7394+ struct au_dinfo *dinfo;
7395+
7396+ dinfo = au_di(dentry);
7397+ AuRwDestroy(&dinfo->di_rwsem);
7398+ au_di_free(dinfo);
4a4d8108
AM
7399+}
7400+
1facf9fc 7401+int au_di_realloc(struct au_dinfo *dinfo, int nbr)
7402+{
7403+ int err, sz;
7404+ struct au_hdentry *hdp;
7405+
1308ab2a 7406+ AuRwMustWriteLock(&dinfo->di_rwsem);
7407+
1facf9fc 7408+ err = -ENOMEM;
7409+ sz = sizeof(*hdp) * (dinfo->di_bend + 1);
7410+ if (!sz)
7411+ sz = sizeof(*hdp);
7412+ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS);
7413+ if (hdp) {
7414+ dinfo->di_hdentry = hdp;
7415+ err = 0;
7416+ }
7417+
7418+ return err;
7419+}
7420+
7421+/* ---------------------------------------------------------------------- */
7422+
7423+static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
7424+{
7425+ switch (lsc) {
7426+ case AuLsc_DI_CHILD:
7427+ ii_write_lock_child(inode);
7428+ break;
7429+ case AuLsc_DI_CHILD2:
7430+ ii_write_lock_child2(inode);
7431+ break;
7432+ case AuLsc_DI_CHILD3:
7433+ ii_write_lock_child3(inode);
7434+ break;
7435+ case AuLsc_DI_PARENT:
7436+ ii_write_lock_parent(inode);
7437+ break;
7438+ case AuLsc_DI_PARENT2:
7439+ ii_write_lock_parent2(inode);
7440+ break;
7441+ case AuLsc_DI_PARENT3:
7442+ ii_write_lock_parent3(inode);
7443+ break;
7444+ default:
7445+ BUG();
7446+ }
7447+}
7448+
7449+static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
7450+{
7451+ switch (lsc) {
7452+ case AuLsc_DI_CHILD:
7453+ ii_read_lock_child(inode);
7454+ break;
7455+ case AuLsc_DI_CHILD2:
7456+ ii_read_lock_child2(inode);
7457+ break;
7458+ case AuLsc_DI_CHILD3:
7459+ ii_read_lock_child3(inode);
7460+ break;
7461+ case AuLsc_DI_PARENT:
7462+ ii_read_lock_parent(inode);
7463+ break;
7464+ case AuLsc_DI_PARENT2:
7465+ ii_read_lock_parent2(inode);
7466+ break;
7467+ case AuLsc_DI_PARENT3:
7468+ ii_read_lock_parent3(inode);
7469+ break;
7470+ default:
7471+ BUG();
7472+ }
7473+}
7474+
7475+void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
7476+{
dece6358 7477+ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
1facf9fc 7478+ if (d->d_inode) {
7479+ if (au_ftest_lock(flags, IW))
7480+ do_ii_write_lock(d->d_inode, lsc);
7481+ else if (au_ftest_lock(flags, IR))
7482+ do_ii_read_lock(d->d_inode, lsc);
7483+ }
7484+}
7485+
7486+void di_read_unlock(struct dentry *d, int flags)
7487+{
7488+ if (d->d_inode) {
027c5e7a
AM
7489+ if (au_ftest_lock(flags, IW)) {
7490+ au_dbg_verify_dinode(d);
1facf9fc 7491+ ii_write_unlock(d->d_inode);
027c5e7a
AM
7492+ } else if (au_ftest_lock(flags, IR)) {
7493+ au_dbg_verify_dinode(d);
1facf9fc 7494+ ii_read_unlock(d->d_inode);
027c5e7a 7495+ }
1facf9fc 7496+ }
dece6358 7497+ au_rw_read_unlock(&au_di(d)->di_rwsem);
1facf9fc 7498+}
7499+
7500+void di_downgrade_lock(struct dentry *d, int flags)
7501+{
1facf9fc 7502+ if (d->d_inode && au_ftest_lock(flags, IR))
7503+ ii_downgrade_lock(d->d_inode);
dece6358 7504+ au_rw_dgrade_lock(&au_di(d)->di_rwsem);
1facf9fc 7505+}
7506+
7507+void di_write_lock(struct dentry *d, unsigned int lsc)
7508+{
dece6358 7509+ au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
1facf9fc 7510+ if (d->d_inode)
7511+ do_ii_write_lock(d->d_inode, lsc);
7512+}
7513+
7514+void di_write_unlock(struct dentry *d)
7515+{
027c5e7a 7516+ au_dbg_verify_dinode(d);
1facf9fc 7517+ if (d->d_inode)
7518+ ii_write_unlock(d->d_inode);
dece6358 7519+ au_rw_write_unlock(&au_di(d)->di_rwsem);
1facf9fc 7520+}
7521+
7522+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
7523+{
7524+ AuDebugOn(d1 == d2
7525+ || d1->d_inode == d2->d_inode
7526+ || d1->d_sb != d2->d_sb);
7527+
7528+ if (isdir && au_test_subdir(d1, d2)) {
7529+ di_write_lock_child(d1);
7530+ di_write_lock_child2(d2);
7531+ } else {
7532+ /* there should be no races */
7533+ di_write_lock_child(d2);
7534+ di_write_lock_child2(d1);
7535+ }
7536+}
7537+
7538+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
7539+{
7540+ AuDebugOn(d1 == d2
7541+ || d1->d_inode == d2->d_inode
7542+ || d1->d_sb != d2->d_sb);
7543+
7544+ if (isdir && au_test_subdir(d1, d2)) {
7545+ di_write_lock_parent(d1);
7546+ di_write_lock_parent2(d2);
7547+ } else {
7548+ /* there should be no races */
7549+ di_write_lock_parent(d2);
7550+ di_write_lock_parent2(d1);
7551+ }
7552+}
7553+
7554+void di_write_unlock2(struct dentry *d1, struct dentry *d2)
7555+{
7556+ di_write_unlock(d1);
7557+ if (d1->d_inode == d2->d_inode)
dece6358 7558+ au_rw_write_unlock(&au_di(d2)->di_rwsem);
1facf9fc 7559+ else
7560+ di_write_unlock(d2);
7561+}
7562+
7563+/* ---------------------------------------------------------------------- */
7564+
7565+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
7566+{
7567+ struct dentry *d;
7568+
1308ab2a 7569+ DiMustAnyLock(dentry);
7570+
1facf9fc 7571+ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
7572+ return NULL;
7573+ AuDebugOn(bindex < 0);
7574+ d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry;
027c5e7a 7575+ AuDebugOn(d && d->d_count <= 0);
1facf9fc 7576+ return d;
7577+}
7578+
2cbb1c4b
JR
7579+/*
7580+ * extended version of au_h_dptr().
7581+ * returns a hashed and positive h_dentry in bindex, NULL, or error.
7582+ */
7583+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
7584+{
7585+ struct dentry *h_dentry;
7586+ struct inode *inode, *h_inode;
7587+
7588+ inode = dentry->d_inode;
7589+ AuDebugOn(!inode);
7590+
7591+ h_dentry = NULL;
7592+ if (au_dbstart(dentry) <= bindex
7593+ && bindex <= au_dbend(dentry))
7594+ h_dentry = au_h_dptr(dentry, bindex);
7595+ if (h_dentry && !au_d_hashed_positive(h_dentry)) {
7596+ dget(h_dentry);
7597+ goto out; /* success */
7598+ }
7599+
7600+ AuDebugOn(bindex < au_ibstart(inode));
7601+ AuDebugOn(au_ibend(inode) < bindex);
7602+ h_inode = au_h_iptr(inode, bindex);
7603+ h_dentry = d_find_alias(h_inode);
7604+ if (h_dentry) {
7605+ if (!IS_ERR(h_dentry)) {
7606+ if (!au_d_hashed_positive(h_dentry))
7607+ goto out; /* success */
7608+ dput(h_dentry);
7609+ } else
7610+ goto out;
7611+ }
7612+
7613+ if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
7614+ h_dentry = au_plink_lkup(inode, bindex);
7615+ AuDebugOn(!h_dentry);
7616+ if (!IS_ERR(h_dentry)) {
7617+ if (!au_d_hashed_positive(h_dentry))
7618+ goto out; /* success */
7619+ dput(h_dentry);
7620+ h_dentry = NULL;
7621+ }
7622+ }
7623+
7624+out:
7625+ AuDbgDentry(h_dentry);
7626+ return h_dentry;
7627+}
7628+
1facf9fc 7629+aufs_bindex_t au_dbtail(struct dentry *dentry)
7630+{
7631+ aufs_bindex_t bend, bwh;
7632+
7633+ bend = au_dbend(dentry);
7634+ if (0 <= bend) {
7635+ bwh = au_dbwh(dentry);
7636+ if (!bwh)
7637+ return bwh;
7638+ if (0 < bwh && bwh < bend)
7639+ return bwh - 1;
7640+ }
7641+ return bend;
7642+}
7643+
7644+aufs_bindex_t au_dbtaildir(struct dentry *dentry)
7645+{
7646+ aufs_bindex_t bend, bopq;
7647+
7648+ bend = au_dbtail(dentry);
7649+ if (0 <= bend) {
7650+ bopq = au_dbdiropq(dentry);
7651+ if (0 <= bopq && bopq < bend)
7652+ bend = bopq;
7653+ }
7654+ return bend;
7655+}
7656+
7657+/* ---------------------------------------------------------------------- */
7658+
7659+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
7660+ struct dentry *h_dentry)
7661+{
7662+ struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
027c5e7a 7663+ struct au_branch *br;
1facf9fc 7664+
1308ab2a 7665+ DiMustWriteLock(dentry);
7666+
4a4d8108 7667+ au_hdput(hd);
1facf9fc 7668+ hd->hd_dentry = h_dentry;
027c5e7a
AM
7669+ if (h_dentry) {
7670+ br = au_sbr(dentry->d_sb, bindex);
7671+ hd->hd_id = br->br_id;
7672+ }
7673+}
7674+
7675+int au_dbrange_test(struct dentry *dentry)
7676+{
7677+ int err;
7678+ aufs_bindex_t bstart, bend;
7679+
7680+ err = 0;
7681+ bstart = au_dbstart(dentry);
7682+ bend = au_dbend(dentry);
7683+ if (bstart >= 0)
7684+ AuDebugOn(bend < 0 && bstart > bend);
7685+ else {
7686+ err = -EIO;
7687+ AuDebugOn(bend >= 0);
7688+ }
7689+
7690+ return err;
7691+}
7692+
7693+int au_digen_test(struct dentry *dentry, unsigned int sigen)
7694+{
7695+ int err;
7696+
7697+ err = 0;
7698+ if (unlikely(au_digen(dentry) != sigen
7699+ || au_iigen_test(dentry->d_inode, sigen)))
7700+ err = -EIO;
7701+
7702+ return err;
1facf9fc 7703+}
7704+
7705+void au_update_digen(struct dentry *dentry)
7706+{
7707+ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
7708+ /* smp_mb(); */ /* atomic_set */
7709+}
7710+
7711+void au_update_dbrange(struct dentry *dentry, int do_put_zero)
7712+{
7713+ struct au_dinfo *dinfo;
7714+ struct dentry *h_d;
4a4d8108 7715+ struct au_hdentry *hdp;
1facf9fc 7716+
1308ab2a 7717+ DiMustWriteLock(dentry);
7718+
1facf9fc 7719+ dinfo = au_di(dentry);
7720+ if (!dinfo || dinfo->di_bstart < 0)
7721+ return;
7722+
4a4d8108 7723+ hdp = dinfo->di_hdentry;
1facf9fc 7724+ if (do_put_zero) {
7725+ aufs_bindex_t bindex, bend;
7726+
7727+ bend = dinfo->di_bend;
7728+ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) {
4a4d8108 7729+ h_d = hdp[0 + bindex].hd_dentry;
1facf9fc 7730+ if (h_d && !h_d->d_inode)
7731+ au_set_h_dptr(dentry, bindex, NULL);
7732+ }
7733+ }
7734+
7735+ dinfo->di_bstart = -1;
7736+ while (++dinfo->di_bstart <= dinfo->di_bend)
4a4d8108 7737+ if (hdp[0 + dinfo->di_bstart].hd_dentry)
1facf9fc 7738+ break;
7739+ if (dinfo->di_bstart > dinfo->di_bend) {
7740+ dinfo->di_bstart = -1;
7741+ dinfo->di_bend = -1;
7742+ return;
7743+ }
7744+
7745+ dinfo->di_bend++;
7746+ while (0 <= --dinfo->di_bend)
4a4d8108 7747+ if (hdp[0 + dinfo->di_bend].hd_dentry)
1facf9fc 7748+ break;
7749+ AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0);
7750+}
7751+
7752+void au_update_dbstart(struct dentry *dentry)
7753+{
7754+ aufs_bindex_t bindex, bend;
7755+ struct dentry *h_dentry;
7756+
7757+ bend = au_dbend(dentry);
7758+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
7759+ h_dentry = au_h_dptr(dentry, bindex);
7760+ if (!h_dentry)
7761+ continue;
7762+ if (h_dentry->d_inode) {
7763+ au_set_dbstart(dentry, bindex);
7764+ return;
7765+ }
7766+ au_set_h_dptr(dentry, bindex, NULL);
7767+ }
7768+}
7769+
7770+void au_update_dbend(struct dentry *dentry)
7771+{
7772+ aufs_bindex_t bindex, bstart;
7773+ struct dentry *h_dentry;
7774+
7775+ bstart = au_dbstart(dentry);
7f207e10 7776+ for (bindex = au_dbend(dentry); bindex >= bstart; bindex--) {
1facf9fc 7777+ h_dentry = au_h_dptr(dentry, bindex);
7778+ if (!h_dentry)
7779+ continue;
7780+ if (h_dentry->d_inode) {
7781+ au_set_dbend(dentry, bindex);
7782+ return;
7783+ }
7784+ au_set_h_dptr(dentry, bindex, NULL);
7785+ }
7786+}
7787+
7788+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
7789+{
7790+ aufs_bindex_t bindex, bend;
7791+
7792+ bend = au_dbend(dentry);
7793+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++)
7794+ if (au_h_dptr(dentry, bindex) == h_dentry)
7795+ return bindex;
7796+ return -1;
7797+}
7f207e10
AM
7798diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
7799--- /usr/share/empty/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
a2a7ad62 7800+++ linux/fs/aufs/dir.c 2013-03-14 20:07:41.038119650 +0100
b4510431 7801@@ -0,0 +1,633 @@
1facf9fc 7802+/*
7a9e40b8 7803+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 7804+ *
7805+ * This program, aufs is free software; you can redistribute it and/or modify
7806+ * it under the terms of the GNU General Public License as published by
7807+ * the Free Software Foundation; either version 2 of the License, or
7808+ * (at your option) any later version.
dece6358
AM
7809+ *
7810+ * This program is distributed in the hope that it will be useful,
7811+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7812+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7813+ * GNU General Public License for more details.
7814+ *
7815+ * You should have received a copy of the GNU General Public License
7816+ * along with this program; if not, write to the Free Software
7817+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 7818+ */
7819+
7820+/*
7821+ * directory operations
7822+ */
7823+
7824+#include <linux/fs_stack.h>
7825+#include "aufs.h"
7826+
7827+void au_add_nlink(struct inode *dir, struct inode *h_dir)
7828+{
9dbd164d
AM
7829+ unsigned int nlink;
7830+
1facf9fc 7831+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
7832+
9dbd164d
AM
7833+ nlink = dir->i_nlink;
7834+ nlink += h_dir->i_nlink - 2;
1facf9fc 7835+ if (h_dir->i_nlink < 2)
9dbd164d 7836+ nlink += 2;
7eafdf33 7837+ /* 0 can happen in revaliding */
92d182d2 7838+ set_nlink(dir, nlink);
1facf9fc 7839+}
7840+
7841+void au_sub_nlink(struct inode *dir, struct inode *h_dir)
7842+{
9dbd164d
AM
7843+ unsigned int nlink;
7844+
1facf9fc 7845+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
7846+
9dbd164d
AM
7847+ nlink = dir->i_nlink;
7848+ nlink -= h_dir->i_nlink - 2;
1facf9fc 7849+ if (h_dir->i_nlink < 2)
9dbd164d 7850+ nlink -= 2;
92d182d2 7851+ /* nlink == 0 means the branch-fs is broken */
9dbd164d 7852+ set_nlink(dir, nlink);
1facf9fc 7853+}
7854+
1308ab2a 7855+loff_t au_dir_size(struct file *file, struct dentry *dentry)
7856+{
7857+ loff_t sz;
7858+ aufs_bindex_t bindex, bend;
7859+ struct file *h_file;
7860+ struct dentry *h_dentry;
7861+
7862+ sz = 0;
7863+ if (file) {
7864+ AuDebugOn(!file->f_dentry);
7865+ AuDebugOn(!file->f_dentry->d_inode);
7866+ AuDebugOn(!S_ISDIR(file->f_dentry->d_inode->i_mode));
7867+
4a4d8108 7868+ bend = au_fbend_dir(file);
1308ab2a 7869+ for (bindex = au_fbstart(file);
7870+ bindex <= bend && sz < KMALLOC_MAX_SIZE;
7871+ bindex++) {
4a4d8108 7872+ h_file = au_hf_dir(file, bindex);
1308ab2a 7873+ if (h_file
7874+ && h_file->f_dentry
7875+ && h_file->f_dentry->d_inode)
7876+ sz += i_size_read(h_file->f_dentry->d_inode);
7877+ }
7878+ } else {
7879+ AuDebugOn(!dentry);
7880+ AuDebugOn(!dentry->d_inode);
7881+ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
7882+
7883+ bend = au_dbtaildir(dentry);
7884+ for (bindex = au_dbstart(dentry);
7885+ bindex <= bend && sz < KMALLOC_MAX_SIZE;
7886+ bindex++) {
7887+ h_dentry = au_h_dptr(dentry, bindex);
7888+ if (h_dentry && h_dentry->d_inode)
7889+ sz += i_size_read(h_dentry->d_inode);
7890+ }
7891+ }
7892+ if (sz < KMALLOC_MAX_SIZE)
7893+ sz = roundup_pow_of_two(sz);
7894+ if (sz > KMALLOC_MAX_SIZE)
7895+ sz = KMALLOC_MAX_SIZE;
7896+ else if (sz < NAME_MAX) {
7897+ BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX);
7898+ sz = AUFS_RDBLK_DEF;
7899+ }
7900+ return sz;
7901+}
7902+
1facf9fc 7903+/* ---------------------------------------------------------------------- */
7904+
7905+static int reopen_dir(struct file *file)
7906+{
7907+ int err;
7908+ unsigned int flags;
7909+ aufs_bindex_t bindex, btail, bstart;
7910+ struct dentry *dentry, *h_dentry;
7911+ struct file *h_file;
7912+
7913+ /* open all lower dirs */
7914+ dentry = file->f_dentry;
7915+ bstart = au_dbstart(dentry);
7916+ for (bindex = au_fbstart(file); bindex < bstart; bindex++)
7917+ au_set_h_fptr(file, bindex, NULL);
7918+ au_set_fbstart(file, bstart);
7919+
7920+ btail = au_dbtaildir(dentry);
4a4d8108 7921+ for (bindex = au_fbend_dir(file); btail < bindex; bindex--)
1facf9fc 7922+ au_set_h_fptr(file, bindex, NULL);
4a4d8108 7923+ au_set_fbend_dir(file, btail);
1facf9fc 7924+
4a4d8108 7925+ flags = vfsub_file_flags(file);
1facf9fc 7926+ for (bindex = bstart; bindex <= btail; bindex++) {
7927+ h_dentry = au_h_dptr(dentry, bindex);
7928+ if (!h_dentry)
7929+ continue;
4a4d8108 7930+ h_file = au_hf_dir(file, bindex);
1facf9fc 7931+ if (h_file)
7932+ continue;
7933+
7934+ h_file = au_h_open(dentry, bindex, flags, file);
7935+ err = PTR_ERR(h_file);
7936+ if (IS_ERR(h_file))
7937+ goto out; /* close all? */
7938+ au_set_h_fptr(file, bindex, h_file);
7939+ }
7940+ au_update_figen(file);
7941+ /* todo: necessary? */
7942+ /* file->f_ra = h_file->f_ra; */
7943+ err = 0;
7944+
4f0767ce 7945+out:
1facf9fc 7946+ return err;
7947+}
7948+
7949+static int do_open_dir(struct file *file, int flags)
7950+{
7951+ int err;
7952+ aufs_bindex_t bindex, btail;
7953+ struct dentry *dentry, *h_dentry;
7954+ struct file *h_file;
7955+
1308ab2a 7956+ FiMustWriteLock(file);
7957+
1facf9fc 7958+ dentry = file->f_dentry;
027c5e7a
AM
7959+ err = au_alive_dir(dentry);
7960+ if (unlikely(err))
7961+ goto out;
7962+
1facf9fc 7963+ file->f_version = dentry->d_inode->i_version;
7964+ bindex = au_dbstart(dentry);
7965+ au_set_fbstart(file, bindex);
7966+ btail = au_dbtaildir(dentry);
4a4d8108 7967+ au_set_fbend_dir(file, btail);
1facf9fc 7968+ for (; !err && bindex <= btail; bindex++) {
7969+ h_dentry = au_h_dptr(dentry, bindex);
7970+ if (!h_dentry)
7971+ continue;
7972+
7973+ h_file = au_h_open(dentry, bindex, flags, file);
7974+ if (IS_ERR(h_file)) {
7975+ err = PTR_ERR(h_file);
7976+ break;
7977+ }
7978+ au_set_h_fptr(file, bindex, h_file);
7979+ }
7980+ au_update_figen(file);
7981+ /* todo: necessary? */
7982+ /* file->f_ra = h_file->f_ra; */
7983+ if (!err)
7984+ return 0; /* success */
7985+
7986+ /* close all */
7987+ for (bindex = au_fbstart(file); bindex <= btail; bindex++)
7988+ au_set_h_fptr(file, bindex, NULL);
7989+ au_set_fbstart(file, -1);
4a4d8108
AM
7990+ au_set_fbend_dir(file, -1);
7991+
027c5e7a 7992+out:
1facf9fc 7993+ return err;
7994+}
7995+
7996+static int aufs_open_dir(struct inode *inode __maybe_unused,
7997+ struct file *file)
7998+{
4a4d8108
AM
7999+ int err;
8000+ struct super_block *sb;
8001+ struct au_fidir *fidir;
8002+
8003+ err = -ENOMEM;
8004+ sb = file->f_dentry->d_sb;
8005+ si_read_lock(sb, AuLock_FLUSH);
e49829fe 8006+ fidir = au_fidir_alloc(sb);
4a4d8108
AM
8007+ if (fidir) {
8008+ err = au_do_open(file, do_open_dir, fidir);
8009+ if (unlikely(err))
8010+ kfree(fidir);
8011+ }
8012+ si_read_unlock(sb);
8013+ return err;
1facf9fc 8014+}
8015+
8016+static int aufs_release_dir(struct inode *inode __maybe_unused,
8017+ struct file *file)
8018+{
8019+ struct au_vdir *vdir_cache;
4a4d8108
AM
8020+ struct au_finfo *finfo;
8021+ struct au_fidir *fidir;
8022+ aufs_bindex_t bindex, bend;
1facf9fc 8023+
4a4d8108
AM
8024+ finfo = au_fi(file);
8025+ fidir = finfo->fi_hdir;
8026+ if (fidir) {
8027+ vdir_cache = fidir->fd_vdir_cache; /* lock-free */
8028+ if (vdir_cache)
8029+ au_vdir_free(vdir_cache);
8030+
8031+ bindex = finfo->fi_btop;
8032+ if (bindex >= 0) {
8033+ /*
8034+ * calls fput() instead of filp_close(),
8035+ * since no dnotify or lock for the lower file.
8036+ */
8037+ bend = fidir->fd_bbot;
8038+ for (; bindex <= bend; bindex++)
8039+ au_set_h_fptr(file, bindex, NULL);
8040+ }
8041+ kfree(fidir);
8042+ finfo->fi_hdir = NULL;
1facf9fc 8043+ }
1facf9fc 8044+ au_finfo_fin(file);
1facf9fc 8045+ return 0;
8046+}
8047+
8048+/* ---------------------------------------------------------------------- */
8049+
4a4d8108
AM
8050+static int au_do_flush_dir(struct file *file, fl_owner_t id)
8051+{
8052+ int err;
8053+ aufs_bindex_t bindex, bend;
8054+ struct file *h_file;
8055+
8056+ err = 0;
8057+ bend = au_fbend_dir(file);
8058+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
8059+ h_file = au_hf_dir(file, bindex);
8060+ if (h_file)
8061+ err = vfsub_flush(h_file, id);
8062+ }
8063+ return err;
8064+}
8065+
8066+static int aufs_flush_dir(struct file *file, fl_owner_t id)
8067+{
8068+ return au_do_flush(file, id, au_do_flush_dir);
8069+}
8070+
8071+/* ---------------------------------------------------------------------- */
8072+
1facf9fc 8073+static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
8074+{
8075+ int err;
8076+ aufs_bindex_t bend, bindex;
8077+ struct inode *inode;
8078+ struct super_block *sb;
8079+
8080+ err = 0;
8081+ sb = dentry->d_sb;
8082+ inode = dentry->d_inode;
8083+ IMustLock(inode);
8084+ bend = au_dbend(dentry);
8085+ for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) {
8086+ struct path h_path;
1facf9fc 8087+
8088+ if (au_test_ro(sb, bindex, inode))
8089+ continue;
8090+ h_path.dentry = au_h_dptr(dentry, bindex);
8091+ if (!h_path.dentry)
8092+ continue;
1facf9fc 8093+
1facf9fc 8094+ h_path.mnt = au_sbr_mnt(sb, bindex);
53392da6 8095+ err = vfsub_fsync(NULL, &h_path, datasync);
1facf9fc 8096+ }
8097+
8098+ return err;
8099+}
8100+
8101+static int au_do_fsync_dir(struct file *file, int datasync)
8102+{
8103+ int err;
8104+ aufs_bindex_t bend, bindex;
8105+ struct file *h_file;
8106+ struct super_block *sb;
8107+ struct inode *inode;
1facf9fc 8108+
8109+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
8110+ if (unlikely(err))
8111+ goto out;
8112+
8113+ sb = file->f_dentry->d_sb;
8114+ inode = file->f_dentry->d_inode;
4a4d8108 8115+ bend = au_fbend_dir(file);
1facf9fc 8116+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
4a4d8108 8117+ h_file = au_hf_dir(file, bindex);
1facf9fc 8118+ if (!h_file || au_test_ro(sb, bindex, inode))
8119+ continue;
8120+
53392da6 8121+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
1facf9fc 8122+ }
8123+
4f0767ce 8124+out:
1facf9fc 8125+ return err;
8126+}
8127+
8128+/*
8129+ * @file may be NULL
8130+ */
1e00d052
AM
8131+static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end,
8132+ int datasync)
1facf9fc 8133+{
8134+ int err;
b752ccd1 8135+ struct dentry *dentry;
1facf9fc 8136+ struct super_block *sb;
1e00d052 8137+ struct mutex *mtx;
1facf9fc 8138+
8139+ err = 0;
1e00d052
AM
8140+ dentry = file->f_dentry;
8141+ mtx = &dentry->d_inode->i_mutex;
8142+ mutex_lock(mtx);
1facf9fc 8143+ sb = dentry->d_sb;
8144+ si_noflush_read_lock(sb);
8145+ if (file)
8146+ err = au_do_fsync_dir(file, datasync);
8147+ else {
8148+ di_write_lock_child(dentry);
8149+ err = au_do_fsync_dir_no_file(dentry, datasync);
8150+ }
8151+ au_cpup_attr_timesizes(dentry->d_inode);
8152+ di_write_unlock(dentry);
8153+ if (file)
8154+ fi_write_unlock(file);
8155+
8156+ si_read_unlock(sb);
1e00d052 8157+ mutex_unlock(mtx);
1facf9fc 8158+ return err;
8159+}
8160+
8161+/* ---------------------------------------------------------------------- */
8162+
8163+static int aufs_readdir(struct file *file, void *dirent, filldir_t filldir)
8164+{
8165+ int err;
8166+ struct dentry *dentry;
9dbd164d 8167+ struct inode *inode, *h_inode;
1facf9fc 8168+ struct super_block *sb;
8169+
8170+ dentry = file->f_dentry;
8171+ inode = dentry->d_inode;
8172+ IMustLock(inode);
8173+
8174+ sb = dentry->d_sb;
8175+ si_read_lock(sb, AuLock_FLUSH);
8176+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
8177+ if (unlikely(err))
8178+ goto out;
027c5e7a
AM
8179+ err = au_alive_dir(dentry);
8180+ if (!err)
8181+ err = au_vdir_init(file);
1facf9fc 8182+ di_downgrade_lock(dentry, AuLock_IR);
8183+ if (unlikely(err))
8184+ goto out_unlock;
8185+
9dbd164d 8186+ h_inode = au_h_iptr(inode, au_ibstart(inode));
b752ccd1 8187+ if (!au_test_nfsd()) {
1facf9fc 8188+ err = au_vdir_fill_de(file, dirent, filldir);
9dbd164d 8189+ fsstack_copy_attr_atime(inode, h_inode);
1facf9fc 8190+ } else {
8191+ /*
8192+ * nfsd filldir may call lookup_one_len(), vfs_getattr(),
8193+ * encode_fh() and others.
8194+ */
9dbd164d 8195+ atomic_inc(&h_inode->i_count);
1facf9fc 8196+ di_read_unlock(dentry, AuLock_IR);
8197+ si_read_unlock(sb);
1facf9fc 8198+ err = au_vdir_fill_de(file, dirent, filldir);
1facf9fc 8199+ fsstack_copy_attr_atime(inode, h_inode);
8200+ fi_write_unlock(file);
9dbd164d 8201+ iput(h_inode);
1facf9fc 8202+
8203+ AuTraceErr(err);
8204+ return err;
8205+ }
8206+
4f0767ce 8207+out_unlock:
1facf9fc 8208+ di_read_unlock(dentry, AuLock_IR);
8209+ fi_write_unlock(file);
4f0767ce 8210+out:
1facf9fc 8211+ si_read_unlock(sb);
8212+ return err;
8213+}
8214+
8215+/* ---------------------------------------------------------------------- */
8216+
8217+#define AuTestEmpty_WHONLY 1
dece6358
AM
8218+#define AuTestEmpty_CALLED (1 << 1)
8219+#define AuTestEmpty_SHWH (1 << 2)
1facf9fc 8220+#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
7f207e10
AM
8221+#define au_fset_testempty(flags, name) \
8222+ do { (flags) |= AuTestEmpty_##name; } while (0)
8223+#define au_fclr_testempty(flags, name) \
8224+ do { (flags) &= ~AuTestEmpty_##name; } while (0)
1facf9fc 8225+
dece6358
AM
8226+#ifndef CONFIG_AUFS_SHWH
8227+#undef AuTestEmpty_SHWH
8228+#define AuTestEmpty_SHWH 0
8229+#endif
8230+
1facf9fc 8231+struct test_empty_arg {
1308ab2a 8232+ struct au_nhash *whlist;
1facf9fc 8233+ unsigned int flags;
8234+ int err;
8235+ aufs_bindex_t bindex;
8236+};
8237+
8238+static int test_empty_cb(void *__arg, const char *__name, int namelen,
dece6358
AM
8239+ loff_t offset __maybe_unused, u64 ino,
8240+ unsigned int d_type)
1facf9fc 8241+{
8242+ struct test_empty_arg *arg = __arg;
8243+ char *name = (void *)__name;
8244+
8245+ arg->err = 0;
8246+ au_fset_testempty(arg->flags, CALLED);
8247+ /* smp_mb(); */
8248+ if (name[0] == '.'
8249+ && (namelen == 1 || (name[1] == '.' && namelen == 2)))
8250+ goto out; /* success */
8251+
8252+ if (namelen <= AUFS_WH_PFX_LEN
8253+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
8254+ if (au_ftest_testempty(arg->flags, WHONLY)
1308ab2a 8255+ && !au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 8256+ arg->err = -ENOTEMPTY;
8257+ goto out;
8258+ }
8259+
8260+ name += AUFS_WH_PFX_LEN;
8261+ namelen -= AUFS_WH_PFX_LEN;
1308ab2a 8262+ if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 8263+ arg->err = au_nhash_append_wh
1308ab2a 8264+ (arg->whlist, name, namelen, ino, d_type, arg->bindex,
dece6358 8265+ au_ftest_testempty(arg->flags, SHWH));
1facf9fc 8266+
4f0767ce 8267+out:
1facf9fc 8268+ /* smp_mb(); */
8269+ AuTraceErr(arg->err);
8270+ return arg->err;
8271+}
8272+
8273+static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
8274+{
8275+ int err;
8276+ struct file *h_file;
8277+
8278+ h_file = au_h_open(dentry, arg->bindex,
8279+ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
8280+ /*file*/NULL);
8281+ err = PTR_ERR(h_file);
8282+ if (IS_ERR(h_file))
8283+ goto out;
8284+
8285+ err = 0;
8286+ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
8287+ && !h_file->f_dentry->d_inode->i_nlink)
8288+ goto out_put;
8289+
8290+ do {
8291+ arg->err = 0;
8292+ au_fclr_testempty(arg->flags, CALLED);
8293+ /* smp_mb(); */
8294+ err = vfsub_readdir(h_file, test_empty_cb, arg);
8295+ if (err >= 0)
8296+ err = arg->err;
8297+ } while (!err && au_ftest_testempty(arg->flags, CALLED));
8298+
4f0767ce 8299+out_put:
1facf9fc 8300+ fput(h_file);
8301+ au_sbr_put(dentry->d_sb, arg->bindex);
4f0767ce 8302+out:
1facf9fc 8303+ return err;
8304+}
8305+
8306+struct do_test_empty_args {
8307+ int *errp;
8308+ struct dentry *dentry;
8309+ struct test_empty_arg *arg;
8310+};
8311+
8312+static void call_do_test_empty(void *args)
8313+{
8314+ struct do_test_empty_args *a = args;
8315+ *a->errp = do_test_empty(a->dentry, a->arg);
8316+}
8317+
8318+static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
8319+{
8320+ int err, wkq_err;
8321+ struct dentry *h_dentry;
8322+ struct inode *h_inode;
8323+
8324+ h_dentry = au_h_dptr(dentry, arg->bindex);
8325+ h_inode = h_dentry->d_inode;
53392da6 8326+ /* todo: i_mode changes anytime? */
1facf9fc 8327+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
8328+ err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
8329+ mutex_unlock(&h_inode->i_mutex);
8330+ if (!err)
8331+ err = do_test_empty(dentry, arg);
8332+ else {
8333+ struct do_test_empty_args args = {
8334+ .errp = &err,
8335+ .dentry = dentry,
8336+ .arg = arg
8337+ };
8338+ unsigned int flags = arg->flags;
8339+
8340+ wkq_err = au_wkq_wait(call_do_test_empty, &args);
8341+ if (unlikely(wkq_err))
8342+ err = wkq_err;
8343+ arg->flags = flags;
8344+ }
8345+
8346+ return err;
8347+}
8348+
8349+int au_test_empty_lower(struct dentry *dentry)
8350+{
8351+ int err;
1308ab2a 8352+ unsigned int rdhash;
1facf9fc 8353+ aufs_bindex_t bindex, bstart, btail;
1308ab2a 8354+ struct au_nhash whlist;
1facf9fc 8355+ struct test_empty_arg arg;
1facf9fc 8356+
dece6358
AM
8357+ SiMustAnyLock(dentry->d_sb);
8358+
1308ab2a 8359+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
8360+ if (!rdhash)
8361+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry));
8362+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
dece6358 8363+ if (unlikely(err))
1facf9fc 8364+ goto out;
8365+
1facf9fc 8366+ arg.flags = 0;
1308ab2a 8367+ arg.whlist = &whlist;
8368+ bstart = au_dbstart(dentry);
dece6358
AM
8369+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
8370+ au_fset_testempty(arg.flags, SHWH);
1facf9fc 8371+ arg.bindex = bstart;
8372+ err = do_test_empty(dentry, &arg);
8373+ if (unlikely(err))
8374+ goto out_whlist;
8375+
8376+ au_fset_testempty(arg.flags, WHONLY);
8377+ btail = au_dbtaildir(dentry);
8378+ for (bindex = bstart + 1; !err && bindex <= btail; bindex++) {
8379+ struct dentry *h_dentry;
8380+
8381+ h_dentry = au_h_dptr(dentry, bindex);
8382+ if (h_dentry && h_dentry->d_inode) {
8383+ arg.bindex = bindex;
8384+ err = do_test_empty(dentry, &arg);
8385+ }
8386+ }
8387+
4f0767ce 8388+out_whlist:
1308ab2a 8389+ au_nhash_wh_free(&whlist);
4f0767ce 8390+out:
1facf9fc 8391+ return err;
8392+}
8393+
8394+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
8395+{
8396+ int err;
8397+ struct test_empty_arg arg;
8398+ aufs_bindex_t bindex, btail;
8399+
8400+ err = 0;
1308ab2a 8401+ arg.whlist = whlist;
1facf9fc 8402+ arg.flags = AuTestEmpty_WHONLY;
dece6358
AM
8403+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
8404+ au_fset_testempty(arg.flags, SHWH);
1facf9fc 8405+ btail = au_dbtaildir(dentry);
8406+ for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) {
8407+ struct dentry *h_dentry;
8408+
8409+ h_dentry = au_h_dptr(dentry, bindex);
8410+ if (h_dentry && h_dentry->d_inode) {
8411+ arg.bindex = bindex;
8412+ err = sio_test_empty(dentry, &arg);
8413+ }
8414+ }
8415+
8416+ return err;
8417+}
8418+
8419+/* ---------------------------------------------------------------------- */
8420+
8421+const struct file_operations aufs_dir_fop = {
4a4d8108 8422+ .owner = THIS_MODULE,
027c5e7a 8423+ .llseek = default_llseek,
1facf9fc 8424+ .read = generic_read_dir,
8425+ .readdir = aufs_readdir,
8426+ .unlocked_ioctl = aufs_ioctl_dir,
b752ccd1
AM
8427+#ifdef CONFIG_COMPAT
8428+ .compat_ioctl = aufs_compat_ioctl_dir,
8429+#endif
1facf9fc 8430+ .open = aufs_open_dir,
8431+ .release = aufs_release_dir,
4a4d8108 8432+ .flush = aufs_flush_dir,
1facf9fc 8433+ .fsync = aufs_fsync_dir
8434+};
7f207e10
AM
8435diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
8436--- /usr/share/empty/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100
1716fcea 8437+++ linux/fs/aufs/dir.h 2013-02-19 08:40:03.946892891 +0100
f6c5ef8b 8438@@ -0,0 +1,137 @@
1facf9fc 8439+/*
7a9e40b8 8440+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 8441+ *
8442+ * This program, aufs is free software; you can redistribute it and/or modify
8443+ * it under the terms of the GNU General Public License as published by
8444+ * the Free Software Foundation; either version 2 of the License, or
8445+ * (at your option) any later version.
dece6358
AM
8446+ *
8447+ * This program is distributed in the hope that it will be useful,
8448+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8449+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8450+ * GNU General Public License for more details.
8451+ *
8452+ * You should have received a copy of the GNU General Public License
8453+ * along with this program; if not, write to the Free Software
8454+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 8455+ */
8456+
8457+/*
8458+ * directory operations
8459+ */
8460+
8461+#ifndef __AUFS_DIR_H__
8462+#define __AUFS_DIR_H__
8463+
8464+#ifdef __KERNEL__
8465+
8466+#include <linux/fs.h>
1facf9fc 8467+
8468+/* ---------------------------------------------------------------------- */
8469+
8470+/* need to be faster and smaller */
8471+
8472+struct au_nhash {
dece6358
AM
8473+ unsigned int nh_num;
8474+ struct hlist_head *nh_head;
1facf9fc 8475+};
8476+
8477+struct au_vdir_destr {
8478+ unsigned char len;
8479+ unsigned char name[0];
8480+} __packed;
8481+
8482+struct au_vdir_dehstr {
8483+ struct hlist_node hash;
8484+ struct au_vdir_destr *str;
4a4d8108 8485+} ____cacheline_aligned_in_smp;
1facf9fc 8486+
8487+struct au_vdir_de {
8488+ ino_t de_ino;
8489+ unsigned char de_type;
8490+ /* caution: packed */
8491+ struct au_vdir_destr de_str;
8492+} __packed;
8493+
8494+struct au_vdir_wh {
8495+ struct hlist_node wh_hash;
dece6358
AM
8496+#ifdef CONFIG_AUFS_SHWH
8497+ ino_t wh_ino;
1facf9fc 8498+ aufs_bindex_t wh_bindex;
dece6358
AM
8499+ unsigned char wh_type;
8500+#else
8501+ aufs_bindex_t wh_bindex;
8502+#endif
8503+ /* caution: packed */
1facf9fc 8504+ struct au_vdir_destr wh_str;
8505+} __packed;
8506+
8507+union au_vdir_deblk_p {
8508+ unsigned char *deblk;
8509+ struct au_vdir_de *de;
8510+};
8511+
8512+struct au_vdir {
8513+ unsigned char **vd_deblk;
8514+ unsigned long vd_nblk;
1facf9fc 8515+ struct {
8516+ unsigned long ul;
8517+ union au_vdir_deblk_p p;
8518+ } vd_last;
8519+
8520+ unsigned long vd_version;
dece6358 8521+ unsigned int vd_deblk_sz;
1facf9fc 8522+ unsigned long vd_jiffy;
4a4d8108 8523+} ____cacheline_aligned_in_smp;
1facf9fc 8524+
8525+/* ---------------------------------------------------------------------- */
8526+
8527+/* dir.c */
8528+extern const struct file_operations aufs_dir_fop;
8529+void au_add_nlink(struct inode *dir, struct inode *h_dir);
8530+void au_sub_nlink(struct inode *dir, struct inode *h_dir);
1308ab2a 8531+loff_t au_dir_size(struct file *file, struct dentry *dentry);
1facf9fc 8532+int au_test_empty_lower(struct dentry *dentry);
8533+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
8534+
8535+/* vdir.c */
1308ab2a 8536+unsigned int au_rdhash_est(loff_t sz);
dece6358
AM
8537+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
8538+void au_nhash_wh_free(struct au_nhash *whlist);
1facf9fc 8539+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
8540+ int limit);
dece6358
AM
8541+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
8542+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
8543+ unsigned int d_type, aufs_bindex_t bindex,
8544+ unsigned char shwh);
1facf9fc 8545+void au_vdir_free(struct au_vdir *vdir);
8546+int au_vdir_init(struct file *file);
8547+int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir);
8548+
8549+/* ioctl.c */
8550+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
8551+
1308ab2a 8552+#ifdef CONFIG_AUFS_RDU
8553+/* rdu.c */
8554+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
8555+#ifdef CONFIG_COMPAT
8556+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
8557+ unsigned long arg);
8558+#endif
1308ab2a 8559+#else
8560+static inline long au_rdu_ioctl(struct file *file, unsigned int cmd,
8561+ unsigned long arg)
8562+{
8563+ return -EINVAL;
8564+}
b752ccd1
AM
8565+#ifdef CONFIG_COMPAT
8566+static inline long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
8567+ unsigned long arg)
8568+{
8569+ return -EINVAL;
8570+}
8571+#endif
1308ab2a 8572+#endif
8573+
1facf9fc 8574+#endif /* __KERNEL__ */
8575+#endif /* __AUFS_DIR_H__ */
7f207e10
AM
8576diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
8577--- /usr/share/empty/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100
1716fcea 8578+++ linux/fs/aufs/dynop.c 2013-02-19 08:40:03.946892891 +0100
b4510431 8579@@ -0,0 +1,379 @@
1facf9fc 8580+/*
7a9e40b8 8581+ * Copyright (C) 2010-2013 Junjiro R. Okajima
1facf9fc 8582+ *
8583+ * This program, aufs is free software; you can redistribute it and/or modify
8584+ * it under the terms of the GNU General Public License as published by
8585+ * the Free Software Foundation; either version 2 of the License, or
8586+ * (at your option) any later version.
dece6358
AM
8587+ *
8588+ * This program is distributed in the hope that it will be useful,
8589+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8590+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8591+ * GNU General Public License for more details.
8592+ *
8593+ * You should have received a copy of the GNU General Public License
8594+ * along with this program; if not, write to the Free Software
8595+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 8596+ */
8597+
8598+/*
4a4d8108 8599+ * dynamically customizable operations for regular files
1facf9fc 8600+ */
8601+
1facf9fc 8602+#include "aufs.h"
8603+
4a4d8108 8604+#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop)
1facf9fc 8605+
4a4d8108
AM
8606+/*
8607+ * How large will these lists be?
8608+ * Usually just a few elements, 20-30 at most for each, I guess.
8609+ */
8610+static struct au_splhead dynop[AuDyLast];
8611+
8612+static struct au_dykey *dy_gfind_get(struct au_splhead *spl, const void *h_op)
1facf9fc 8613+{
4a4d8108
AM
8614+ struct au_dykey *key, *tmp;
8615+ struct list_head *head;
1facf9fc 8616+
4a4d8108
AM
8617+ key = NULL;
8618+ head = &spl->head;
8619+ rcu_read_lock();
8620+ list_for_each_entry_rcu(tmp, head, dk_list)
8621+ if (tmp->dk_op.dy_hop == h_op) {
8622+ key = tmp;
8623+ kref_get(&key->dk_kref);
8624+ break;
8625+ }
8626+ rcu_read_unlock();
8627+
8628+ return key;
1facf9fc 8629+}
8630+
4a4d8108 8631+static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
1facf9fc 8632+{
4a4d8108
AM
8633+ struct au_dykey **k, *found;
8634+ const void *h_op = key->dk_op.dy_hop;
8635+ int i;
1facf9fc 8636+
4a4d8108
AM
8637+ found = NULL;
8638+ k = br->br_dykey;
8639+ for (i = 0; i < AuBrDynOp; i++)
8640+ if (k[i]) {
8641+ if (k[i]->dk_op.dy_hop == h_op) {
8642+ found = k[i];
8643+ break;
8644+ }
8645+ } else
8646+ break;
8647+ if (!found) {
8648+ spin_lock(&br->br_dykey_lock);
8649+ for (; i < AuBrDynOp; i++)
8650+ if (k[i]) {
8651+ if (k[i]->dk_op.dy_hop == h_op) {
8652+ found = k[i];
8653+ break;
8654+ }
8655+ } else {
8656+ k[i] = key;
8657+ break;
8658+ }
8659+ spin_unlock(&br->br_dykey_lock);
8660+ BUG_ON(i == AuBrDynOp); /* expand the array */
8661+ }
8662+
8663+ return found;
1facf9fc 8664+}
8665+
4a4d8108
AM
8666+/* kref_get() if @key is already added */
8667+static struct au_dykey *dy_gadd(struct au_splhead *spl, struct au_dykey *key)
8668+{
8669+ struct au_dykey *tmp, *found;
8670+ struct list_head *head;
8671+ const void *h_op = key->dk_op.dy_hop;
1facf9fc 8672+
4a4d8108
AM
8673+ found = NULL;
8674+ head = &spl->head;
8675+ spin_lock(&spl->spin);
8676+ list_for_each_entry(tmp, head, dk_list)
8677+ if (tmp->dk_op.dy_hop == h_op) {
8678+ kref_get(&tmp->dk_kref);
8679+ found = tmp;
8680+ break;
8681+ }
8682+ if (!found)
8683+ list_add_rcu(&key->dk_list, head);
8684+ spin_unlock(&spl->spin);
1facf9fc 8685+
4a4d8108
AM
8686+ if (!found)
8687+ DyPrSym(key);
8688+ return found;
8689+}
8690+
8691+static void dy_free_rcu(struct rcu_head *rcu)
1facf9fc 8692+{
4a4d8108
AM
8693+ struct au_dykey *key;
8694+
8695+ key = container_of(rcu, struct au_dykey, dk_rcu);
8696+ DyPrSym(key);
8697+ kfree(key);
1facf9fc 8698+}
8699+
4a4d8108
AM
8700+static void dy_free(struct kref *kref)
8701+{
8702+ struct au_dykey *key;
8703+ struct au_splhead *spl;
1facf9fc 8704+
4a4d8108
AM
8705+ key = container_of(kref, struct au_dykey, dk_kref);
8706+ spl = dynop + key->dk_op.dy_type;
8707+ au_spl_del_rcu(&key->dk_list, spl);
8708+ call_rcu(&key->dk_rcu, dy_free_rcu);
8709+}
8710+
8711+void au_dy_put(struct au_dykey *key)
1facf9fc 8712+{
4a4d8108
AM
8713+ kref_put(&key->dk_kref, dy_free);
8714+}
1facf9fc 8715+
4a4d8108
AM
8716+/* ---------------------------------------------------------------------- */
8717+
8718+#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *))
8719+
8720+#ifdef CONFIG_AUFS_DEBUG
8721+#define DyDbgDeclare(cnt) unsigned int cnt = 0
4f0767ce 8722+#define DyDbgInc(cnt) do { cnt++; } while (0)
4a4d8108
AM
8723+#else
8724+#define DyDbgDeclare(cnt) do {} while (0)
8725+#define DyDbgInc(cnt) do {} while (0)
8726+#endif
8727+
8728+#define DySet(func, dst, src, h_op, h_sb) do { \
8729+ DyDbgInc(cnt); \
8730+ if (h_op->func) { \
8731+ if (src.func) \
8732+ dst.func = src.func; \
8733+ else \
8734+ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \
8735+ } \
8736+} while (0)
8737+
8738+#define DySetForce(func, dst, src) do { \
8739+ AuDebugOn(!src.func); \
8740+ DyDbgInc(cnt); \
8741+ dst.func = src.func; \
8742+} while (0)
8743+
8744+#define DySetAop(func) \
8745+ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
8746+#define DySetAopForce(func) \
8747+ DySetForce(func, dyaop->da_op, aufs_aop)
8748+
8749+static void dy_aop(struct au_dykey *key, const void *h_op,
8750+ struct super_block *h_sb __maybe_unused)
8751+{
8752+ struct au_dyaop *dyaop = (void *)key;
8753+ const struct address_space_operations *h_aop = h_op;
8754+ DyDbgDeclare(cnt);
8755+
8756+ AuDbg("%s\n", au_sbtype(h_sb));
8757+
8758+ DySetAop(writepage);
8759+ DySetAopForce(readpage); /* force */
4a4d8108
AM
8760+ DySetAop(writepages);
8761+ DySetAop(set_page_dirty);
8762+ DySetAop(readpages);
8763+ DySetAop(write_begin);
8764+ DySetAop(write_end);
8765+ DySetAop(bmap);
8766+ DySetAop(invalidatepage);
8767+ DySetAop(releasepage);
027c5e7a 8768+ DySetAop(freepage);
4a4d8108
AM
8769+ /* these two will be changed according to an aufs mount option */
8770+ DySetAop(direct_IO);
8771+ DySetAop(get_xip_mem);
8772+ DySetAop(migratepage);
8773+ DySetAop(launder_page);
8774+ DySetAop(is_partially_uptodate);
8775+ DySetAop(error_remove_page);
b4510431
AM
8776+ DySetAop(swap_activate);
8777+ DySetAop(swap_deactivate);
4a4d8108
AM
8778+
8779+ DyDbgSize(cnt, *h_aop);
8780+ dyaop->da_get_xip_mem = h_aop->get_xip_mem;
8781+}
8782+
4a4d8108
AM
8783+/* ---------------------------------------------------------------------- */
8784+
8785+static void dy_bug(struct kref *kref)
8786+{
8787+ BUG();
8788+}
8789+
8790+static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
8791+{
8792+ struct au_dykey *key, *old;
8793+ struct au_splhead *spl;
b752ccd1 8794+ struct op {
4a4d8108 8795+ unsigned int sz;
b752ccd1
AM
8796+ void (*set)(struct au_dykey *key, const void *h_op,
8797+ struct super_block *h_sb __maybe_unused);
8798+ };
8799+ static const struct op a[] = {
4a4d8108
AM
8800+ [AuDy_AOP] = {
8801+ .sz = sizeof(struct au_dyaop),
b752ccd1 8802+ .set = dy_aop
4a4d8108 8803+ }
b752ccd1
AM
8804+ };
8805+ const struct op *p;
4a4d8108
AM
8806+
8807+ spl = dynop + op->dy_type;
8808+ key = dy_gfind_get(spl, op->dy_hop);
8809+ if (key)
8810+ goto out_add; /* success */
8811+
8812+ p = a + op->dy_type;
8813+ key = kzalloc(p->sz, GFP_NOFS);
8814+ if (unlikely(!key)) {
8815+ key = ERR_PTR(-ENOMEM);
8816+ goto out;
8817+ }
8818+
8819+ key->dk_op.dy_hop = op->dy_hop;
8820+ kref_init(&key->dk_kref);
b752ccd1 8821+ p->set(key, op->dy_hop, br->br_mnt->mnt_sb);
4a4d8108
AM
8822+ old = dy_gadd(spl, key);
8823+ if (old) {
8824+ kfree(key);
8825+ key = old;
8826+ }
8827+
8828+out_add:
8829+ old = dy_bradd(br, key);
8830+ if (old)
8831+ /* its ref-count should never be zero here */
8832+ kref_put(&key->dk_kref, dy_bug);
8833+out:
8834+ return key;
8835+}
8836+
8837+/* ---------------------------------------------------------------------- */
8838+/*
8839+ * Aufs prohibits O_DIRECT by defaut even if the branch supports it.
8840+ * This behaviour is neccessary to return an error from open(O_DIRECT) instead
8841+ * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
8842+ * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
8843+ * See the aufs manual in detail.
8844+ *
8845+ * To keep this behaviour, aufs has to set NULL to ->get_xip_mem too, and the
8846+ * performance of fadvise() and madvise() may be affected.
8847+ */
8848+static void dy_adx(struct au_dyaop *dyaop, int do_dx)
8849+{
8850+ if (!do_dx) {
8851+ dyaop->da_op.direct_IO = NULL;
8852+ dyaop->da_op.get_xip_mem = NULL;
8853+ } else {
8854+ dyaop->da_op.direct_IO = aufs_aop.direct_IO;
8855+ dyaop->da_op.get_xip_mem = aufs_aop.get_xip_mem;
8856+ if (!dyaop->da_get_xip_mem)
8857+ dyaop->da_op.get_xip_mem = NULL;
8858+ }
8859+}
8860+
8861+static struct au_dyaop *dy_aget(struct au_branch *br,
8862+ const struct address_space_operations *h_aop,
8863+ int do_dx)
8864+{
8865+ struct au_dyaop *dyaop;
8866+ struct au_dynop op;
8867+
8868+ op.dy_type = AuDy_AOP;
8869+ op.dy_haop = h_aop;
8870+ dyaop = (void *)dy_get(&op, br);
8871+ if (IS_ERR(dyaop))
8872+ goto out;
8873+ dy_adx(dyaop, do_dx);
8874+
8875+out:
8876+ return dyaop;
8877+}
8878+
8879+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
8880+ struct inode *h_inode)
8881+{
8882+ int err, do_dx;
8883+ struct super_block *sb;
8884+ struct au_branch *br;
8885+ struct au_dyaop *dyaop;
8886+
8887+ AuDebugOn(!S_ISREG(h_inode->i_mode));
8888+ IiMustWriteLock(inode);
8889+
8890+ sb = inode->i_sb;
8891+ br = au_sbr(sb, bindex);
8892+ do_dx = !!au_opt_test(au_mntflags(sb), DIO);
8893+ dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
8894+ err = PTR_ERR(dyaop);
8895+ if (IS_ERR(dyaop))
8896+ /* unnecessary to call dy_fput() */
8897+ goto out;
8898+
8899+ err = 0;
8900+ inode->i_mapping->a_ops = &dyaop->da_op;
8901+
8902+out:
8903+ return err;
8904+}
8905+
b752ccd1
AM
8906+/*
8907+ * Is it safe to replace a_ops during the inode/file is in operation?
8908+ * Yes, I hope so.
8909+ */
8910+int au_dy_irefresh(struct inode *inode)
8911+{
8912+ int err;
8913+ aufs_bindex_t bstart;
8914+ struct inode *h_inode;
8915+
8916+ err = 0;
8917+ if (S_ISREG(inode->i_mode)) {
8918+ bstart = au_ibstart(inode);
8919+ h_inode = au_h_iptr(inode, bstart);
8920+ err = au_dy_iaop(inode, bstart, h_inode);
8921+ }
8922+ return err;
8923+}
8924+
4a4d8108
AM
8925+void au_dy_arefresh(int do_dx)
8926+{
8927+ struct au_splhead *spl;
8928+ struct list_head *head;
8929+ struct au_dykey *key;
8930+
8931+ spl = dynop + AuDy_AOP;
8932+ head = &spl->head;
8933+ spin_lock(&spl->spin);
8934+ list_for_each_entry(key, head, dk_list)
8935+ dy_adx((void *)key, do_dx);
8936+ spin_unlock(&spl->spin);
8937+}
8938+
4a4d8108
AM
8939+/* ---------------------------------------------------------------------- */
8940+
8941+void __init au_dy_init(void)
8942+{
8943+ int i;
8944+
8945+ /* make sure that 'struct au_dykey *' can be any type */
8946+ BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
4a4d8108
AM
8947+
8948+ for (i = 0; i < AuDyLast; i++)
8949+ au_spl_init(dynop + i);
8950+}
8951+
8952+void au_dy_fin(void)
8953+{
8954+ int i;
8955+
8956+ for (i = 0; i < AuDyLast; i++)
8957+ WARN_ON(!list_empty(&dynop[i].head));
8958+}
7f207e10
AM
8959diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
8960--- /usr/share/empty/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100
1716fcea 8961+++ linux/fs/aufs/dynop.h 2013-02-19 08:40:03.946892891 +0100
f6c5ef8b 8962@@ -0,0 +1,76 @@
4a4d8108 8963+/*
7a9e40b8 8964+ * Copyright (C) 2010-2013 Junjiro R. Okajima
4a4d8108
AM
8965+ *
8966+ * This program, aufs is free software; you can redistribute it and/or modify
8967+ * it under the terms of the GNU General Public License as published by
8968+ * the Free Software Foundation; either version 2 of the License, or
8969+ * (at your option) any later version.
8970+ *
8971+ * This program is distributed in the hope that it will be useful,
8972+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8973+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8974+ * GNU General Public License for more details.
8975+ *
8976+ * You should have received a copy of the GNU General Public License
8977+ * along with this program; if not, write to the Free Software
8978+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
8979+ */
8980+
8981+/*
8982+ * dynamically customizable operations (for regular files only)
8983+ */
8984+
8985+#ifndef __AUFS_DYNOP_H__
8986+#define __AUFS_DYNOP_H__
8987+
8988+#ifdef __KERNEL__
8989+
4a4d8108
AM
8990+#include "inode.h"
8991+
2cbb1c4b 8992+enum {AuDy_AOP, AuDyLast};
4a4d8108
AM
8993+
8994+struct au_dynop {
8995+ int dy_type;
8996+ union {
8997+ const void *dy_hop;
8998+ const struct address_space_operations *dy_haop;
4a4d8108
AM
8999+ };
9000+};
9001+
9002+struct au_dykey {
9003+ union {
9004+ struct list_head dk_list;
9005+ struct rcu_head dk_rcu;
9006+ };
9007+ struct au_dynop dk_op;
9008+
9009+ /*
9010+ * during I am in the branch local array, kref is gotten. when the
9011+ * branch is removed, kref is put.
9012+ */
9013+ struct kref dk_kref;
9014+};
9015+
9016+/* stop unioning since their sizes are very different from each other */
9017+struct au_dyaop {
9018+ struct au_dykey da_key;
9019+ struct address_space_operations da_op; /* not const */
9020+ int (*da_get_xip_mem)(struct address_space *, pgoff_t, int,
9021+ void **, unsigned long *);
9022+};
9023+
4a4d8108
AM
9024+/* ---------------------------------------------------------------------- */
9025+
9026+/* dynop.c */
9027+struct au_branch;
9028+void au_dy_put(struct au_dykey *key);
9029+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
9030+ struct inode *h_inode);
b752ccd1 9031+int au_dy_irefresh(struct inode *inode);
4a4d8108 9032+void au_dy_arefresh(int do_dio);
4a4d8108
AM
9033+
9034+void __init au_dy_init(void);
9035+void au_dy_fin(void);
9036+
4a4d8108
AM
9037+#endif /* __KERNEL__ */
9038+#endif /* __AUFS_DYNOP_H__ */
7f207e10
AM
9039diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
9040--- /usr/share/empty/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
a2a7ad62
AM
9041+++ linux/fs/aufs/export.c 2013-03-14 20:07:41.038119650 +0100
9042@@ -0,0 +1,827 @@
4a4d8108 9043+/*
7a9e40b8 9044+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
9045+ *
9046+ * This program, aufs is free software; you can redistribute it and/or modify
9047+ * it under the terms of the GNU General Public License as published by
9048+ * the Free Software Foundation; either version 2 of the License, or
9049+ * (at your option) any later version.
9050+ *
9051+ * This program is distributed in the hope that it will be useful,
9052+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9053+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9054+ * GNU General Public License for more details.
9055+ *
9056+ * You should have received a copy of the GNU General Public License
9057+ * along with this program; if not, write to the Free Software
9058+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9059+ */
9060+
9061+/*
9062+ * export via nfs
9063+ */
9064+
9065+#include <linux/exportfs.h>
7eafdf33 9066+#include <linux/fs_struct.h>
4a4d8108
AM
9067+#include <linux/namei.h>
9068+#include <linux/nsproxy.h>
9069+#include <linux/random.h>
9070+#include <linux/writeback.h>
7eafdf33 9071+#include "../fs/mount.h"
4a4d8108
AM
9072+#include "aufs.h"
9073+
9074+union conv {
9075+#ifdef CONFIG_AUFS_INO_T_64
9076+ __u32 a[2];
9077+#else
9078+ __u32 a[1];
9079+#endif
9080+ ino_t ino;
9081+};
9082+
9083+static ino_t decode_ino(__u32 *a)
9084+{
9085+ union conv u;
9086+
9087+ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
9088+ u.a[0] = a[0];
9089+#ifdef CONFIG_AUFS_INO_T_64
9090+ u.a[1] = a[1];
9091+#endif
9092+ return u.ino;
9093+}
9094+
9095+static void encode_ino(__u32 *a, ino_t ino)
9096+{
9097+ union conv u;
9098+
9099+ u.ino = ino;
9100+ a[0] = u.a[0];
9101+#ifdef CONFIG_AUFS_INO_T_64
9102+ a[1] = u.a[1];
9103+#endif
9104+}
9105+
9106+/* NFS file handle */
9107+enum {
9108+ Fh_br_id,
9109+ Fh_sigen,
9110+#ifdef CONFIG_AUFS_INO_T_64
9111+ /* support 64bit inode number */
9112+ Fh_ino1,
9113+ Fh_ino2,
9114+ Fh_dir_ino1,
9115+ Fh_dir_ino2,
9116+#else
9117+ Fh_ino1,
9118+ Fh_dir_ino1,
9119+#endif
9120+ Fh_igen,
9121+ Fh_h_type,
9122+ Fh_tail,
9123+
9124+ Fh_ino = Fh_ino1,
9125+ Fh_dir_ino = Fh_dir_ino1
9126+};
9127+
9128+static int au_test_anon(struct dentry *dentry)
9129+{
027c5e7a 9130+ /* note: read d_flags without d_lock */
4a4d8108
AM
9131+ return !!(dentry->d_flags & DCACHE_DISCONNECTED);
9132+}
9133+
a2a7ad62
AM
9134+int au_test_nfsd(void)
9135+{
9136+ int ret;
9137+ struct task_struct *tsk = current;
9138+ char comm[sizeof(tsk->comm)];
9139+
9140+ ret = 0;
9141+ if (tsk->flags & PF_KTHREAD) {
9142+ get_task_comm(comm, tsk);
9143+ ret = !strcmp(comm, "nfsd");
9144+ }
9145+
9146+ return ret;
9147+}
9148+
4a4d8108
AM
9149+/* ---------------------------------------------------------------------- */
9150+/* inode generation external table */
9151+
b752ccd1 9152+void au_xigen_inc(struct inode *inode)
4a4d8108 9153+{
4a4d8108
AM
9154+ loff_t pos;
9155+ ssize_t sz;
9156+ __u32 igen;
9157+ struct super_block *sb;
9158+ struct au_sbinfo *sbinfo;
9159+
4a4d8108 9160+ sb = inode->i_sb;
b752ccd1 9161+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
1facf9fc 9162+
b752ccd1 9163+ sbinfo = au_sbi(sb);
1facf9fc 9164+ pos = inode->i_ino;
9165+ pos *= sizeof(igen);
9166+ igen = inode->i_generation + 1;
1facf9fc 9167+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
9168+ sizeof(igen), &pos);
9169+ if (sz == sizeof(igen))
b752ccd1 9170+ return; /* success */
1facf9fc 9171+
b752ccd1 9172+ if (unlikely(sz >= 0))
1facf9fc 9173+ AuIOErr("xigen error (%zd)\n", sz);
1facf9fc 9174+}
9175+
9176+int au_xigen_new(struct inode *inode)
9177+{
9178+ int err;
9179+ loff_t pos;
9180+ ssize_t sz;
9181+ struct super_block *sb;
9182+ struct au_sbinfo *sbinfo;
9183+ struct file *file;
9184+
9185+ err = 0;
9186+ /* todo: dirty, at mount time */
9187+ if (inode->i_ino == AUFS_ROOT_INO)
9188+ goto out;
9189+ sb = inode->i_sb;
dece6358 9190+ SiMustAnyLock(sb);
1facf9fc 9191+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
9192+ goto out;
9193+
9194+ err = -EFBIG;
9195+ pos = inode->i_ino;
9196+ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
9197+ AuIOErr1("too large i%lld\n", pos);
9198+ goto out;
9199+ }
9200+ pos *= sizeof(inode->i_generation);
9201+
9202+ err = 0;
9203+ sbinfo = au_sbi(sb);
9204+ file = sbinfo->si_xigen;
9205+ BUG_ON(!file);
9206+
9207+ if (i_size_read(file->f_dentry->d_inode)
9208+ < pos + sizeof(inode->i_generation)) {
9209+ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
9210+ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
9211+ sizeof(inode->i_generation), &pos);
9212+ } else
9213+ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
9214+ sizeof(inode->i_generation), &pos);
9215+ if (sz == sizeof(inode->i_generation))
9216+ goto out; /* success */
9217+
9218+ err = sz;
9219+ if (unlikely(sz >= 0)) {
9220+ err = -EIO;
9221+ AuIOErr("xigen error (%zd)\n", sz);
9222+ }
9223+
4f0767ce 9224+out:
1facf9fc 9225+ return err;
9226+}
9227+
9228+int au_xigen_set(struct super_block *sb, struct file *base)
9229+{
9230+ int err;
9231+ struct au_sbinfo *sbinfo;
9232+ struct file *file;
9233+
dece6358
AM
9234+ SiMustWriteLock(sb);
9235+
1facf9fc 9236+ sbinfo = au_sbi(sb);
9237+ file = au_xino_create2(base, sbinfo->si_xigen);
9238+ err = PTR_ERR(file);
9239+ if (IS_ERR(file))
9240+ goto out;
9241+ err = 0;
9242+ if (sbinfo->si_xigen)
9243+ fput(sbinfo->si_xigen);
9244+ sbinfo->si_xigen = file;
9245+
4f0767ce 9246+out:
1facf9fc 9247+ return err;
9248+}
9249+
9250+void au_xigen_clr(struct super_block *sb)
9251+{
9252+ struct au_sbinfo *sbinfo;
9253+
dece6358
AM
9254+ SiMustWriteLock(sb);
9255+
1facf9fc 9256+ sbinfo = au_sbi(sb);
9257+ if (sbinfo->si_xigen) {
9258+ fput(sbinfo->si_xigen);
9259+ sbinfo->si_xigen = NULL;
9260+ }
9261+}
9262+
9263+/* ---------------------------------------------------------------------- */
9264+
9265+static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
9266+ ino_t dir_ino)
9267+{
9268+ struct dentry *dentry, *d;
9269+ struct inode *inode;
9270+ unsigned int sigen;
b4510431 9271+ struct hlist_node *p;
1facf9fc 9272+
9273+ dentry = NULL;
9274+ inode = ilookup(sb, ino);
9275+ if (!inode)
9276+ goto out;
9277+
9278+ dentry = ERR_PTR(-ESTALE);
9279+ sigen = au_sigen(sb);
9280+ if (unlikely(is_bad_inode(inode)
9281+ || IS_DEADDIR(inode)
537831f9 9282+ || sigen != au_iigen(inode, NULL)))
1facf9fc 9283+ goto out_iput;
9284+
9285+ dentry = NULL;
9286+ if (!dir_ino || S_ISDIR(inode->i_mode))
9287+ dentry = d_find_alias(inode);
9288+ else {
027c5e7a 9289+ spin_lock(&inode->i_lock);
b4510431 9290+ hlist_for_each_entry(d, p, &inode->i_dentry, d_alias) {
027c5e7a 9291+ spin_lock(&d->d_lock);
1facf9fc 9292+ if (!au_test_anon(d)
9293+ && d->d_parent->d_inode->i_ino == dir_ino) {
027c5e7a
AM
9294+ dentry = dget_dlock(d);
9295+ spin_unlock(&d->d_lock);
1facf9fc 9296+ break;
9297+ }
027c5e7a
AM
9298+ spin_unlock(&d->d_lock);
9299+ }
9300+ spin_unlock(&inode->i_lock);
1facf9fc 9301+ }
027c5e7a 9302+ if (unlikely(dentry && au_digen_test(dentry, sigen))) {
2cbb1c4b 9303+ /* need to refresh */
1facf9fc 9304+ dput(dentry);
2cbb1c4b 9305+ dentry = NULL;
1facf9fc 9306+ }
9307+
4f0767ce 9308+out_iput:
1facf9fc 9309+ iput(inode);
4f0767ce 9310+out:
2cbb1c4b 9311+ AuTraceErrPtr(dentry);
1facf9fc 9312+ return dentry;
9313+}
9314+
9315+/* ---------------------------------------------------------------------- */
9316+
9317+/* todo: dirty? */
9318+/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
4a4d8108
AM
9319+
9320+struct au_compare_mnt_args {
9321+ /* input */
9322+ struct super_block *sb;
9323+
9324+ /* output */
9325+ struct vfsmount *mnt;
9326+};
9327+
9328+static int au_compare_mnt(struct vfsmount *mnt, void *arg)
9329+{
9330+ struct au_compare_mnt_args *a = arg;
9331+
9332+ if (mnt->mnt_sb != a->sb)
9333+ return 0;
9334+ a->mnt = mntget(mnt);
9335+ return 1;
9336+}
9337+
1facf9fc 9338+static struct vfsmount *au_mnt_get(struct super_block *sb)
9339+{
4a4d8108 9340+ int err;
7eafdf33 9341+ struct path root;
4a4d8108
AM
9342+ struct au_compare_mnt_args args = {
9343+ .sb = sb
9344+ };
1facf9fc 9345+
7eafdf33 9346+ get_fs_root(current->fs, &root);
0c3ec466 9347+ br_read_lock(&vfsmount_lock);
7eafdf33 9348+ err = iterate_mounts(au_compare_mnt, &args, root.mnt);
0c3ec466 9349+ br_read_unlock(&vfsmount_lock);
7eafdf33 9350+ path_put(&root);
4a4d8108
AM
9351+ AuDebugOn(!err);
9352+ AuDebugOn(!args.mnt);
9353+ return args.mnt;
1facf9fc 9354+}
9355+
9356+struct au_nfsd_si_lock {
4a4d8108 9357+ unsigned int sigen;
027c5e7a 9358+ aufs_bindex_t bindex, br_id;
1facf9fc 9359+ unsigned char force_lock;
9360+};
9361+
027c5e7a
AM
9362+static int si_nfsd_read_lock(struct super_block *sb,
9363+ struct au_nfsd_si_lock *nsi_lock)
1facf9fc 9364+{
027c5e7a 9365+ int err;
1facf9fc 9366+ aufs_bindex_t bindex;
9367+
9368+ si_read_lock(sb, AuLock_FLUSH);
9369+
9370+ /* branch id may be wrapped around */
027c5e7a 9371+ err = 0;
1facf9fc 9372+ bindex = au_br_index(sb, nsi_lock->br_id);
9373+ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
9374+ goto out; /* success */
9375+
027c5e7a
AM
9376+ err = -ESTALE;
9377+ bindex = -1;
1facf9fc 9378+ if (!nsi_lock->force_lock)
9379+ si_read_unlock(sb);
1facf9fc 9380+
4f0767ce 9381+out:
027c5e7a
AM
9382+ nsi_lock->bindex = bindex;
9383+ return err;
1facf9fc 9384+}
9385+
9386+struct find_name_by_ino {
9387+ int called, found;
9388+ ino_t ino;
9389+ char *name;
9390+ int namelen;
9391+};
9392+
9393+static int
9394+find_name_by_ino(void *arg, const char *name, int namelen, loff_t offset,
9395+ u64 ino, unsigned int d_type)
9396+{
9397+ struct find_name_by_ino *a = arg;
9398+
9399+ a->called++;
9400+ if (a->ino != ino)
9401+ return 0;
9402+
9403+ memcpy(a->name, name, namelen);
9404+ a->namelen = namelen;
9405+ a->found = 1;
9406+ return 1;
9407+}
9408+
9409+static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
9410+ struct au_nfsd_si_lock *nsi_lock)
9411+{
9412+ struct dentry *dentry, *parent;
9413+ struct file *file;
9414+ struct inode *dir;
9415+ struct find_name_by_ino arg;
9416+ int err;
9417+
9418+ parent = path->dentry;
9419+ if (nsi_lock)
9420+ si_read_unlock(parent->d_sb);
4a4d8108 9421+ file = vfsub_dentry_open(path, au_dir_roflags);
1facf9fc 9422+ dentry = (void *)file;
9423+ if (IS_ERR(file))
9424+ goto out;
9425+
9426+ dentry = ERR_PTR(-ENOMEM);
537831f9 9427+ arg.name = (void *)__get_free_page(GFP_NOFS);
1facf9fc 9428+ if (unlikely(!arg.name))
9429+ goto out_file;
9430+ arg.ino = ino;
9431+ arg.found = 0;
9432+ do {
9433+ arg.called = 0;
9434+ /* smp_mb(); */
9435+ err = vfsub_readdir(file, find_name_by_ino, &arg);
9436+ } while (!err && !arg.found && arg.called);
9437+ dentry = ERR_PTR(err);
9438+ if (unlikely(err))
9439+ goto out_name;
1716fcea
AM
9440+ /* instead of ENOENT */
9441+ dentry = ERR_PTR(-ESTALE);
1facf9fc 9442+ if (!arg.found)
9443+ goto out_name;
9444+
b4510431 9445+ /* do not call vfsub_lkup_one() */
1facf9fc 9446+ dir = parent->d_inode;
9447+ mutex_lock(&dir->i_mutex);
9448+ dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
9449+ mutex_unlock(&dir->i_mutex);
9450+ AuTraceErrPtr(dentry);
9451+ if (IS_ERR(dentry))
9452+ goto out_name;
9453+ AuDebugOn(au_test_anon(dentry));
9454+ if (unlikely(!dentry->d_inode)) {
9455+ dput(dentry);
9456+ dentry = ERR_PTR(-ENOENT);
9457+ }
9458+
4f0767ce 9459+out_name:
537831f9 9460+ free_page((unsigned long)arg.name);
4f0767ce 9461+out_file:
1facf9fc 9462+ fput(file);
4f0767ce 9463+out:
1facf9fc 9464+ if (unlikely(nsi_lock
9465+ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
9466+ if (!IS_ERR(dentry)) {
9467+ dput(dentry);
9468+ dentry = ERR_PTR(-ESTALE);
9469+ }
9470+ AuTraceErrPtr(dentry);
9471+ return dentry;
9472+}
9473+
9474+static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
9475+ ino_t dir_ino,
9476+ struct au_nfsd_si_lock *nsi_lock)
9477+{
9478+ struct dentry *dentry;
9479+ struct path path;
9480+
9481+ if (dir_ino != AUFS_ROOT_INO) {
9482+ path.dentry = decode_by_ino(sb, dir_ino, 0);
9483+ dentry = path.dentry;
9484+ if (!path.dentry || IS_ERR(path.dentry))
9485+ goto out;
9486+ AuDebugOn(au_test_anon(path.dentry));
9487+ } else
9488+ path.dentry = dget(sb->s_root);
9489+
9490+ path.mnt = au_mnt_get(sb);
9491+ dentry = au_lkup_by_ino(&path, ino, nsi_lock);
9492+ path_put(&path);
9493+
4f0767ce 9494+out:
1facf9fc 9495+ AuTraceErrPtr(dentry);
9496+ return dentry;
9497+}
9498+
9499+/* ---------------------------------------------------------------------- */
9500+
9501+static int h_acceptable(void *expv, struct dentry *dentry)
9502+{
9503+ return 1;
9504+}
9505+
9506+static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
9507+ char *buf, int len, struct super_block *sb)
9508+{
9509+ char *p;
9510+ int n;
9511+ struct path path;
9512+
9513+ p = d_path(h_rootpath, buf, len);
9514+ if (IS_ERR(p))
9515+ goto out;
9516+ n = strlen(p);
9517+
9518+ path.mnt = h_rootpath->mnt;
9519+ path.dentry = h_parent;
9520+ p = d_path(&path, buf, len);
9521+ if (IS_ERR(p))
9522+ goto out;
9523+ if (n != 1)
9524+ p += n;
9525+
9526+ path.mnt = au_mnt_get(sb);
9527+ path.dentry = sb->s_root;
9528+ p = d_path(&path, buf, len - strlen(p));
9529+ mntput(path.mnt);
9530+ if (IS_ERR(p))
9531+ goto out;
9532+ if (n != 1)
9533+ p[strlen(p)] = '/';
9534+
4f0767ce 9535+out:
1facf9fc 9536+ AuTraceErrPtr(p);
9537+ return p;
9538+}
9539+
9540+static
027c5e7a
AM
9541+struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
9542+ int fh_len, struct au_nfsd_si_lock *nsi_lock)
1facf9fc 9543+{
9544+ struct dentry *dentry, *h_parent, *root;
9545+ struct super_block *h_sb;
9546+ char *pathname, *p;
9547+ struct vfsmount *h_mnt;
9548+ struct au_branch *br;
9549+ int err;
9550+ struct path path;
9551+
027c5e7a 9552+ br = au_sbr(sb, nsi_lock->bindex);
1facf9fc 9553+ h_mnt = br->br_mnt;
9554+ h_sb = h_mnt->mnt_sb;
9555+ /* todo: call lower fh_to_dentry()? fh_to_parent()? */
9556+ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
9557+ fh_len - Fh_tail, fh[Fh_h_type],
9558+ h_acceptable, /*context*/NULL);
9559+ dentry = h_parent;
9560+ if (unlikely(!h_parent || IS_ERR(h_parent))) {
9561+ AuWarn1("%s decode_fh failed, %ld\n",
9562+ au_sbtype(h_sb), PTR_ERR(h_parent));
9563+ goto out;
9564+ }
9565+ dentry = NULL;
9566+ if (unlikely(au_test_anon(h_parent))) {
9567+ AuWarn1("%s decode_fh returned a disconnected dentry\n",
9568+ au_sbtype(h_sb));
9569+ goto out_h_parent;
9570+ }
9571+
9572+ dentry = ERR_PTR(-ENOMEM);
9573+ pathname = (void *)__get_free_page(GFP_NOFS);
9574+ if (unlikely(!pathname))
9575+ goto out_h_parent;
9576+
9577+ root = sb->s_root;
9578+ path.mnt = h_mnt;
9579+ di_read_lock_parent(root, !AuLock_IR);
027c5e7a 9580+ path.dentry = au_h_dptr(root, nsi_lock->bindex);
1facf9fc 9581+ di_read_unlock(root, !AuLock_IR);
9582+ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
9583+ dentry = (void *)p;
9584+ if (IS_ERR(p))
9585+ goto out_pathname;
9586+
9587+ si_read_unlock(sb);
9588+ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
9589+ dentry = ERR_PTR(err);
9590+ if (unlikely(err))
9591+ goto out_relock;
9592+
9593+ dentry = ERR_PTR(-ENOENT);
9594+ AuDebugOn(au_test_anon(path.dentry));
9595+ if (unlikely(!path.dentry->d_inode))
9596+ goto out_path;
9597+
9598+ if (ino != path.dentry->d_inode->i_ino)
9599+ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
9600+ else
9601+ dentry = dget(path.dentry);
9602+
4f0767ce 9603+out_path:
1facf9fc 9604+ path_put(&path);
4f0767ce 9605+out_relock:
1facf9fc 9606+ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
9607+ if (!IS_ERR(dentry)) {
9608+ dput(dentry);
9609+ dentry = ERR_PTR(-ESTALE);
9610+ }
4f0767ce 9611+out_pathname:
1facf9fc 9612+ free_page((unsigned long)pathname);
4f0767ce 9613+out_h_parent:
1facf9fc 9614+ dput(h_parent);
4f0767ce 9615+out:
1facf9fc 9616+ AuTraceErrPtr(dentry);
9617+ return dentry;
9618+}
9619+
9620+/* ---------------------------------------------------------------------- */
9621+
9622+static struct dentry *
9623+aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
9624+ int fh_type)
9625+{
9626+ struct dentry *dentry;
9627+ __u32 *fh = fid->raw;
027c5e7a 9628+ struct au_branch *br;
1facf9fc 9629+ ino_t ino, dir_ino;
1facf9fc 9630+ struct au_nfsd_si_lock nsi_lock = {
1facf9fc 9631+ .force_lock = 0
9632+ };
9633+
1facf9fc 9634+ dentry = ERR_PTR(-ESTALE);
4a4d8108
AM
9635+ /* it should never happen, but the file handle is unreliable */
9636+ if (unlikely(fh_len < Fh_tail))
9637+ goto out;
9638+ nsi_lock.sigen = fh[Fh_sigen];
9639+ nsi_lock.br_id = fh[Fh_br_id];
9640+
1facf9fc 9641+ /* branch id may be wrapped around */
027c5e7a
AM
9642+ br = NULL;
9643+ if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
1facf9fc 9644+ goto out;
9645+ nsi_lock.force_lock = 1;
9646+
9647+ /* is this inode still cached? */
9648+ ino = decode_ino(fh + Fh_ino);
4a4d8108
AM
9649+ /* it should never happen */
9650+ if (unlikely(ino == AUFS_ROOT_INO))
9651+ goto out;
9652+
1facf9fc 9653+ dir_ino = decode_ino(fh + Fh_dir_ino);
9654+ dentry = decode_by_ino(sb, ino, dir_ino);
9655+ if (IS_ERR(dentry))
9656+ goto out_unlock;
9657+ if (dentry)
9658+ goto accept;
9659+
9660+ /* is the parent dir cached? */
027c5e7a
AM
9661+ br = au_sbr(sb, nsi_lock.bindex);
9662+ atomic_inc(&br->br_count);
1facf9fc 9663+ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
9664+ if (IS_ERR(dentry))
9665+ goto out_unlock;
9666+ if (dentry)
9667+ goto accept;
9668+
9669+ /* lookup path */
027c5e7a 9670+ dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
1facf9fc 9671+ if (IS_ERR(dentry))
9672+ goto out_unlock;
9673+ if (unlikely(!dentry))
9674+ /* todo?: make it ESTALE */
9675+ goto out_unlock;
9676+
4f0767ce 9677+accept:
027c5e7a
AM
9678+ if (!au_digen_test(dentry, au_sigen(sb))
9679+ && dentry->d_inode->i_generation == fh[Fh_igen])
1facf9fc 9680+ goto out_unlock; /* success */
9681+
9682+ dput(dentry);
9683+ dentry = ERR_PTR(-ESTALE);
4f0767ce 9684+out_unlock:
027c5e7a
AM
9685+ if (br)
9686+ atomic_dec(&br->br_count);
1facf9fc 9687+ si_read_unlock(sb);
4f0767ce 9688+out:
1facf9fc 9689+ AuTraceErrPtr(dentry);
9690+ return dentry;
9691+}
9692+
9693+#if 0 /* reserved for future use */
9694+/* support subtreecheck option */
9695+static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
9696+ int fh_len, int fh_type)
9697+{
9698+ struct dentry *parent;
9699+ __u32 *fh = fid->raw;
9700+ ino_t dir_ino;
9701+
9702+ dir_ino = decode_ino(fh + Fh_dir_ino);
9703+ parent = decode_by_ino(sb, dir_ino, 0);
9704+ if (IS_ERR(parent))
9705+ goto out;
9706+ if (!parent)
9707+ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
9708+ dir_ino, fh, fh_len);
9709+
4f0767ce 9710+out:
1facf9fc 9711+ AuTraceErrPtr(parent);
9712+ return parent;
9713+}
9714+#endif
9715+
9716+/* ---------------------------------------------------------------------- */
9717+
0c3ec466
AM
9718+static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
9719+ struct inode *dir)
1facf9fc 9720+{
9721+ int err;
0c3ec466 9722+ aufs_bindex_t bindex;
1facf9fc 9723+ struct super_block *sb, *h_sb;
0c3ec466
AM
9724+ struct dentry *dentry, *parent, *h_parent;
9725+ struct inode *h_dir;
1facf9fc 9726+ struct au_branch *br;
9727+
1facf9fc 9728+ err = -ENOSPC;
9729+ if (unlikely(*max_len <= Fh_tail)) {
9730+ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
9731+ goto out;
9732+ }
9733+
9734+ err = FILEID_ROOT;
0c3ec466
AM
9735+ if (inode->i_ino == AUFS_ROOT_INO) {
9736+ AuDebugOn(inode->i_ino != AUFS_ROOT_INO);
1facf9fc 9737+ goto out;
9738+ }
9739+
1facf9fc 9740+ h_parent = NULL;
0c3ec466
AM
9741+ sb = inode->i_sb;
9742+ err = si_read_lock(sb, AuLock_FLUSH);
027c5e7a
AM
9743+ if (unlikely(err))
9744+ goto out;
9745+
1facf9fc 9746+#ifdef CONFIG_AUFS_DEBUG
9747+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
9748+ AuWarn1("NFS-exporting requires xino\n");
9749+#endif
027c5e7a 9750+ err = -EIO;
0c3ec466
AM
9751+ parent = NULL;
9752+ ii_read_lock_child(inode);
9753+ bindex = au_ibstart(inode);
9754+ if (!dir) {
9755+ dentry = d_find_alias(inode);
9756+ if (unlikely(!dentry))
9757+ goto out_unlock;
9758+ AuDebugOn(au_test_anon(dentry));
9759+ parent = dget_parent(dentry);
9760+ dput(dentry);
9761+ if (unlikely(!parent))
9762+ goto out_unlock;
9763+ dir = parent->d_inode;
1facf9fc 9764+ }
0c3ec466
AM
9765+
9766+ ii_read_lock_parent(dir);
9767+ h_dir = au_h_iptr(dir, bindex);
9768+ ii_read_unlock(dir);
9769+ if (unlikely(!h_dir))
9770+ goto out_parent;
9771+ h_parent = d_find_alias(h_dir);
1facf9fc 9772+ if (unlikely(!h_parent))
0c3ec466 9773+ goto out_hparent;
1facf9fc 9774+
9775+ err = -EPERM;
9776+ br = au_sbr(sb, bindex);
9777+ h_sb = br->br_mnt->mnt_sb;
9778+ if (unlikely(!h_sb->s_export_op)) {
9779+ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
0c3ec466 9780+ goto out_hparent;
1facf9fc 9781+ }
9782+
9783+ fh[Fh_br_id] = br->br_id;
9784+ fh[Fh_sigen] = au_sigen(sb);
9785+ encode_ino(fh + Fh_ino, inode->i_ino);
0c3ec466 9786+ encode_ino(fh + Fh_dir_ino, dir->i_ino);
1facf9fc 9787+ fh[Fh_igen] = inode->i_generation;
9788+
9789+ *max_len -= Fh_tail;
9790+ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
9791+ max_len,
9792+ /*connectable or subtreecheck*/0);
9793+ err = fh[Fh_h_type];
9794+ *max_len += Fh_tail;
9795+ /* todo: macros? */
1716fcea 9796+ if (err != FILEID_INVALID)
1facf9fc 9797+ err = 99;
9798+ else
9799+ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
9800+
0c3ec466 9801+out_hparent:
1facf9fc 9802+ dput(h_parent);
0c3ec466 9803+out_parent:
1facf9fc 9804+ dput(parent);
0c3ec466
AM
9805+out_unlock:
9806+ ii_read_unlock(inode);
9807+ si_read_unlock(sb);
4f0767ce 9808+out:
1facf9fc 9809+ if (unlikely(err < 0))
1716fcea 9810+ err = FILEID_INVALID;
1facf9fc 9811+ return err;
9812+}
9813+
9814+/* ---------------------------------------------------------------------- */
9815+
4a4d8108
AM
9816+static int aufs_commit_metadata(struct inode *inode)
9817+{
9818+ int err;
9819+ aufs_bindex_t bindex;
9820+ struct super_block *sb;
9821+ struct inode *h_inode;
9822+ int (*f)(struct inode *inode);
9823+
9824+ sb = inode->i_sb;
e49829fe 9825+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
9826+ ii_write_lock_child(inode);
9827+ bindex = au_ibstart(inode);
9828+ AuDebugOn(bindex < 0);
9829+ h_inode = au_h_iptr(inode, bindex);
9830+
9831+ f = h_inode->i_sb->s_export_op->commit_metadata;
9832+ if (f)
9833+ err = f(h_inode);
9834+ else {
9835+ struct writeback_control wbc = {
9836+ .sync_mode = WB_SYNC_ALL,
9837+ .nr_to_write = 0 /* metadata only */
9838+ };
9839+
9840+ err = sync_inode(h_inode, &wbc);
9841+ }
9842+
9843+ au_cpup_attr_timesizes(inode);
9844+ ii_write_unlock(inode);
9845+ si_read_unlock(sb);
9846+ return err;
9847+}
9848+
9849+/* ---------------------------------------------------------------------- */
9850+
1facf9fc 9851+static struct export_operations aufs_export_op = {
4a4d8108 9852+ .fh_to_dentry = aufs_fh_to_dentry,
1facf9fc 9853+ /* .fh_to_parent = aufs_fh_to_parent, */
4a4d8108
AM
9854+ .encode_fh = aufs_encode_fh,
9855+ .commit_metadata = aufs_commit_metadata
1facf9fc 9856+};
9857+
9858+void au_export_init(struct super_block *sb)
9859+{
9860+ struct au_sbinfo *sbinfo;
9861+ __u32 u;
9862+
9863+ sb->s_export_op = &aufs_export_op;
9864+ sbinfo = au_sbi(sb);
9865+ sbinfo->si_xigen = NULL;
9866+ get_random_bytes(&u, sizeof(u));
9867+ BUILD_BUG_ON(sizeof(u) != sizeof(int));
9868+ atomic_set(&sbinfo->si_xigen_next, u);
9869+}
7f207e10
AM
9870diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
9871--- /usr/share/empty/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
a2a7ad62 9872+++ linux/fs/aufs/file.c 2013-03-14 20:07:41.041453062 +0100
b4510431 9873@@ -0,0 +1,683 @@
1facf9fc 9874+/*
7a9e40b8 9875+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 9876+ *
9877+ * This program, aufs is free software; you can redistribute it and/or modify
9878+ * it under the terms of the GNU General Public License as published by
9879+ * the Free Software Foundation; either version 2 of the License, or
9880+ * (at your option) any later version.
dece6358
AM
9881+ *
9882+ * This program is distributed in the hope that it will be useful,
9883+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9884+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9885+ * GNU General Public License for more details.
9886+ *
9887+ * You should have received a copy of the GNU General Public License
9888+ * along with this program; if not, write to the Free Software
9889+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 9890+ */
9891+
9892+/*
4a4d8108 9893+ * handling file/dir, and address_space operation
1facf9fc 9894+ */
9895+
7eafdf33
AM
9896+#ifdef CONFIG_AUFS_DEBUG
9897+#include <linux/migrate.h>
9898+#endif
4a4d8108 9899+#include <linux/pagemap.h>
1facf9fc 9900+#include "aufs.h"
9901+
4a4d8108
AM
9902+/* drop flags for writing */
9903+unsigned int au_file_roflags(unsigned int flags)
9904+{
9905+ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
9906+ flags |= O_RDONLY | O_NOATIME;
9907+ return flags;
9908+}
9909+
9910+/* common functions to regular file and dir */
9911+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
9912+ struct file *file)
1facf9fc 9913+{
1308ab2a 9914+ struct file *h_file;
4a4d8108
AM
9915+ struct dentry *h_dentry;
9916+ struct inode *h_inode;
9917+ struct super_block *sb;
9918+ struct au_branch *br;
9919+ struct path h_path;
9920+ int err, exec_flag;
1facf9fc 9921+
4a4d8108
AM
9922+ /* a race condition can happen between open and unlink/rmdir */
9923+ h_file = ERR_PTR(-ENOENT);
9924+ h_dentry = au_h_dptr(dentry, bindex);
b752ccd1 9925+ if (au_test_nfsd() && !h_dentry)
4a4d8108
AM
9926+ goto out;
9927+ h_inode = h_dentry->d_inode;
b752ccd1 9928+ if (au_test_nfsd() && !h_inode)
4a4d8108 9929+ goto out;
027c5e7a
AM
9930+ spin_lock(&h_dentry->d_lock);
9931+ err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
9932+ || !h_inode
9933+ /* || !dentry->d_inode->i_nlink */
9934+ ;
9935+ spin_unlock(&h_dentry->d_lock);
9936+ if (unlikely(err))
4a4d8108 9937+ goto out;
1facf9fc 9938+
4a4d8108
AM
9939+ sb = dentry->d_sb;
9940+ br = au_sbr(sb, bindex);
9941+ h_file = ERR_PTR(-EACCES);
2cbb1c4b 9942+ exec_flag = flags & __FMODE_EXEC;
4a4d8108 9943+ if (exec_flag && (br->br_mnt->mnt_flags & MNT_NOEXEC))
027c5e7a 9944+ goto out;
1facf9fc 9945+
4a4d8108
AM
9946+ /* drop flags for writing */
9947+ if (au_test_ro(sb, bindex, dentry->d_inode))
9948+ flags = au_file_roflags(flags);
9949+ flags &= ~O_CREAT;
9950+ atomic_inc(&br->br_count);
9951+ h_path.dentry = h_dentry;
9952+ h_path.mnt = br->br_mnt;
9953+ if (!au_special_file(h_inode->i_mode))
9954+ h_file = vfsub_dentry_open(&h_path, flags);
9955+ else {
9956+ /* this block depends upon the configuration */
9957+ di_read_unlock(dentry, AuLock_IR);
9958+ fi_write_unlock(file);
9959+ si_read_unlock(sb);
9960+ h_file = vfsub_dentry_open(&h_path, flags);
9961+ si_noflush_read_lock(sb);
9962+ fi_write_lock(file);
9963+ di_read_lock_child(dentry, AuLock_IR);
dece6358 9964+ }
4a4d8108
AM
9965+ if (IS_ERR(h_file))
9966+ goto out_br;
dece6358 9967+
4a4d8108
AM
9968+ if (exec_flag) {
9969+ err = deny_write_access(h_file);
9970+ if (unlikely(err)) {
9971+ fput(h_file);
9972+ h_file = ERR_PTR(err);
9973+ goto out_br;
9974+ }
9975+ }
953406b4 9976+ fsnotify_open(h_file);
4a4d8108 9977+ goto out; /* success */
1facf9fc 9978+
4f0767ce 9979+out_br:
4a4d8108 9980+ atomic_dec(&br->br_count);
4f0767ce 9981+out:
4a4d8108
AM
9982+ return h_file;
9983+}
1308ab2a 9984+
4a4d8108
AM
9985+int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
9986+ struct au_fidir *fidir)
1facf9fc 9987+{
dece6358 9988+ int err;
1facf9fc 9989+ struct dentry *dentry;
1308ab2a 9990+
4a4d8108
AM
9991+ err = au_finfo_init(file, fidir);
9992+ if (unlikely(err))
9993+ goto out;
1facf9fc 9994+
9995+ dentry = file->f_dentry;
4a4d8108
AM
9996+ di_read_lock_child(dentry, AuLock_IR);
9997+ err = open(file, vfsub_file_flags(file));
9998+ di_read_unlock(dentry, AuLock_IR);
1facf9fc 9999+
4a4d8108
AM
10000+ fi_write_unlock(file);
10001+ if (unlikely(err)) {
10002+ au_fi(file)->fi_hdir = NULL;
10003+ au_finfo_fin(file);
1308ab2a 10004+ }
4a4d8108 10005+
4f0767ce 10006+out:
1308ab2a 10007+ return err;
10008+}
dece6358 10009+
4a4d8108 10010+int au_reopen_nondir(struct file *file)
1308ab2a 10011+{
4a4d8108
AM
10012+ int err;
10013+ aufs_bindex_t bstart;
10014+ struct dentry *dentry;
10015+ struct file *h_file, *h_file_tmp;
1308ab2a 10016+
4a4d8108
AM
10017+ dentry = file->f_dentry;
10018+ AuDebugOn(au_special_file(dentry->d_inode->i_mode));
10019+ bstart = au_dbstart(dentry);
10020+ h_file_tmp = NULL;
10021+ if (au_fbstart(file) == bstart) {
10022+ h_file = au_hf_top(file);
10023+ if (file->f_mode == h_file->f_mode)
10024+ return 0; /* success */
10025+ h_file_tmp = h_file;
10026+ get_file(h_file_tmp);
10027+ au_set_h_fptr(file, bstart, NULL);
10028+ }
10029+ AuDebugOn(au_fi(file)->fi_hdir);
10030+ AuDebugOn(au_fbstart(file) < bstart);
1308ab2a 10031+
4a4d8108
AM
10032+ h_file = au_h_open(dentry, bstart, vfsub_file_flags(file) & ~O_TRUNC,
10033+ file);
10034+ err = PTR_ERR(h_file);
10035+ if (IS_ERR(h_file))
10036+ goto out; /* todo: close all? */
10037+
10038+ err = 0;
10039+ au_set_fbstart(file, bstart);
10040+ au_set_h_fptr(file, bstart, h_file);
10041+ au_update_figen(file);
10042+ /* todo: necessary? */
10043+ /* file->f_ra = h_file->f_ra; */
10044+
4f0767ce 10045+out:
4a4d8108
AM
10046+ if (h_file_tmp)
10047+ fput(h_file_tmp);
10048+ return err;
1facf9fc 10049+}
10050+
1308ab2a 10051+/* ---------------------------------------------------------------------- */
10052+
4a4d8108
AM
10053+static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
10054+ struct dentry *hi_wh)
1facf9fc 10055+{
4a4d8108
AM
10056+ int err;
10057+ aufs_bindex_t bstart;
10058+ struct au_dinfo *dinfo;
10059+ struct dentry *h_dentry;
10060+ struct au_hdentry *hdp;
1facf9fc 10061+
4a4d8108
AM
10062+ dinfo = au_di(file->f_dentry);
10063+ AuRwMustWriteLock(&dinfo->di_rwsem);
dece6358 10064+
4a4d8108
AM
10065+ bstart = dinfo->di_bstart;
10066+ dinfo->di_bstart = btgt;
10067+ hdp = dinfo->di_hdentry;
10068+ h_dentry = hdp[0 + btgt].hd_dentry;
10069+ hdp[0 + btgt].hd_dentry = hi_wh;
10070+ err = au_reopen_nondir(file);
10071+ hdp[0 + btgt].hd_dentry = h_dentry;
10072+ dinfo->di_bstart = bstart;
1facf9fc 10073+
1facf9fc 10074+ return err;
10075+}
10076+
4a4d8108
AM
10077+static int au_ready_to_write_wh(struct file *file, loff_t len,
10078+ aufs_bindex_t bcpup)
1facf9fc 10079+{
4a4d8108 10080+ int err;
027c5e7a
AM
10081+ struct inode *inode, *h_inode;
10082+ struct dentry *dentry, *h_dentry, *hi_wh;
1facf9fc 10083+
dece6358 10084+ dentry = file->f_dentry;
4a4d8108 10085+ au_update_dbstart(dentry);
dece6358 10086+ inode = dentry->d_inode;
027c5e7a
AM
10087+ h_inode = NULL;
10088+ if (au_dbstart(dentry) <= bcpup && au_dbend(dentry) >= bcpup) {
10089+ h_dentry = au_h_dptr(dentry, bcpup);
10090+ if (h_dentry)
10091+ h_inode = h_dentry->d_inode;
10092+ }
4a4d8108 10093+ hi_wh = au_hi_wh(inode, bcpup);
027c5e7a 10094+ if (!hi_wh && !h_inode)
4a4d8108
AM
10095+ err = au_sio_cpup_wh(dentry, bcpup, len, file);
10096+ else
10097+ /* already copied-up after unlink */
10098+ err = au_reopen_wh(file, bcpup, hi_wh);
1facf9fc 10099+
4a4d8108
AM
10100+ if (!err
10101+ && inode->i_nlink > 1
10102+ && au_opt_test(au_mntflags(dentry->d_sb), PLINK))
10103+ au_plink_append(inode, bcpup, au_h_dptr(dentry, bcpup));
1308ab2a 10104+
dece6358 10105+ return err;
1facf9fc 10106+}
10107+
4a4d8108
AM
10108+/*
10109+ * prepare the @file for writing.
10110+ */
10111+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
1facf9fc 10112+{
4a4d8108 10113+ int err;
027c5e7a 10114+ aufs_bindex_t bstart, bcpup, dbstart;
4a4d8108
AM
10115+ struct dentry *dentry, *parent, *h_dentry;
10116+ struct inode *h_inode, *inode;
1facf9fc 10117+ struct super_block *sb;
4a4d8108 10118+ struct file *h_file;
1facf9fc 10119+
10120+ dentry = file->f_dentry;
1facf9fc 10121+ sb = dentry->d_sb;
4a4d8108
AM
10122+ inode = dentry->d_inode;
10123+ AuDebugOn(au_special_file(inode->i_mode));
10124+ bstart = au_fbstart(file);
10125+ err = au_test_ro(sb, bstart, inode);
10126+ if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
10127+ err = au_pin(pin, dentry, bstart, AuOpt_UDBA_NONE, /*flags*/0);
1facf9fc 10128+ goto out;
4a4d8108 10129+ }
1facf9fc 10130+
027c5e7a 10131+ /* need to cpup or reopen */
4a4d8108
AM
10132+ parent = dget_parent(dentry);
10133+ di_write_lock_parent(parent);
10134+ err = AuWbrCopyup(au_sbi(sb), dentry);
10135+ bcpup = err;
10136+ if (unlikely(err < 0))
10137+ goto out_dgrade;
10138+ err = 0;
10139+
027c5e7a 10140+ if (!d_unhashed(dentry) && !au_h_dptr(parent, bcpup)) {
4a4d8108 10141+ err = au_cpup_dirs(dentry, bcpup);
1facf9fc 10142+ if (unlikely(err))
4a4d8108
AM
10143+ goto out_dgrade;
10144+ }
10145+
10146+ err = au_pin(pin, dentry, bcpup, AuOpt_UDBA_NONE,
10147+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
10148+ if (unlikely(err))
10149+ goto out_dgrade;
10150+
10151+ h_dentry = au_hf_top(file)->f_dentry;
10152+ h_inode = h_dentry->d_inode;
027c5e7a
AM
10153+ dbstart = au_dbstart(dentry);
10154+ if (dbstart <= bcpup) {
10155+ h_dentry = au_h_dptr(dentry, bcpup);
10156+ AuDebugOn(!h_dentry);
10157+ h_inode = h_dentry->d_inode;
10158+ AuDebugOn(!h_inode);
10159+ bstart = bcpup;
10160+ }
10161+
10162+ if (dbstart <= bcpup /* just reopen */
10163+ || !d_unhashed(dentry) /* copyup and reopen */
10164+ ) {
10165+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
10166+ h_file = au_h_open_pre(dentry, bstart);
10167+ if (IS_ERR(h_file)) {
10168+ err = PTR_ERR(h_file);
10169+ h_file = NULL;
10170+ } else {
10171+ di_downgrade_lock(parent, AuLock_IR);
10172+ if (dbstart > bcpup)
10173+ err = au_sio_cpup_simple(dentry, bcpup, len,
10174+ AuCpup_DTIME);
10175+ if (!err)
10176+ err = au_reopen_nondir(file);
10177+ }
10178+ mutex_unlock(&h_inode->i_mutex);
10179+ au_h_open_post(dentry, bstart, h_file);
10180+ } else { /* copyup as wh and reopen */
10181+ /*
10182+ * since writable hfsplus branch is not supported,
10183+ * h_open_pre/post() are unnecessary.
10184+ */
10185+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
4a4d8108
AM
10186+ err = au_ready_to_write_wh(file, len, bcpup);
10187+ di_downgrade_lock(parent, AuLock_IR);
027c5e7a 10188+ mutex_unlock(&h_inode->i_mutex);
4a4d8108 10189+ }
4a4d8108
AM
10190+
10191+ if (!err) {
10192+ au_pin_set_parent_lflag(pin, /*lflag*/0);
10193+ goto out_dput; /* success */
10194+ }
10195+ au_unpin(pin);
10196+ goto out_unlock;
1facf9fc 10197+
4f0767ce 10198+out_dgrade:
4a4d8108 10199+ di_downgrade_lock(parent, AuLock_IR);
4f0767ce 10200+out_unlock:
4a4d8108 10201+ di_read_unlock(parent, AuLock_IR);
4f0767ce 10202+out_dput:
4a4d8108 10203+ dput(parent);
4f0767ce 10204+out:
1facf9fc 10205+ return err;
10206+}
10207+
4a4d8108
AM
10208+/* ---------------------------------------------------------------------- */
10209+
10210+int au_do_flush(struct file *file, fl_owner_t id,
10211+ int (*flush)(struct file *file, fl_owner_t id))
1facf9fc 10212+{
4a4d8108 10213+ int err;
1308ab2a 10214+ struct dentry *dentry;
1facf9fc 10215+ struct super_block *sb;
4a4d8108 10216+ struct inode *inode;
1facf9fc 10217+
1facf9fc 10218+ dentry = file->f_dentry;
10219+ sb = dentry->d_sb;
dece6358 10220+ inode = dentry->d_inode;
4a4d8108
AM
10221+ si_noflush_read_lock(sb);
10222+ fi_read_lock(file);
b752ccd1 10223+ ii_read_lock_child(inode);
1facf9fc 10224+
4a4d8108
AM
10225+ err = flush(file, id);
10226+ au_cpup_attr_timesizes(inode);
1facf9fc 10227+
b752ccd1 10228+ ii_read_unlock(inode);
4a4d8108 10229+ fi_read_unlock(file);
1308ab2a 10230+ si_read_unlock(sb);
dece6358 10231+ return err;
1facf9fc 10232+}
10233+
4a4d8108
AM
10234+/* ---------------------------------------------------------------------- */
10235+
10236+static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
1facf9fc 10237+{
4a4d8108
AM
10238+ int err;
10239+ aufs_bindex_t bstart;
10240+ struct au_pin pin;
10241+ struct au_finfo *finfo;
10242+ struct dentry *dentry, *parent, *hi_wh;
10243+ struct inode *inode;
1facf9fc 10244+ struct super_block *sb;
10245+
4a4d8108
AM
10246+ FiMustWriteLock(file);
10247+
10248+ err = 0;
10249+ finfo = au_fi(file);
1308ab2a 10250+ dentry = file->f_dentry;
10251+ sb = dentry->d_sb;
4a4d8108
AM
10252+ inode = dentry->d_inode;
10253+ bstart = au_ibstart(inode);
027c5e7a 10254+ if (bstart == finfo->fi_btop || IS_ROOT(dentry))
1308ab2a 10255+ goto out;
dece6358 10256+
4a4d8108
AM
10257+ parent = dget_parent(dentry);
10258+ if (au_test_ro(sb, bstart, inode)) {
10259+ di_read_lock_parent(parent, !AuLock_IR);
10260+ err = AuWbrCopyup(au_sbi(sb), dentry);
10261+ bstart = err;
10262+ di_read_unlock(parent, !AuLock_IR);
10263+ if (unlikely(err < 0))
10264+ goto out_parent;
10265+ err = 0;
1facf9fc 10266+ }
1facf9fc 10267+
4a4d8108
AM
10268+ di_read_lock_parent(parent, AuLock_IR);
10269+ hi_wh = au_hi_wh(inode, bstart);
7f207e10
AM
10270+ if (!S_ISDIR(inode->i_mode)
10271+ && au_opt_test(au_mntflags(sb), PLINK)
4a4d8108
AM
10272+ && au_plink_test(inode)
10273+ && !d_unhashed(dentry)) {
10274+ err = au_test_and_cpup_dirs(dentry, bstart);
10275+ if (unlikely(err))
10276+ goto out_unlock;
10277+
10278+ /* always superio. */
10279+ err = au_pin(&pin, dentry, bstart, AuOpt_UDBA_NONE,
10280+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
10281+ if (!err)
10282+ err = au_sio_cpup_simple(dentry, bstart, -1,
10283+ AuCpup_DTIME);
10284+ au_unpin(&pin);
10285+ } else if (hi_wh) {
10286+ /* already copied-up after unlink */
10287+ err = au_reopen_wh(file, bstart, hi_wh);
10288+ *need_reopen = 0;
10289+ }
1facf9fc 10290+
4f0767ce 10291+out_unlock:
4a4d8108 10292+ di_read_unlock(parent, AuLock_IR);
4f0767ce 10293+out_parent:
4a4d8108 10294+ dput(parent);
4f0767ce 10295+out:
1308ab2a 10296+ return err;
dece6358 10297+}
1facf9fc 10298+
4a4d8108 10299+static void au_do_refresh_dir(struct file *file)
dece6358 10300+{
4a4d8108
AM
10301+ aufs_bindex_t bindex, bend, new_bindex, brid;
10302+ struct au_hfile *p, tmp, *q;
10303+ struct au_finfo *finfo;
1308ab2a 10304+ struct super_block *sb;
4a4d8108 10305+ struct au_fidir *fidir;
1facf9fc 10306+
4a4d8108 10307+ FiMustWriteLock(file);
1facf9fc 10308+
4a4d8108
AM
10309+ sb = file->f_dentry->d_sb;
10310+ finfo = au_fi(file);
10311+ fidir = finfo->fi_hdir;
10312+ AuDebugOn(!fidir);
10313+ p = fidir->fd_hfile + finfo->fi_btop;
10314+ brid = p->hf_br->br_id;
10315+ bend = fidir->fd_bbot;
10316+ for (bindex = finfo->fi_btop; bindex <= bend; bindex++, p++) {
10317+ if (!p->hf_file)
10318+ continue;
1308ab2a 10319+
4a4d8108
AM
10320+ new_bindex = au_br_index(sb, p->hf_br->br_id);
10321+ if (new_bindex == bindex)
10322+ continue;
10323+ if (new_bindex < 0) {
10324+ au_set_h_fptr(file, bindex, NULL);
10325+ continue;
10326+ }
1308ab2a 10327+
4a4d8108
AM
10328+ /* swap two lower inode, and loop again */
10329+ q = fidir->fd_hfile + new_bindex;
10330+ tmp = *q;
10331+ *q = *p;
10332+ *p = tmp;
10333+ if (tmp.hf_file) {
10334+ bindex--;
10335+ p--;
10336+ }
10337+ }
1308ab2a 10338+
4a4d8108 10339+ p = fidir->fd_hfile;
027c5e7a 10340+ if (!au_test_mmapped(file) && !d_unlinked(file->f_dentry)) {
4a4d8108
AM
10341+ bend = au_sbend(sb);
10342+ for (finfo->fi_btop = 0; finfo->fi_btop <= bend;
10343+ finfo->fi_btop++, p++)
10344+ if (p->hf_file) {
10345+ if (p->hf_file->f_dentry
10346+ && p->hf_file->f_dentry->d_inode)
10347+ break;
10348+ else
10349+ au_hfput(p, file);
10350+ }
10351+ } else {
10352+ bend = au_br_index(sb, brid);
10353+ for (finfo->fi_btop = 0; finfo->fi_btop < bend;
10354+ finfo->fi_btop++, p++)
10355+ if (p->hf_file)
10356+ au_hfput(p, file);
10357+ bend = au_sbend(sb);
10358+ }
1308ab2a 10359+
4a4d8108
AM
10360+ p = fidir->fd_hfile + bend;
10361+ for (fidir->fd_bbot = bend; fidir->fd_bbot >= finfo->fi_btop;
10362+ fidir->fd_bbot--, p--)
10363+ if (p->hf_file) {
10364+ if (p->hf_file->f_dentry
10365+ && p->hf_file->f_dentry->d_inode)
10366+ break;
10367+ else
10368+ au_hfput(p, file);
10369+ }
10370+ AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
1308ab2a 10371+}
10372+
4a4d8108
AM
10373+/*
10374+ * after branch manipulating, refresh the file.
10375+ */
10376+static int refresh_file(struct file *file, int (*reopen)(struct file *file))
1facf9fc 10377+{
4a4d8108
AM
10378+ int err, need_reopen;
10379+ aufs_bindex_t bend, bindex;
10380+ struct dentry *dentry;
1308ab2a 10381+ struct au_finfo *finfo;
4a4d8108 10382+ struct au_hfile *hfile;
1facf9fc 10383+
4a4d8108 10384+ dentry = file->f_dentry;
1308ab2a 10385+ finfo = au_fi(file);
4a4d8108
AM
10386+ if (!finfo->fi_hdir) {
10387+ hfile = &finfo->fi_htop;
10388+ AuDebugOn(!hfile->hf_file);
10389+ bindex = au_br_index(dentry->d_sb, hfile->hf_br->br_id);
10390+ AuDebugOn(bindex < 0);
10391+ if (bindex != finfo->fi_btop)
10392+ au_set_fbstart(file, bindex);
10393+ } else {
10394+ err = au_fidir_realloc(finfo, au_sbend(dentry->d_sb) + 1);
10395+ if (unlikely(err))
10396+ goto out;
10397+ au_do_refresh_dir(file);
10398+ }
1facf9fc 10399+
4a4d8108
AM
10400+ err = 0;
10401+ need_reopen = 1;
10402+ if (!au_test_mmapped(file))
10403+ err = au_file_refresh_by_inode(file, &need_reopen);
027c5e7a 10404+ if (!err && need_reopen && !d_unlinked(dentry))
4a4d8108
AM
10405+ err = reopen(file);
10406+ if (!err) {
10407+ au_update_figen(file);
10408+ goto out; /* success */
10409+ }
10410+
10411+ /* error, close all lower files */
10412+ if (finfo->fi_hdir) {
10413+ bend = au_fbend_dir(file);
10414+ for (bindex = au_fbstart(file); bindex <= bend; bindex++)
10415+ au_set_h_fptr(file, bindex, NULL);
10416+ }
1facf9fc 10417+
4f0767ce 10418+out:
1facf9fc 10419+ return err;
10420+}
10421+
4a4d8108
AM
10422+/* common function to regular file and dir */
10423+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
10424+ int wlock)
dece6358 10425+{
1308ab2a 10426+ int err;
4a4d8108
AM
10427+ unsigned int sigen, figen;
10428+ aufs_bindex_t bstart;
10429+ unsigned char pseudo_link;
10430+ struct dentry *dentry;
10431+ struct inode *inode;
1facf9fc 10432+
4a4d8108
AM
10433+ err = 0;
10434+ dentry = file->f_dentry;
10435+ inode = dentry->d_inode;
10436+ AuDebugOn(au_special_file(inode->i_mode));
10437+ sigen = au_sigen(dentry->d_sb);
10438+ fi_write_lock(file);
10439+ figen = au_figen(file);
10440+ di_write_lock_child(dentry);
10441+ bstart = au_dbstart(dentry);
10442+ pseudo_link = (bstart != au_ibstart(inode));
10443+ if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) {
10444+ if (!wlock) {
10445+ di_downgrade_lock(dentry, AuLock_IR);
10446+ fi_downgrade_lock(file);
10447+ }
10448+ goto out; /* success */
10449+ }
dece6358 10450+
4a4d8108 10451+ AuDbg("sigen %d, figen %d\n", sigen, figen);
027c5e7a 10452+ if (au_digen_test(dentry, sigen)) {
4a4d8108 10453+ err = au_reval_dpath(dentry, sigen);
027c5e7a 10454+ AuDebugOn(!err && au_digen_test(dentry, sigen));
4a4d8108 10455+ }
dece6358 10456+
027c5e7a
AM
10457+ if (!err)
10458+ err = refresh_file(file, reopen);
4a4d8108
AM
10459+ if (!err) {
10460+ if (!wlock) {
10461+ di_downgrade_lock(dentry, AuLock_IR);
10462+ fi_downgrade_lock(file);
10463+ }
10464+ } else {
10465+ di_write_unlock(dentry);
10466+ fi_write_unlock(file);
10467+ }
1facf9fc 10468+
4f0767ce 10469+out:
1308ab2a 10470+ return err;
10471+}
1facf9fc 10472+
4a4d8108
AM
10473+/* ---------------------------------------------------------------------- */
10474+
10475+/* cf. aufs_nopage() */
10476+/* for madvise(2) */
10477+static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
1308ab2a 10478+{
4a4d8108
AM
10479+ unlock_page(page);
10480+ return 0;
10481+}
1facf9fc 10482+
4a4d8108
AM
10483+/* it will never be called, but necessary to support O_DIRECT */
10484+static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb,
10485+ const struct iovec *iov, loff_t offset,
10486+ unsigned long nr_segs)
10487+{ BUG(); return 0; }
1facf9fc 10488+
4a4d8108
AM
10489+/*
10490+ * it will never be called, but madvise and fadvise behaves differently
10491+ * when get_xip_mem is defined
10492+ */
10493+static int aufs_get_xip_mem(struct address_space *mapping, pgoff_t pgoff,
10494+ int create, void **kmem, unsigned long *pfn)
10495+{ BUG(); return 0; }
1facf9fc 10496+
4a4d8108
AM
10497+/* they will never be called. */
10498+#ifdef CONFIG_AUFS_DEBUG
10499+static int aufs_write_begin(struct file *file, struct address_space *mapping,
10500+ loff_t pos, unsigned len, unsigned flags,
10501+ struct page **pagep, void **fsdata)
10502+{ AuUnsupport(); return 0; }
10503+static int aufs_write_end(struct file *file, struct address_space *mapping,
10504+ loff_t pos, unsigned len, unsigned copied,
10505+ struct page *page, void *fsdata)
10506+{ AuUnsupport(); return 0; }
10507+static int aufs_writepage(struct page *page, struct writeback_control *wbc)
10508+{ AuUnsupport(); return 0; }
1308ab2a 10509+
4a4d8108
AM
10510+static int aufs_set_page_dirty(struct page *page)
10511+{ AuUnsupport(); return 0; }
10512+static void aufs_invalidatepage(struct page *page, unsigned long offset)
10513+{ AuUnsupport(); }
10514+static int aufs_releasepage(struct page *page, gfp_t gfp)
10515+{ AuUnsupport(); return 0; }
10516+static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
7eafdf33 10517+ struct page *page, enum migrate_mode mode)
4a4d8108
AM
10518+{ AuUnsupport(); return 0; }
10519+static int aufs_launder_page(struct page *page)
10520+{ AuUnsupport(); return 0; }
10521+static int aufs_is_partially_uptodate(struct page *page,
10522+ read_descriptor_t *desc,
10523+ unsigned long from)
10524+{ AuUnsupport(); return 0; }
10525+static int aufs_error_remove_page(struct address_space *mapping,
10526+ struct page *page)
10527+{ AuUnsupport(); return 0; }
b4510431
AM
10528+static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file,
10529+ sector_t *span)
10530+{ AuUnsupport(); return 0; }
10531+static void aufs_swap_deactivate(struct file *file)
10532+{ AuUnsupport(); }
4a4d8108
AM
10533+#endif /* CONFIG_AUFS_DEBUG */
10534+
10535+const struct address_space_operations aufs_aop = {
10536+ .readpage = aufs_readpage,
10537+ .direct_IO = aufs_direct_IO,
10538+ .get_xip_mem = aufs_get_xip_mem,
10539+#ifdef CONFIG_AUFS_DEBUG
10540+ .writepage = aufs_writepage,
4a4d8108
AM
10541+ /* no writepages, because of writepage */
10542+ .set_page_dirty = aufs_set_page_dirty,
10543+ /* no readpages, because of readpage */
10544+ .write_begin = aufs_write_begin,
10545+ .write_end = aufs_write_end,
10546+ /* no bmap, no block device */
10547+ .invalidatepage = aufs_invalidatepage,
10548+ .releasepage = aufs_releasepage,
10549+ .migratepage = aufs_migratepage,
10550+ .launder_page = aufs_launder_page,
10551+ .is_partially_uptodate = aufs_is_partially_uptodate,
b4510431
AM
10552+ .error_remove_page = aufs_error_remove_page,
10553+ .swap_activate = aufs_swap_activate,
10554+ .swap_deactivate = aufs_swap_deactivate
4a4d8108 10555+#endif /* CONFIG_AUFS_DEBUG */
dece6358 10556+};
7f207e10
AM
10557diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
10558--- /usr/share/empty/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100
1716fcea 10559+++ linux/fs/aufs/file.h 2013-02-19 08:40:03.946892891 +0100
2dfbb274 10560@@ -0,0 +1,298 @@
4a4d8108 10561+/*
7a9e40b8 10562+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
10563+ *
10564+ * This program, aufs is free software; you can redistribute it and/or modify
10565+ * it under the terms of the GNU General Public License as published by
10566+ * the Free Software Foundation; either version 2 of the License, or
10567+ * (at your option) any later version.
10568+ *
10569+ * This program is distributed in the hope that it will be useful,
10570+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10571+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10572+ * GNU General Public License for more details.
10573+ *
10574+ * You should have received a copy of the GNU General Public License
10575+ * along with this program; if not, write to the Free Software
10576+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
10577+ */
1facf9fc 10578+
4a4d8108
AM
10579+/*
10580+ * file operations
10581+ */
1facf9fc 10582+
4a4d8108
AM
10583+#ifndef __AUFS_FILE_H__
10584+#define __AUFS_FILE_H__
1facf9fc 10585+
4a4d8108 10586+#ifdef __KERNEL__
1facf9fc 10587+
2cbb1c4b 10588+#include <linux/file.h>
4a4d8108
AM
10589+#include <linux/fs.h>
10590+#include <linux/poll.h>
4a4d8108 10591+#include "rwsem.h"
1facf9fc 10592+
4a4d8108
AM
10593+struct au_branch;
10594+struct au_hfile {
10595+ struct file *hf_file;
10596+ struct au_branch *hf_br;
10597+};
1facf9fc 10598+
4a4d8108
AM
10599+struct au_vdir;
10600+struct au_fidir {
10601+ aufs_bindex_t fd_bbot;
10602+ aufs_bindex_t fd_nent;
10603+ struct au_vdir *fd_vdir_cache;
10604+ struct au_hfile fd_hfile[];
10605+};
1facf9fc 10606+
4a4d8108 10607+static inline int au_fidir_sz(int nent)
dece6358 10608+{
4f0767ce
JR
10609+ AuDebugOn(nent < 0);
10610+ return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
4a4d8108 10611+}
1facf9fc 10612+
4a4d8108
AM
10613+struct au_finfo {
10614+ atomic_t fi_generation;
dece6358 10615+
4a4d8108
AM
10616+ struct au_rwsem fi_rwsem;
10617+ aufs_bindex_t fi_btop;
10618+
10619+ /* do not union them */
10620+ struct { /* for non-dir */
10621+ struct au_hfile fi_htop;
2cbb1c4b 10622+ atomic_t fi_mmapped;
4a4d8108
AM
10623+ };
10624+ struct au_fidir *fi_hdir; /* for dir only */
10625+} ____cacheline_aligned_in_smp;
1facf9fc 10626+
4a4d8108 10627+/* ---------------------------------------------------------------------- */
1facf9fc 10628+
4a4d8108
AM
10629+/* file.c */
10630+extern const struct address_space_operations aufs_aop;
10631+unsigned int au_file_roflags(unsigned int flags);
10632+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
10633+ struct file *file);
10634+int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
10635+ struct au_fidir *fidir);
10636+int au_reopen_nondir(struct file *file);
10637+struct au_pin;
10638+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
10639+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
10640+ int wlock);
10641+int au_do_flush(struct file *file, fl_owner_t id,
10642+ int (*flush)(struct file *file, fl_owner_t id));
1facf9fc 10643+
4a4d8108
AM
10644+/* poll.c */
10645+#ifdef CONFIG_AUFS_POLL
10646+unsigned int aufs_poll(struct file *file, poll_table *wait);
10647+#endif
1facf9fc 10648+
4a4d8108
AM
10649+#ifdef CONFIG_AUFS_BR_HFSPLUS
10650+/* hfsplus.c */
10651+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex);
10652+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
10653+ struct file *h_file);
10654+#else
10655+static inline
10656+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex)
dece6358 10657+{
4a4d8108
AM
10658+ return NULL;
10659+}
1facf9fc 10660+
4a4d8108
AM
10661+AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
10662+ struct file *h_file);
10663+#endif
1facf9fc 10664+
4a4d8108
AM
10665+/* f_op.c */
10666+extern const struct file_operations aufs_file_fop;
4a4d8108
AM
10667+int au_do_open_nondir(struct file *file, int flags);
10668+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
10669+
10670+#ifdef CONFIG_AUFS_SP_IATTR
10671+/* f_op_sp.c */
10672+int au_special_file(umode_t mode);
10673+void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev);
10674+#else
10675+AuStubInt0(au_special_file, umode_t mode)
10676+static inline void au_init_special_fop(struct inode *inode, umode_t mode,
10677+ dev_t rdev)
10678+{
10679+ init_special_inode(inode, mode, rdev);
10680+}
10681+#endif
1facf9fc 10682+
4a4d8108
AM
10683+/* finfo.c */
10684+void au_hfput(struct au_hfile *hf, struct file *file);
10685+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
10686+ struct file *h_file);
1facf9fc 10687+
4a4d8108 10688+void au_update_figen(struct file *file);
4a4d8108
AM
10689+struct au_fidir *au_fidir_alloc(struct super_block *sb);
10690+int au_fidir_realloc(struct au_finfo *finfo, int nbr);
1facf9fc 10691+
4a4d8108
AM
10692+void au_fi_init_once(void *_fi);
10693+void au_finfo_fin(struct file *file);
10694+int au_finfo_init(struct file *file, struct au_fidir *fidir);
1facf9fc 10695+
4a4d8108
AM
10696+/* ioctl.c */
10697+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
10698+#ifdef CONFIG_COMPAT
10699+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
10700+ unsigned long arg);
10701+#endif
1facf9fc 10702+
4a4d8108 10703+/* ---------------------------------------------------------------------- */
1facf9fc 10704+
4a4d8108
AM
10705+static inline struct au_finfo *au_fi(struct file *file)
10706+{
10707+ return file->private_data;
10708+}
1facf9fc 10709+
4a4d8108 10710+/* ---------------------------------------------------------------------- */
1facf9fc 10711+
4a4d8108
AM
10712+/*
10713+ * fi_read_lock, fi_write_lock,
10714+ * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
10715+ */
10716+AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
1308ab2a 10717+
4a4d8108
AM
10718+#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
10719+#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
10720+#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
1facf9fc 10721+
1308ab2a 10722+/* ---------------------------------------------------------------------- */
10723+
4a4d8108
AM
10724+/* todo: hard/soft set? */
10725+static inline aufs_bindex_t au_fbstart(struct file *file)
dece6358 10726+{
4a4d8108
AM
10727+ FiMustAnyLock(file);
10728+ return au_fi(file)->fi_btop;
10729+}
dece6358 10730+
4a4d8108
AM
10731+static inline aufs_bindex_t au_fbend_dir(struct file *file)
10732+{
10733+ FiMustAnyLock(file);
10734+ AuDebugOn(!au_fi(file)->fi_hdir);
10735+ return au_fi(file)->fi_hdir->fd_bbot;
10736+}
1facf9fc 10737+
4a4d8108
AM
10738+static inline struct au_vdir *au_fvdir_cache(struct file *file)
10739+{
10740+ FiMustAnyLock(file);
10741+ AuDebugOn(!au_fi(file)->fi_hdir);
10742+ return au_fi(file)->fi_hdir->fd_vdir_cache;
10743+}
1facf9fc 10744+
4a4d8108
AM
10745+static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex)
10746+{
10747+ FiMustWriteLock(file);
10748+ au_fi(file)->fi_btop = bindex;
10749+}
1facf9fc 10750+
4a4d8108
AM
10751+static inline void au_set_fbend_dir(struct file *file, aufs_bindex_t bindex)
10752+{
10753+ FiMustWriteLock(file);
10754+ AuDebugOn(!au_fi(file)->fi_hdir);
10755+ au_fi(file)->fi_hdir->fd_bbot = bindex;
10756+}
1308ab2a 10757+
4a4d8108
AM
10758+static inline void au_set_fvdir_cache(struct file *file,
10759+ struct au_vdir *vdir_cache)
10760+{
10761+ FiMustWriteLock(file);
10762+ AuDebugOn(!au_fi(file)->fi_hdir);
10763+ au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
10764+}
dece6358 10765+
4a4d8108
AM
10766+static inline struct file *au_hf_top(struct file *file)
10767+{
10768+ FiMustAnyLock(file);
10769+ AuDebugOn(au_fi(file)->fi_hdir);
10770+ return au_fi(file)->fi_htop.hf_file;
10771+}
1facf9fc 10772+
4a4d8108
AM
10773+static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
10774+{
10775+ FiMustAnyLock(file);
10776+ AuDebugOn(!au_fi(file)->fi_hdir);
10777+ return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
dece6358
AM
10778+}
10779+
4a4d8108
AM
10780+/* todo: memory barrier? */
10781+static inline unsigned int au_figen(struct file *f)
dece6358 10782+{
4a4d8108
AM
10783+ return atomic_read(&au_fi(f)->fi_generation);
10784+}
dece6358 10785+
2cbb1c4b
JR
10786+static inline void au_set_mmapped(struct file *f)
10787+{
10788+ if (atomic_inc_return(&au_fi(f)->fi_mmapped))
10789+ return;
0c3ec466 10790+ pr_warn("fi_mmapped wrapped around\n");
2cbb1c4b
JR
10791+ while (!atomic_inc_return(&au_fi(f)->fi_mmapped))
10792+ ;
10793+}
10794+
10795+static inline void au_unset_mmapped(struct file *f)
10796+{
10797+ atomic_dec(&au_fi(f)->fi_mmapped);
10798+}
10799+
4a4d8108
AM
10800+static inline int au_test_mmapped(struct file *f)
10801+{
2cbb1c4b
JR
10802+ return atomic_read(&au_fi(f)->fi_mmapped);
10803+}
10804+
10805+/* customize vma->vm_file */
10806+
10807+static inline void au_do_vm_file_reset(struct vm_area_struct *vma,
10808+ struct file *file)
10809+{
53392da6
AM
10810+ struct file *f;
10811+
10812+ f = vma->vm_file;
2cbb1c4b
JR
10813+ get_file(file);
10814+ vma->vm_file = file;
53392da6 10815+ fput(f);
2cbb1c4b
JR
10816+}
10817+
10818+#ifdef CONFIG_MMU
10819+#define AuDbgVmRegion(file, vma) do {} while (0)
10820+
10821+static inline void au_vm_file_reset(struct vm_area_struct *vma,
10822+ struct file *file)
10823+{
10824+ au_do_vm_file_reset(vma, file);
10825+}
10826+#else
10827+#define AuDbgVmRegion(file, vma) \
10828+ AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
10829+
10830+static inline void au_vm_file_reset(struct vm_area_struct *vma,
10831+ struct file *file)
10832+{
53392da6
AM
10833+ struct file *f;
10834+
2cbb1c4b 10835+ au_do_vm_file_reset(vma, file);
53392da6 10836+ f = vma->vm_region->vm_file;
2cbb1c4b
JR
10837+ get_file(file);
10838+ vma->vm_region->vm_file = file;
53392da6 10839+ fput(f);
2cbb1c4b
JR
10840+}
10841+#endif /* CONFIG_MMU */
10842+
10843+/* handle vma->vm_prfile */
10844+static inline void au_vm_prfile_set(struct vm_area_struct *vma,
10845+ struct file *file)
10846+{
10847+#ifdef CONFIG_AUFS_PROC_MAP
10848+ get_file(file);
10849+ vma->vm_prfile = file;
10850+#ifndef CONFIG_MMU
10851+ get_file(file);
10852+ vma->vm_region->vm_prfile = file;
10853+#endif
10854+#endif
4a4d8108 10855+}
1308ab2a 10856+
4a4d8108
AM
10857+#endif /* __KERNEL__ */
10858+#endif /* __AUFS_FILE_H__ */
7f207e10
AM
10859diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
10860--- /usr/share/empty/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100
1716fcea
AM
10861+++ linux/fs/aufs/finfo.c 2013-02-19 08:40:03.946892891 +0100
10862@@ -0,0 +1,157 @@
4a4d8108 10863+/*
7a9e40b8 10864+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
10865+ *
10866+ * This program, aufs is free software; you can redistribute it and/or modify
10867+ * it under the terms of the GNU General Public License as published by
10868+ * the Free Software Foundation; either version 2 of the License, or
10869+ * (at your option) any later version.
10870+ *
10871+ * This program is distributed in the hope that it will be useful,
10872+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10873+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10874+ * GNU General Public License for more details.
10875+ *
10876+ * You should have received a copy of the GNU General Public License
10877+ * along with this program; if not, write to the Free Software
10878+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
10879+ */
1308ab2a 10880+
4a4d8108
AM
10881+/*
10882+ * file private data
10883+ */
1facf9fc 10884+
4a4d8108 10885+#include "aufs.h"
1facf9fc 10886+
4a4d8108
AM
10887+void au_hfput(struct au_hfile *hf, struct file *file)
10888+{
10889+ /* todo: direct access f_flags */
2cbb1c4b 10890+ if (vfsub_file_flags(file) & __FMODE_EXEC)
4a4d8108
AM
10891+ allow_write_access(hf->hf_file);
10892+ fput(hf->hf_file);
10893+ hf->hf_file = NULL;
e49829fe 10894+ atomic_dec(&hf->hf_br->br_count);
4a4d8108
AM
10895+ hf->hf_br = NULL;
10896+}
1facf9fc 10897+
4a4d8108
AM
10898+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
10899+{
10900+ struct au_finfo *finfo = au_fi(file);
10901+ struct au_hfile *hf;
10902+ struct au_fidir *fidir;
10903+
10904+ fidir = finfo->fi_hdir;
10905+ if (!fidir) {
10906+ AuDebugOn(finfo->fi_btop != bindex);
10907+ hf = &finfo->fi_htop;
10908+ } else
10909+ hf = fidir->fd_hfile + bindex;
10910+
10911+ if (hf && hf->hf_file)
10912+ au_hfput(hf, file);
10913+ if (val) {
10914+ FiMustWriteLock(file);
10915+ hf->hf_file = val;
10916+ hf->hf_br = au_sbr(file->f_dentry->d_sb, bindex);
1308ab2a 10917+ }
4a4d8108 10918+}
1facf9fc 10919+
4a4d8108
AM
10920+void au_update_figen(struct file *file)
10921+{
10922+ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_dentry));
10923+ /* smp_mb(); */ /* atomic_set */
1facf9fc 10924+}
10925+
4a4d8108
AM
10926+/* ---------------------------------------------------------------------- */
10927+
4a4d8108
AM
10928+struct au_fidir *au_fidir_alloc(struct super_block *sb)
10929+{
10930+ struct au_fidir *fidir;
10931+ int nbr;
10932+
10933+ nbr = au_sbend(sb) + 1;
10934+ if (nbr < 2)
10935+ nbr = 2; /* initial allocate for 2 branches */
10936+ fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS);
10937+ if (fidir) {
10938+ fidir->fd_bbot = -1;
10939+ fidir->fd_nent = nbr;
10940+ fidir->fd_vdir_cache = NULL;
10941+ }
10942+
10943+ return fidir;
10944+}
10945+
10946+int au_fidir_realloc(struct au_finfo *finfo, int nbr)
10947+{
10948+ int err;
10949+ struct au_fidir *fidir, *p;
10950+
10951+ AuRwMustWriteLock(&finfo->fi_rwsem);
10952+ fidir = finfo->fi_hdir;
10953+ AuDebugOn(!fidir);
10954+
10955+ err = -ENOMEM;
10956+ p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr),
10957+ GFP_NOFS);
10958+ if (p) {
10959+ p->fd_nent = nbr;
10960+ finfo->fi_hdir = p;
10961+ err = 0;
10962+ }
1facf9fc 10963+
dece6358 10964+ return err;
1facf9fc 10965+}
1308ab2a 10966+
10967+/* ---------------------------------------------------------------------- */
10968+
4a4d8108 10969+void au_finfo_fin(struct file *file)
1308ab2a 10970+{
4a4d8108
AM
10971+ struct au_finfo *finfo;
10972+
7f207e10
AM
10973+ au_nfiles_dec(file->f_dentry->d_sb);
10974+
4a4d8108
AM
10975+ finfo = au_fi(file);
10976+ AuDebugOn(finfo->fi_hdir);
10977+ AuRwDestroy(&finfo->fi_rwsem);
10978+ au_cache_free_finfo(finfo);
1308ab2a 10979+}
1308ab2a 10980+
e49829fe 10981+void au_fi_init_once(void *_finfo)
4a4d8108 10982+{
e49829fe 10983+ struct au_finfo *finfo = _finfo;
2cbb1c4b 10984+ static struct lock_class_key aufs_fi;
1308ab2a 10985+
e49829fe
JR
10986+ au_rw_init(&finfo->fi_rwsem);
10987+ au_rw_class(&finfo->fi_rwsem, &aufs_fi);
4a4d8108 10988+}
1308ab2a 10989+
4a4d8108
AM
10990+int au_finfo_init(struct file *file, struct au_fidir *fidir)
10991+{
1716fcea 10992+ int err;
4a4d8108
AM
10993+ struct au_finfo *finfo;
10994+ struct dentry *dentry;
10995+
10996+ err = -ENOMEM;
10997+ dentry = file->f_dentry;
10998+ finfo = au_cache_alloc_finfo();
10999+ if (unlikely(!finfo))
11000+ goto out;
11001+
11002+ err = 0;
7f207e10 11003+ au_nfiles_inc(dentry->d_sb);
1716fcea
AM
11004+ /* verbose coding for lock class name */
11005+ if (!fidir)
11006+ au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcNonDir_FIINFO);
11007+ else
11008+ au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcDir_FIINFO);
4a4d8108
AM
11009+ au_rw_write_lock(&finfo->fi_rwsem);
11010+ finfo->fi_btop = -1;
11011+ finfo->fi_hdir = fidir;
11012+ atomic_set(&finfo->fi_generation, au_digen(dentry));
11013+ /* smp_mb(); */ /* atomic_set */
11014+
11015+ file->private_data = finfo;
11016+
11017+out:
11018+ return err;
11019+}
7f207e10
AM
11020diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
11021--- /usr/share/empty/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100
a2a7ad62 11022+++ linux/fs/aufs/f_op.c 2013-03-14 20:07:41.041453062 +0100
537831f9 11023@@ -0,0 +1,723 @@
dece6358 11024+/*
7a9e40b8 11025+ * Copyright (C) 2005-2013 Junjiro R. Okajima
dece6358
AM
11026+ *
11027+ * This program, aufs is free software; you can redistribute it and/or modify
11028+ * it under the terms of the GNU General Public License as published by
11029+ * the Free Software Foundation; either version 2 of the License, or
11030+ * (at your option) any later version.
11031+ *
11032+ * This program is distributed in the hope that it will be useful,
11033+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11034+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11035+ * GNU General Public License for more details.
11036+ *
11037+ * You should have received a copy of the GNU General Public License
11038+ * along with this program; if not, write to the Free Software
11039+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11040+ */
1facf9fc 11041+
11042+/*
4a4d8108 11043+ * file and vm operations
1facf9fc 11044+ */
dece6358 11045+
4a4d8108
AM
11046+#include <linux/fs_stack.h>
11047+#include <linux/mman.h>
4a4d8108 11048+#include <linux/security.h>
dece6358
AM
11049+#include "aufs.h"
11050+
4a4d8108 11051+int au_do_open_nondir(struct file *file, int flags)
1facf9fc 11052+{
4a4d8108
AM
11053+ int err;
11054+ aufs_bindex_t bindex;
11055+ struct file *h_file;
11056+ struct dentry *dentry;
11057+ struct au_finfo *finfo;
11058+
11059+ FiMustWriteLock(file);
11060+
4a4d8108 11061+ dentry = file->f_dentry;
027c5e7a
AM
11062+ err = au_d_alive(dentry);
11063+ if (unlikely(err))
11064+ goto out;
11065+
4a4d8108
AM
11066+ finfo = au_fi(file);
11067+ memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
2cbb1c4b 11068+ atomic_set(&finfo->fi_mmapped, 0);
4a4d8108
AM
11069+ bindex = au_dbstart(dentry);
11070+ h_file = au_h_open(dentry, bindex, flags, file);
11071+ if (IS_ERR(h_file))
11072+ err = PTR_ERR(h_file);
11073+ else {
11074+ au_set_fbstart(file, bindex);
11075+ au_set_h_fptr(file, bindex, h_file);
11076+ au_update_figen(file);
11077+ /* todo: necessary? */
11078+ /* file->f_ra = h_file->f_ra; */
11079+ }
027c5e7a
AM
11080+
11081+out:
4a4d8108 11082+ return err;
1facf9fc 11083+}
11084+
4a4d8108
AM
11085+static int aufs_open_nondir(struct inode *inode __maybe_unused,
11086+ struct file *file)
1facf9fc 11087+{
4a4d8108 11088+ int err;
1308ab2a 11089+ struct super_block *sb;
1facf9fc 11090+
2cbb1c4b 11091+ AuDbg("%.*s, f_flags 0x%x, f_mode 0x%x\n",
4a4d8108
AM
11092+ AuDLNPair(file->f_dentry), vfsub_file_flags(file),
11093+ file->f_mode);
1facf9fc 11094+
4a4d8108
AM
11095+ sb = file->f_dentry->d_sb;
11096+ si_read_lock(sb, AuLock_FLUSH);
11097+ err = au_do_open(file, au_do_open_nondir, /*fidir*/NULL);
11098+ si_read_unlock(sb);
11099+ return err;
11100+}
1facf9fc 11101+
4a4d8108
AM
11102+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
11103+{
11104+ struct au_finfo *finfo;
11105+ aufs_bindex_t bindex;
1facf9fc 11106+
4a4d8108
AM
11107+ finfo = au_fi(file);
11108+ bindex = finfo->fi_btop;
b4510431 11109+ if (bindex >= 0)
4a4d8108 11110+ au_set_h_fptr(file, bindex, NULL);
7f207e10 11111+
4a4d8108
AM
11112+ au_finfo_fin(file);
11113+ return 0;
1facf9fc 11114+}
11115+
4a4d8108
AM
11116+/* ---------------------------------------------------------------------- */
11117+
11118+static int au_do_flush_nondir(struct file *file, fl_owner_t id)
dece6358 11119+{
1308ab2a 11120+ int err;
4a4d8108
AM
11121+ struct file *h_file;
11122+
11123+ err = 0;
11124+ h_file = au_hf_top(file);
11125+ if (h_file)
11126+ err = vfsub_flush(h_file, id);
11127+ return err;
11128+}
11129+
11130+static int aufs_flush_nondir(struct file *file, fl_owner_t id)
11131+{
11132+ return au_do_flush(file, id, au_do_flush_nondir);
11133+}
11134+
11135+/* ---------------------------------------------------------------------- */
9dbd164d
AM
11136+/*
11137+ * read and write functions acquire [fdi]_rwsem once, but release before
11138+ * mmap_sem. This is because to stop a race condition between mmap(2).
11139+ * Releasing these aufs-rwsem should be safe, no branch-mamagement (by keeping
11140+ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in
11141+ * read functions after [fdi]_rwsem are released, but it should be harmless.
11142+ */
4a4d8108
AM
11143+
11144+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
11145+ loff_t *ppos)
11146+{
11147+ ssize_t err;
dece6358 11148+ struct dentry *dentry;
4a4d8108 11149+ struct file *h_file;
dece6358 11150+ struct super_block *sb;
1facf9fc 11151+
dece6358
AM
11152+ dentry = file->f_dentry;
11153+ sb = dentry->d_sb;
e49829fe 11154+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108 11155+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
dece6358
AM
11156+ if (unlikely(err))
11157+ goto out;
1facf9fc 11158+
4a4d8108 11159+ h_file = au_hf_top(file);
9dbd164d
AM
11160+ get_file(h_file);
11161+ di_read_unlock(dentry, AuLock_IR);
11162+ fi_read_unlock(file);
11163+
11164+ /* filedata may be obsoleted by concurrent copyup, but no problem */
4a4d8108
AM
11165+ err = vfsub_read_u(h_file, buf, count, ppos);
11166+ /* todo: necessary? */
11167+ /* file->f_ra = h_file->f_ra; */
9dbd164d 11168+ /* update without lock, I don't think it a problem */
4a4d8108 11169+ fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
9dbd164d 11170+ fput(h_file);
1308ab2a 11171+
4f0767ce 11172+out:
dece6358
AM
11173+ si_read_unlock(sb);
11174+ return err;
11175+}
1facf9fc 11176+
e49829fe
JR
11177+/*
11178+ * todo: very ugly
11179+ * it locks both of i_mutex and si_rwsem for read in safe.
11180+ * if the plink maintenance mode continues forever (that is the problem),
11181+ * may loop forever.
11182+ */
11183+static void au_mtx_and_read_lock(struct inode *inode)
11184+{
11185+ int err;
11186+ struct super_block *sb = inode->i_sb;
11187+
11188+ while (1) {
11189+ mutex_lock(&inode->i_mutex);
11190+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
11191+ if (!err)
11192+ break;
11193+ mutex_unlock(&inode->i_mutex);
11194+ si_read_lock(sb, AuLock_NOPLMW);
11195+ si_read_unlock(sb);
11196+ }
11197+}
11198+
4a4d8108
AM
11199+static ssize_t aufs_write(struct file *file, const char __user *ubuf,
11200+ size_t count, loff_t *ppos)
dece6358 11201+{
4a4d8108
AM
11202+ ssize_t err;
11203+ struct au_pin pin;
dece6358 11204+ struct dentry *dentry;
9dbd164d 11205+ struct super_block *sb;
4a4d8108 11206+ struct inode *inode;
4a4d8108
AM
11207+ struct file *h_file;
11208+ char __user *buf = (char __user *)ubuf;
1facf9fc 11209+
dece6358 11210+ dentry = file->f_dentry;
9dbd164d 11211+ sb = dentry->d_sb;
4a4d8108 11212+ inode = dentry->d_inode;
e49829fe 11213+ au_mtx_and_read_lock(inode);
1facf9fc 11214+
4a4d8108
AM
11215+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11216+ if (unlikely(err))
11217+ goto out;
1facf9fc 11218+
4a4d8108
AM
11219+ err = au_ready_to_write(file, -1, &pin);
11220+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
11221+ if (unlikely(err)) {
11222+ di_read_unlock(dentry, AuLock_IR);
11223+ fi_write_unlock(file);
11224+ goto out;
11225+ }
1facf9fc 11226+
4a4d8108 11227+ h_file = au_hf_top(file);
9dbd164d 11228+ get_file(h_file);
4a4d8108 11229+ au_unpin(&pin);
9dbd164d
AM
11230+ di_read_unlock(dentry, AuLock_IR);
11231+ fi_write_unlock(file);
11232+
4a4d8108 11233+ err = vfsub_write_u(h_file, buf, count, ppos);
9dbd164d 11234+ ii_write_lock_child(inode);
4a4d8108
AM
11235+ au_cpup_attr_timesizes(inode);
11236+ inode->i_mode = h_file->f_dentry->d_inode->i_mode;
9dbd164d
AM
11237+ ii_write_unlock(inode);
11238+ fput(h_file);
1facf9fc 11239+
4f0767ce 11240+out:
9dbd164d 11241+ si_read_unlock(sb);
4a4d8108 11242+ mutex_unlock(&inode->i_mutex);
dece6358
AM
11243+ return err;
11244+}
1facf9fc 11245+
4a4d8108
AM
11246+static ssize_t au_do_aio(struct file *h_file, int rw, struct kiocb *kio,
11247+ const struct iovec *iov, unsigned long nv, loff_t pos)
dece6358 11248+{
4a4d8108
AM
11249+ ssize_t err;
11250+ struct file *file;
11251+ ssize_t (*func)(struct kiocb *, const struct iovec *, unsigned long,
11252+ loff_t);
1facf9fc 11253+
4a4d8108
AM
11254+ err = security_file_permission(h_file, rw);
11255+ if (unlikely(err))
11256+ goto out;
1facf9fc 11257+
4a4d8108
AM
11258+ err = -ENOSYS;
11259+ func = NULL;
11260+ if (rw == MAY_READ)
11261+ func = h_file->f_op->aio_read;
11262+ else if (rw == MAY_WRITE)
11263+ func = h_file->f_op->aio_write;
11264+ if (func) {
11265+ file = kio->ki_filp;
11266+ kio->ki_filp = h_file;
2cbb1c4b 11267+ lockdep_off();
4a4d8108 11268+ err = func(kio, iov, nv, pos);
2cbb1c4b 11269+ lockdep_on();
4a4d8108
AM
11270+ kio->ki_filp = file;
11271+ } else
11272+ /* currently there is no such fs */
11273+ WARN_ON_ONCE(1);
1facf9fc 11274+
4f0767ce 11275+out:
dece6358
AM
11276+ return err;
11277+}
1facf9fc 11278+
4a4d8108
AM
11279+static ssize_t aufs_aio_read(struct kiocb *kio, const struct iovec *iov,
11280+ unsigned long nv, loff_t pos)
1facf9fc 11281+{
4a4d8108
AM
11282+ ssize_t err;
11283+ struct file *file, *h_file;
11284+ struct dentry *dentry;
dece6358 11285+ struct super_block *sb;
1facf9fc 11286+
4a4d8108 11287+ file = kio->ki_filp;
dece6358 11288+ dentry = file->f_dentry;
1308ab2a 11289+ sb = dentry->d_sb;
e49829fe 11290+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
11291+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
11292+ if (unlikely(err))
11293+ goto out;
11294+
11295+ h_file = au_hf_top(file);
9dbd164d
AM
11296+ get_file(h_file);
11297+ di_read_unlock(dentry, AuLock_IR);
11298+ fi_read_unlock(file);
11299+
4a4d8108
AM
11300+ err = au_do_aio(h_file, MAY_READ, kio, iov, nv, pos);
11301+ /* todo: necessary? */
11302+ /* file->f_ra = h_file->f_ra; */
9dbd164d 11303+ /* update without lock, I don't think it a problem */
4a4d8108 11304+ fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
9dbd164d 11305+ fput(h_file);
1facf9fc 11306+
4f0767ce 11307+out:
4a4d8108 11308+ si_read_unlock(sb);
1308ab2a 11309+ return err;
11310+}
1facf9fc 11311+
4a4d8108
AM
11312+static ssize_t aufs_aio_write(struct kiocb *kio, const struct iovec *iov,
11313+ unsigned long nv, loff_t pos)
1308ab2a 11314+{
4a4d8108
AM
11315+ ssize_t err;
11316+ struct au_pin pin;
11317+ struct dentry *dentry;
11318+ struct inode *inode;
4a4d8108 11319+ struct file *file, *h_file;
9dbd164d 11320+ struct super_block *sb;
1308ab2a 11321+
4a4d8108 11322+ file = kio->ki_filp;
1308ab2a 11323+ dentry = file->f_dentry;
9dbd164d 11324+ sb = dentry->d_sb;
1308ab2a 11325+ inode = dentry->d_inode;
e49829fe
JR
11326+ au_mtx_and_read_lock(inode);
11327+
4a4d8108
AM
11328+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11329+ if (unlikely(err))
1308ab2a 11330+ goto out;
1facf9fc 11331+
4a4d8108
AM
11332+ err = au_ready_to_write(file, -1, &pin);
11333+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
11334+ if (unlikely(err)) {
11335+ di_read_unlock(dentry, AuLock_IR);
11336+ fi_write_unlock(file);
11337+ goto out;
11338+ }
1facf9fc 11339+
4a4d8108 11340+ h_file = au_hf_top(file);
9dbd164d
AM
11341+ get_file(h_file);
11342+ au_unpin(&pin);
11343+ di_read_unlock(dentry, AuLock_IR);
11344+ fi_write_unlock(file);
11345+
4a4d8108 11346+ err = au_do_aio(h_file, MAY_WRITE, kio, iov, nv, pos);
9dbd164d 11347+ ii_write_lock_child(inode);
4a4d8108
AM
11348+ au_cpup_attr_timesizes(inode);
11349+ inode->i_mode = h_file->f_dentry->d_inode->i_mode;
9dbd164d
AM
11350+ ii_write_unlock(inode);
11351+ fput(h_file);
1facf9fc 11352+
4f0767ce 11353+out:
9dbd164d 11354+ si_read_unlock(sb);
4a4d8108 11355+ mutex_unlock(&inode->i_mutex);
dece6358 11356+ return err;
1facf9fc 11357+}
11358+
4a4d8108
AM
11359+static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
11360+ struct pipe_inode_info *pipe, size_t len,
11361+ unsigned int flags)
1facf9fc 11362+{
4a4d8108
AM
11363+ ssize_t err;
11364+ struct file *h_file;
11365+ struct dentry *dentry;
dece6358 11366+ struct super_block *sb;
1facf9fc 11367+
dece6358 11368+ dentry = file->f_dentry;
dece6358 11369+ sb = dentry->d_sb;
e49829fe 11370+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
11371+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
11372+ if (unlikely(err))
dece6358 11373+ goto out;
1facf9fc 11374+
4a4d8108
AM
11375+ err = -EINVAL;
11376+ h_file = au_hf_top(file);
9dbd164d 11377+ get_file(h_file);
4a4d8108 11378+ if (au_test_loopback_kthread()) {
87a755f4
AM
11379+ au_warn_loopback(h_file->f_dentry->d_sb);
11380+ if (file->f_mapping != h_file->f_mapping) {
11381+ file->f_mapping = h_file->f_mapping;
11382+ smp_mb(); /* unnecessary? */
11383+ }
1308ab2a 11384+ }
9dbd164d
AM
11385+ di_read_unlock(dentry, AuLock_IR);
11386+ fi_read_unlock(file);
11387+
4a4d8108
AM
11388+ err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
11389+ /* todo: necessasry? */
11390+ /* file->f_ra = h_file->f_ra; */
9dbd164d 11391+ /* update without lock, I don't think it a problem */
4a4d8108 11392+ fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
9dbd164d 11393+ fput(h_file);
1facf9fc 11394+
4f0767ce 11395+out:
4a4d8108 11396+ si_read_unlock(sb);
dece6358 11397+ return err;
1facf9fc 11398+}
11399+
4a4d8108
AM
11400+static ssize_t
11401+aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
11402+ size_t len, unsigned int flags)
1facf9fc 11403+{
4a4d8108
AM
11404+ ssize_t err;
11405+ struct au_pin pin;
11406+ struct dentry *dentry;
11407+ struct inode *inode;
4a4d8108 11408+ struct file *h_file;
9dbd164d 11409+ struct super_block *sb;
1facf9fc 11410+
4a4d8108 11411+ dentry = file->f_dentry;
9dbd164d 11412+ sb = dentry->d_sb;
4a4d8108 11413+ inode = dentry->d_inode;
e49829fe 11414+ au_mtx_and_read_lock(inode);
9dbd164d 11415+
4a4d8108
AM
11416+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11417+ if (unlikely(err))
11418+ goto out;
1facf9fc 11419+
4a4d8108
AM
11420+ err = au_ready_to_write(file, -1, &pin);
11421+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
11422+ if (unlikely(err)) {
11423+ di_read_unlock(dentry, AuLock_IR);
11424+ fi_write_unlock(file);
11425+ goto out;
11426+ }
1facf9fc 11427+
4a4d8108 11428+ h_file = au_hf_top(file);
9dbd164d 11429+ get_file(h_file);
4a4d8108 11430+ au_unpin(&pin);
9dbd164d
AM
11431+ di_read_unlock(dentry, AuLock_IR);
11432+ fi_write_unlock(file);
11433+
4a4d8108 11434+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
9dbd164d 11435+ ii_write_lock_child(inode);
4a4d8108
AM
11436+ au_cpup_attr_timesizes(inode);
11437+ inode->i_mode = h_file->f_dentry->d_inode->i_mode;
9dbd164d
AM
11438+ ii_write_unlock(inode);
11439+ fput(h_file);
1facf9fc 11440+
4f0767ce 11441+out:
9dbd164d 11442+ si_read_unlock(sb);
4a4d8108
AM
11443+ mutex_unlock(&inode->i_mutex);
11444+ return err;
11445+}
1facf9fc 11446+
4a4d8108
AM
11447+/* ---------------------------------------------------------------------- */
11448+
9dbd164d
AM
11449+/*
11450+ * The locking order around current->mmap_sem.
11451+ * - in most and regular cases
11452+ * file I/O syscall -- aufs_read() or something
11453+ * -- si_rwsem for read -- mmap_sem
11454+ * (Note that [fdi]i_rwsem are released before mmap_sem).
11455+ * - in mmap case
11456+ * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem
11457+ * This AB-BA order is definitly bad, but is not a problem since "si_rwsem for
11458+ * read" allows muliple processes to acquire it and [fdi]i_rwsem are not held in
11459+ * file I/O. Aufs needs to stop lockdep in aufs_mmap() though.
11460+ * It means that when aufs acquires si_rwsem for write, the process should never
11461+ * acquire mmap_sem.
11462+ *
11463+ * Actually aufs_readdir() holds [fdi]i_rwsem before mmap_sem, but this is not a
11464+ * problem either since any directory is not able to be mmap-ed.
11465+ * The similar scenario is applied to aufs_readlink() too.
11466+ */
11467+
2dfbb274
AM
11468+/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
11469+#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b)
11470+
11471+static unsigned long au_arch_prot_conv(unsigned long flags)
11472+{
11473+ /* currently ppc64 only */
11474+#ifdef CONFIG_PPC64
11475+ /* cf. linux/arch/powerpc/include/asm/mman.h */
11476+ AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO);
11477+ return AuConv_VM_PROT(flags, SAO);
11478+#else
11479+ AuDebugOn(arch_calc_vm_prot_bits(-1));
11480+ return 0;
11481+#endif
11482+}
11483+
11484+static unsigned long au_prot_conv(unsigned long flags)
11485+{
11486+ return AuConv_VM_PROT(flags, READ)
11487+ | AuConv_VM_PROT(flags, WRITE)
11488+ | AuConv_VM_PROT(flags, EXEC)
11489+ | au_arch_prot_conv(flags);
11490+}
11491+
11492+/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */
11493+#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b)
11494+
11495+static unsigned long au_flag_conv(unsigned long flags)
11496+{
11497+ return AuConv_VM_MAP(flags, GROWSDOWN)
11498+ | AuConv_VM_MAP(flags, DENYWRITE)
2dfbb274
AM
11499+ | AuConv_VM_MAP(flags, LOCKED);
11500+}
11501+
9dbd164d 11502+static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
dece6358 11503+{
4a4d8108
AM
11504+ int err;
11505+ aufs_bindex_t bstart;
11506+ const unsigned char wlock
9dbd164d 11507+ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
4a4d8108
AM
11508+ struct dentry *dentry;
11509+ struct super_block *sb;
9dbd164d
AM
11510+ struct file *h_file;
11511+ struct au_branch *br;
11512+ struct au_pin pin;
11513+
11514+ AuDbgVmRegion(file, vma);
1308ab2a 11515+
4a4d8108
AM
11516+ dentry = file->f_dentry;
11517+ sb = dentry->d_sb;
9dbd164d 11518+ lockdep_off();
e49829fe 11519+ si_read_lock(sb, AuLock_NOPLMW);
4a4d8108
AM
11520+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11521+ if (unlikely(err))
11522+ goto out;
11523+
4a4d8108 11524+ if (wlock) {
4a4d8108
AM
11525+ err = au_ready_to_write(file, -1, &pin);
11526+ di_write_unlock(dentry);
9dbd164d
AM
11527+ if (unlikely(err)) {
11528+ fi_write_unlock(file);
11529+ goto out;
11530+ }
4a4d8108
AM
11531+ au_unpin(&pin);
11532+ } else
11533+ di_write_unlock(dentry);
9dbd164d 11534+
4a4d8108 11535+ bstart = au_fbstart(file);
9dbd164d
AM
11536+ br = au_sbr(sb, bstart);
11537+ h_file = au_hf_top(file);
11538+ get_file(h_file);
2cbb1c4b 11539+ au_set_mmapped(file);
4a4d8108 11540+ fi_write_unlock(file);
9dbd164d 11541+ lockdep_on();
1308ab2a 11542+
9dbd164d 11543+ au_vm_file_reset(vma, h_file);
2dfbb274
AM
11544+ err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
11545+ au_flag_conv(vma->vm_flags));
9dbd164d
AM
11546+ if (!err)
11547+ err = h_file->f_op->mmap(h_file, vma);
2cbb1c4b
JR
11548+ if (unlikely(err))
11549+ goto out_reset;
4a4d8108 11550+
2cbb1c4b 11551+ au_vm_prfile_set(vma, file);
4a4d8108 11552+ /* update without lock, I don't think it a problem */
2cbb1c4b 11553+ fsstack_copy_attr_atime(file->f_dentry->d_inode,
9dbd164d 11554+ h_file->f_dentry->d_inode);
2cbb1c4b 11555+ goto out_fput; /* success */
4a4d8108 11556+
2cbb1c4b
JR
11557+out_reset:
11558+ au_unset_mmapped(file);
11559+ au_vm_file_reset(vma, file);
11560+out_fput:
9dbd164d
AM
11561+ fput(h_file);
11562+ lockdep_off();
4f0767ce 11563+out:
9dbd164d
AM
11564+ si_read_unlock(sb);
11565+ lockdep_on();
11566+ AuTraceErr(err);
4a4d8108
AM
11567+ return err;
11568+}
11569+
11570+/* ---------------------------------------------------------------------- */
11571+
1e00d052
AM
11572+static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end,
11573+ int datasync)
4a4d8108
AM
11574+{
11575+ int err;
11576+ struct au_pin pin;
b752ccd1 11577+ struct dentry *dentry;
4a4d8108
AM
11578+ struct inode *inode;
11579+ struct file *h_file;
11580+ struct super_block *sb;
11581+
b752ccd1 11582+ dentry = file->f_dentry;
4a4d8108 11583+ inode = dentry->d_inode;
4a4d8108 11584+ sb = dentry->d_sb;
1e00d052 11585+ mutex_lock(&inode->i_mutex);
e49829fe
JR
11586+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
11587+ if (unlikely(err))
11588+ goto out;
4a4d8108
AM
11589+
11590+ err = 0; /* -EBADF; */ /* posix? */
11591+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
e49829fe 11592+ goto out_si;
4a4d8108
AM
11593+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11594+ if (unlikely(err))
e49829fe 11595+ goto out_si;
4a4d8108
AM
11596+
11597+ err = au_ready_to_write(file, -1, &pin);
11598+ di_downgrade_lock(dentry, AuLock_IR);
11599+ if (unlikely(err))
11600+ goto out_unlock;
11601+ au_unpin(&pin);
11602+
11603+ err = -EINVAL;
11604+ h_file = au_hf_top(file);
53392da6
AM
11605+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
11606+ au_cpup_attr_timesizes(inode);
4a4d8108 11607+
4f0767ce 11608+out_unlock:
4a4d8108 11609+ di_read_unlock(dentry, AuLock_IR);
1308ab2a 11610+ fi_write_unlock(file);
e49829fe 11611+out_si:
953406b4 11612+ si_read_unlock(sb);
e49829fe 11613+out:
1e00d052 11614+ mutex_unlock(&inode->i_mutex);
4a4d8108 11615+ return err;
dece6358
AM
11616+}
11617+
4a4d8108
AM
11618+/* no one supports this operation, currently */
11619+#if 0
11620+static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync)
dece6358 11621+{
4a4d8108
AM
11622+ int err;
11623+ struct au_pin pin;
1308ab2a 11624+ struct dentry *dentry;
4a4d8108
AM
11625+ struct inode *inode;
11626+ struct file *file, *h_file;
1308ab2a 11627+
4a4d8108 11628+ file = kio->ki_filp;
1308ab2a 11629+ dentry = file->f_dentry;
4a4d8108 11630+ inode = dentry->d_inode;
e49829fe 11631+ au_mtx_and_read_lock(inode);
4a4d8108
AM
11632+
11633+ err = 0; /* -EBADF; */ /* posix? */
11634+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
11635+ goto out;
11636+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11637+ if (unlikely(err))
1308ab2a 11638+ goto out;
11639+
4a4d8108
AM
11640+ err = au_ready_to_write(file, -1, &pin);
11641+ di_downgrade_lock(dentry, AuLock_IR);
11642+ if (unlikely(err))
11643+ goto out_unlock;
11644+ au_unpin(&pin);
1308ab2a 11645+
4a4d8108
AM
11646+ err = -ENOSYS;
11647+ h_file = au_hf_top(file);
11648+ if (h_file->f_op && h_file->f_op->aio_fsync) {
11649+ struct dentry *h_d;
11650+ struct mutex *h_mtx;
1308ab2a 11651+
4a4d8108
AM
11652+ h_d = h_file->f_dentry;
11653+ h_mtx = &h_d->d_inode->i_mutex;
11654+ if (!is_sync_kiocb(kio)) {
11655+ get_file(h_file);
11656+ fput(file);
11657+ }
11658+ kio->ki_filp = h_file;
11659+ err = h_file->f_op->aio_fsync(kio, datasync);
11660+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
11661+ if (!err)
11662+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
11663+ /*ignore*/
11664+ au_cpup_attr_timesizes(inode);
11665+ mutex_unlock(h_mtx);
11666+ }
1308ab2a 11667+
4f0767ce 11668+out_unlock:
4a4d8108
AM
11669+ di_read_unlock(dentry, AuLock_IR);
11670+ fi_write_unlock(file);
4f0767ce 11671+out:
e49829fe 11672+ si_read_unlock(inode->sb);
4a4d8108
AM
11673+ mutex_unlock(&inode->i_mutex);
11674+ return err;
dece6358 11675+}
4a4d8108 11676+#endif
dece6358 11677+
4a4d8108 11678+static int aufs_fasync(int fd, struct file *file, int flag)
dece6358 11679+{
4a4d8108
AM
11680+ int err;
11681+ struct file *h_file;
11682+ struct dentry *dentry;
11683+ struct super_block *sb;
1308ab2a 11684+
4a4d8108
AM
11685+ dentry = file->f_dentry;
11686+ sb = dentry->d_sb;
e49829fe 11687+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
11688+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
11689+ if (unlikely(err))
11690+ goto out;
11691+
11692+ h_file = au_hf_top(file);
11693+ if (h_file->f_op && h_file->f_op->fasync)
11694+ err = h_file->f_op->fasync(fd, h_file, flag);
11695+
11696+ di_read_unlock(dentry, AuLock_IR);
11697+ fi_read_unlock(file);
1308ab2a 11698+
4f0767ce 11699+out:
4a4d8108 11700+ si_read_unlock(sb);
1308ab2a 11701+ return err;
dece6358 11702+}
4a4d8108
AM
11703+
11704+/* ---------------------------------------------------------------------- */
11705+
11706+/* no one supports this operation, currently */
11707+#if 0
11708+static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
11709+ size_t len, loff_t *pos , int more)
11710+{
11711+}
11712+#endif
11713+
11714+/* ---------------------------------------------------------------------- */
11715+
11716+const struct file_operations aufs_file_fop = {
11717+ .owner = THIS_MODULE,
2cbb1c4b 11718+
027c5e7a 11719+ .llseek = default_llseek,
4a4d8108
AM
11720+
11721+ .read = aufs_read,
11722+ .write = aufs_write,
11723+ .aio_read = aufs_aio_read,
11724+ .aio_write = aufs_aio_write,
11725+#ifdef CONFIG_AUFS_POLL
11726+ .poll = aufs_poll,
11727+#endif
11728+ .unlocked_ioctl = aufs_ioctl_nondir,
b752ccd1
AM
11729+#ifdef CONFIG_COMPAT
11730+ .compat_ioctl = aufs_ioctl_nondir, /* same */
11731+#endif
4a4d8108
AM
11732+ .mmap = aufs_mmap,
11733+ .open = aufs_open_nondir,
11734+ .flush = aufs_flush_nondir,
11735+ .release = aufs_release_nondir,
11736+ .fsync = aufs_fsync_nondir,
11737+ /* .aio_fsync = aufs_aio_fsync_nondir, */
11738+ .fasync = aufs_fasync,
11739+ /* .sendpage = aufs_sendpage, */
11740+ .splice_write = aufs_splice_write,
11741+ .splice_read = aufs_splice_read,
11742+#if 0
11743+ .aio_splice_write = aufs_aio_splice_write,
11744+ .aio_splice_read = aufs_aio_splice_read
11745+#endif
11746+};
7f207e10
AM
11747diff -urN /usr/share/empty/fs/aufs/f_op_sp.c linux/fs/aufs/f_op_sp.c
11748--- /usr/share/empty/fs/aufs/f_op_sp.c 1970-01-01 01:00:00.000000000 +0100
a2a7ad62 11749+++ linux/fs/aufs/f_op_sp.c 2013-03-14 20:07:41.041453062 +0100
0c3ec466 11750@@ -0,0 +1,295 @@
1308ab2a 11751+/*
7a9e40b8 11752+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1308ab2a 11753+ *
11754+ * This program, aufs is free software; you can redistribute it and/or modify
11755+ * it under the terms of the GNU General Public License as published by
11756+ * the Free Software Foundation; either version 2 of the License, or
11757+ * (at your option) any later version.
11758+ *
11759+ * This program is distributed in the hope that it will be useful,
11760+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11761+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11762+ * GNU General Public License for more details.
11763+ *
11764+ * You should have received a copy of the GNU General Public License
11765+ * along with this program; if not, write to the Free Software
11766+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11767+ */
dece6358 11768+
1308ab2a 11769+/*
4a4d8108
AM
11770+ * file operations for special files.
11771+ * while they exist in aufs virtually,
11772+ * their file I/O is handled out of aufs.
1308ab2a 11773+ */
11774+
4a4d8108 11775+#include "aufs.h"
1308ab2a 11776+
4a4d8108
AM
11777+static ssize_t aufs_aio_read_sp(struct kiocb *kio, const struct iovec *iov,
11778+ unsigned long nv, loff_t pos)
dece6358 11779+{
4a4d8108
AM
11780+ ssize_t err;
11781+ aufs_bindex_t bstart;
11782+ unsigned char wbr;
11783+ struct file *file, *h_file;
11784+ struct super_block *sb;
1308ab2a 11785+
4a4d8108
AM
11786+ file = kio->ki_filp;
11787+ sb = file->f_dentry->d_sb;
11788+ si_read_lock(sb, AuLock_FLUSH);
11789+ fi_read_lock(file);
11790+ bstart = au_fbstart(file);
11791+ h_file = au_hf_top(file);
11792+ fi_read_unlock(file);
11793+ wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
11794+ si_read_unlock(sb);
11795+
11796+ /* do not change the file in kio */
11797+ AuDebugOn(!h_file->f_op || !h_file->f_op->aio_read);
11798+ err = h_file->f_op->aio_read(kio, iov, nv, pos);
11799+ if (err > 0 && wbr)
11800+ file_accessed(h_file);
11801+
11802+ return err;
11803+}
11804+
11805+static ssize_t aufs_aio_write_sp(struct kiocb *kio, const struct iovec *iov,
11806+ unsigned long nv, loff_t pos)
11807+{
11808+ ssize_t err;
11809+ aufs_bindex_t bstart;
11810+ unsigned char wbr;
11811+ struct super_block *sb;
11812+ struct file *file, *h_file;
11813+
11814+ file = kio->ki_filp;
11815+ sb = file->f_dentry->d_sb;
11816+ si_read_lock(sb, AuLock_FLUSH);
11817+ fi_read_lock(file);
11818+ bstart = au_fbstart(file);
11819+ h_file = au_hf_top(file);
11820+ fi_read_unlock(file);
11821+ wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
11822+ si_read_unlock(sb);
11823+
11824+ /* do not change the file in kio */
11825+ AuDebugOn(!h_file->f_op || !h_file->f_op->aio_write);
11826+ err = h_file->f_op->aio_write(kio, iov, nv, pos);
4a4d8108
AM
11827+ return err;
11828+}
11829+
11830+/* ---------------------------------------------------------------------- */
11831+
11832+static int aufs_release_sp(struct inode *inode, struct file *file)
11833+{
11834+ int err;
11835+ struct file *h_file;
11836+
11837+ fi_read_lock(file);
11838+ h_file = au_hf_top(file);
11839+ fi_read_unlock(file);
11840+ /* close this fifo in aufs */
11841+ err = h_file->f_op->release(inode, file); /* ignore */
11842+ aufs_release_nondir(inode, file); /* ignore */
11843+ return err;
11844+}
11845+
11846+/* ---------------------------------------------------------------------- */
11847+
11848+/* currently, support only FIFO */
4f0767ce
JR
11849+enum {
11850+ AuSp_FIFO, AuSp_FIFO_R, AuSp_FIFO_W, AuSp_FIFO_RW,
11851+ /* AuSp_SOCK, AuSp_CHR, AuSp_BLK, */
11852+ AuSp_Last
11853+};
4a4d8108
AM
11854+static int aufs_open_sp(struct inode *inode, struct file *file);
11855+static struct au_sp_fop {
11856+ int done;
11857+ struct file_operations fop; /* not 'const' */
11858+ spinlock_t spin;
11859+} au_sp_fop[AuSp_Last] = {
11860+ [AuSp_FIFO] = {
11861+ .fop = {
11862+ .owner = THIS_MODULE,
11863+ .open = aufs_open_sp
11864+ }
11865+ }
11866+};
11867+
11868+static void au_init_fop_sp(struct file *file)
11869+{
11870+ struct au_sp_fop *p;
11871+ int i;
11872+ struct file *h_file;
11873+
11874+ p = au_sp_fop;
11875+ if (unlikely(!p->done)) {
11876+ /* initialize first time only */
11877+ static DEFINE_SPINLOCK(spin);
11878+
11879+ spin_lock(&spin);
11880+ if (!p->done) {
11881+ BUILD_BUG_ON(sizeof(au_sp_fop)/sizeof(*au_sp_fop)
11882+ != AuSp_Last);
11883+ for (i = 0; i < AuSp_Last; i++)
11884+ spin_lock_init(&p[i].spin);
11885+ p->done = 1;
11886+ }
11887+ spin_unlock(&spin);
11888+ }
11889+
11890+ switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) {
11891+ case FMODE_READ:
11892+ i = AuSp_FIFO_R;
11893+ break;
11894+ case FMODE_WRITE:
11895+ i = AuSp_FIFO_W;
11896+ break;
11897+ case FMODE_READ | FMODE_WRITE:
11898+ i = AuSp_FIFO_RW;
11899+ break;
11900+ default:
11901+ BUG();
11902+ }
11903+
11904+ p += i;
11905+ if (unlikely(!p->done)) {
11906+ /* initialize first time only */
11907+ h_file = au_hf_top(file);
11908+ spin_lock(&p->spin);
11909+ if (!p->done) {
11910+ p->fop = *h_file->f_op;
11911+ p->fop.owner = THIS_MODULE;
11912+ if (p->fop.aio_read)
11913+ p->fop.aio_read = aufs_aio_read_sp;
11914+ if (p->fop.aio_write)
11915+ p->fop.aio_write = aufs_aio_write_sp;
11916+ p->fop.release = aufs_release_sp;
11917+ p->done = 1;
11918+ }
11919+ spin_unlock(&p->spin);
11920+ }
11921+ file->f_op = &p->fop;
11922+}
11923+
11924+static int au_cpup_sp(struct dentry *dentry)
11925+{
11926+ int err;
11927+ aufs_bindex_t bcpup;
11928+ struct au_pin pin;
11929+ struct au_wr_dir_args wr_dir_args = {
11930+ .force_btgt = -1,
11931+ .flags = 0
11932+ };
11933+
11934+ AuDbg("%.*s\n", AuDLNPair(dentry));
11935+
11936+ di_read_unlock(dentry, AuLock_IR);
11937+ di_write_lock_child(dentry);
11938+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
11939+ if (unlikely(err < 0))
11940+ goto out;
11941+ bcpup = err;
11942+ err = 0;
11943+ if (bcpup == au_dbstart(dentry))
11944+ goto out; /* success */
11945+
11946+ err = au_pin(&pin, dentry, bcpup, au_opt_udba(dentry->d_sb),
11947+ AuPin_MNT_WRITE);
11948+ if (!err) {
11949+ err = au_sio_cpup_simple(dentry, bcpup, -1, AuCpup_DTIME);
11950+ au_unpin(&pin);
11951+ }
11952+
4f0767ce 11953+out:
4a4d8108
AM
11954+ di_downgrade_lock(dentry, AuLock_IR);
11955+ return err;
11956+}
11957+
11958+static int au_do_open_sp(struct file *file, int flags)
11959+{
11960+ int err;
11961+ struct dentry *dentry;
11962+ struct super_block *sb;
11963+ struct file *h_file;
11964+ struct inode *h_inode;
11965+
11966+ dentry = file->f_dentry;
11967+ AuDbg("%.*s\n", AuDLNPair(dentry));
11968+
11969+ /*
11970+ * try copying-up.
11971+ * operate on the ro branch is not an error.
11972+ */
11973+ au_cpup_sp(dentry); /* ignore */
11974+
11975+ /* prepare h_file */
11976+ err = au_do_open_nondir(file, vfsub_file_flags(file));
11977+ if (unlikely(err))
11978+ goto out;
11979+
11980+ sb = dentry->d_sb;
11981+ h_file = au_hf_top(file);
11982+ h_inode = h_file->f_dentry->d_inode;
11983+ di_read_unlock(dentry, AuLock_IR);
11984+ fi_write_unlock(file);
11985+ si_read_unlock(sb);
11986+ /* open this fifo in aufs */
11987+ err = h_inode->i_fop->open(file->f_dentry->d_inode, file);
11988+ si_noflush_read_lock(sb);
11989+ fi_write_lock(file);
11990+ di_read_lock_child(dentry, AuLock_IR);
11991+ if (!err)
11992+ au_init_fop_sp(file);
4a4d8108 11993+
4f0767ce 11994+out:
4a4d8108
AM
11995+ return err;
11996+}
11997+
11998+static int aufs_open_sp(struct inode *inode, struct file *file)
11999+{
12000+ int err;
12001+ struct super_block *sb;
12002+
12003+ sb = file->f_dentry->d_sb;
12004+ si_read_lock(sb, AuLock_FLUSH);
12005+ err = au_do_open(file, au_do_open_sp, /*fidir*/NULL);
12006+ si_read_unlock(sb);
12007+ return err;
12008+}
12009+
12010+/* ---------------------------------------------------------------------- */
12011+
12012+void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev)
12013+{
12014+ init_special_inode(inode, mode, rdev);
12015+
12016+ switch (mode & S_IFMT) {
12017+ case S_IFIFO:
12018+ inode->i_fop = &au_sp_fop[AuSp_FIFO].fop;
12019+ /*FALLTHROUGH*/
12020+ case S_IFCHR:
12021+ case S_IFBLK:
12022+ case S_IFSOCK:
12023+ break;
12024+ default:
12025+ AuDebugOn(1);
12026+ }
12027+}
12028+
12029+int au_special_file(umode_t mode)
12030+{
12031+ int ret;
12032+
12033+ ret = 0;
12034+ switch (mode & S_IFMT) {
12035+ case S_IFIFO:
12036+#if 0
12037+ case S_IFCHR:
12038+ case S_IFBLK:
12039+ case S_IFSOCK:
12040+#endif
12041+ ret = 1;
12042+ }
12043+
12044+ return ret;
12045+}
7f207e10
AM
12046diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
12047--- /usr/share/empty/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100
1716fcea 12048+++ linux/fs/aufs/fstype.h 2013-02-19 08:40:03.946892891 +0100
b4510431 12049@@ -0,0 +1,481 @@
4a4d8108 12050+/*
7a9e40b8 12051+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
12052+ *
12053+ * This program, aufs is free software; you can redistribute it and/or modify
12054+ * it under the terms of the GNU General Public License as published by
12055+ * the Free Software Foundation; either version 2 of the License, or
12056+ * (at your option) any later version.
12057+ *
12058+ * This program is distributed in the hope that it will be useful,
12059+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12060+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12061+ * GNU General Public License for more details.
12062+ *
12063+ * You should have received a copy of the GNU General Public License
12064+ * along with this program; if not, write to the Free Software
12065+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12066+ */
12067+
12068+/*
12069+ * judging filesystem type
12070+ */
12071+
12072+#ifndef __AUFS_FSTYPE_H__
12073+#define __AUFS_FSTYPE_H__
12074+
12075+#ifdef __KERNEL__
12076+
12077+#include <linux/fs.h>
12078+#include <linux/magic.h>
12079+#include <linux/romfs_fs.h>
4a4d8108
AM
12080+
12081+static inline int au_test_aufs(struct super_block *sb)
12082+{
12083+ return sb->s_magic == AUFS_SUPER_MAGIC;
12084+}
12085+
12086+static inline const char *au_sbtype(struct super_block *sb)
12087+{
12088+ return sb->s_type->name;
12089+}
1308ab2a 12090+
12091+static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
12092+{
12093+#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE)
12094+ return sb->s_magic == ROMFS_MAGIC;
dece6358
AM
12095+#else
12096+ return 0;
12097+#endif
12098+}
12099+
1308ab2a 12100+static inline int au_test_romfs(struct super_block *sb __maybe_unused)
dece6358 12101+{
1308ab2a 12102+#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE)
12103+ return sb->s_magic == ISOFS_SUPER_MAGIC;
dece6358
AM
12104+#else
12105+ return 0;
12106+#endif
12107+}
12108+
1308ab2a 12109+static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
dece6358 12110+{
1308ab2a 12111+#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE)
12112+ return sb->s_magic == CRAMFS_MAGIC;
12113+#endif
12114+ return 0;
12115+}
12116+
12117+static inline int au_test_nfs(struct super_block *sb __maybe_unused)
12118+{
12119+#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE)
12120+ return sb->s_magic == NFS_SUPER_MAGIC;
dece6358
AM
12121+#else
12122+ return 0;
12123+#endif
12124+}
12125+
1308ab2a 12126+static inline int au_test_fuse(struct super_block *sb __maybe_unused)
dece6358 12127+{
1308ab2a 12128+#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE)
12129+ return sb->s_magic == FUSE_SUPER_MAGIC;
dece6358
AM
12130+#else
12131+ return 0;
12132+#endif
12133+}
12134+
1308ab2a 12135+static inline int au_test_xfs(struct super_block *sb __maybe_unused)
dece6358 12136+{
1308ab2a 12137+#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE)
12138+ return sb->s_magic == XFS_SB_MAGIC;
dece6358
AM
12139+#else
12140+ return 0;
12141+#endif
12142+}
12143+
1308ab2a 12144+static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
dece6358 12145+{
1308ab2a 12146+#ifdef CONFIG_TMPFS
12147+ return sb->s_magic == TMPFS_MAGIC;
12148+#else
12149+ return 0;
dece6358 12150+#endif
dece6358
AM
12151+}
12152+
1308ab2a 12153+static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
1facf9fc 12154+{
1308ab2a 12155+#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE)
12156+ return !strcmp(au_sbtype(sb), "ecryptfs");
12157+#else
12158+ return 0;
12159+#endif
1facf9fc 12160+}
12161+
1308ab2a 12162+static inline int au_test_smbfs(struct super_block *sb __maybe_unused)
1facf9fc 12163+{
1308ab2a 12164+#if defined(CONFIG_SMB_FS) || defined(CONFIG_SMB_FS_MODULE)
12165+ return sb->s_magic == SMB_SUPER_MAGIC;
12166+#else
12167+ return 0;
1facf9fc 12168+#endif
1facf9fc 12169+}
12170+
1308ab2a 12171+static inline int au_test_ocfs2(struct super_block *sb __maybe_unused)
1facf9fc 12172+{
1308ab2a 12173+#if defined(CONFIG_OCFS2_FS) || defined(CONFIG_OCFS2_FS_MODULE)
12174+ return sb->s_magic == OCFS2_SUPER_MAGIC;
12175+#else
12176+ return 0;
12177+#endif
1facf9fc 12178+}
12179+
1308ab2a 12180+static inline int au_test_ocfs2_dlmfs(struct super_block *sb __maybe_unused)
1facf9fc 12181+{
1308ab2a 12182+#if defined(CONFIG_OCFS2_FS_O2CB) || defined(CONFIG_OCFS2_FS_O2CB_MODULE)
12183+ return sb->s_magic == DLMFS_MAGIC;
12184+#else
12185+ return 0;
12186+#endif
1facf9fc 12187+}
12188+
1308ab2a 12189+static inline int au_test_coda(struct super_block *sb __maybe_unused)
1facf9fc 12190+{
1308ab2a 12191+#if defined(CONFIG_CODA_FS) || defined(CONFIG_CODA_FS_MODULE)
12192+ return sb->s_magic == CODA_SUPER_MAGIC;
12193+#else
12194+ return 0;
12195+#endif
12196+}
12197+
12198+static inline int au_test_v9fs(struct super_block *sb __maybe_unused)
12199+{
12200+#if defined(CONFIG_9P_FS) || defined(CONFIG_9P_FS_MODULE)
12201+ return sb->s_magic == V9FS_MAGIC;
12202+#else
12203+ return 0;
12204+#endif
12205+}
12206+
12207+static inline int au_test_ext4(struct super_block *sb __maybe_unused)
12208+{
12209+#if defined(CONFIG_EXT4DEV_FS) || defined(CONFIG_EXT4DEV_FS_MODULE)
12210+ return sb->s_magic == EXT4_SUPER_MAGIC;
12211+#else
12212+ return 0;
12213+#endif
12214+}
12215+
12216+static inline int au_test_sysv(struct super_block *sb __maybe_unused)
12217+{
12218+#if defined(CONFIG_SYSV_FS) || defined(CONFIG_SYSV_FS_MODULE)
12219+ return !strcmp(au_sbtype(sb), "sysv");
12220+#else
12221+ return 0;
12222+#endif
12223+}
12224+
12225+static inline int au_test_ramfs(struct super_block *sb)
12226+{
12227+ return sb->s_magic == RAMFS_MAGIC;
12228+}
12229+
12230+static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
12231+{
12232+#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE)
12233+ return sb->s_magic == UBIFS_SUPER_MAGIC;
12234+#else
12235+ return 0;
12236+#endif
12237+}
12238+
12239+static inline int au_test_procfs(struct super_block *sb __maybe_unused)
12240+{
12241+#ifdef CONFIG_PROC_FS
12242+ return sb->s_magic == PROC_SUPER_MAGIC;
12243+#else
12244+ return 0;
12245+#endif
12246+}
12247+
12248+static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
12249+{
12250+#ifdef CONFIG_SYSFS
12251+ return sb->s_magic == SYSFS_MAGIC;
12252+#else
12253+ return 0;
12254+#endif
12255+}
12256+
12257+static inline int au_test_configfs(struct super_block *sb __maybe_unused)
12258+{
12259+#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE)
12260+ return sb->s_magic == CONFIGFS_MAGIC;
12261+#else
12262+ return 0;
12263+#endif
12264+}
12265+
12266+static inline int au_test_minix(struct super_block *sb __maybe_unused)
12267+{
12268+#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE)
12269+ return sb->s_magic == MINIX3_SUPER_MAGIC
12270+ || sb->s_magic == MINIX2_SUPER_MAGIC
12271+ || sb->s_magic == MINIX2_SUPER_MAGIC2
12272+ || sb->s_magic == MINIX_SUPER_MAGIC
12273+ || sb->s_magic == MINIX_SUPER_MAGIC2;
12274+#else
12275+ return 0;
12276+#endif
12277+}
12278+
12279+static inline int au_test_cifs(struct super_block *sb __maybe_unused)
12280+{
12281+#if defined(CONFIG_CIFS_FS) || defined(CONFIGCIFS_FS_MODULE)
12282+ return sb->s_magic == CIFS_MAGIC_NUMBER;
12283+#else
12284+ return 0;
12285+#endif
12286+}
12287+
12288+static inline int au_test_fat(struct super_block *sb __maybe_unused)
12289+{
12290+#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE)
12291+ return sb->s_magic == MSDOS_SUPER_MAGIC;
12292+#else
12293+ return 0;
12294+#endif
12295+}
12296+
12297+static inline int au_test_msdos(struct super_block *sb)
12298+{
12299+ return au_test_fat(sb);
12300+}
12301+
12302+static inline int au_test_vfat(struct super_block *sb)
12303+{
12304+ return au_test_fat(sb);
12305+}
12306+
12307+static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
12308+{
12309+#ifdef CONFIG_SECURITYFS
12310+ return sb->s_magic == SECURITYFS_MAGIC;
12311+#else
12312+ return 0;
12313+#endif
12314+}
12315+
12316+static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
12317+{
12318+#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE)
12319+ return sb->s_magic == SQUASHFS_MAGIC;
12320+#else
12321+ return 0;
12322+#endif
12323+}
12324+
12325+static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
12326+{
12327+#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE)
12328+ return sb->s_magic == BTRFS_SUPER_MAGIC;
12329+#else
12330+ return 0;
12331+#endif
12332+}
12333+
12334+static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
12335+{
12336+#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE)
12337+ return sb->s_magic == XENFS_SUPER_MAGIC;
12338+#else
12339+ return 0;
12340+#endif
12341+}
12342+
12343+static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
12344+{
12345+#ifdef CONFIG_DEBUG_FS
12346+ return sb->s_magic == DEBUGFS_MAGIC;
12347+#else
12348+ return 0;
12349+#endif
12350+}
12351+
12352+static inline int au_test_nilfs(struct super_block *sb __maybe_unused)
12353+{
12354+#if defined(CONFIG_NILFS) || defined(CONFIG_NILFS_MODULE)
12355+ return sb->s_magic == NILFS_SUPER_MAGIC;
12356+#else
12357+ return 0;
12358+#endif
12359+}
12360+
4a4d8108
AM
12361+static inline int au_test_hfsplus(struct super_block *sb __maybe_unused)
12362+{
12363+#if defined(CONFIG_HFSPLUS_FS) || defined(CONFIG_HFSPLUS_FS_MODULE)
12364+ return sb->s_magic == HFSPLUS_SUPER_MAGIC;
12365+#else
12366+ return 0;
12367+#endif
12368+}
12369+
1308ab2a 12370+/* ---------------------------------------------------------------------- */
12371+/*
12372+ * they can't be an aufs branch.
12373+ */
12374+static inline int au_test_fs_unsuppoted(struct super_block *sb)
12375+{
12376+ return
12377+#ifndef CONFIG_AUFS_BR_RAMFS
12378+ au_test_ramfs(sb) ||
12379+#endif
12380+ au_test_procfs(sb)
12381+ || au_test_sysfs(sb)
12382+ || au_test_configfs(sb)
12383+ || au_test_debugfs(sb)
12384+ || au_test_securityfs(sb)
12385+ || au_test_xenfs(sb)
12386+ || au_test_ecryptfs(sb)
12387+ /* || !strcmp(au_sbtype(sb), "unionfs") */
12388+ || au_test_aufs(sb); /* will be supported in next version */
12389+}
12390+
1308ab2a 12391+static inline int au_test_fs_remote(struct super_block *sb)
12392+{
12393+ return !au_test_tmpfs(sb)
12394+#ifdef CONFIG_AUFS_BR_RAMFS
12395+ && !au_test_ramfs(sb)
12396+#endif
12397+ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
12398+}
12399+
12400+/* ---------------------------------------------------------------------- */
12401+
12402+/*
12403+ * Note: these functions (below) are created after reading ->getattr() in all
12404+ * filesystems under linux/fs. it means we have to do so in every update...
12405+ */
12406+
12407+/*
12408+ * some filesystems require getattr to refresh the inode attributes before
12409+ * referencing.
12410+ * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
12411+ * and leave the work for d_revalidate()
12412+ */
12413+static inline int au_test_fs_refresh_iattr(struct super_block *sb)
12414+{
12415+ return au_test_nfs(sb)
12416+ || au_test_fuse(sb)
12417+ /* || au_test_smbfs(sb) */ /* untested */
12418+ /* || au_test_ocfs2(sb) */ /* untested */
12419+ /* || au_test_btrfs(sb) */ /* untested */
12420+ /* || au_test_coda(sb) */ /* untested */
12421+ /* || au_test_v9fs(sb) */ /* untested */
12422+ ;
12423+}
12424+
12425+/*
12426+ * filesystems which don't maintain i_size or i_blocks.
12427+ */
12428+static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
12429+{
12430+ return au_test_xfs(sb)
4a4d8108
AM
12431+ || au_test_btrfs(sb)
12432+ || au_test_ubifs(sb)
12433+ || au_test_hfsplus(sb) /* maintained, but incorrect */
1308ab2a 12434+ /* || au_test_ext4(sb) */ /* untested */
12435+ /* || au_test_ocfs2(sb) */ /* untested */
12436+ /* || au_test_ocfs2_dlmfs(sb) */ /* untested */
12437+ /* || au_test_sysv(sb) */ /* untested */
1308ab2a 12438+ /* || au_test_minix(sb) */ /* untested */
12439+ ;
12440+}
12441+
12442+/*
12443+ * filesystems which don't store the correct value in some of their inode
12444+ * attributes.
12445+ */
12446+static inline int au_test_fs_bad_iattr(struct super_block *sb)
12447+{
12448+ return au_test_fs_bad_iattr_size(sb)
12449+ /* || au_test_cifs(sb) */ /* untested */
12450+ || au_test_fat(sb)
12451+ || au_test_msdos(sb)
12452+ || au_test_vfat(sb);
1facf9fc 12453+}
12454+
12455+/* they don't check i_nlink in link(2) */
12456+static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
12457+{
12458+ return au_test_tmpfs(sb)
12459+#ifdef CONFIG_AUFS_BR_RAMFS
12460+ || au_test_ramfs(sb)
12461+#endif
4a4d8108
AM
12462+ || au_test_ubifs(sb)
12463+ || au_test_btrfs(sb)
12464+ || au_test_hfsplus(sb);
1facf9fc 12465+}
12466+
12467+/*
12468+ * filesystems which sets S_NOATIME and S_NOCMTIME.
12469+ */
12470+static inline int au_test_fs_notime(struct super_block *sb)
12471+{
12472+ return au_test_nfs(sb)
12473+ || au_test_fuse(sb)
dece6358 12474+ || au_test_ubifs(sb)
1facf9fc 12475+ /* || au_test_cifs(sb) */ /* untested */
1facf9fc 12476+ ;
12477+}
12478+
12479+/*
12480+ * filesystems which requires replacing i_mapping.
12481+ */
12482+static inline int au_test_fs_bad_mapping(struct super_block *sb)
12483+{
dece6358
AM
12484+ return au_test_fuse(sb)
12485+ || au_test_ubifs(sb);
1facf9fc 12486+}
12487+
12488+/* temporary support for i#1 in cramfs */
12489+static inline int au_test_fs_unique_ino(struct inode *inode)
12490+{
12491+ if (au_test_cramfs(inode->i_sb))
12492+ return inode->i_ino != 1;
12493+ return 1;
12494+}
12495+
12496+/* ---------------------------------------------------------------------- */
12497+
12498+/*
12499+ * the filesystem where the xino files placed must support i/o after unlink and
12500+ * maintain i_size and i_blocks.
12501+ */
12502+static inline int au_test_fs_bad_xino(struct super_block *sb)
12503+{
12504+ return au_test_fs_remote(sb)
12505+ || au_test_fs_bad_iattr_size(sb)
1facf9fc 12506+ /* don't want unnecessary work for xino */
12507+ || au_test_aufs(sb)
1308ab2a 12508+ || au_test_ecryptfs(sb)
12509+ || au_test_nilfs(sb);
1facf9fc 12510+}
12511+
12512+static inline int au_test_fs_trunc_xino(struct super_block *sb)
12513+{
12514+ return au_test_tmpfs(sb)
12515+ || au_test_ramfs(sb);
12516+}
12517+
12518+/*
12519+ * test if the @sb is real-readonly.
12520+ */
12521+static inline int au_test_fs_rr(struct super_block *sb)
12522+{
12523+ return au_test_squashfs(sb)
12524+ || au_test_iso9660(sb)
12525+ || au_test_cramfs(sb)
12526+ || au_test_romfs(sb);
12527+}
12528+
12529+#endif /* __KERNEL__ */
12530+#endif /* __AUFS_FSTYPE_H__ */
7f207e10
AM
12531diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
12532--- /usr/share/empty/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100
1716fcea
AM
12533+++ linux/fs/aufs/hfsnotify.c 2013-02-19 08:40:03.946892891 +0100
12534@@ -0,0 +1,293 @@
1facf9fc 12535+/*
7a9e40b8 12536+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 12537+ *
12538+ * This program, aufs is free software; you can redistribute it and/or modify
12539+ * it under the terms of the GNU General Public License as published by
12540+ * the Free Software Foundation; either version 2 of the License, or
12541+ * (at your option) any later version.
dece6358
AM
12542+ *
12543+ * This program is distributed in the hope that it will be useful,
12544+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12545+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12546+ * GNU General Public License for more details.
12547+ *
12548+ * You should have received a copy of the GNU General Public License
12549+ * along with this program; if not, write to the Free Software
12550+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 12551+ */
12552+
12553+/*
4a4d8108 12554+ * fsnotify for the lower directories
1facf9fc 12555+ */
12556+
12557+#include "aufs.h"
12558+
4a4d8108
AM
12559+/* FS_IN_IGNORED is unnecessary */
12560+static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE
12561+ | FS_CREATE | FS_EVENT_ON_CHILD);
7f207e10 12562+static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
7eafdf33 12563+static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0);
1facf9fc 12564+
0c5527e5 12565+static void au_hfsn_free_mark(struct fsnotify_mark *mark)
1facf9fc 12566+{
0c5527e5
AM
12567+ struct au_hnotify *hn = container_of(mark, struct au_hnotify,
12568+ hn_mark);
4a4d8108 12569+ AuDbg("here\n");
7eafdf33
AM
12570+ au_cache_free_hnotify(hn);
12571+ smp_mb__before_atomic_dec();
1716fcea
AM
12572+ if (atomic64_dec_and_test(&au_hfsn_ifree))
12573+ wake_up(&au_hfsn_wq);
4a4d8108 12574+}
1facf9fc 12575+
027c5e7a 12576+static int au_hfsn_alloc(struct au_hinode *hinode)
4a4d8108 12577+{
1716fcea 12578+ int err;
027c5e7a
AM
12579+ struct au_hnotify *hn;
12580+ struct super_block *sb;
12581+ struct au_branch *br;
0c5527e5 12582+ struct fsnotify_mark *mark;
027c5e7a 12583+ aufs_bindex_t bindex;
1facf9fc 12584+
027c5e7a
AM
12585+ hn = hinode->hi_notify;
12586+ sb = hn->hn_aufs_inode->i_sb;
12587+ bindex = au_br_index(sb, hinode->hi_id);
12588+ br = au_sbr(sb, bindex);
1716fcea
AM
12589+ AuDebugOn(!br->br_hfsn);
12590+
0c5527e5
AM
12591+ mark = &hn->hn_mark;
12592+ fsnotify_init_mark(mark, au_hfsn_free_mark);
12593+ mark->mask = AuHfsnMask;
7f207e10
AM
12594+ /*
12595+ * by udba rename or rmdir, aufs assign a new inode to the known
12596+ * h_inode, so specify 1 to allow dups.
12597+ */
1716fcea 12598+ err = fsnotify_add_mark(mark, br->br_hfsn->hfsn_group, hinode->hi_inode,
027c5e7a 12599+ /*mnt*/NULL, /*allow_dups*/1);
1716fcea
AM
12600+ /* even if err */
12601+ fsnotify_put_mark(mark);
12602+
12603+ return err;
1facf9fc 12604+}
12605+
7eafdf33 12606+static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn)
1facf9fc 12607+{
0c5527e5 12608+ struct fsnotify_mark *mark;
7eafdf33 12609+ unsigned long long ull;
1716fcea 12610+ struct fsnotify_group *group;
7eafdf33
AM
12611+
12612+ ull = atomic64_inc_return(&au_hfsn_ifree);
12613+ BUG_ON(!ull);
953406b4 12614+
0c5527e5 12615+ mark = &hn->hn_mark;
1716fcea
AM
12616+ spin_lock(&mark->lock);
12617+ group = mark->group;
12618+ fsnotify_get_group(group);
12619+ spin_unlock(&mark->lock);
12620+ fsnotify_destroy_mark(mark, group);
12621+ fsnotify_put_group(group);
7f207e10 12622+
7eafdf33
AM
12623+ /* free hn by myself */
12624+ return 0;
1facf9fc 12625+}
12626+
12627+/* ---------------------------------------------------------------------- */
12628+
4a4d8108 12629+static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
1facf9fc 12630+{
0c5527e5 12631+ struct fsnotify_mark *mark;
1facf9fc 12632+
0c5527e5
AM
12633+ mark = &hinode->hi_notify->hn_mark;
12634+ spin_lock(&mark->lock);
1facf9fc 12635+ if (do_set) {
0c5527e5
AM
12636+ AuDebugOn(mark->mask & AuHfsnMask);
12637+ mark->mask |= AuHfsnMask;
1facf9fc 12638+ } else {
0c5527e5
AM
12639+ AuDebugOn(!(mark->mask & AuHfsnMask));
12640+ mark->mask &= ~AuHfsnMask;
1facf9fc 12641+ }
0c5527e5 12642+ spin_unlock(&mark->lock);
4a4d8108 12643+ /* fsnotify_recalc_inode_mask(hinode->hi_inode); */
1facf9fc 12644+}
12645+
4a4d8108 12646+/* ---------------------------------------------------------------------- */
1facf9fc 12647+
4a4d8108
AM
12648+/* #define AuDbgHnotify */
12649+#ifdef AuDbgHnotify
12650+static char *au_hfsn_name(u32 mask)
12651+{
12652+#ifdef CONFIG_AUFS_DEBUG
12653+#define test_ret(flag) if (mask & flag) \
12654+ return #flag;
12655+ test_ret(FS_ACCESS);
12656+ test_ret(FS_MODIFY);
12657+ test_ret(FS_ATTRIB);
12658+ test_ret(FS_CLOSE_WRITE);
12659+ test_ret(FS_CLOSE_NOWRITE);
12660+ test_ret(FS_OPEN);
12661+ test_ret(FS_MOVED_FROM);
12662+ test_ret(FS_MOVED_TO);
12663+ test_ret(FS_CREATE);
12664+ test_ret(FS_DELETE);
12665+ test_ret(FS_DELETE_SELF);
12666+ test_ret(FS_MOVE_SELF);
12667+ test_ret(FS_UNMOUNT);
12668+ test_ret(FS_Q_OVERFLOW);
12669+ test_ret(FS_IN_IGNORED);
12670+ test_ret(FS_IN_ISDIR);
12671+ test_ret(FS_IN_ONESHOT);
12672+ test_ret(FS_EVENT_ON_CHILD);
12673+ return "";
12674+#undef test_ret
12675+#else
12676+ return "??";
12677+#endif
1facf9fc 12678+}
4a4d8108 12679+#endif
1facf9fc 12680+
12681+/* ---------------------------------------------------------------------- */
12682+
1716fcea
AM
12683+static void au_hfsn_free_group(struct fsnotify_group *group)
12684+{
12685+ struct au_br_hfsnotify *hfsn = group->private;
12686+
12687+ AuDbg("here\n");
12688+ kfree(hfsn);
12689+}
12690+
4a4d8108 12691+static int au_hfsn_handle_event(struct fsnotify_group *group,
0c5527e5
AM
12692+ struct fsnotify_mark *inode_mark,
12693+ struct fsnotify_mark *vfsmount_mark,
4a4d8108 12694+ struct fsnotify_event *event)
1facf9fc 12695+{
12696+ int err;
4a4d8108
AM
12697+ struct au_hnotify *hnotify;
12698+ struct inode *h_dir, *h_inode;
12699+ __u32 mask;
0c3ec466 12700+ struct qstr h_child_qstr = QSTR_INIT(event->file_name, event->name_len);
4a4d8108
AM
12701+
12702+ AuDebugOn(event->data_type != FSNOTIFY_EVENT_INODE);
1facf9fc 12703+
12704+ err = 0;
0c5527e5 12705+ /* if FS_UNMOUNT happens, there must be another bug */
4a4d8108
AM
12706+ mask = event->mask;
12707+ AuDebugOn(mask & FS_UNMOUNT);
0c5527e5 12708+ if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
1facf9fc 12709+ goto out;
1facf9fc 12710+
4a4d8108
AM
12711+ h_dir = event->to_tell;
12712+ h_inode = event->inode;
12713+#ifdef AuDbgHnotify
12714+ au_debug(1);
12715+ if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
12716+ || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
12717+ AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
12718+ h_dir->i_ino, mask, au_hfsn_name(mask),
12719+ AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
12720+ /* WARN_ON(1); */
1facf9fc 12721+ }
4a4d8108 12722+ au_debug(0);
1facf9fc 12723+#endif
4a4d8108 12724+
0c5527e5
AM
12725+ AuDebugOn(!inode_mark);
12726+ hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
12727+ err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode);
1facf9fc 12728+
4a4d8108
AM
12729+out:
12730+ return err;
12731+}
1facf9fc 12732+
027c5e7a 12733+/* isn't it waste to ask every registered 'group'? */
7f207e10 12734+/* copied from linux/fs/notify/inotify/inotify_fsnotiry.c */
4a4d8108 12735+/* it should be exported to modules */
7f207e10
AM
12736+static bool au_hfsn_should_send_event(struct fsnotify_group *group,
12737+ struct inode *h_inode,
0c5527e5
AM
12738+ struct fsnotify_mark *inode_mark,
12739+ struct fsnotify_mark *vfsmount_mark,
12740+ __u32 mask, void *data, int data_type)
4a4d8108 12741+{
4a4d8108 12742+ mask = (mask & ~FS_EVENT_ON_CHILD);
7f207e10 12743+ return inode_mark->mask & mask;
4a4d8108
AM
12744+}
12745+
12746+static struct fsnotify_ops au_hfsn_ops = {
12747+ .should_send_event = au_hfsn_should_send_event,
1716fcea
AM
12748+ .handle_event = au_hfsn_handle_event,
12749+ .free_group_priv = au_hfsn_free_group
4a4d8108
AM
12750+};
12751+
12752+/* ---------------------------------------------------------------------- */
12753+
027c5e7a
AM
12754+static void au_hfsn_fin_br(struct au_branch *br)
12755+{
1716fcea 12756+ struct au_br_hfsnotify *hfsn;
027c5e7a 12757+
1716fcea
AM
12758+ hfsn = br->br_hfsn;
12759+ if (hfsn)
12760+ fsnotify_put_group(hfsn->hfsn_group);
027c5e7a
AM
12761+}
12762+
1716fcea 12763+static int au_hfsn_init_br(struct au_branch *br, int perm)
4a4d8108
AM
12764+{
12765+ int err;
1716fcea
AM
12766+ struct fsnotify_group *group;
12767+ struct au_br_hfsnotify *hfsn;
1facf9fc 12768+
4a4d8108 12769+ err = 0;
1716fcea
AM
12770+ br->br_hfsn = NULL;
12771+ if (!au_br_hnotifyable(perm))
027c5e7a 12772+ goto out;
027c5e7a 12773+
1716fcea
AM
12774+ err = -ENOMEM;
12775+ hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS);
12776+ if (unlikely(!hfsn))
027c5e7a
AM
12777+ goto out;
12778+
1716fcea
AM
12779+ err = 0;
12780+ group = fsnotify_alloc_group(&au_hfsn_ops);
12781+ if (IS_ERR(group)) {
12782+ err = PTR_ERR(group);
0c5527e5 12783+ pr_err("fsnotify_alloc_group() failed, %d\n", err);
1716fcea 12784+ goto out_hfsn;
4a4d8108 12785+ }
1facf9fc 12786+
1716fcea
AM
12787+ group->private = hfsn;
12788+ hfsn->hfsn_group = group;
12789+ br->br_hfsn = hfsn;
12790+ goto out; /* success */
12791+
12792+out_hfsn:
12793+ kfree(hfsn);
027c5e7a 12794+out:
1716fcea
AM
12795+ return err;
12796+}
12797+
12798+static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm)
12799+{
12800+ int err;
12801+
12802+ err = 0;
12803+ if (!br->br_hfsn)
12804+ err = au_hfsn_init_br(br, perm);
12805+
1facf9fc 12806+ return err;
12807+}
12808+
7eafdf33
AM
12809+/* ---------------------------------------------------------------------- */
12810+
12811+static void au_hfsn_fin(void)
12812+{
12813+ AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree));
12814+ wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree));
12815+}
12816+
4a4d8108
AM
12817+const struct au_hnotify_op au_hnotify_op = {
12818+ .ctl = au_hfsn_ctl,
12819+ .alloc = au_hfsn_alloc,
12820+ .free = au_hfsn_free,
1facf9fc 12821+
7eafdf33
AM
12822+ .fin = au_hfsn_fin,
12823+
027c5e7a
AM
12824+ .reset_br = au_hfsn_reset_br,
12825+ .fin_br = au_hfsn_fin_br,
12826+ .init_br = au_hfsn_init_br
4a4d8108 12827+};
7f207e10
AM
12828diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c
12829--- /usr/share/empty/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100
1716fcea 12830+++ linux/fs/aufs/hfsplus.c 2013-02-19 08:40:03.946892891 +0100
f6c5ef8b 12831@@ -0,0 +1,57 @@
4a4d8108 12832+/*
7a9e40b8 12833+ * Copyright (C) 2010-2013 Junjiro R. Okajima
4a4d8108
AM
12834+ *
12835+ * This program, aufs is free software; you can redistribute it and/or modify
12836+ * it under the terms of the GNU General Public License as published by
12837+ * the Free Software Foundation; either version 2 of the License, or
12838+ * (at your option) any later version.
12839+ *
12840+ * This program is distributed in the hope that it will be useful,
12841+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12842+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12843+ * GNU General Public License for more details.
12844+ *
12845+ * You should have received a copy of the GNU General Public License
12846+ * along with this program; if not, write to the Free Software
12847+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12848+ */
1facf9fc 12849+
4a4d8108
AM
12850+/*
12851+ * special support for filesystems which aqucires an inode mutex
12852+ * at final closing a file, eg, hfsplus.
12853+ *
12854+ * This trick is very simple and stupid, just to open the file before really
12855+ * neceeary open to tell hfsplus that this is not the final closing.
12856+ * The caller should call au_h_open_pre() after acquiring the inode mutex,
12857+ * and au_h_open_post() after releasing it.
12858+ */
1facf9fc 12859+
4a4d8108 12860+#include "aufs.h"
1facf9fc 12861+
4a4d8108
AM
12862+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex)
12863+{
12864+ struct file *h_file;
12865+ struct dentry *h_dentry;
1facf9fc 12866+
4a4d8108
AM
12867+ h_dentry = au_h_dptr(dentry, bindex);
12868+ AuDebugOn(!h_dentry);
12869+ AuDebugOn(!h_dentry->d_inode);
12870+ IMustLock(h_dentry->d_inode);
12871+
12872+ h_file = NULL;
12873+ if (au_test_hfsplus(h_dentry->d_sb)
12874+ && S_ISREG(h_dentry->d_inode->i_mode))
12875+ h_file = au_h_open(dentry, bindex,
12876+ O_RDONLY | O_NOATIME | O_LARGEFILE,
12877+ /*file*/NULL);
12878+ return h_file;
1facf9fc 12879+}
12880+
4a4d8108
AM
12881+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
12882+ struct file *h_file)
12883+{
12884+ if (h_file) {
12885+ fput(h_file);
12886+ au_sbr_put(dentry->d_sb, bindex);
12887+ }
12888+}
7f207e10
AM
12889diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
12890--- /usr/share/empty/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100
a2a7ad62 12891+++ linux/fs/aufs/hnotify.c 2013-03-14 20:07:41.041453062 +0100
b4510431 12892@@ -0,0 +1,713 @@
e49829fe 12893+/*
7a9e40b8 12894+ * Copyright (C) 2005-2013 Junjiro R. Okajima
e49829fe
JR
12895+ *
12896+ * This program, aufs is free software; you can redistribute it and/or modify
12897+ * it under the terms of the GNU General Public License as published by
12898+ * the Free Software Foundation; either version 2 of the License, or
12899+ * (at your option) any later version.
12900+ *
12901+ * This program is distributed in the hope that it will be useful,
12902+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12903+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12904+ * GNU General Public License for more details.
12905+ *
12906+ * You should have received a copy of the GNU General Public License
12907+ * along with this program; if not, write to the Free Software
12908+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12909+ */
12910+
12911+/*
7f207e10 12912+ * abstraction to notify the direct changes on lower directories
e49829fe
JR
12913+ */
12914+
12915+#include "aufs.h"
12916+
027c5e7a 12917+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
e49829fe
JR
12918+{
12919+ int err;
7f207e10 12920+ struct au_hnotify *hn;
1facf9fc 12921+
4a4d8108
AM
12922+ err = -ENOMEM;
12923+ hn = au_cache_alloc_hnotify();
12924+ if (hn) {
12925+ hn->hn_aufs_inode = inode;
027c5e7a
AM
12926+ hinode->hi_notify = hn;
12927+ err = au_hnotify_op.alloc(hinode);
12928+ AuTraceErr(err);
12929+ if (unlikely(err)) {
12930+ hinode->hi_notify = NULL;
4a4d8108
AM
12931+ au_cache_free_hnotify(hn);
12932+ /*
12933+ * The upper dir was removed by udba, but the same named
12934+ * dir left. In this case, aufs assignes a new inode
12935+ * number and set the monitor again.
12936+ * For the lower dir, the old monitnor is still left.
12937+ */
12938+ if (err == -EEXIST)
12939+ err = 0;
12940+ }
1308ab2a 12941+ }
1308ab2a 12942+
027c5e7a 12943+ AuTraceErr(err);
1308ab2a 12944+ return err;
dece6358 12945+}
1facf9fc 12946+
4a4d8108 12947+void au_hn_free(struct au_hinode *hinode)
dece6358 12948+{
4a4d8108 12949+ struct au_hnotify *hn;
1facf9fc 12950+
4a4d8108
AM
12951+ hn = hinode->hi_notify;
12952+ if (hn) {
4a4d8108 12953+ hinode->hi_notify = NULL;
7eafdf33
AM
12954+ if (au_hnotify_op.free(hinode, hn))
12955+ au_cache_free_hnotify(hn);
4a4d8108
AM
12956+ }
12957+}
dece6358 12958+
4a4d8108 12959+/* ---------------------------------------------------------------------- */
dece6358 12960+
4a4d8108
AM
12961+void au_hn_ctl(struct au_hinode *hinode, int do_set)
12962+{
12963+ if (hinode->hi_notify)
12964+ au_hnotify_op.ctl(hinode, do_set);
12965+}
12966+
12967+void au_hn_reset(struct inode *inode, unsigned int flags)
12968+{
12969+ aufs_bindex_t bindex, bend;
12970+ struct inode *hi;
12971+ struct dentry *iwhdentry;
1facf9fc 12972+
1308ab2a 12973+ bend = au_ibend(inode);
4a4d8108
AM
12974+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
12975+ hi = au_h_iptr(inode, bindex);
12976+ if (!hi)
12977+ continue;
1308ab2a 12978+
4a4d8108
AM
12979+ /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */
12980+ iwhdentry = au_hi_wh(inode, bindex);
12981+ if (iwhdentry)
12982+ dget(iwhdentry);
12983+ au_igrab(hi);
12984+ au_set_h_iptr(inode, bindex, NULL, 0);
12985+ au_set_h_iptr(inode, bindex, au_igrab(hi),
12986+ flags & ~AuHi_XINO);
12987+ iput(hi);
12988+ dput(iwhdentry);
12989+ /* mutex_unlock(&hi->i_mutex); */
1facf9fc 12990+ }
1facf9fc 12991+}
12992+
1308ab2a 12993+/* ---------------------------------------------------------------------- */
1facf9fc 12994+
4a4d8108 12995+static int hn_xino(struct inode *inode, struct inode *h_inode)
1facf9fc 12996+{
4a4d8108
AM
12997+ int err;
12998+ aufs_bindex_t bindex, bend, bfound, bstart;
12999+ struct inode *h_i;
1facf9fc 13000+
4a4d8108
AM
13001+ err = 0;
13002+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 13003+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
13004+ goto out;
13005+ }
1facf9fc 13006+
4a4d8108
AM
13007+ bfound = -1;
13008+ bend = au_ibend(inode);
13009+ bstart = au_ibstart(inode);
13010+#if 0 /* reserved for future use */
13011+ if (bindex == bend) {
13012+ /* keep this ino in rename case */
13013+ goto out;
13014+ }
13015+#endif
13016+ for (bindex = bstart; bindex <= bend; bindex++)
13017+ if (au_h_iptr(inode, bindex) == h_inode) {
13018+ bfound = bindex;
13019+ break;
13020+ }
13021+ if (bfound < 0)
1308ab2a 13022+ goto out;
1facf9fc 13023+
4a4d8108
AM
13024+ for (bindex = bstart; bindex <= bend; bindex++) {
13025+ h_i = au_h_iptr(inode, bindex);
13026+ if (!h_i)
13027+ continue;
1facf9fc 13028+
4a4d8108
AM
13029+ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
13030+ /* ignore this error */
13031+ /* bad action? */
1facf9fc 13032+ }
1facf9fc 13033+
4a4d8108 13034+ /* children inode number will be broken */
1facf9fc 13035+
4f0767ce 13036+out:
4a4d8108
AM
13037+ AuTraceErr(err);
13038+ return err;
1facf9fc 13039+}
13040+
4a4d8108 13041+static int hn_gen_tree(struct dentry *dentry)
1facf9fc 13042+{
4a4d8108
AM
13043+ int err, i, j, ndentry;
13044+ struct au_dcsub_pages dpages;
13045+ struct au_dpage *dpage;
13046+ struct dentry **dentries;
1facf9fc 13047+
4a4d8108
AM
13048+ err = au_dpages_init(&dpages, GFP_NOFS);
13049+ if (unlikely(err))
13050+ goto out;
13051+ err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
13052+ if (unlikely(err))
13053+ goto out_dpages;
1facf9fc 13054+
4a4d8108
AM
13055+ for (i = 0; i < dpages.ndpage; i++) {
13056+ dpage = dpages.dpages + i;
13057+ dentries = dpage->dentries;
13058+ ndentry = dpage->ndentry;
13059+ for (j = 0; j < ndentry; j++) {
13060+ struct dentry *d;
13061+
13062+ d = dentries[j];
13063+ if (IS_ROOT(d))
13064+ continue;
13065+
4a4d8108
AM
13066+ au_digen_dec(d);
13067+ if (d->d_inode)
13068+ /* todo: reset children xino?
13069+ cached children only? */
13070+ au_iigen_dec(d->d_inode);
1308ab2a 13071+ }
dece6358 13072+ }
1facf9fc 13073+
4f0767ce 13074+out_dpages:
4a4d8108 13075+ au_dpages_free(&dpages);
dece6358 13076+
027c5e7a 13077+#if 0
4a4d8108
AM
13078+ /* discard children */
13079+ dentry_unhash(dentry);
13080+ dput(dentry);
027c5e7a 13081+#endif
4f0767ce 13082+out:
dece6358
AM
13083+ return err;
13084+}
13085+
1308ab2a 13086+/*
4a4d8108 13087+ * return 0 if processed.
1308ab2a 13088+ */
4a4d8108
AM
13089+static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
13090+ const unsigned int isdir)
dece6358 13091+{
1308ab2a 13092+ int err;
4a4d8108
AM
13093+ struct dentry *d;
13094+ struct qstr *dname;
b4510431 13095+ struct hlist_node *p;
1facf9fc 13096+
4a4d8108
AM
13097+ err = 1;
13098+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 13099+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
13100+ err = 0;
13101+ goto out;
13102+ }
dece6358 13103+
4a4d8108
AM
13104+ if (!isdir) {
13105+ AuDebugOn(!name);
13106+ au_iigen_dec(inode);
027c5e7a 13107+ spin_lock(&inode->i_lock);
b4510431 13108+ hlist_for_each_entry(d, p, &inode->i_dentry, d_alias) {
027c5e7a 13109+ spin_lock(&d->d_lock);
4a4d8108
AM
13110+ dname = &d->d_name;
13111+ if (dname->len != nlen
027c5e7a
AM
13112+ && memcmp(dname->name, name, nlen)) {
13113+ spin_unlock(&d->d_lock);
4a4d8108 13114+ continue;
027c5e7a 13115+ }
4a4d8108 13116+ err = 0;
4a4d8108
AM
13117+ au_digen_dec(d);
13118+ spin_unlock(&d->d_lock);
13119+ break;
1facf9fc 13120+ }
027c5e7a 13121+ spin_unlock(&inode->i_lock);
1308ab2a 13122+ } else {
027c5e7a 13123+ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
4a4d8108
AM
13124+ d = d_find_alias(inode);
13125+ if (!d) {
13126+ au_iigen_dec(inode);
13127+ goto out;
13128+ }
1facf9fc 13129+
027c5e7a 13130+ spin_lock(&d->d_lock);
4a4d8108 13131+ dname = &d->d_name;
027c5e7a
AM
13132+ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
13133+ spin_unlock(&d->d_lock);
4a4d8108 13134+ err = hn_gen_tree(d);
027c5e7a
AM
13135+ spin_lock(&d->d_lock);
13136+ }
13137+ spin_unlock(&d->d_lock);
4a4d8108
AM
13138+ dput(d);
13139+ }
1facf9fc 13140+
4f0767ce 13141+out:
4a4d8108 13142+ AuTraceErr(err);
1308ab2a 13143+ return err;
13144+}
dece6358 13145+
4a4d8108 13146+static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
1facf9fc 13147+{
4a4d8108
AM
13148+ int err;
13149+ struct inode *inode;
1facf9fc 13150+
4a4d8108
AM
13151+ inode = dentry->d_inode;
13152+ if (IS_ROOT(dentry)
13153+ /* || (inode && inode->i_ino == AUFS_ROOT_INO) */
13154+ ) {
0c3ec466 13155+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
13156+ return 0;
13157+ }
1308ab2a 13158+
4a4d8108
AM
13159+ err = 0;
13160+ if (!isdir) {
4a4d8108
AM
13161+ au_digen_dec(dentry);
13162+ if (inode)
13163+ au_iigen_dec(inode);
13164+ } else {
027c5e7a 13165+ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
4a4d8108
AM
13166+ if (inode)
13167+ err = hn_gen_tree(dentry);
13168+ }
13169+
13170+ AuTraceErr(err);
13171+ return err;
1facf9fc 13172+}
13173+
4a4d8108 13174+/* ---------------------------------------------------------------------- */
1facf9fc 13175+
4a4d8108
AM
13176+/* hnotify job flags */
13177+#define AuHnJob_XINO0 1
13178+#define AuHnJob_GEN (1 << 1)
13179+#define AuHnJob_DIRENT (1 << 2)
13180+#define AuHnJob_ISDIR (1 << 3)
13181+#define AuHnJob_TRYXINO0 (1 << 4)
13182+#define AuHnJob_MNTPNT (1 << 5)
13183+#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name)
7f207e10
AM
13184+#define au_fset_hnjob(flags, name) \
13185+ do { (flags) |= AuHnJob_##name; } while (0)
13186+#define au_fclr_hnjob(flags, name) \
13187+ do { (flags) &= ~AuHnJob_##name; } while (0)
1facf9fc 13188+
4a4d8108
AM
13189+enum {
13190+ AuHn_CHILD,
13191+ AuHn_PARENT,
13192+ AuHnLast
13193+};
1facf9fc 13194+
4a4d8108
AM
13195+struct au_hnotify_args {
13196+ struct inode *h_dir, *dir, *h_child_inode;
13197+ u32 mask;
13198+ unsigned int flags[AuHnLast];
13199+ unsigned int h_child_nlen;
13200+ char h_child_name[];
13201+};
1facf9fc 13202+
4a4d8108
AM
13203+struct hn_job_args {
13204+ unsigned int flags;
13205+ struct inode *inode, *h_inode, *dir, *h_dir;
13206+ struct dentry *dentry;
13207+ char *h_name;
13208+ int h_nlen;
13209+};
1308ab2a 13210+
4a4d8108
AM
13211+static int hn_job(struct hn_job_args *a)
13212+{
13213+ const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
1308ab2a 13214+
4a4d8108
AM
13215+ /* reset xino */
13216+ if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
13217+ hn_xino(a->inode, a->h_inode); /* ignore this error */
1308ab2a 13218+
4a4d8108
AM
13219+ if (au_ftest_hnjob(a->flags, TRYXINO0)
13220+ && a->inode
13221+ && a->h_inode) {
13222+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
13223+ if (!a->h_inode->i_nlink)
13224+ hn_xino(a->inode, a->h_inode); /* ignore this error */
13225+ mutex_unlock(&a->h_inode->i_mutex);
1308ab2a 13226+ }
1facf9fc 13227+
4a4d8108
AM
13228+ /* make the generation obsolete */
13229+ if (au_ftest_hnjob(a->flags, GEN)) {
13230+ int err = -1;
13231+ if (a->inode)
13232+ err = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
13233+ isdir);
13234+ if (err && a->dentry)
13235+ hn_gen_by_name(a->dentry, isdir);
13236+ /* ignore this error */
1facf9fc 13237+ }
1facf9fc 13238+
4a4d8108
AM
13239+ /* make dir entries obsolete */
13240+ if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
13241+ struct au_vdir *vdir;
1facf9fc 13242+
4a4d8108
AM
13243+ vdir = au_ivdir(a->inode);
13244+ if (vdir)
13245+ vdir->vd_jiffy = 0;
13246+ /* IMustLock(a->inode); */
13247+ /* a->inode->i_version++; */
13248+ }
1facf9fc 13249+
4a4d8108
AM
13250+ /* can do nothing but warn */
13251+ if (au_ftest_hnjob(a->flags, MNTPNT)
13252+ && a->dentry
13253+ && d_mountpoint(a->dentry))
0c3ec466
AM
13254+ pr_warn("mount-point %.*s is removed or renamed\n",
13255+ AuDLNPair(a->dentry));
1facf9fc 13256+
4a4d8108 13257+ return 0;
1308ab2a 13258+}
1facf9fc 13259+
1308ab2a 13260+/* ---------------------------------------------------------------------- */
1facf9fc 13261+
4a4d8108
AM
13262+static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
13263+ struct inode *dir)
1308ab2a 13264+{
4a4d8108
AM
13265+ struct dentry *dentry, *d, *parent;
13266+ struct qstr *dname;
1308ab2a 13267+
4a4d8108
AM
13268+ parent = d_find_alias(dir);
13269+ if (!parent)
13270+ return NULL;
1308ab2a 13271+
4a4d8108 13272+ dentry = NULL;
027c5e7a 13273+ spin_lock(&parent->d_lock);
4a4d8108
AM
13274+ list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) {
13275+ /* AuDbg("%.*s\n", AuDLNPair(d)); */
027c5e7a 13276+ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
4a4d8108
AM
13277+ dname = &d->d_name;
13278+ if (dname->len != nlen || memcmp(dname->name, name, nlen))
027c5e7a
AM
13279+ goto cont_unlock;
13280+ if (au_di(d))
13281+ au_digen_dec(d);
13282+ else
13283+ goto cont_unlock;
13284+ if (d->d_count) {
13285+ dentry = dget_dlock(d);
4a4d8108 13286+ spin_unlock(&d->d_lock);
027c5e7a 13287+ break;
dece6358 13288+ }
1facf9fc 13289+
027c5e7a
AM
13290+ cont_unlock:
13291+ spin_unlock(&d->d_lock);
1308ab2a 13292+ }
027c5e7a 13293+ spin_unlock(&parent->d_lock);
4a4d8108 13294+ dput(parent);
1facf9fc 13295+
4a4d8108
AM
13296+ if (dentry)
13297+ di_write_lock_child(dentry);
1308ab2a 13298+
4a4d8108
AM
13299+ return dentry;
13300+}
dece6358 13301+
4a4d8108
AM
13302+static struct inode *lookup_wlock_by_ino(struct super_block *sb,
13303+ aufs_bindex_t bindex, ino_t h_ino)
13304+{
13305+ struct inode *inode;
13306+ ino_t ino;
13307+ int err;
13308+
13309+ inode = NULL;
13310+ err = au_xino_read(sb, bindex, h_ino, &ino);
13311+ if (!err && ino)
13312+ inode = ilookup(sb, ino);
13313+ if (!inode)
13314+ goto out;
13315+
13316+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 13317+ pr_warn("wrong root branch\n");
4a4d8108
AM
13318+ iput(inode);
13319+ inode = NULL;
13320+ goto out;
1308ab2a 13321+ }
13322+
4a4d8108 13323+ ii_write_lock_child(inode);
1308ab2a 13324+
4f0767ce 13325+out:
4a4d8108 13326+ return inode;
dece6358
AM
13327+}
13328+
4a4d8108 13329+static void au_hn_bh(void *_args)
1facf9fc 13330+{
4a4d8108
AM
13331+ struct au_hnotify_args *a = _args;
13332+ struct super_block *sb;
13333+ aufs_bindex_t bindex, bend, bfound;
13334+ unsigned char xino, try_iput;
1facf9fc 13335+ int err;
1308ab2a 13336+ struct inode *inode;
4a4d8108
AM
13337+ ino_t h_ino;
13338+ struct hn_job_args args;
13339+ struct dentry *dentry;
13340+ struct au_sbinfo *sbinfo;
1facf9fc 13341+
4a4d8108
AM
13342+ AuDebugOn(!_args);
13343+ AuDebugOn(!a->h_dir);
13344+ AuDebugOn(!a->dir);
13345+ AuDebugOn(!a->mask);
13346+ AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
13347+ a->mask, a->dir->i_ino, a->h_dir->i_ino,
13348+ a->h_child_inode ? a->h_child_inode->i_ino : 0);
1facf9fc 13349+
4a4d8108
AM
13350+ inode = NULL;
13351+ dentry = NULL;
13352+ /*
13353+ * do not lock a->dir->i_mutex here
13354+ * because of d_revalidate() may cause a deadlock.
13355+ */
13356+ sb = a->dir->i_sb;
13357+ AuDebugOn(!sb);
13358+ sbinfo = au_sbi(sb);
13359+ AuDebugOn(!sbinfo);
7f207e10 13360+ si_write_lock(sb, AuLock_NOPLMW);
1facf9fc 13361+
4a4d8108
AM
13362+ ii_read_lock_parent(a->dir);
13363+ bfound = -1;
13364+ bend = au_ibend(a->dir);
13365+ for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
13366+ if (au_h_iptr(a->dir, bindex) == a->h_dir) {
13367+ bfound = bindex;
13368+ break;
13369+ }
13370+ ii_read_unlock(a->dir);
13371+ if (unlikely(bfound < 0))
13372+ goto out;
1facf9fc 13373+
4a4d8108
AM
13374+ xino = !!au_opt_test(au_mntflags(sb), XINO);
13375+ h_ino = 0;
13376+ if (a->h_child_inode)
13377+ h_ino = a->h_child_inode->i_ino;
1facf9fc 13378+
4a4d8108
AM
13379+ if (a->h_child_nlen
13380+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
13381+ || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
13382+ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
13383+ a->dir);
13384+ try_iput = 0;
13385+ if (dentry)
13386+ inode = dentry->d_inode;
13387+ if (xino && !inode && h_ino
13388+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
13389+ || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
13390+ || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
13391+ inode = lookup_wlock_by_ino(sb, bfound, h_ino);
13392+ try_iput = 1;
13393+ }
1facf9fc 13394+
4a4d8108
AM
13395+ args.flags = a->flags[AuHn_CHILD];
13396+ args.dentry = dentry;
13397+ args.inode = inode;
13398+ args.h_inode = a->h_child_inode;
13399+ args.dir = a->dir;
13400+ args.h_dir = a->h_dir;
13401+ args.h_name = a->h_child_name;
13402+ args.h_nlen = a->h_child_nlen;
13403+ err = hn_job(&args);
13404+ if (dentry) {
027c5e7a 13405+ if (au_di(dentry))
4a4d8108
AM
13406+ di_write_unlock(dentry);
13407+ dput(dentry);
13408+ }
13409+ if (inode && try_iput) {
13410+ ii_write_unlock(inode);
13411+ iput(inode);
13412+ }
1facf9fc 13413+
4a4d8108
AM
13414+ ii_write_lock_parent(a->dir);
13415+ args.flags = a->flags[AuHn_PARENT];
13416+ args.dentry = NULL;
13417+ args.inode = a->dir;
13418+ args.h_inode = a->h_dir;
13419+ args.dir = NULL;
13420+ args.h_dir = NULL;
13421+ args.h_name = NULL;
13422+ args.h_nlen = 0;
13423+ err = hn_job(&args);
13424+ ii_write_unlock(a->dir);
1facf9fc 13425+
4f0767ce 13426+out:
4a4d8108
AM
13427+ iput(a->h_child_inode);
13428+ iput(a->h_dir);
13429+ iput(a->dir);
027c5e7a
AM
13430+ si_write_unlock(sb);
13431+ au_nwt_done(&sbinfo->si_nowait);
1308ab2a 13432+ kfree(a);
dece6358 13433+}
1facf9fc 13434+
4a4d8108
AM
13435+/* ---------------------------------------------------------------------- */
13436+
13437+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
13438+ struct qstr *h_child_qstr, struct inode *h_child_inode)
dece6358 13439+{
4a4d8108 13440+ int err, len;
53392da6 13441+ unsigned int flags[AuHnLast], f;
4a4d8108
AM
13442+ unsigned char isdir, isroot, wh;
13443+ struct inode *dir;
13444+ struct au_hnotify_args *args;
13445+ char *p, *h_child_name;
dece6358 13446+
1308ab2a 13447+ err = 0;
4a4d8108
AM
13448+ AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
13449+ dir = igrab(hnotify->hn_aufs_inode);
13450+ if (!dir)
13451+ goto out;
1facf9fc 13452+
4a4d8108
AM
13453+ isroot = (dir->i_ino == AUFS_ROOT_INO);
13454+ wh = 0;
13455+ h_child_name = (void *)h_child_qstr->name;
13456+ len = h_child_qstr->len;
13457+ if (h_child_name) {
13458+ if (len > AUFS_WH_PFX_LEN
13459+ && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
13460+ h_child_name += AUFS_WH_PFX_LEN;
13461+ len -= AUFS_WH_PFX_LEN;
13462+ wh = 1;
13463+ }
1facf9fc 13464+ }
dece6358 13465+
4a4d8108
AM
13466+ isdir = 0;
13467+ if (h_child_inode)
13468+ isdir = !!S_ISDIR(h_child_inode->i_mode);
13469+ flags[AuHn_PARENT] = AuHnJob_ISDIR;
13470+ flags[AuHn_CHILD] = 0;
13471+ if (isdir)
13472+ flags[AuHn_CHILD] = AuHnJob_ISDIR;
13473+ au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
13474+ au_fset_hnjob(flags[AuHn_CHILD], GEN);
13475+ switch (mask & FS_EVENTS_POSS_ON_CHILD) {
13476+ case FS_MOVED_FROM:
13477+ case FS_MOVED_TO:
13478+ au_fset_hnjob(flags[AuHn_CHILD], XINO0);
13479+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
13480+ /*FALLTHROUGH*/
13481+ case FS_CREATE:
13482+ AuDebugOn(!h_child_name || !h_child_inode);
13483+ break;
1facf9fc 13484+
4a4d8108
AM
13485+ case FS_DELETE:
13486+ /*
13487+ * aufs never be able to get this child inode.
13488+ * revalidation should be in d_revalidate()
13489+ * by checking i_nlink, i_generation or d_unhashed().
13490+ */
13491+ AuDebugOn(!h_child_name);
13492+ au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
13493+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
13494+ break;
dece6358 13495+
4a4d8108
AM
13496+ default:
13497+ AuDebugOn(1);
13498+ }
1308ab2a 13499+
4a4d8108
AM
13500+ if (wh)
13501+ h_child_inode = NULL;
1308ab2a 13502+
4a4d8108
AM
13503+ err = -ENOMEM;
13504+ /* iput() and kfree() will be called in au_hnotify() */
4a4d8108 13505+ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
4a4d8108
AM
13506+ if (unlikely(!args)) {
13507+ AuErr1("no memory\n");
13508+ iput(dir);
13509+ goto out;
13510+ }
13511+ args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
13512+ args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
13513+ args->mask = mask;
13514+ args->dir = dir;
13515+ args->h_dir = igrab(h_dir);
13516+ if (h_child_inode)
13517+ h_child_inode = igrab(h_child_inode); /* can be NULL */
13518+ args->h_child_inode = h_child_inode;
13519+ args->h_child_nlen = len;
13520+ if (len) {
13521+ p = (void *)args;
13522+ p += sizeof(*args);
13523+ memcpy(p, h_child_name, len);
13524+ p[len] = 0;
1308ab2a 13525+ }
1308ab2a 13526+
53392da6
AM
13527+ f = 0;
13528+ if (!dir->i_nlink)
13529+ f = AuWkq_NEST;
13530+ err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
4a4d8108
AM
13531+ if (unlikely(err)) {
13532+ pr_err("wkq %d\n", err);
13533+ iput(args->h_child_inode);
13534+ iput(args->h_dir);
13535+ iput(args->dir);
13536+ kfree(args);
1facf9fc 13537+ }
1facf9fc 13538+
4a4d8108 13539+out:
1facf9fc 13540+ return err;
13541+}
13542+
027c5e7a
AM
13543+/* ---------------------------------------------------------------------- */
13544+
13545+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
13546+{
13547+ int err;
13548+
13549+ AuDebugOn(!(udba & AuOptMask_UDBA));
13550+
13551+ err = 0;
13552+ if (au_hnotify_op.reset_br)
13553+ err = au_hnotify_op.reset_br(udba, br, perm);
13554+
13555+ return err;
13556+}
13557+
13558+int au_hnotify_init_br(struct au_branch *br, int perm)
13559+{
13560+ int err;
13561+
13562+ err = 0;
13563+ if (au_hnotify_op.init_br)
13564+ err = au_hnotify_op.init_br(br, perm);
13565+
13566+ return err;
13567+}
13568+
13569+void au_hnotify_fin_br(struct au_branch *br)
13570+{
13571+ if (au_hnotify_op.fin_br)
13572+ au_hnotify_op.fin_br(br);
13573+}
13574+
4a4d8108
AM
13575+static void au_hn_destroy_cache(void)
13576+{
13577+ kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]);
13578+ au_cachep[AuCache_HNOTIFY] = NULL;
13579+}
1308ab2a 13580+
4a4d8108 13581+int __init au_hnotify_init(void)
1facf9fc 13582+{
1308ab2a 13583+ int err;
1308ab2a 13584+
4a4d8108
AM
13585+ err = -ENOMEM;
13586+ au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify);
13587+ if (au_cachep[AuCache_HNOTIFY]) {
027c5e7a
AM
13588+ err = 0;
13589+ if (au_hnotify_op.init)
13590+ err = au_hnotify_op.init();
4a4d8108
AM
13591+ if (unlikely(err))
13592+ au_hn_destroy_cache();
1308ab2a 13593+ }
1308ab2a 13594+ AuTraceErr(err);
4a4d8108 13595+ return err;
1308ab2a 13596+}
13597+
4a4d8108 13598+void au_hnotify_fin(void)
1308ab2a 13599+{
027c5e7a
AM
13600+ if (au_hnotify_op.fin)
13601+ au_hnotify_op.fin();
4a4d8108
AM
13602+ /* cf. au_cache_fin() */
13603+ if (au_cachep[AuCache_HNOTIFY])
13604+ au_hn_destroy_cache();
dece6358 13605+}
7f207e10
AM
13606diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
13607--- /usr/share/empty/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100
1716fcea 13608+++ linux/fs/aufs/iinfo.c 2013-02-19 08:40:03.950226347 +0100
537831f9 13609@@ -0,0 +1,276 @@
dece6358 13610+/*
7a9e40b8 13611+ * Copyright (C) 2005-2013 Junjiro R. Okajima
dece6358
AM
13612+ *
13613+ * This program, aufs is free software; you can redistribute it and/or modify
13614+ * it under the terms of the GNU General Public License as published by
13615+ * the Free Software Foundation; either version 2 of the License, or
13616+ * (at your option) any later version.
13617+ *
13618+ * This program is distributed in the hope that it will be useful,
13619+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13620+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13621+ * GNU General Public License for more details.
13622+ *
13623+ * You should have received a copy of the GNU General Public License
13624+ * along with this program; if not, write to the Free Software
13625+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13626+ */
1facf9fc 13627+
dece6358 13628+/*
4a4d8108 13629+ * inode private data
dece6358 13630+ */
1facf9fc 13631+
1308ab2a 13632+#include "aufs.h"
1facf9fc 13633+
4a4d8108 13634+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 13635+{
4a4d8108 13636+ struct inode *h_inode;
1facf9fc 13637+
4a4d8108 13638+ IiMustAnyLock(inode);
1facf9fc 13639+
4a4d8108
AM
13640+ h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode;
13641+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
13642+ return h_inode;
13643+}
1facf9fc 13644+
4a4d8108
AM
13645+/* todo: hard/soft set? */
13646+void au_hiput(struct au_hinode *hinode)
13647+{
13648+ au_hn_free(hinode);
13649+ dput(hinode->hi_whdentry);
13650+ iput(hinode->hi_inode);
13651+}
1facf9fc 13652+
4a4d8108
AM
13653+unsigned int au_hi_flags(struct inode *inode, int isdir)
13654+{
13655+ unsigned int flags;
13656+ const unsigned int mnt_flags = au_mntflags(inode->i_sb);
1facf9fc 13657+
4a4d8108
AM
13658+ flags = 0;
13659+ if (au_opt_test(mnt_flags, XINO))
13660+ au_fset_hi(flags, XINO);
13661+ if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY))
13662+ au_fset_hi(flags, HNOTIFY);
13663+ return flags;
1facf9fc 13664+}
13665+
4a4d8108
AM
13666+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
13667+ struct inode *h_inode, unsigned int flags)
1308ab2a 13668+{
4a4d8108
AM
13669+ struct au_hinode *hinode;
13670+ struct inode *hi;
13671+ struct au_iinfo *iinfo = au_ii(inode);
1facf9fc 13672+
4a4d8108 13673+ IiMustWriteLock(inode);
dece6358 13674+
4a4d8108
AM
13675+ hinode = iinfo->ii_hinode + bindex;
13676+ hi = hinode->hi_inode;
13677+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
13678+
13679+ if (hi)
13680+ au_hiput(hinode);
13681+ hinode->hi_inode = h_inode;
13682+ if (h_inode) {
13683+ int err;
13684+ struct super_block *sb = inode->i_sb;
13685+ struct au_branch *br;
13686+
027c5e7a
AM
13687+ AuDebugOn(inode->i_mode
13688+ && (h_inode->i_mode & S_IFMT)
13689+ != (inode->i_mode & S_IFMT));
4a4d8108
AM
13690+ if (bindex == iinfo->ii_bstart)
13691+ au_cpup_igen(inode, h_inode);
13692+ br = au_sbr(sb, bindex);
13693+ hinode->hi_id = br->br_id;
13694+ if (au_ftest_hi(flags, XINO)) {
13695+ err = au_xino_write(sb, bindex, h_inode->i_ino,
13696+ inode->i_ino);
13697+ if (unlikely(err))
13698+ AuIOErr1("failed au_xino_write() %d\n", err);
13699+ }
13700+
13701+ if (au_ftest_hi(flags, HNOTIFY)
13702+ && au_br_hnotifyable(br->br_perm)) {
027c5e7a 13703+ err = au_hn_alloc(hinode, inode);
4a4d8108
AM
13704+ if (unlikely(err))
13705+ AuIOErr1("au_hn_alloc() %d\n", err);
1308ab2a 13706+ }
13707+ }
4a4d8108 13708+}
dece6358 13709+
4a4d8108
AM
13710+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
13711+ struct dentry *h_wh)
13712+{
13713+ struct au_hinode *hinode;
dece6358 13714+
4a4d8108
AM
13715+ IiMustWriteLock(inode);
13716+
13717+ hinode = au_ii(inode)->ii_hinode + bindex;
13718+ AuDebugOn(hinode->hi_whdentry);
13719+ hinode->hi_whdentry = h_wh;
1facf9fc 13720+}
13721+
537831f9 13722+void au_update_iigen(struct inode *inode, int half)
1308ab2a 13723+{
537831f9
AM
13724+ struct au_iinfo *iinfo;
13725+ struct au_iigen *iigen;
13726+ unsigned int sigen;
13727+
13728+ sigen = au_sigen(inode->i_sb);
13729+ iinfo = au_ii(inode);
13730+ iigen = &iinfo->ii_generation;
13731+ spin_lock(&iinfo->ii_genspin);
13732+ iigen->ig_generation = sigen;
13733+ if (half)
13734+ au_ig_fset(iigen->ig_flags, HALF_REFRESHED);
13735+ else
13736+ au_ig_fclr(iigen->ig_flags, HALF_REFRESHED);
13737+ spin_unlock(&iinfo->ii_genspin);
4a4d8108 13738+}
1facf9fc 13739+
4a4d8108
AM
13740+/* it may be called at remount time, too */
13741+void au_update_ibrange(struct inode *inode, int do_put_zero)
13742+{
13743+ struct au_iinfo *iinfo;
027c5e7a 13744+ aufs_bindex_t bindex, bend;
1facf9fc 13745+
4a4d8108 13746+ iinfo = au_ii(inode);
027c5e7a 13747+ if (!iinfo)
4a4d8108 13748+ return;
1facf9fc 13749+
4a4d8108 13750+ IiMustWriteLock(inode);
1facf9fc 13751+
027c5e7a 13752+ if (do_put_zero && iinfo->ii_bstart >= 0) {
4a4d8108
AM
13753+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
13754+ bindex++) {
13755+ struct inode *h_i;
1facf9fc 13756+
4a4d8108 13757+ h_i = iinfo->ii_hinode[0 + bindex].hi_inode;
027c5e7a
AM
13758+ if (h_i && !h_i->i_nlink)
13759+ au_set_h_iptr(inode, bindex, NULL, 0);
13760+ }
4a4d8108
AM
13761+ }
13762+
027c5e7a
AM
13763+ iinfo->ii_bstart = -1;
13764+ iinfo->ii_bend = -1;
13765+ bend = au_sbend(inode->i_sb);
13766+ for (bindex = 0; bindex <= bend; bindex++)
13767+ if (iinfo->ii_hinode[0 + bindex].hi_inode) {
13768+ iinfo->ii_bstart = bindex;
4a4d8108 13769+ break;
027c5e7a
AM
13770+ }
13771+ if (iinfo->ii_bstart >= 0)
13772+ for (bindex = bend; bindex >= iinfo->ii_bstart; bindex--)
13773+ if (iinfo->ii_hinode[0 + bindex].hi_inode) {
13774+ iinfo->ii_bend = bindex;
13775+ break;
13776+ }
13777+ AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend);
1308ab2a 13778+}
1facf9fc 13779+
dece6358 13780+/* ---------------------------------------------------------------------- */
1facf9fc 13781+
4a4d8108 13782+void au_icntnr_init_once(void *_c)
dece6358 13783+{
4a4d8108
AM
13784+ struct au_icntnr *c = _c;
13785+ struct au_iinfo *iinfo = &c->iinfo;
e49829fe 13786+ static struct lock_class_key aufs_ii;
1facf9fc 13787+
537831f9 13788+ spin_lock_init(&iinfo->ii_genspin);
4a4d8108 13789+ au_rw_init(&iinfo->ii_rwsem);
e49829fe 13790+ au_rw_class(&iinfo->ii_rwsem, &aufs_ii);
4a4d8108
AM
13791+ inode_init_once(&c->vfs_inode);
13792+}
1facf9fc 13793+
4a4d8108
AM
13794+int au_iinfo_init(struct inode *inode)
13795+{
13796+ struct au_iinfo *iinfo;
13797+ struct super_block *sb;
13798+ int nbr, i;
1facf9fc 13799+
4a4d8108
AM
13800+ sb = inode->i_sb;
13801+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
13802+ nbr = au_sbend(sb) + 1;
13803+ if (unlikely(nbr <= 0))
13804+ nbr = 1;
13805+ iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
13806+ if (iinfo->ii_hinode) {
7f207e10 13807+ au_ninodes_inc(sb);
4a4d8108
AM
13808+ for (i = 0; i < nbr; i++)
13809+ iinfo->ii_hinode[i].hi_id = -1;
1facf9fc 13810+
537831f9 13811+ iinfo->ii_generation.ig_generation = au_sigen(sb);
4a4d8108
AM
13812+ iinfo->ii_bstart = -1;
13813+ iinfo->ii_bend = -1;
13814+ iinfo->ii_vdir = NULL;
13815+ return 0;
1308ab2a 13816+ }
4a4d8108
AM
13817+ return -ENOMEM;
13818+}
1facf9fc 13819+
4a4d8108
AM
13820+int au_ii_realloc(struct au_iinfo *iinfo, int nbr)
13821+{
13822+ int err, sz;
13823+ struct au_hinode *hip;
1facf9fc 13824+
4a4d8108
AM
13825+ AuRwMustWriteLock(&iinfo->ii_rwsem);
13826+
13827+ err = -ENOMEM;
13828+ sz = sizeof(*hip) * (iinfo->ii_bend + 1);
13829+ if (!sz)
13830+ sz = sizeof(*hip);
13831+ hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS);
13832+ if (hip) {
13833+ iinfo->ii_hinode = hip;
13834+ err = 0;
1308ab2a 13835+ }
4a4d8108 13836+
1308ab2a 13837+ return err;
1facf9fc 13838+}
13839+
4a4d8108 13840+void au_iinfo_fin(struct inode *inode)
1facf9fc 13841+{
4a4d8108
AM
13842+ struct au_iinfo *iinfo;
13843+ struct au_hinode *hi;
13844+ struct super_block *sb;
b752ccd1
AM
13845+ aufs_bindex_t bindex, bend;
13846+ const unsigned char unlinked = !inode->i_nlink;
1308ab2a 13847+
4a4d8108
AM
13848+ iinfo = au_ii(inode);
13849+ /* bad_inode case */
13850+ if (!iinfo)
13851+ return;
1308ab2a 13852+
b752ccd1 13853+ sb = inode->i_sb;
7f207e10 13854+ au_ninodes_dec(sb);
b752ccd1
AM
13855+ if (si_pid_test(sb))
13856+ au_xino_delete_inode(inode, unlinked);
13857+ else {
13858+ /*
13859+ * it is safe to hide the dependency between sbinfo and
13860+ * sb->s_umount.
13861+ */
13862+ lockdep_off();
13863+ si_noflush_read_lock(sb);
13864+ au_xino_delete_inode(inode, unlinked);
13865+ si_read_unlock(sb);
13866+ lockdep_on();
13867+ }
13868+
4a4d8108
AM
13869+ if (iinfo->ii_vdir)
13870+ au_vdir_free(iinfo->ii_vdir);
1308ab2a 13871+
b752ccd1
AM
13872+ bindex = iinfo->ii_bstart;
13873+ if (bindex >= 0) {
13874+ hi = iinfo->ii_hinode + bindex;
4a4d8108 13875+ bend = iinfo->ii_bend;
b752ccd1
AM
13876+ while (bindex++ <= bend) {
13877+ if (hi->hi_inode)
4a4d8108 13878+ au_hiput(hi);
4a4d8108
AM
13879+ hi++;
13880+ }
13881+ }
4a4d8108 13882+ kfree(iinfo->ii_hinode);
027c5e7a 13883+ iinfo->ii_hinode = NULL;
4a4d8108 13884+ AuRwDestroy(&iinfo->ii_rwsem);
dece6358 13885+}
7f207e10
AM
13886diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
13887--- /usr/share/empty/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100
1716fcea
AM
13888+++ linux/fs/aufs/inode.c 2013-02-19 08:40:03.950226347 +0100
13889@@ -0,0 +1,492 @@
4a4d8108 13890+/*
7a9e40b8 13891+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
13892+ *
13893+ * This program, aufs is free software; you can redistribute it and/or modify
13894+ * it under the terms of the GNU General Public License as published by
13895+ * the Free Software Foundation; either version 2 of the License, or
13896+ * (at your option) any later version.
13897+ *
13898+ * This program is distributed in the hope that it will be useful,
13899+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13900+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13901+ * GNU General Public License for more details.
13902+ *
13903+ * You should have received a copy of the GNU General Public License
13904+ * along with this program; if not, write to the Free Software
13905+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13906+ */
1facf9fc 13907+
4a4d8108
AM
13908+/*
13909+ * inode functions
13910+ */
1facf9fc 13911+
4a4d8108 13912+#include "aufs.h"
1308ab2a 13913+
4a4d8108
AM
13914+struct inode *au_igrab(struct inode *inode)
13915+{
13916+ if (inode) {
13917+ AuDebugOn(!atomic_read(&inode->i_count));
027c5e7a 13918+ ihold(inode);
1facf9fc 13919+ }
4a4d8108
AM
13920+ return inode;
13921+}
1facf9fc 13922+
4a4d8108
AM
13923+static void au_refresh_hinode_attr(struct inode *inode, int do_version)
13924+{
13925+ au_cpup_attr_all(inode, /*force*/0);
537831f9 13926+ au_update_iigen(inode, /*half*/1);
4a4d8108
AM
13927+ if (do_version)
13928+ inode->i_version++;
dece6358 13929+}
1facf9fc 13930+
027c5e7a 13931+static int au_ii_refresh(struct inode *inode, int *update)
dece6358 13932+{
4a4d8108 13933+ int err, e;
027c5e7a 13934+ umode_t type;
4a4d8108 13935+ aufs_bindex_t bindex, new_bindex;
1308ab2a 13936+ struct super_block *sb;
4a4d8108 13937+ struct au_iinfo *iinfo;
027c5e7a 13938+ struct au_hinode *p, *q, tmp;
1facf9fc 13939+
4a4d8108 13940+ IiMustWriteLock(inode);
1facf9fc 13941+
027c5e7a 13942+ *update = 0;
4a4d8108 13943+ sb = inode->i_sb;
027c5e7a 13944+ type = inode->i_mode & S_IFMT;
4a4d8108
AM
13945+ iinfo = au_ii(inode);
13946+ err = au_ii_realloc(iinfo, au_sbend(sb) + 1);
13947+ if (unlikely(err))
1308ab2a 13948+ goto out;
1facf9fc 13949+
027c5e7a 13950+ AuDebugOn(iinfo->ii_bstart < 0);
4a4d8108 13951+ p = iinfo->ii_hinode + iinfo->ii_bstart;
4a4d8108
AM
13952+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
13953+ bindex++, p++) {
13954+ if (!p->hi_inode)
13955+ continue;
1facf9fc 13956+
027c5e7a 13957+ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT));
4a4d8108
AM
13958+ new_bindex = au_br_index(sb, p->hi_id);
13959+ if (new_bindex == bindex)
13960+ continue;
1facf9fc 13961+
4a4d8108 13962+ if (new_bindex < 0) {
027c5e7a 13963+ *update = 1;
4a4d8108
AM
13964+ au_hiput(p);
13965+ p->hi_inode = NULL;
13966+ continue;
1308ab2a 13967+ }
4a4d8108
AM
13968+
13969+ if (new_bindex < iinfo->ii_bstart)
13970+ iinfo->ii_bstart = new_bindex;
13971+ if (iinfo->ii_bend < new_bindex)
13972+ iinfo->ii_bend = new_bindex;
13973+ /* swap two lower inode, and loop again */
13974+ q = iinfo->ii_hinode + new_bindex;
13975+ tmp = *q;
13976+ *q = *p;
13977+ *p = tmp;
13978+ if (tmp.hi_inode) {
13979+ bindex--;
13980+ p--;
1308ab2a 13981+ }
13982+ }
4a4d8108
AM
13983+ au_update_ibrange(inode, /*do_put_zero*/0);
13984+ e = au_dy_irefresh(inode);
13985+ if (unlikely(e && !err))
13986+ err = e;
1facf9fc 13987+
4f0767ce 13988+out:
027c5e7a
AM
13989+ AuTraceErr(err);
13990+ return err;
13991+}
13992+
13993+int au_refresh_hinode_self(struct inode *inode)
13994+{
13995+ int err, update;
13996+
13997+ err = au_ii_refresh(inode, &update);
13998+ if (!err)
13999+ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
14000+
14001+ AuTraceErr(err);
4a4d8108
AM
14002+ return err;
14003+}
1facf9fc 14004+
4a4d8108
AM
14005+int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
14006+{
027c5e7a 14007+ int err, e, update;
4a4d8108 14008+ unsigned int flags;
027c5e7a 14009+ umode_t mode;
4a4d8108 14010+ aufs_bindex_t bindex, bend;
027c5e7a 14011+ unsigned char isdir;
4a4d8108
AM
14012+ struct au_hinode *p;
14013+ struct au_iinfo *iinfo;
1facf9fc 14014+
027c5e7a 14015+ err = au_ii_refresh(inode, &update);
4a4d8108
AM
14016+ if (unlikely(err))
14017+ goto out;
14018+
14019+ update = 0;
14020+ iinfo = au_ii(inode);
14021+ p = iinfo->ii_hinode + iinfo->ii_bstart;
027c5e7a
AM
14022+ mode = (inode->i_mode & S_IFMT);
14023+ isdir = S_ISDIR(mode);
4a4d8108
AM
14024+ flags = au_hi_flags(inode, isdir);
14025+ bend = au_dbend(dentry);
14026+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
14027+ struct inode *h_i;
14028+ struct dentry *h_d;
14029+
14030+ h_d = au_h_dptr(dentry, bindex);
14031+ if (!h_d || !h_d->d_inode)
14032+ continue;
14033+
027c5e7a 14034+ AuDebugOn(mode != (h_d->d_inode->i_mode & S_IFMT));
4a4d8108
AM
14035+ if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) {
14036+ h_i = au_h_iptr(inode, bindex);
14037+ if (h_i) {
14038+ if (h_i == h_d->d_inode)
14039+ continue;
14040+ err = -EIO;
14041+ break;
14042+ }
14043+ }
14044+ if (bindex < iinfo->ii_bstart)
14045+ iinfo->ii_bstart = bindex;
14046+ if (iinfo->ii_bend < bindex)
14047+ iinfo->ii_bend = bindex;
14048+ au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags);
14049+ update = 1;
1308ab2a 14050+ }
4a4d8108
AM
14051+ au_update_ibrange(inode, /*do_put_zero*/0);
14052+ e = au_dy_irefresh(inode);
14053+ if (unlikely(e && !err))
14054+ err = e;
027c5e7a
AM
14055+ if (!err)
14056+ au_refresh_hinode_attr(inode, update && isdir);
4a4d8108 14057+
4f0767ce 14058+out:
4a4d8108 14059+ AuTraceErr(err);
1308ab2a 14060+ return err;
dece6358
AM
14061+}
14062+
4a4d8108 14063+static int set_inode(struct inode *inode, struct dentry *dentry)
dece6358 14064+{
4a4d8108
AM
14065+ int err;
14066+ unsigned int flags;
14067+ umode_t mode;
14068+ aufs_bindex_t bindex, bstart, btail;
14069+ unsigned char isdir;
14070+ struct dentry *h_dentry;
14071+ struct inode *h_inode;
14072+ struct au_iinfo *iinfo;
dece6358 14073+
4a4d8108 14074+ IiMustWriteLock(inode);
dece6358 14075+
4a4d8108
AM
14076+ err = 0;
14077+ isdir = 0;
14078+ bstart = au_dbstart(dentry);
14079+ h_inode = au_h_dptr(dentry, bstart)->d_inode;
14080+ mode = h_inode->i_mode;
14081+ switch (mode & S_IFMT) {
14082+ case S_IFREG:
14083+ btail = au_dbtail(dentry);
14084+ inode->i_op = &aufs_iop;
14085+ inode->i_fop = &aufs_file_fop;
14086+ err = au_dy_iaop(inode, bstart, h_inode);
14087+ if (unlikely(err))
14088+ goto out;
14089+ break;
14090+ case S_IFDIR:
14091+ isdir = 1;
14092+ btail = au_dbtaildir(dentry);
14093+ inode->i_op = &aufs_dir_iop;
14094+ inode->i_fop = &aufs_dir_fop;
14095+ break;
14096+ case S_IFLNK:
14097+ btail = au_dbtail(dentry);
14098+ inode->i_op = &aufs_symlink_iop;
14099+ break;
14100+ case S_IFBLK:
14101+ case S_IFCHR:
14102+ case S_IFIFO:
14103+ case S_IFSOCK:
14104+ btail = au_dbtail(dentry);
14105+ inode->i_op = &aufs_iop;
14106+ au_init_special_fop(inode, mode, h_inode->i_rdev);
14107+ break;
14108+ default:
14109+ AuIOErr("Unknown file type 0%o\n", mode);
14110+ err = -EIO;
1308ab2a 14111+ goto out;
4a4d8108 14112+ }
dece6358 14113+
4a4d8108
AM
14114+ /* do not set hnotify for whiteouted dirs (SHWH mode) */
14115+ flags = au_hi_flags(inode, isdir);
14116+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
14117+ && au_ftest_hi(flags, HNOTIFY)
14118+ && dentry->d_name.len > AUFS_WH_PFX_LEN
14119+ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
14120+ au_fclr_hi(flags, HNOTIFY);
14121+ iinfo = au_ii(inode);
14122+ iinfo->ii_bstart = bstart;
14123+ iinfo->ii_bend = btail;
14124+ for (bindex = bstart; bindex <= btail; bindex++) {
14125+ h_dentry = au_h_dptr(dentry, bindex);
14126+ if (h_dentry)
14127+ au_set_h_iptr(inode, bindex,
14128+ au_igrab(h_dentry->d_inode), flags);
14129+ }
14130+ au_cpup_attr_all(inode, /*force*/1);
dece6358 14131+
4f0767ce 14132+out:
4a4d8108
AM
14133+ return err;
14134+}
dece6358 14135+
027c5e7a
AM
14136+/*
14137+ * successful returns with iinfo write_locked
14138+ * minus: errno
14139+ * zero: success, matched
14140+ * plus: no error, but unmatched
14141+ */
14142+static int reval_inode(struct inode *inode, struct dentry *dentry)
4a4d8108
AM
14143+{
14144+ int err;
537831f9
AM
14145+ unsigned int gen;
14146+ struct au_iigen iigen;
4a4d8108
AM
14147+ aufs_bindex_t bindex, bend;
14148+ struct inode *h_inode, *h_dinode;
dece6358 14149+
4a4d8108
AM
14150+ /*
14151+ * before this function, if aufs got any iinfo lock, it must be only
14152+ * one, the parent dir.
14153+ * it can happen by UDBA and the obsoleted inode number.
14154+ */
14155+ err = -EIO;
14156+ if (unlikely(inode->i_ino == parent_ino(dentry)))
14157+ goto out;
14158+
027c5e7a 14159+ err = 1;
4a4d8108
AM
14160+ ii_write_lock_new_child(inode);
14161+ h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode;
14162+ bend = au_ibend(inode);
14163+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
14164+ h_inode = au_h_iptr(inode, bindex);
537831f9
AM
14165+ if (!h_inode || h_inode != h_dinode)
14166+ continue;
14167+
14168+ err = 0;
14169+ gen = au_iigen(inode, &iigen);
14170+ if (gen == au_digen(dentry)
14171+ && !au_ig_ftest(iigen.ig_flags, HALF_REFRESHED))
4a4d8108 14172+ break;
537831f9
AM
14173+
14174+ /* fully refresh inode using dentry */
14175+ err = au_refresh_hinode(inode, dentry);
14176+ if (!err)
14177+ au_update_iigen(inode, /*half*/0);
14178+ break;
1facf9fc 14179+ }
dece6358 14180+
4a4d8108
AM
14181+ if (unlikely(err))
14182+ ii_write_unlock(inode);
4f0767ce 14183+out:
1facf9fc 14184+ return err;
14185+}
1facf9fc 14186+
4a4d8108
AM
14187+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
14188+ unsigned int d_type, ino_t *ino)
1facf9fc 14189+{
4a4d8108
AM
14190+ int err;
14191+ struct mutex *mtx;
1facf9fc 14192+
b752ccd1 14193+ /* prevent hardlinked inode number from race condition */
4a4d8108 14194+ mtx = NULL;
b752ccd1 14195+ if (d_type != DT_DIR) {
4a4d8108
AM
14196+ mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx;
14197+ mutex_lock(mtx);
14198+ }
14199+ err = au_xino_read(sb, bindex, h_ino, ino);
14200+ if (unlikely(err))
14201+ goto out;
1308ab2a 14202+
4a4d8108
AM
14203+ if (!*ino) {
14204+ err = -EIO;
14205+ *ino = au_xino_new_ino(sb);
14206+ if (unlikely(!*ino))
1facf9fc 14207+ goto out;
4a4d8108
AM
14208+ err = au_xino_write(sb, bindex, h_ino, *ino);
14209+ if (unlikely(err))
1308ab2a 14210+ goto out;
1308ab2a 14211+ }
1facf9fc 14212+
4f0767ce 14213+out:
b752ccd1 14214+ if (mtx)
4a4d8108 14215+ mutex_unlock(mtx);
1facf9fc 14216+ return err;
14217+}
14218+
4a4d8108
AM
14219+/* successful returns with iinfo write_locked */
14220+/* todo: return with unlocked? */
14221+struct inode *au_new_inode(struct dentry *dentry, int must_new)
1facf9fc 14222+{
b752ccd1 14223+ struct inode *inode, *h_inode;
4a4d8108
AM
14224+ struct dentry *h_dentry;
14225+ struct super_block *sb;
b752ccd1 14226+ struct mutex *mtx;
4a4d8108 14227+ ino_t h_ino, ino;
1716fcea 14228+ int err;
4a4d8108 14229+ aufs_bindex_t bstart;
1facf9fc 14230+
4a4d8108
AM
14231+ sb = dentry->d_sb;
14232+ bstart = au_dbstart(dentry);
14233+ h_dentry = au_h_dptr(dentry, bstart);
b752ccd1
AM
14234+ h_inode = h_dentry->d_inode;
14235+ h_ino = h_inode->i_ino;
14236+
14237+ /*
14238+ * stop 'race'-ing between hardlinks under different
14239+ * parents.
14240+ */
14241+ mtx = NULL;
14242+ if (!S_ISDIR(h_inode->i_mode))
14243+ mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;
14244+
4f0767ce 14245+new_ino:
b752ccd1
AM
14246+ if (mtx)
14247+ mutex_lock(mtx);
4a4d8108
AM
14248+ err = au_xino_read(sb, bstart, h_ino, &ino);
14249+ inode = ERR_PTR(err);
14250+ if (unlikely(err))
14251+ goto out;
b752ccd1 14252+
4a4d8108
AM
14253+ if (!ino) {
14254+ ino = au_xino_new_ino(sb);
14255+ if (unlikely(!ino)) {
14256+ inode = ERR_PTR(-EIO);
dece6358
AM
14257+ goto out;
14258+ }
14259+ }
1facf9fc 14260+
4a4d8108
AM
14261+ AuDbg("i%lu\n", (unsigned long)ino);
14262+ inode = au_iget_locked(sb, ino);
14263+ err = PTR_ERR(inode);
14264+ if (IS_ERR(inode))
1facf9fc 14265+ goto out;
1facf9fc 14266+
4a4d8108
AM
14267+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
14268+ if (inode->i_state & I_NEW) {
1716fcea
AM
14269+ /* verbose coding for lock class name */
14270+ if (unlikely(S_ISLNK(h_inode->i_mode)))
14271+ au_rw_class(&au_ii(inode)->ii_rwsem,
14272+ au_lc_key + AuLcSymlink_IIINFO);
14273+ else if (unlikely(S_ISDIR(h_inode->i_mode)))
14274+ au_rw_class(&au_ii(inode)->ii_rwsem,
14275+ au_lc_key + AuLcDir_IIINFO);
14276+ else /* likely */
14277+ au_rw_class(&au_ii(inode)->ii_rwsem,
14278+ au_lc_key + AuLcNonDir_IIINFO);
2dfbb274 14279+
4a4d8108
AM
14280+ ii_write_lock_new_child(inode);
14281+ err = set_inode(inode, dentry);
14282+ if (!err) {
14283+ unlock_new_inode(inode);
14284+ goto out; /* success */
14285+ }
1308ab2a 14286+
027c5e7a
AM
14287+ /*
14288+ * iget_failed() calls iput(), but we need to call
14289+ * ii_write_unlock() after iget_failed(). so dirty hack for
14290+ * i_count.
14291+ */
14292+ atomic_inc(&inode->i_count);
4a4d8108 14293+ iget_failed(inode);
027c5e7a
AM
14294+ ii_write_unlock(inode);
14295+ au_xino_write(sb, bstart, h_ino, /*ino*/0);
14296+ /* ignore this error */
14297+ goto out_iput;
14298+ } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) {
b752ccd1
AM
14299+ /*
14300+ * horrible race condition between lookup, readdir and copyup
14301+ * (or something).
14302+ */
14303+ if (mtx)
14304+ mutex_unlock(mtx);
027c5e7a
AM
14305+ err = reval_inode(inode, dentry);
14306+ if (unlikely(err < 0)) {
14307+ mtx = NULL;
14308+ goto out_iput;
14309+ }
14310+
b752ccd1
AM
14311+ if (!err) {
14312+ mtx = NULL;
4a4d8108 14313+ goto out; /* success */
b752ccd1
AM
14314+ } else if (mtx)
14315+ mutex_lock(mtx);
4a4d8108
AM
14316+ }
14317+
14318+ if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode)))
14319+ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
14320+ " b%d, %s, %.*s, hi%lu, i%lu.\n",
14321+ bstart, au_sbtype(h_dentry->d_sb), AuDLNPair(dentry),
14322+ (unsigned long)h_ino, (unsigned long)ino);
14323+ ino = 0;
14324+ err = au_xino_write(sb, bstart, h_ino, /*ino*/0);
14325+ if (!err) {
14326+ iput(inode);
b752ccd1
AM
14327+ if (mtx)
14328+ mutex_unlock(mtx);
4a4d8108
AM
14329+ goto new_ino;
14330+ }
1308ab2a 14331+
4f0767ce 14332+out_iput:
4a4d8108 14333+ iput(inode);
4a4d8108 14334+ inode = ERR_PTR(err);
4f0767ce 14335+out:
b752ccd1
AM
14336+ if (mtx)
14337+ mutex_unlock(mtx);
4a4d8108 14338+ return inode;
1facf9fc 14339+}
14340+
4a4d8108 14341+/* ---------------------------------------------------------------------- */
1facf9fc 14342+
4a4d8108
AM
14343+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
14344+ struct inode *inode)
14345+{
14346+ int err;
1facf9fc 14347+
4a4d8108 14348+ err = au_br_rdonly(au_sbr(sb, bindex));
1facf9fc 14349+
4a4d8108
AM
14350+ /* pseudo-link after flushed may happen out of bounds */
14351+ if (!err
14352+ && inode
14353+ && au_ibstart(inode) <= bindex
14354+ && bindex <= au_ibend(inode)) {
14355+ /*
14356+ * permission check is unnecessary since vfsub routine
14357+ * will be called later
14358+ */
14359+ struct inode *hi = au_h_iptr(inode, bindex);
14360+ if (hi)
14361+ err = IS_IMMUTABLE(hi) ? -EROFS : 0;
1facf9fc 14362+ }
14363+
4a4d8108
AM
14364+ return err;
14365+}
dece6358 14366+
4a4d8108
AM
14367+int au_test_h_perm(struct inode *h_inode, int mask)
14368+{
2dfbb274 14369+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
4a4d8108
AM
14370+ return 0;
14371+ return inode_permission(h_inode, mask);
14372+}
1facf9fc 14373+
4a4d8108
AM
14374+int au_test_h_perm_sio(struct inode *h_inode, int mask)
14375+{
14376+ if (au_test_nfs(h_inode->i_sb)
14377+ && (mask & MAY_WRITE)
14378+ && S_ISDIR(h_inode->i_mode))
14379+ mask |= MAY_READ; /* force permission check */
14380+ return au_test_h_perm(h_inode, mask);
1facf9fc 14381+}
7f207e10
AM
14382diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
14383--- /usr/share/empty/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
1716fcea 14384+++ linux/fs/aufs/inode.h 2013-02-19 08:40:03.950226347 +0100
537831f9 14385@@ -0,0 +1,588 @@
4a4d8108 14386+/*
7a9e40b8 14387+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
14388+ *
14389+ * This program, aufs is free software; you can redistribute it and/or modify
14390+ * it under the terms of the GNU General Public License as published by
14391+ * the Free Software Foundation; either version 2 of the License, or
14392+ * (at your option) any later version.
14393+ *
14394+ * This program is distributed in the hope that it will be useful,
14395+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14396+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14397+ * GNU General Public License for more details.
14398+ *
14399+ * You should have received a copy of the GNU General Public License
14400+ * along with this program; if not, write to the Free Software
14401+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14402+ */
1facf9fc 14403+
1308ab2a 14404+/*
4a4d8108 14405+ * inode operations
1308ab2a 14406+ */
dece6358 14407+
4a4d8108
AM
14408+#ifndef __AUFS_INODE_H__
14409+#define __AUFS_INODE_H__
dece6358 14410+
4a4d8108 14411+#ifdef __KERNEL__
1308ab2a 14412+
4a4d8108 14413+#include <linux/fsnotify.h>
4a4d8108 14414+#include "rwsem.h"
1308ab2a 14415+
4a4d8108 14416+struct vfsmount;
1facf9fc 14417+
4a4d8108
AM
14418+struct au_hnotify {
14419+#ifdef CONFIG_AUFS_HNOTIFY
14420+#ifdef CONFIG_AUFS_HFSNOTIFY
7f207e10 14421+ /* never use fsnotify_add_vfsmount_mark() */
0c5527e5 14422+ struct fsnotify_mark hn_mark;
4a4d8108 14423+#endif
7f207e10 14424+ struct inode *hn_aufs_inode; /* no get/put */
4a4d8108
AM
14425+#endif
14426+} ____cacheline_aligned_in_smp;
1facf9fc 14427+
4a4d8108
AM
14428+struct au_hinode {
14429+ struct inode *hi_inode;
14430+ aufs_bindex_t hi_id;
14431+#ifdef CONFIG_AUFS_HNOTIFY
14432+ struct au_hnotify *hi_notify;
14433+#endif
dece6358 14434+
4a4d8108
AM
14435+ /* reference to the copied-up whiteout with get/put */
14436+ struct dentry *hi_whdentry;
14437+};
dece6358 14438+
537831f9
AM
14439+/* ig_flags */
14440+#define AuIG_HALF_REFRESHED 1
14441+#define au_ig_ftest(flags, name) ((flags) & AuIG_##name)
14442+#define au_ig_fset(flags, name) \
14443+ do { (flags) |= AuIG_##name; } while (0)
14444+#define au_ig_fclr(flags, name) \
14445+ do { (flags) &= ~AuIG_##name; } while (0)
14446+
14447+struct au_iigen {
14448+ __u32 ig_generation, ig_flags;
14449+};
14450+
4a4d8108
AM
14451+struct au_vdir;
14452+struct au_iinfo {
537831f9 14453+ spinlock_t ii_genspin;
7a9e40b8 14454+ struct au_iigen ii_generation;
4a4d8108 14455+ struct super_block *ii_hsb1; /* no get/put */
1facf9fc 14456+
4a4d8108
AM
14457+ struct au_rwsem ii_rwsem;
14458+ aufs_bindex_t ii_bstart, ii_bend;
14459+ __u32 ii_higen;
14460+ struct au_hinode *ii_hinode;
14461+ struct au_vdir *ii_vdir;
14462+};
1facf9fc 14463+
4a4d8108
AM
14464+struct au_icntnr {
14465+ struct au_iinfo iinfo;
14466+ struct inode vfs_inode;
14467+} ____cacheline_aligned_in_smp;
1308ab2a 14468+
4a4d8108
AM
14469+/* au_pin flags */
14470+#define AuPin_DI_LOCKED 1
14471+#define AuPin_MNT_WRITE (1 << 1)
14472+#define au_ftest_pin(flags, name) ((flags) & AuPin_##name)
7f207e10
AM
14473+#define au_fset_pin(flags, name) \
14474+ do { (flags) |= AuPin_##name; } while (0)
14475+#define au_fclr_pin(flags, name) \
14476+ do { (flags) &= ~AuPin_##name; } while (0)
4a4d8108
AM
14477+
14478+struct au_pin {
14479+ /* input */
14480+ struct dentry *dentry;
14481+ unsigned int udba;
14482+ unsigned char lsc_di, lsc_hi, flags;
14483+ aufs_bindex_t bindex;
14484+
14485+ /* output */
14486+ struct dentry *parent;
14487+ struct au_hinode *hdir;
14488+ struct vfsmount *h_mnt;
14489+};
1facf9fc 14490+
1308ab2a 14491+/* ---------------------------------------------------------------------- */
14492+
4a4d8108 14493+static inline struct au_iinfo *au_ii(struct inode *inode)
1facf9fc 14494+{
4a4d8108 14495+ struct au_iinfo *iinfo;
1facf9fc 14496+
4a4d8108
AM
14497+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
14498+ if (iinfo->ii_hinode)
14499+ return iinfo;
14500+ return NULL; /* debugging bad_inode case */
14501+}
1facf9fc 14502+
4a4d8108 14503+/* ---------------------------------------------------------------------- */
1facf9fc 14504+
4a4d8108
AM
14505+/* inode.c */
14506+struct inode *au_igrab(struct inode *inode);
027c5e7a 14507+int au_refresh_hinode_self(struct inode *inode);
4a4d8108
AM
14508+int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
14509+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
14510+ unsigned int d_type, ino_t *ino);
14511+struct inode *au_new_inode(struct dentry *dentry, int must_new);
14512+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
14513+ struct inode *inode);
14514+int au_test_h_perm(struct inode *h_inode, int mask);
14515+int au_test_h_perm_sio(struct inode *h_inode, int mask);
1facf9fc 14516+
4a4d8108
AM
14517+static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex,
14518+ ino_t h_ino, unsigned int d_type, ino_t *ino)
14519+{
14520+#ifdef CONFIG_AUFS_SHWH
14521+ return au_ino(sb, bindex, h_ino, d_type, ino);
14522+#else
14523+ return 0;
14524+#endif
14525+}
1facf9fc 14526+
4a4d8108
AM
14527+/* i_op.c */
14528+extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
1308ab2a 14529+
4a4d8108
AM
14530+/* au_wr_dir flags */
14531+#define AuWrDir_ADD_ENTRY 1
14532+#define AuWrDir_ISDIR (1 << 1)
14533+#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
7f207e10
AM
14534+#define au_fset_wrdir(flags, name) \
14535+ do { (flags) |= AuWrDir_##name; } while (0)
14536+#define au_fclr_wrdir(flags, name) \
14537+ do { (flags) &= ~AuWrDir_##name; } while (0)
1facf9fc 14538+
4a4d8108
AM
14539+struct au_wr_dir_args {
14540+ aufs_bindex_t force_btgt;
14541+ unsigned char flags;
14542+};
14543+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
14544+ struct au_wr_dir_args *args);
dece6358 14545+
4a4d8108
AM
14546+struct dentry *au_pinned_h_parent(struct au_pin *pin);
14547+void au_pin_init(struct au_pin *pin, struct dentry *dentry,
14548+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
14549+ unsigned int udba, unsigned char flags);
14550+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
14551+ unsigned int udba, unsigned char flags) __must_check;
14552+int au_do_pin(struct au_pin *pin) __must_check;
14553+void au_unpin(struct au_pin *pin);
1facf9fc 14554+
4a4d8108
AM
14555+/* i_op_add.c */
14556+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
14557+ struct dentry *h_parent, int isdir);
7eafdf33
AM
14558+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
14559+ dev_t dev);
4a4d8108 14560+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
7eafdf33 14561+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 14562+ bool want_excl);
4a4d8108
AM
14563+int aufs_link(struct dentry *src_dentry, struct inode *dir,
14564+ struct dentry *dentry);
7eafdf33 14565+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
1facf9fc 14566+
4a4d8108
AM
14567+/* i_op_del.c */
14568+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
14569+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
14570+ struct dentry *h_parent, int isdir);
14571+int aufs_unlink(struct inode *dir, struct dentry *dentry);
14572+int aufs_rmdir(struct inode *dir, struct dentry *dentry);
1308ab2a 14573+
4a4d8108
AM
14574+/* i_op_ren.c */
14575+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
14576+int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
14577+ struct inode *dir, struct dentry *dentry);
1facf9fc 14578+
4a4d8108
AM
14579+/* iinfo.c */
14580+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
14581+void au_hiput(struct au_hinode *hinode);
14582+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
14583+ struct dentry *h_wh);
14584+unsigned int au_hi_flags(struct inode *inode, int isdir);
1308ab2a 14585+
4a4d8108
AM
14586+/* hinode flags */
14587+#define AuHi_XINO 1
14588+#define AuHi_HNOTIFY (1 << 1)
14589+#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
7f207e10
AM
14590+#define au_fset_hi(flags, name) \
14591+ do { (flags) |= AuHi_##name; } while (0)
14592+#define au_fclr_hi(flags, name) \
14593+ do { (flags) &= ~AuHi_##name; } while (0)
1facf9fc 14594+
4a4d8108
AM
14595+#ifndef CONFIG_AUFS_HNOTIFY
14596+#undef AuHi_HNOTIFY
14597+#define AuHi_HNOTIFY 0
14598+#endif
1facf9fc 14599+
4a4d8108
AM
14600+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
14601+ struct inode *h_inode, unsigned int flags);
1facf9fc 14602+
537831f9 14603+void au_update_iigen(struct inode *inode, int half);
4a4d8108 14604+void au_update_ibrange(struct inode *inode, int do_put_zero);
1facf9fc 14605+
4a4d8108
AM
14606+void au_icntnr_init_once(void *_c);
14607+int au_iinfo_init(struct inode *inode);
14608+void au_iinfo_fin(struct inode *inode);
14609+int au_ii_realloc(struct au_iinfo *iinfo, int nbr);
1308ab2a 14610+
e49829fe 14611+#ifdef CONFIG_PROC_FS
4a4d8108 14612+/* plink.c */
e49829fe
JR
14613+int au_plink_maint(struct super_block *sb, int flags);
14614+void au_plink_maint_leave(struct au_sbinfo *sbinfo);
14615+int au_plink_maint_enter(struct super_block *sb);
4a4d8108
AM
14616+#ifdef CONFIG_AUFS_DEBUG
14617+void au_plink_list(struct super_block *sb);
14618+#else
14619+AuStubVoid(au_plink_list, struct super_block *sb)
14620+#endif
14621+int au_plink_test(struct inode *inode);
14622+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
14623+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
14624+ struct dentry *h_dentry);
e49829fe
JR
14625+void au_plink_put(struct super_block *sb, int verbose);
14626+void au_plink_clean(struct super_block *sb, int verbose);
4a4d8108 14627+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
e49829fe
JR
14628+#else
14629+AuStubInt0(au_plink_maint, struct super_block *sb, int flags);
14630+AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo);
14631+AuStubInt0(au_plink_maint_enter, struct super_block *sb);
14632+AuStubVoid(au_plink_list, struct super_block *sb);
14633+AuStubInt0(au_plink_test, struct inode *inode);
14634+AuStub(struct dentry *, au_plink_lkup, return NULL,
14635+ struct inode *inode, aufs_bindex_t bindex);
14636+AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex,
14637+ struct dentry *h_dentry);
14638+AuStubVoid(au_plink_put, struct super_block *sb, int verbose);
14639+AuStubVoid(au_plink_clean, struct super_block *sb, int verbose);
14640+AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id);
14641+#endif /* CONFIG_PROC_FS */
1facf9fc 14642+
4a4d8108 14643+/* ---------------------------------------------------------------------- */
1308ab2a 14644+
4a4d8108
AM
14645+/* lock subclass for iinfo */
14646+enum {
14647+ AuLsc_II_CHILD, /* child first */
14648+ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */
14649+ AuLsc_II_CHILD3, /* copyup dirs */
14650+ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
14651+ AuLsc_II_PARENT2,
14652+ AuLsc_II_PARENT3, /* copyup dirs */
14653+ AuLsc_II_NEW_CHILD
14654+};
1308ab2a 14655+
1facf9fc 14656+/*
4a4d8108
AM
14657+ * ii_read_lock_child, ii_write_lock_child,
14658+ * ii_read_lock_child2, ii_write_lock_child2,
14659+ * ii_read_lock_child3, ii_write_lock_child3,
14660+ * ii_read_lock_parent, ii_write_lock_parent,
14661+ * ii_read_lock_parent2, ii_write_lock_parent2,
14662+ * ii_read_lock_parent3, ii_write_lock_parent3,
14663+ * ii_read_lock_new_child, ii_write_lock_new_child,
1facf9fc 14664+ */
4a4d8108
AM
14665+#define AuReadLockFunc(name, lsc) \
14666+static inline void ii_read_lock_##name(struct inode *i) \
14667+{ \
14668+ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
14669+}
14670+
14671+#define AuWriteLockFunc(name, lsc) \
14672+static inline void ii_write_lock_##name(struct inode *i) \
14673+{ \
14674+ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
14675+}
14676+
14677+#define AuRWLockFuncs(name, lsc) \
14678+ AuReadLockFunc(name, lsc) \
14679+ AuWriteLockFunc(name, lsc)
14680+
14681+AuRWLockFuncs(child, CHILD);
14682+AuRWLockFuncs(child2, CHILD2);
14683+AuRWLockFuncs(child3, CHILD3);
14684+AuRWLockFuncs(parent, PARENT);
14685+AuRWLockFuncs(parent2, PARENT2);
14686+AuRWLockFuncs(parent3, PARENT3);
14687+AuRWLockFuncs(new_child, NEW_CHILD);
14688+
14689+#undef AuReadLockFunc
14690+#undef AuWriteLockFunc
14691+#undef AuRWLockFuncs
1facf9fc 14692+
14693+/*
4a4d8108 14694+ * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
1facf9fc 14695+ */
4a4d8108 14696+AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
1facf9fc 14697+
4a4d8108
AM
14698+#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
14699+#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
14700+#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
1facf9fc 14701+
4a4d8108 14702+/* ---------------------------------------------------------------------- */
1308ab2a 14703+
027c5e7a
AM
14704+static inline void au_icntnr_init(struct au_icntnr *c)
14705+{
14706+#ifdef CONFIG_AUFS_DEBUG
14707+ c->vfs_inode.i_mode = 0;
14708+#endif
14709+}
14710+
537831f9 14711+static inline unsigned int au_iigen(struct inode *inode, struct au_iigen *iigen)
4a4d8108 14712+{
537831f9
AM
14713+ unsigned int gen;
14714+ struct au_iinfo *iinfo;
14715+
14716+ iinfo = au_ii(inode);
14717+ spin_lock(&iinfo->ii_genspin);
14718+ if (iigen)
14719+ *iigen = iinfo->ii_generation;
14720+ gen = iinfo->ii_generation.ig_generation;
14721+ spin_unlock(&iinfo->ii_genspin);
14722+
14723+ return gen;
4a4d8108 14724+}
1308ab2a 14725+
4a4d8108
AM
14726+/* tiny test for inode number */
14727+/* tmpfs generation is too rough */
14728+static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
14729+{
14730+ struct au_iinfo *iinfo;
1308ab2a 14731+
4a4d8108
AM
14732+ iinfo = au_ii(inode);
14733+ AuRwMustAnyLock(&iinfo->ii_rwsem);
14734+ return !(iinfo->ii_hsb1 == h_inode->i_sb
14735+ && iinfo->ii_higen == h_inode->i_generation);
14736+}
1308ab2a 14737+
4a4d8108
AM
14738+static inline void au_iigen_dec(struct inode *inode)
14739+{
537831f9
AM
14740+ struct au_iinfo *iinfo;
14741+
14742+ iinfo = au_ii(inode);
14743+ spin_lock(&iinfo->ii_genspin);
14744+ iinfo->ii_generation.ig_generation--;
14745+ spin_unlock(&iinfo->ii_genspin);
027c5e7a
AM
14746+}
14747+
14748+static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
14749+{
14750+ int err;
14751+
14752+ err = 0;
537831f9 14753+ if (unlikely(inode && au_iigen(inode, NULL) != sigen))
027c5e7a
AM
14754+ err = -EIO;
14755+
14756+ return err;
4a4d8108 14757+}
1308ab2a 14758+
4a4d8108 14759+/* ---------------------------------------------------------------------- */
1308ab2a 14760+
4a4d8108
AM
14761+static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
14762+ aufs_bindex_t bindex)
14763+{
14764+ IiMustAnyLock(inode);
14765+ return au_ii(inode)->ii_hinode[0 + bindex].hi_id;
14766+}
1308ab2a 14767+
4a4d8108
AM
14768+static inline aufs_bindex_t au_ibstart(struct inode *inode)
14769+{
14770+ IiMustAnyLock(inode);
14771+ return au_ii(inode)->ii_bstart;
14772+}
1308ab2a 14773+
4a4d8108
AM
14774+static inline aufs_bindex_t au_ibend(struct inode *inode)
14775+{
14776+ IiMustAnyLock(inode);
14777+ return au_ii(inode)->ii_bend;
14778+}
1308ab2a 14779+
4a4d8108
AM
14780+static inline struct au_vdir *au_ivdir(struct inode *inode)
14781+{
14782+ IiMustAnyLock(inode);
14783+ return au_ii(inode)->ii_vdir;
14784+}
1308ab2a 14785+
4a4d8108
AM
14786+static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
14787+{
14788+ IiMustAnyLock(inode);
14789+ return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry;
14790+}
1308ab2a 14791+
4a4d8108 14792+static inline void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 14793+{
4a4d8108
AM
14794+ IiMustWriteLock(inode);
14795+ au_ii(inode)->ii_bstart = bindex;
14796+}
1308ab2a 14797+
4a4d8108
AM
14798+static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex)
14799+{
14800+ IiMustWriteLock(inode);
14801+ au_ii(inode)->ii_bend = bindex;
1308ab2a 14802+}
14803+
4a4d8108
AM
14804+static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
14805+{
14806+ IiMustWriteLock(inode);
14807+ au_ii(inode)->ii_vdir = vdir;
14808+}
1facf9fc 14809+
4a4d8108 14810+static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 14811+{
4a4d8108
AM
14812+ IiMustAnyLock(inode);
14813+ return au_ii(inode)->ii_hinode + bindex;
14814+}
dece6358 14815+
4a4d8108 14816+/* ---------------------------------------------------------------------- */
1facf9fc 14817+
4a4d8108
AM
14818+static inline struct dentry *au_pinned_parent(struct au_pin *pin)
14819+{
14820+ if (pin)
14821+ return pin->parent;
14822+ return NULL;
1facf9fc 14823+}
14824+
4a4d8108 14825+static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
1facf9fc 14826+{
4a4d8108
AM
14827+ if (pin && pin->hdir)
14828+ return pin->hdir->hi_inode;
14829+ return NULL;
1308ab2a 14830+}
1facf9fc 14831+
4a4d8108
AM
14832+static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
14833+{
14834+ if (pin)
14835+ return pin->hdir;
14836+ return NULL;
14837+}
1facf9fc 14838+
4a4d8108 14839+static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
1308ab2a 14840+{
4a4d8108
AM
14841+ if (pin)
14842+ pin->dentry = dentry;
14843+}
1308ab2a 14844+
4a4d8108
AM
14845+static inline void au_pin_set_parent_lflag(struct au_pin *pin,
14846+ unsigned char lflag)
14847+{
14848+ if (pin) {
7f207e10 14849+ if (lflag)
4a4d8108 14850+ au_fset_pin(pin->flags, DI_LOCKED);
7f207e10 14851+ else
4a4d8108 14852+ au_fclr_pin(pin->flags, DI_LOCKED);
1308ab2a 14853+ }
4a4d8108
AM
14854+}
14855+
14856+static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
14857+{
14858+ if (pin) {
14859+ dput(pin->parent);
14860+ pin->parent = dget(parent);
1facf9fc 14861+ }
4a4d8108 14862+}
1facf9fc 14863+
4a4d8108
AM
14864+/* ---------------------------------------------------------------------- */
14865+
027c5e7a 14866+struct au_branch;
4a4d8108
AM
14867+#ifdef CONFIG_AUFS_HNOTIFY
14868+struct au_hnotify_op {
14869+ void (*ctl)(struct au_hinode *hinode, int do_set);
027c5e7a 14870+ int (*alloc)(struct au_hinode *hinode);
7eafdf33
AM
14871+
14872+ /*
14873+ * if it returns true, the the caller should free hinode->hi_notify,
14874+ * otherwise ->free() frees it.
14875+ */
14876+ int (*free)(struct au_hinode *hinode,
14877+ struct au_hnotify *hn) __must_check;
4a4d8108
AM
14878+
14879+ void (*fin)(void);
14880+ int (*init)(void);
027c5e7a
AM
14881+
14882+ int (*reset_br)(unsigned int udba, struct au_branch *br, int perm);
14883+ void (*fin_br)(struct au_branch *br);
14884+ int (*init_br)(struct au_branch *br, int perm);
4a4d8108
AM
14885+};
14886+
14887+/* hnotify.c */
027c5e7a 14888+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
4a4d8108
AM
14889+void au_hn_free(struct au_hinode *hinode);
14890+void au_hn_ctl(struct au_hinode *hinode, int do_set);
14891+void au_hn_reset(struct inode *inode, unsigned int flags);
14892+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
14893+ struct qstr *h_child_qstr, struct inode *h_child_inode);
027c5e7a
AM
14894+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm);
14895+int au_hnotify_init_br(struct au_branch *br, int perm);
14896+void au_hnotify_fin_br(struct au_branch *br);
4a4d8108
AM
14897+int __init au_hnotify_init(void);
14898+void au_hnotify_fin(void);
14899+
7f207e10 14900+/* hfsnotify.c */
4a4d8108
AM
14901+extern const struct au_hnotify_op au_hnotify_op;
14902+
14903+static inline
14904+void au_hn_init(struct au_hinode *hinode)
14905+{
14906+ hinode->hi_notify = NULL;
1308ab2a 14907+}
14908+
53392da6
AM
14909+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
14910+{
14911+ return hinode->hi_notify;
14912+}
14913+
4a4d8108
AM
14914+#else
14915+static inline
14916+int au_hn_alloc(struct au_hinode *hinode __maybe_unused,
027c5e7a 14917+ struct inode *inode __maybe_unused)
1308ab2a 14918+{
4a4d8108
AM
14919+ return -EOPNOTSUPP;
14920+}
1308ab2a 14921+
53392da6
AM
14922+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
14923+{
14924+ return NULL;
14925+}
14926+
4a4d8108
AM
14927+AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused)
14928+AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused,
14929+ int do_set __maybe_unused)
14930+AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused,
14931+ unsigned int flags __maybe_unused)
027c5e7a
AM
14932+AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused,
14933+ struct au_branch *br __maybe_unused,
14934+ int perm __maybe_unused)
14935+AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused,
14936+ int perm __maybe_unused)
14937+AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused)
4a4d8108
AM
14938+AuStubInt0(__init au_hnotify_init, void)
14939+AuStubVoid(au_hnotify_fin, void)
14940+AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused)
14941+#endif /* CONFIG_AUFS_HNOTIFY */
14942+
14943+static inline void au_hn_suspend(struct au_hinode *hdir)
14944+{
14945+ au_hn_ctl(hdir, /*do_set*/0);
1308ab2a 14946+}
14947+
4a4d8108 14948+static inline void au_hn_resume(struct au_hinode *hdir)
1308ab2a 14949+{
4a4d8108
AM
14950+ au_hn_ctl(hdir, /*do_set*/1);
14951+}
1308ab2a 14952+
4a4d8108
AM
14953+static inline void au_hn_imtx_lock(struct au_hinode *hdir)
14954+{
14955+ mutex_lock(&hdir->hi_inode->i_mutex);
14956+ au_hn_suspend(hdir);
14957+}
dece6358 14958+
4a4d8108
AM
14959+static inline void au_hn_imtx_lock_nested(struct au_hinode *hdir,
14960+ unsigned int sc __maybe_unused)
14961+{
14962+ mutex_lock_nested(&hdir->hi_inode->i_mutex, sc);
14963+ au_hn_suspend(hdir);
1facf9fc 14964+}
1facf9fc 14965+
4a4d8108
AM
14966+static inline void au_hn_imtx_unlock(struct au_hinode *hdir)
14967+{
14968+ au_hn_resume(hdir);
14969+ mutex_unlock(&hdir->hi_inode->i_mutex);
14970+}
14971+
14972+#endif /* __KERNEL__ */
14973+#endif /* __AUFS_INODE_H__ */
7f207e10
AM
14974diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c
14975--- /usr/share/empty/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100
1716fcea 14976+++ linux/fs/aufs/ioctl.c 2013-02-19 08:40:03.950226347 +0100
f6c5ef8b 14977@@ -0,0 +1,196 @@
4a4d8108 14978+/*
7a9e40b8 14979+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
14980+ *
14981+ * This program, aufs is free software; you can redistribute it and/or modify
14982+ * it under the terms of the GNU General Public License as published by
14983+ * the Free Software Foundation; either version 2 of the License, or
14984+ * (at your option) any later version.
14985+ *
14986+ * This program is distributed in the hope that it will be useful,
14987+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14988+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14989+ * GNU General Public License for more details.
14990+ *
14991+ * You should have received a copy of the GNU General Public License
14992+ * along with this program; if not, write to the Free Software
14993+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14994+ */
14995+
14996+/*
14997+ * ioctl
14998+ * plink-management and readdir in userspace.
14999+ * assist the pathconf(3) wrapper library.
15000+ */
15001+
4a4d8108
AM
15002+#include "aufs.h"
15003+
1e00d052 15004+static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
4a4d8108
AM
15005+{
15006+ int err, fd;
15007+ aufs_bindex_t wbi, bindex, bend;
15008+ struct file *h_file;
15009+ struct super_block *sb;
15010+ struct dentry *root;
1e00d052
AM
15011+ struct au_branch *br;
15012+ struct aufs_wbr_fd wbrfd = {
15013+ .oflags = au_dir_roflags,
15014+ .brid = -1
15015+ };
15016+ const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY
15017+ | O_NOATIME | O_CLOEXEC;
4a4d8108 15018+
1e00d052
AM
15019+ AuDebugOn(wbrfd.oflags & ~valid);
15020+
15021+ if (arg) {
15022+ err = copy_from_user(&wbrfd, arg, sizeof(wbrfd));
15023+ if (unlikely(err)) {
15024+ err = -EFAULT;
15025+ goto out;
15026+ }
15027+
15028+ err = -EINVAL;
15029+ AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid);
15030+ wbrfd.oflags |= au_dir_roflags;
15031+ AuDbg("0%o\n", wbrfd.oflags);
15032+ if (unlikely(wbrfd.oflags & ~valid))
15033+ goto out;
15034+ }
15035+
15036+ fd = get_unused_fd();
15037+ err = fd;
15038+ if (unlikely(fd < 0))
4a4d8108 15039+ goto out;
4a4d8108 15040+
1e00d052 15041+ h_file = ERR_PTR(-EINVAL);
4a4d8108 15042+ wbi = 0;
1e00d052 15043+ br = NULL;
4a4d8108
AM
15044+ sb = path->dentry->d_sb;
15045+ root = sb->s_root;
15046+ aufs_read_lock(root, AuLock_IR);
1e00d052
AM
15047+ bend = au_sbend(sb);
15048+ if (wbrfd.brid >= 0) {
15049+ wbi = au_br_index(sb, wbrfd.brid);
15050+ if (unlikely(wbi < 0 || wbi > bend))
15051+ goto out_unlock;
15052+ }
15053+
15054+ h_file = ERR_PTR(-ENOENT);
15055+ br = au_sbr(sb, wbi);
15056+ if (!au_br_writable(br->br_perm)) {
15057+ if (arg)
15058+ goto out_unlock;
15059+
15060+ bindex = wbi + 1;
15061+ wbi = -1;
15062+ for (; bindex <= bend; bindex++) {
15063+ br = au_sbr(sb, bindex);
15064+ if (au_br_writable(br->br_perm)) {
4a4d8108 15065+ wbi = bindex;
1e00d052 15066+ br = au_sbr(sb, wbi);
4a4d8108
AM
15067+ break;
15068+ }
15069+ }
4a4d8108
AM
15070+ }
15071+ AuDbg("wbi %d\n", wbi);
1e00d052
AM
15072+ if (wbi >= 0)
15073+ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL);
15074+
15075+out_unlock:
4a4d8108
AM
15076+ aufs_read_unlock(root, AuLock_IR);
15077+ err = PTR_ERR(h_file);
15078+ if (IS_ERR(h_file))
15079+ goto out_fd;
15080+
1e00d052 15081+ atomic_dec(&br->br_count); /* cf. au_h_open() */
4a4d8108
AM
15082+ fd_install(fd, h_file);
15083+ err = fd;
15084+ goto out; /* success */
15085+
4f0767ce 15086+out_fd:
4a4d8108 15087+ put_unused_fd(fd);
4f0767ce 15088+out:
1e00d052 15089+ AuTraceErr(err);
4a4d8108
AM
15090+ return err;
15091+}
15092+
15093+/* ---------------------------------------------------------------------- */
15094+
15095+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
15096+{
15097+ long err;
15098+
15099+ switch (cmd) {
4a4d8108
AM
15100+ case AUFS_CTL_RDU:
15101+ case AUFS_CTL_RDU_INO:
15102+ err = au_rdu_ioctl(file, cmd, arg);
15103+ break;
15104+
15105+ case AUFS_CTL_WBR_FD:
1e00d052 15106+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
15107+ break;
15108+
027c5e7a
AM
15109+ case AUFS_CTL_IBUSY:
15110+ err = au_ibusy_ioctl(file, arg);
15111+ break;
15112+
4a4d8108
AM
15113+ default:
15114+ /* do not call the lower */
15115+ AuDbg("0x%x\n", cmd);
15116+ err = -ENOTTY;
15117+ }
15118+
15119+ AuTraceErr(err);
15120+ return err;
15121+}
15122+
15123+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
15124+{
15125+ long err;
15126+
15127+ switch (cmd) {
15128+ case AUFS_CTL_WBR_FD:
1e00d052 15129+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
15130+ break;
15131+
15132+ default:
15133+ /* do not call the lower */
15134+ AuDbg("0x%x\n", cmd);
15135+ err = -ENOTTY;
15136+ }
15137+
15138+ AuTraceErr(err);
15139+ return err;
15140+}
b752ccd1
AM
15141+
15142+#ifdef CONFIG_COMPAT
15143+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
15144+ unsigned long arg)
15145+{
15146+ long err;
15147+
15148+ switch (cmd) {
15149+ case AUFS_CTL_RDU:
15150+ case AUFS_CTL_RDU_INO:
15151+ err = au_rdu_compat_ioctl(file, cmd, arg);
15152+ break;
15153+
027c5e7a
AM
15154+ case AUFS_CTL_IBUSY:
15155+ err = au_ibusy_compat_ioctl(file, arg);
15156+ break;
15157+
b752ccd1
AM
15158+ default:
15159+ err = aufs_ioctl_dir(file, cmd, arg);
15160+ }
15161+
15162+ AuTraceErr(err);
15163+ return err;
15164+}
15165+
15166+#if 0 /* unused yet */
15167+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
15168+ unsigned long arg)
15169+{
15170+ return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg));
15171+}
15172+#endif
15173+#endif
7f207e10
AM
15174diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
15175--- /usr/share/empty/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
1716fcea 15176+++ linux/fs/aufs/i_op_add.c 2013-02-19 08:40:03.950226347 +0100
537831f9 15177@@ -0,0 +1,713 @@
4a4d8108 15178+/*
7a9e40b8 15179+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
15180+ *
15181+ * This program, aufs is free software; you can redistribute it and/or modify
15182+ * it under the terms of the GNU General Public License as published by
15183+ * the Free Software Foundation; either version 2 of the License, or
15184+ * (at your option) any later version.
15185+ *
15186+ * This program is distributed in the hope that it will be useful,
15187+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15188+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15189+ * GNU General Public License for more details.
15190+ *
15191+ * You should have received a copy of the GNU General Public License
15192+ * along with this program; if not, write to the Free Software
15193+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15194+ */
15195+
15196+/*
15197+ * inode operations (add entry)
15198+ */
15199+
15200+#include "aufs.h"
15201+
15202+/*
15203+ * final procedure of adding a new entry, except link(2).
15204+ * remove whiteout, instantiate, copyup the parent dir's times and size
15205+ * and update version.
15206+ * if it failed, re-create the removed whiteout.
15207+ */
15208+static int epilog(struct inode *dir, aufs_bindex_t bindex,
15209+ struct dentry *wh_dentry, struct dentry *dentry)
15210+{
15211+ int err, rerr;
15212+ aufs_bindex_t bwh;
15213+ struct path h_path;
15214+ struct inode *inode, *h_dir;
15215+ struct dentry *wh;
15216+
15217+ bwh = -1;
15218+ if (wh_dentry) {
15219+ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
15220+ IMustLock(h_dir);
15221+ AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
15222+ bwh = au_dbwh(dentry);
15223+ h_path.dentry = wh_dentry;
15224+ h_path.mnt = au_sbr_mnt(dir->i_sb, bindex);
15225+ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
15226+ dentry);
15227+ if (unlikely(err))
15228+ goto out;
15229+ }
15230+
15231+ inode = au_new_inode(dentry, /*must_new*/1);
15232+ if (!IS_ERR(inode)) {
15233+ d_instantiate(dentry, inode);
15234+ dir = dentry->d_parent->d_inode; /* dir inode is locked */
15235+ IMustLock(dir);
15236+ if (au_ibstart(dir) == au_dbstart(dentry))
15237+ au_cpup_attr_timesizes(dir);
15238+ dir->i_version++;
15239+ return 0; /* success */
15240+ }
15241+
15242+ err = PTR_ERR(inode);
15243+ if (!wh_dentry)
15244+ goto out;
15245+
15246+ /* revert */
15247+ /* dir inode is locked */
15248+ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
15249+ rerr = PTR_ERR(wh);
15250+ if (IS_ERR(wh)) {
15251+ AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
15252+ AuDLNPair(dentry), err, rerr);
15253+ err = -EIO;
15254+ } else
15255+ dput(wh);
15256+
4f0767ce 15257+out:
4a4d8108
AM
15258+ return err;
15259+}
15260+
027c5e7a
AM
15261+static int au_d_may_add(struct dentry *dentry)
15262+{
15263+ int err;
15264+
15265+ err = 0;
15266+ if (unlikely(d_unhashed(dentry)))
15267+ err = -ENOENT;
15268+ if (unlikely(dentry->d_inode))
15269+ err = -EEXIST;
15270+ return err;
15271+}
15272+
4a4d8108
AM
15273+/*
15274+ * simple tests for the adding inode operations.
15275+ * following the checks in vfs, plus the parent-child relationship.
15276+ */
15277+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
15278+ struct dentry *h_parent, int isdir)
15279+{
15280+ int err;
15281+ umode_t h_mode;
15282+ struct dentry *h_dentry;
15283+ struct inode *h_inode;
15284+
15285+ err = -ENAMETOOLONG;
15286+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
15287+ goto out;
15288+
15289+ h_dentry = au_h_dptr(dentry, bindex);
15290+ h_inode = h_dentry->d_inode;
15291+ if (!dentry->d_inode) {
15292+ err = -EEXIST;
15293+ if (unlikely(h_inode))
15294+ goto out;
15295+ } else {
15296+ /* rename(2) case */
15297+ err = -EIO;
15298+ if (unlikely(!h_inode || !h_inode->i_nlink))
15299+ goto out;
15300+
15301+ h_mode = h_inode->i_mode;
15302+ if (!isdir) {
15303+ err = -EISDIR;
15304+ if (unlikely(S_ISDIR(h_mode)))
15305+ goto out;
15306+ } else if (unlikely(!S_ISDIR(h_mode))) {
15307+ err = -ENOTDIR;
15308+ goto out;
15309+ }
15310+ }
15311+
15312+ err = 0;
15313+ /* expected parent dir is locked */
15314+ if (unlikely(h_parent != h_dentry->d_parent))
15315+ err = -EIO;
15316+
4f0767ce 15317+out:
4a4d8108
AM
15318+ AuTraceErr(err);
15319+ return err;
15320+}
15321+
15322+/*
15323+ * initial procedure of adding a new entry.
15324+ * prepare writable branch and the parent dir, lock it,
15325+ * and lookup whiteout for the new entry.
15326+ */
15327+static struct dentry*
15328+lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
15329+ struct dentry *src_dentry, struct au_pin *pin,
15330+ struct au_wr_dir_args *wr_dir_args)
15331+{
15332+ struct dentry *wh_dentry, *h_parent;
15333+ struct super_block *sb;
15334+ struct au_branch *br;
15335+ int err;
15336+ unsigned int udba;
15337+ aufs_bindex_t bcpup;
15338+
15339+ AuDbg("%.*s\n", AuDLNPair(dentry));
15340+
15341+ err = au_wr_dir(dentry, src_dentry, wr_dir_args);
15342+ bcpup = err;
15343+ wh_dentry = ERR_PTR(err);
15344+ if (unlikely(err < 0))
15345+ goto out;
15346+
15347+ sb = dentry->d_sb;
15348+ udba = au_opt_udba(sb);
15349+ err = au_pin(pin, dentry, bcpup, udba,
15350+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
15351+ wh_dentry = ERR_PTR(err);
15352+ if (unlikely(err))
15353+ goto out;
15354+
15355+ h_parent = au_pinned_h_parent(pin);
15356+ if (udba != AuOpt_UDBA_NONE
15357+ && au_dbstart(dentry) == bcpup)
15358+ err = au_may_add(dentry, bcpup, h_parent,
15359+ au_ftest_wrdir(wr_dir_args->flags, ISDIR));
15360+ else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
15361+ err = -ENAMETOOLONG;
15362+ wh_dentry = ERR_PTR(err);
15363+ if (unlikely(err))
15364+ goto out_unpin;
15365+
15366+ br = au_sbr(sb, bcpup);
15367+ if (dt) {
15368+ struct path tmp = {
15369+ .dentry = h_parent,
15370+ .mnt = br->br_mnt
15371+ };
15372+ au_dtime_store(dt, au_pinned_parent(pin), &tmp);
15373+ }
15374+
15375+ wh_dentry = NULL;
15376+ if (bcpup != au_dbwh(dentry))
15377+ goto out; /* success */
15378+
15379+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
15380+
4f0767ce 15381+out_unpin:
4a4d8108
AM
15382+ if (IS_ERR(wh_dentry))
15383+ au_unpin(pin);
4f0767ce 15384+out:
4a4d8108
AM
15385+ return wh_dentry;
15386+}
15387+
15388+/* ---------------------------------------------------------------------- */
15389+
15390+enum { Mknod, Symlink, Creat };
15391+struct simple_arg {
15392+ int type;
15393+ union {
15394+ struct {
7eafdf33 15395+ umode_t mode;
b4510431 15396+ bool want_excl;
4a4d8108
AM
15397+ } c;
15398+ struct {
15399+ const char *symname;
15400+ } s;
15401+ struct {
7eafdf33 15402+ umode_t mode;
4a4d8108
AM
15403+ dev_t dev;
15404+ } m;
15405+ } u;
15406+};
15407+
15408+static int add_simple(struct inode *dir, struct dentry *dentry,
15409+ struct simple_arg *arg)
15410+{
15411+ int err;
15412+ aufs_bindex_t bstart;
15413+ unsigned char created;
15414+ struct au_dtime dt;
15415+ struct au_pin pin;
15416+ struct path h_path;
15417+ struct dentry *wh_dentry, *parent;
15418+ struct inode *h_dir;
15419+ struct au_wr_dir_args wr_dir_args = {
15420+ .force_btgt = -1,
15421+ .flags = AuWrDir_ADD_ENTRY
15422+ };
15423+
15424+ AuDbg("%.*s\n", AuDLNPair(dentry));
15425+ IMustLock(dir);
15426+
15427+ parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
15428+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
15429+ if (unlikely(err))
15430+ goto out;
15431+ err = au_d_may_add(dentry);
15432+ if (unlikely(err))
15433+ goto out_unlock;
4a4d8108
AM
15434+ di_write_lock_parent(parent);
15435+ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, /*src_dentry*/NULL, &pin,
15436+ &wr_dir_args);
15437+ err = PTR_ERR(wh_dentry);
15438+ if (IS_ERR(wh_dentry))
027c5e7a 15439+ goto out_parent;
4a4d8108
AM
15440+
15441+ bstart = au_dbstart(dentry);
15442+ h_path.dentry = au_h_dptr(dentry, bstart);
15443+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
15444+ h_dir = au_pinned_h_dir(&pin);
15445+ switch (arg->type) {
15446+ case Creat:
537831f9
AM
15447+ err = vfsub_create(h_dir, &h_path, arg->u.c.mode,
15448+ arg->u.c.want_excl);
4a4d8108
AM
15449+ break;
15450+ case Symlink:
15451+ err = vfsub_symlink(h_dir, &h_path, arg->u.s.symname);
15452+ break;
15453+ case Mknod:
15454+ err = vfsub_mknod(h_dir, &h_path, arg->u.m.mode, arg->u.m.dev);
15455+ break;
15456+ default:
15457+ BUG();
15458+ }
15459+ created = !err;
15460+ if (!err)
15461+ err = epilog(dir, bstart, wh_dentry, dentry);
15462+
15463+ /* revert */
15464+ if (unlikely(created && err && h_path.dentry->d_inode)) {
15465+ int rerr;
15466+ rerr = vfsub_unlink(h_dir, &h_path, /*force*/0);
15467+ if (rerr) {
15468+ AuIOErr("%.*s revert failure(%d, %d)\n",
15469+ AuDLNPair(dentry), err, rerr);
15470+ err = -EIO;
15471+ }
15472+ au_dtime_revert(&dt);
4a4d8108
AM
15473+ }
15474+
15475+ au_unpin(&pin);
15476+ dput(wh_dentry);
15477+
027c5e7a
AM
15478+out_parent:
15479+ di_write_unlock(parent);
15480+out_unlock:
4a4d8108
AM
15481+ if (unlikely(err)) {
15482+ au_update_dbstart(dentry);
15483+ d_drop(dentry);
15484+ }
4a4d8108 15485+ aufs_read_unlock(dentry, AuLock_DW);
027c5e7a 15486+out:
4a4d8108
AM
15487+ return err;
15488+}
15489+
7eafdf33
AM
15490+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
15491+ dev_t dev)
4a4d8108
AM
15492+{
15493+ struct simple_arg arg = {
15494+ .type = Mknod,
15495+ .u.m = {
15496+ .mode = mode,
15497+ .dev = dev
15498+ }
15499+ };
15500+ return add_simple(dir, dentry, &arg);
15501+}
15502+
15503+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
15504+{
15505+ struct simple_arg arg = {
15506+ .type = Symlink,
15507+ .u.s.symname = symname
15508+ };
15509+ return add_simple(dir, dentry, &arg);
15510+}
15511+
7eafdf33 15512+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 15513+ bool want_excl)
4a4d8108
AM
15514+{
15515+ struct simple_arg arg = {
15516+ .type = Creat,
15517+ .u.c = {
b4510431
AM
15518+ .mode = mode,
15519+ .want_excl = want_excl
4a4d8108
AM
15520+ }
15521+ };
15522+ return add_simple(dir, dentry, &arg);
15523+}
15524+
15525+/* ---------------------------------------------------------------------- */
15526+
15527+struct au_link_args {
15528+ aufs_bindex_t bdst, bsrc;
15529+ struct au_pin pin;
15530+ struct path h_path;
15531+ struct dentry *src_parent, *parent;
15532+};
15533+
15534+static int au_cpup_before_link(struct dentry *src_dentry,
15535+ struct au_link_args *a)
15536+{
15537+ int err;
15538+ struct dentry *h_src_dentry;
15539+ struct mutex *h_mtx;
15540+ struct file *h_file;
15541+
15542+ di_read_lock_parent(a->src_parent, AuLock_IR);
15543+ err = au_test_and_cpup_dirs(src_dentry, a->bdst);
15544+ if (unlikely(err))
15545+ goto out;
15546+
15547+ h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
15548+ h_mtx = &h_src_dentry->d_inode->i_mutex;
15549+ err = au_pin(&a->pin, src_dentry, a->bdst,
15550+ au_opt_udba(src_dentry->d_sb),
15551+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
15552+ if (unlikely(err))
15553+ goto out;
15554+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
15555+ h_file = au_h_open_pre(src_dentry, a->bsrc);
15556+ if (IS_ERR(h_file)) {
15557+ err = PTR_ERR(h_file);
15558+ h_file = NULL;
15559+ } else
1e00d052 15560+ err = au_sio_cpup_simple(src_dentry, a->bdst, -1,
4a4d8108
AM
15561+ AuCpup_DTIME /* | AuCpup_KEEPLINO */);
15562+ mutex_unlock(h_mtx);
15563+ au_h_open_post(src_dentry, a->bsrc, h_file);
15564+ au_unpin(&a->pin);
15565+
4f0767ce 15566+out:
4a4d8108
AM
15567+ di_read_unlock(a->src_parent, AuLock_IR);
15568+ return err;
15569+}
15570+
15571+static int au_cpup_or_link(struct dentry *src_dentry, struct au_link_args *a)
15572+{
15573+ int err;
15574+ unsigned char plink;
15575+ struct inode *h_inode, *inode;
15576+ struct dentry *h_src_dentry;
15577+ struct super_block *sb;
15578+ struct file *h_file;
15579+
15580+ plink = 0;
15581+ h_inode = NULL;
15582+ sb = src_dentry->d_sb;
15583+ inode = src_dentry->d_inode;
15584+ if (au_ibstart(inode) <= a->bdst)
15585+ h_inode = au_h_iptr(inode, a->bdst);
15586+ if (!h_inode || !h_inode->i_nlink) {
15587+ /* copyup src_dentry as the name of dentry. */
15588+ au_set_dbstart(src_dentry, a->bdst);
15589+ au_set_h_dptr(src_dentry, a->bdst, dget(a->h_path.dentry));
15590+ h_inode = au_h_dptr(src_dentry, a->bsrc)->d_inode;
15591+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
15592+ h_file = au_h_open_pre(src_dentry, a->bsrc);
15593+ if (IS_ERR(h_file)) {
15594+ err = PTR_ERR(h_file);
15595+ h_file = NULL;
15596+ } else
15597+ err = au_sio_cpup_single(src_dentry, a->bdst, a->bsrc,
15598+ -1, AuCpup_KEEPLINO,
15599+ a->parent);
15600+ mutex_unlock(&h_inode->i_mutex);
15601+ au_h_open_post(src_dentry, a->bsrc, h_file);
15602+ au_set_h_dptr(src_dentry, a->bdst, NULL);
15603+ au_set_dbstart(src_dentry, a->bsrc);
15604+ } else {
15605+ /* the inode of src_dentry already exists on a.bdst branch */
15606+ h_src_dentry = d_find_alias(h_inode);
15607+ if (!h_src_dentry && au_plink_test(inode)) {
15608+ plink = 1;
15609+ h_src_dentry = au_plink_lkup(inode, a->bdst);
15610+ err = PTR_ERR(h_src_dentry);
15611+ if (IS_ERR(h_src_dentry))
15612+ goto out;
15613+
15614+ if (unlikely(!h_src_dentry->d_inode)) {
15615+ dput(h_src_dentry);
15616+ h_src_dentry = NULL;
15617+ }
15618+
15619+ }
15620+ if (h_src_dentry) {
15621+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
15622+ &a->h_path);
15623+ dput(h_src_dentry);
15624+ } else {
15625+ AuIOErr("no dentry found for hi%lu on b%d\n",
15626+ h_inode->i_ino, a->bdst);
15627+ err = -EIO;
15628+ }
15629+ }
15630+
15631+ if (!err && !plink)
15632+ au_plink_append(inode, a->bdst, a->h_path.dentry);
15633+
15634+out:
2cbb1c4b 15635+ AuTraceErr(err);
4a4d8108
AM
15636+ return err;
15637+}
15638+
15639+int aufs_link(struct dentry *src_dentry, struct inode *dir,
15640+ struct dentry *dentry)
15641+{
15642+ int err, rerr;
15643+ struct au_dtime dt;
15644+ struct au_link_args *a;
15645+ struct dentry *wh_dentry, *h_src_dentry;
15646+ struct inode *inode;
15647+ struct super_block *sb;
15648+ struct au_wr_dir_args wr_dir_args = {
15649+ /* .force_btgt = -1, */
15650+ .flags = AuWrDir_ADD_ENTRY
15651+ };
15652+
15653+ IMustLock(dir);
15654+ inode = src_dentry->d_inode;
15655+ IMustLock(inode);
15656+
4a4d8108
AM
15657+ err = -ENOMEM;
15658+ a = kzalloc(sizeof(*a), GFP_NOFS);
15659+ if (unlikely(!a))
15660+ goto out;
15661+
15662+ a->parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
15663+ err = aufs_read_and_write_lock2(dentry, src_dentry,
15664+ AuLock_NOPLM | AuLock_GEN);
e49829fe
JR
15665+ if (unlikely(err))
15666+ goto out_kfree;
027c5e7a
AM
15667+ err = au_d_hashed_positive(src_dentry);
15668+ if (unlikely(err))
15669+ goto out_unlock;
15670+ err = au_d_may_add(dentry);
15671+ if (unlikely(err))
15672+ goto out_unlock;
e49829fe 15673+
4a4d8108 15674+ a->src_parent = dget_parent(src_dentry);
2cbb1c4b 15675+ wr_dir_args.force_btgt = au_ibstart(inode);
4a4d8108
AM
15676+
15677+ di_write_lock_parent(a->parent);
15678+ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
15679+ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
15680+ &wr_dir_args);
15681+ err = PTR_ERR(wh_dentry);
15682+ if (IS_ERR(wh_dentry))
027c5e7a 15683+ goto out_parent;
4a4d8108
AM
15684+
15685+ err = 0;
15686+ sb = dentry->d_sb;
15687+ a->bdst = au_dbstart(dentry);
15688+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
15689+ a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
2cbb1c4b
JR
15690+ a->bsrc = au_ibstart(inode);
15691+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
15692+ if (!h_src_dentry) {
15693+ a->bsrc = au_dbstart(src_dentry);
15694+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
15695+ AuDebugOn(!h_src_dentry);
15696+ } else if (IS_ERR(h_src_dentry))
15697+ goto out_parent;
15698+
4a4d8108
AM
15699+ if (au_opt_test(au_mntflags(sb), PLINK)) {
15700+ if (a->bdst < a->bsrc
15701+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
15702+ err = au_cpup_or_link(src_dentry, a);
2cbb1c4b 15703+ else
4a4d8108
AM
15704+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
15705+ &a->h_path);
2cbb1c4b 15706+ dput(h_src_dentry);
4a4d8108
AM
15707+ } else {
15708+ /*
15709+ * copyup src_dentry to the branch we process,
15710+ * and then link(2) to it.
15711+ */
2cbb1c4b 15712+ dput(h_src_dentry);
4a4d8108
AM
15713+ if (a->bdst < a->bsrc
15714+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
15715+ au_unpin(&a->pin);
15716+ di_write_unlock(a->parent);
15717+ err = au_cpup_before_link(src_dentry, a);
15718+ di_write_lock_parent(a->parent);
15719+ if (!err)
15720+ err = au_pin(&a->pin, dentry, a->bdst,
15721+ au_opt_udba(sb),
15722+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
15723+ if (unlikely(err))
15724+ goto out_wh;
15725+ }
15726+ if (!err) {
15727+ h_src_dentry = au_h_dptr(src_dentry, a->bdst);
15728+ err = -ENOENT;
15729+ if (h_src_dentry && h_src_dentry->d_inode)
15730+ err = vfsub_link(h_src_dentry,
15731+ au_pinned_h_dir(&a->pin),
15732+ &a->h_path);
15733+ }
15734+ }
15735+ if (unlikely(err))
15736+ goto out_unpin;
15737+
15738+ if (wh_dentry) {
15739+ a->h_path.dentry = wh_dentry;
15740+ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
15741+ dentry);
15742+ if (unlikely(err))
15743+ goto out_revert;
15744+ }
15745+
15746+ dir->i_version++;
15747+ if (au_ibstart(dir) == au_dbstart(dentry))
15748+ au_cpup_attr_timesizes(dir);
15749+ inc_nlink(inode);
15750+ inode->i_ctime = dir->i_ctime;
027c5e7a
AM
15751+ d_instantiate(dentry, au_igrab(inode));
15752+ if (d_unhashed(a->h_path.dentry))
4a4d8108
AM
15753+ /* some filesystem calls d_drop() */
15754+ d_drop(dentry);
15755+ goto out_unpin; /* success */
15756+
4f0767ce 15757+out_revert:
4a4d8108 15758+ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path, /*force*/0);
027c5e7a
AM
15759+ if (unlikely(rerr)) {
15760+ AuIOErr("%.*s reverting failed(%d, %d)\n",
15761+ AuDLNPair(dentry), err, rerr);
15762+ err = -EIO;
15763+ }
4a4d8108 15764+ au_dtime_revert(&dt);
4f0767ce 15765+out_unpin:
4a4d8108 15766+ au_unpin(&a->pin);
4f0767ce 15767+out_wh:
4a4d8108 15768+ dput(wh_dentry);
027c5e7a
AM
15769+out_parent:
15770+ di_write_unlock(a->parent);
15771+ dput(a->src_parent);
4f0767ce 15772+out_unlock:
4a4d8108
AM
15773+ if (unlikely(err)) {
15774+ au_update_dbstart(dentry);
15775+ d_drop(dentry);
15776+ }
4a4d8108 15777+ aufs_read_and_write_unlock2(dentry, src_dentry);
e49829fe 15778+out_kfree:
4a4d8108 15779+ kfree(a);
4f0767ce 15780+out:
4a4d8108
AM
15781+ return err;
15782+}
15783+
7eafdf33 15784+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
4a4d8108
AM
15785+{
15786+ int err, rerr;
15787+ aufs_bindex_t bindex;
15788+ unsigned char diropq;
15789+ struct path h_path;
15790+ struct dentry *wh_dentry, *parent, *opq_dentry;
15791+ struct mutex *h_mtx;
15792+ struct super_block *sb;
15793+ struct {
15794+ struct au_pin pin;
15795+ struct au_dtime dt;
15796+ } *a; /* reduce the stack usage */
15797+ struct au_wr_dir_args wr_dir_args = {
15798+ .force_btgt = -1,
15799+ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
15800+ };
15801+
15802+ IMustLock(dir);
15803+
15804+ err = -ENOMEM;
15805+ a = kmalloc(sizeof(*a), GFP_NOFS);
15806+ if (unlikely(!a))
15807+ goto out;
15808+
027c5e7a
AM
15809+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
15810+ if (unlikely(err))
15811+ goto out_free;
15812+ err = au_d_may_add(dentry);
15813+ if (unlikely(err))
15814+ goto out_unlock;
15815+
4a4d8108
AM
15816+ parent = dentry->d_parent; /* dir inode is locked */
15817+ di_write_lock_parent(parent);
15818+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
15819+ &a->pin, &wr_dir_args);
15820+ err = PTR_ERR(wh_dentry);
15821+ if (IS_ERR(wh_dentry))
027c5e7a 15822+ goto out_parent;
4a4d8108
AM
15823+
15824+ sb = dentry->d_sb;
15825+ bindex = au_dbstart(dentry);
15826+ h_path.dentry = au_h_dptr(dentry, bindex);
15827+ h_path.mnt = au_sbr_mnt(sb, bindex);
15828+ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
15829+ if (unlikely(err))
027c5e7a 15830+ goto out_unpin;
4a4d8108
AM
15831+
15832+ /* make the dir opaque */
15833+ diropq = 0;
15834+ h_mtx = &h_path.dentry->d_inode->i_mutex;
15835+ if (wh_dentry
15836+ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
15837+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
15838+ opq_dentry = au_diropq_create(dentry, bindex);
15839+ mutex_unlock(h_mtx);
15840+ err = PTR_ERR(opq_dentry);
15841+ if (IS_ERR(opq_dentry))
15842+ goto out_dir;
15843+ dput(opq_dentry);
15844+ diropq = 1;
15845+ }
15846+
15847+ err = epilog(dir, bindex, wh_dentry, dentry);
15848+ if (!err) {
15849+ inc_nlink(dir);
027c5e7a 15850+ goto out_unpin; /* success */
4a4d8108
AM
15851+ }
15852+
15853+ /* revert */
15854+ if (diropq) {
15855+ AuLabel(revert opq);
15856+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
15857+ rerr = au_diropq_remove(dentry, bindex);
15858+ mutex_unlock(h_mtx);
15859+ if (rerr) {
15860+ AuIOErr("%.*s reverting diropq failed(%d, %d)\n",
15861+ AuDLNPair(dentry), err, rerr);
15862+ err = -EIO;
15863+ }
15864+ }
15865+
4f0767ce 15866+out_dir:
4a4d8108
AM
15867+ AuLabel(revert dir);
15868+ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
15869+ if (rerr) {
15870+ AuIOErr("%.*s reverting dir failed(%d, %d)\n",
15871+ AuDLNPair(dentry), err, rerr);
15872+ err = -EIO;
15873+ }
4a4d8108 15874+ au_dtime_revert(&a->dt);
027c5e7a 15875+out_unpin:
4a4d8108
AM
15876+ au_unpin(&a->pin);
15877+ dput(wh_dentry);
027c5e7a
AM
15878+out_parent:
15879+ di_write_unlock(parent);
15880+out_unlock:
4a4d8108
AM
15881+ if (unlikely(err)) {
15882+ au_update_dbstart(dentry);
15883+ d_drop(dentry);
15884+ }
4a4d8108 15885+ aufs_read_unlock(dentry, AuLock_DW);
027c5e7a 15886+out_free:
4a4d8108 15887+ kfree(a);
4f0767ce 15888+out:
4a4d8108
AM
15889+ return err;
15890+}
7f207e10
AM
15891diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
15892--- /usr/share/empty/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
a2a7ad62 15893+++ linux/fs/aufs/i_op.c 2013-03-14 20:07:41.041453062 +0100
1716fcea 15894@@ -0,0 +1,1030 @@
4a4d8108 15895+/*
7a9e40b8 15896+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
15897+ *
15898+ * This program, aufs is free software; you can redistribute it and/or modify
15899+ * it under the terms of the GNU General Public License as published by
15900+ * the Free Software Foundation; either version 2 of the License, or
15901+ * (at your option) any later version.
15902+ *
15903+ * This program is distributed in the hope that it will be useful,
15904+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15905+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15906+ * GNU General Public License for more details.
15907+ *
15908+ * You should have received a copy of the GNU General Public License
15909+ * along with this program; if not, write to the Free Software
15910+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15911+ */
1facf9fc 15912+
1308ab2a 15913+/*
4a4d8108 15914+ * inode operations (except add/del/rename)
1308ab2a 15915+ */
4a4d8108
AM
15916+
15917+#include <linux/device_cgroup.h>
15918+#include <linux/fs_stack.h>
92d182d2 15919+#include <linux/mm.h>
4a4d8108
AM
15920+#include <linux/namei.h>
15921+#include <linux/security.h>
4a4d8108
AM
15922+#include "aufs.h"
15923+
1e00d052 15924+static int h_permission(struct inode *h_inode, int mask,
4a4d8108 15925+ struct vfsmount *h_mnt, int brperm)
1facf9fc 15926+{
1308ab2a 15927+ int err;
4a4d8108 15928+ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
1facf9fc 15929+
4a4d8108
AM
15930+ err = -EACCES;
15931+ if ((write_mask && IS_IMMUTABLE(h_inode))
15932+ || ((mask & MAY_EXEC)
15933+ && S_ISREG(h_inode->i_mode)
15934+ && ((h_mnt->mnt_flags & MNT_NOEXEC)
15935+ || !(h_inode->i_mode & S_IXUGO))))
15936+ goto out;
15937+
15938+ /*
15939+ * - skip the lower fs test in the case of write to ro branch.
15940+ * - nfs dir permission write check is optimized, but a policy for
15941+ * link/rename requires a real check.
15942+ */
15943+ if ((write_mask && !au_br_writable(brperm))
15944+ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
15945+ && write_mask && !(mask & MAY_READ))
15946+ || !h_inode->i_op->permission) {
15947+ /* AuLabel(generic_permission); */
1e00d052 15948+ err = generic_permission(h_inode, mask);
1308ab2a 15949+ } else {
4a4d8108 15950+ /* AuLabel(h_inode->permission); */
1e00d052 15951+ err = h_inode->i_op->permission(h_inode, mask);
4a4d8108
AM
15952+ AuTraceErr(err);
15953+ }
1facf9fc 15954+
4a4d8108
AM
15955+ if (!err)
15956+ err = devcgroup_inode_permission(h_inode, mask);
7f207e10 15957+ if (!err)
4a4d8108 15958+ err = security_inode_permission(h_inode, mask);
4a4d8108
AM
15959+
15960+#if 0
15961+ if (!err) {
15962+ /* todo: do we need to call ima_path_check()? */
15963+ struct path h_path = {
15964+ .dentry =
15965+ .mnt = h_mnt
15966+ };
15967+ err = ima_path_check(&h_path,
15968+ mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
15969+ IMA_COUNT_LEAVE);
1308ab2a 15970+ }
4a4d8108 15971+#endif
dece6358 15972+
4f0767ce 15973+out:
1308ab2a 15974+ return err;
15975+}
dece6358 15976+
1e00d052 15977+static int aufs_permission(struct inode *inode, int mask)
1308ab2a 15978+{
15979+ int err;
4a4d8108
AM
15980+ aufs_bindex_t bindex, bend;
15981+ const unsigned char isdir = !!S_ISDIR(inode->i_mode),
15982+ write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
15983+ struct inode *h_inode;
15984+ struct super_block *sb;
15985+ struct au_branch *br;
1facf9fc 15986+
027c5e7a 15987+ /* todo: support rcu-walk? */
1e00d052 15988+ if (mask & MAY_NOT_BLOCK)
027c5e7a
AM
15989+ return -ECHILD;
15990+
4a4d8108
AM
15991+ sb = inode->i_sb;
15992+ si_read_lock(sb, AuLock_FLUSH);
15993+ ii_read_lock_child(inode);
027c5e7a
AM
15994+#if 0
15995+ err = au_iigen_test(inode, au_sigen(sb));
15996+ if (unlikely(err))
15997+ goto out;
15998+#endif
dece6358 15999+
4a4d8108
AM
16000+ if (!isdir || write_mask) {
16001+ err = au_busy_or_stale();
16002+ h_inode = au_h_iptr(inode, au_ibstart(inode));
16003+ if (unlikely(!h_inode
16004+ || (h_inode->i_mode & S_IFMT)
16005+ != (inode->i_mode & S_IFMT)))
16006+ goto out;
1facf9fc 16007+
4a4d8108
AM
16008+ err = 0;
16009+ bindex = au_ibstart(inode);
16010+ br = au_sbr(sb, bindex);
1e00d052 16011+ err = h_permission(h_inode, mask, br->br_mnt, br->br_perm);
4a4d8108
AM
16012+ if (write_mask
16013+ && !err
16014+ && !special_file(h_inode->i_mode)) {
16015+ /* test whether the upper writable branch exists */
16016+ err = -EROFS;
16017+ for (; bindex >= 0; bindex--)
16018+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
16019+ err = 0;
16020+ break;
16021+ }
16022+ }
16023+ goto out;
16024+ }
dece6358 16025+
4a4d8108 16026+ /* non-write to dir */
1308ab2a 16027+ err = 0;
4a4d8108
AM
16028+ bend = au_ibend(inode);
16029+ for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) {
16030+ h_inode = au_h_iptr(inode, bindex);
16031+ if (h_inode) {
16032+ err = au_busy_or_stale();
16033+ if (unlikely(!S_ISDIR(h_inode->i_mode)))
16034+ break;
16035+
16036+ br = au_sbr(sb, bindex);
1e00d052 16037+ err = h_permission(h_inode, mask, br->br_mnt,
4a4d8108
AM
16038+ br->br_perm);
16039+ }
16040+ }
1308ab2a 16041+
4f0767ce 16042+out:
4a4d8108
AM
16043+ ii_read_unlock(inode);
16044+ si_read_unlock(sb);
1308ab2a 16045+ return err;
16046+}
16047+
4a4d8108 16048+/* ---------------------------------------------------------------------- */
1facf9fc 16049+
4a4d8108 16050+static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
b4510431 16051+ unsigned int flags)
4a4d8108
AM
16052+{
16053+ struct dentry *ret, *parent;
b752ccd1 16054+ struct inode *inode;
4a4d8108 16055+ struct super_block *sb;
1716fcea 16056+ int err, npositive;
dece6358 16057+
4a4d8108 16058+ IMustLock(dir);
1308ab2a 16059+
537831f9
AM
16060+ /* todo: support rcu-walk? */
16061+ ret = ERR_PTR(-ECHILD);
16062+ if (flags & LOOKUP_RCU)
16063+ goto out;
16064+
16065+ ret = ERR_PTR(-ENAMETOOLONG);
16066+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
16067+ goto out;
16068+
4a4d8108 16069+ sb = dir->i_sb;
7f207e10
AM
16070+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
16071+ ret = ERR_PTR(err);
16072+ if (unlikely(err))
16073+ goto out;
16074+
4a4d8108
AM
16075+ err = au_di_init(dentry);
16076+ ret = ERR_PTR(err);
16077+ if (unlikely(err))
7f207e10 16078+ goto out_si;
1308ab2a 16079+
9dbd164d 16080+ inode = NULL;
027c5e7a 16081+ npositive = 0; /* suppress a warning */
4a4d8108
AM
16082+ parent = dentry->d_parent; /* dir inode is locked */
16083+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
16084+ err = au_alive_dir(parent);
16085+ if (!err)
16086+ err = au_digen_test(parent, au_sigen(sb));
16087+ if (!err) {
16088+ npositive = au_lkup_dentry(dentry, au_dbstart(parent),
537831f9 16089+ /*type*/0);
027c5e7a
AM
16090+ err = npositive;
16091+ }
4a4d8108 16092+ di_read_unlock(parent, AuLock_IR);
4a4d8108
AM
16093+ ret = ERR_PTR(err);
16094+ if (unlikely(err < 0))
16095+ goto out_unlock;
1308ab2a 16096+
4a4d8108 16097+ if (npositive) {
b752ccd1 16098+ inode = au_new_inode(dentry, /*must_new*/0);
4a4d8108 16099+ ret = (void *)inode;
1facf9fc 16100+ }
9dbd164d
AM
16101+ if (IS_ERR(inode)) {
16102+ inode = NULL;
4a4d8108 16103+ goto out_unlock;
9dbd164d 16104+ }
4a4d8108
AM
16105+
16106+ ret = d_splice_alias(inode, dentry);
537831f9
AM
16107+#if 0
16108+ if (unlikely(d_need_lookup(dentry))) {
16109+ spin_lock(&dentry->d_lock);
16110+ dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
16111+ spin_unlock(&dentry->d_lock);
16112+ } else
16113+#endif
7f207e10 16114+ if (unlikely(IS_ERR(ret) && inode)) {
4a4d8108 16115+ ii_write_unlock(inode);
7f207e10 16116+ iput(inode);
2dfbb274 16117+ inode = NULL;
7f207e10 16118+ }
1facf9fc 16119+
4f0767ce 16120+out_unlock:
4a4d8108 16121+ di_write_unlock(dentry);
2dfbb274 16122+ if (inode) {
1716fcea
AM
16123+ /* verbose coding for lock class name */
16124+ if (unlikely(S_ISLNK(inode->i_mode)))
16125+ au_rw_class(&au_di(dentry)->di_rwsem,
16126+ au_lc_key + AuLcSymlink_DIINFO);
16127+ else if (unlikely(S_ISDIR(inode->i_mode)))
16128+ au_rw_class(&au_di(dentry)->di_rwsem,
16129+ au_lc_key + AuLcDir_DIINFO);
16130+ else /* likely */
16131+ au_rw_class(&au_di(dentry)->di_rwsem,
16132+ au_lc_key + AuLcNonDir_DIINFO);
9dbd164d 16133+ }
7f207e10 16134+out_si:
4a4d8108 16135+ si_read_unlock(sb);
7f207e10 16136+out:
4a4d8108
AM
16137+ return ret;
16138+}
1facf9fc 16139+
4a4d8108 16140+/* ---------------------------------------------------------------------- */
1facf9fc 16141+
4a4d8108
AM
16142+static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
16143+ const unsigned char add_entry, aufs_bindex_t bcpup,
16144+ aufs_bindex_t bstart)
16145+{
16146+ int err;
16147+ struct dentry *h_parent;
16148+ struct inode *h_dir;
1facf9fc 16149+
027c5e7a 16150+ if (add_entry)
4a4d8108 16151+ IMustLock(parent->d_inode);
027c5e7a 16152+ else
4a4d8108
AM
16153+ di_write_lock_parent(parent);
16154+
16155+ err = 0;
16156+ if (!au_h_dptr(parent, bcpup)) {
16157+ if (bstart < bcpup)
16158+ err = au_cpdown_dirs(dentry, bcpup);
16159+ else
16160+ err = au_cpup_dirs(dentry, bcpup);
16161+ }
16162+ if (!err && add_entry) {
16163+ h_parent = au_h_dptr(parent, bcpup);
16164+ h_dir = h_parent->d_inode;
16165+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
16166+ err = au_lkup_neg(dentry, bcpup);
16167+ /* todo: no unlock here */
16168+ mutex_unlock(&h_dir->i_mutex);
027c5e7a
AM
16169+
16170+ AuDbg("bcpup %d\n", bcpup);
16171+ if (!err) {
16172+ if (!dentry->d_inode)
16173+ au_set_h_dptr(dentry, bstart, NULL);
4a4d8108
AM
16174+ au_update_dbrange(dentry, /*do_put_zero*/0);
16175+ }
1308ab2a 16176+ }
1facf9fc 16177+
4a4d8108
AM
16178+ if (!add_entry)
16179+ di_write_unlock(parent);
16180+ if (!err)
16181+ err = bcpup; /* success */
1308ab2a 16182+
027c5e7a 16183+ AuTraceErr(err);
4a4d8108
AM
16184+ return err;
16185+}
1facf9fc 16186+
4a4d8108
AM
16187+/*
16188+ * decide the branch and the parent dir where we will create a new entry.
16189+ * returns new bindex or an error.
16190+ * copyup the parent dir if needed.
16191+ */
16192+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
16193+ struct au_wr_dir_args *args)
16194+{
16195+ int err;
16196+ aufs_bindex_t bcpup, bstart, src_bstart;
16197+ const unsigned char add_entry = !!au_ftest_wrdir(args->flags,
16198+ ADD_ENTRY);
16199+ struct super_block *sb;
16200+ struct dentry *parent;
16201+ struct au_sbinfo *sbinfo;
1facf9fc 16202+
4a4d8108
AM
16203+ sb = dentry->d_sb;
16204+ sbinfo = au_sbi(sb);
16205+ parent = dget_parent(dentry);
16206+ bstart = au_dbstart(dentry);
16207+ bcpup = bstart;
16208+ if (args->force_btgt < 0) {
16209+ if (src_dentry) {
16210+ src_bstart = au_dbstart(src_dentry);
16211+ if (src_bstart < bstart)
16212+ bcpup = src_bstart;
16213+ } else if (add_entry) {
16214+ err = AuWbrCreate(sbinfo, dentry,
16215+ au_ftest_wrdir(args->flags, ISDIR));
16216+ bcpup = err;
16217+ }
1facf9fc 16218+
4a4d8108
AM
16219+ if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) {
16220+ if (add_entry)
16221+ err = AuWbrCopyup(sbinfo, dentry);
16222+ else {
16223+ if (!IS_ROOT(dentry)) {
16224+ di_read_lock_parent(parent, !AuLock_IR);
16225+ err = AuWbrCopyup(sbinfo, dentry);
16226+ di_read_unlock(parent, !AuLock_IR);
16227+ } else
16228+ err = AuWbrCopyup(sbinfo, dentry);
16229+ }
16230+ bcpup = err;
16231+ if (unlikely(err < 0))
16232+ goto out;
16233+ }
16234+ } else {
16235+ bcpup = args->force_btgt;
16236+ AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode));
1308ab2a 16237+ }
027c5e7a 16238+
4a4d8108
AM
16239+ AuDbg("bstart %d, bcpup %d\n", bstart, bcpup);
16240+ err = bcpup;
16241+ if (bcpup == bstart)
16242+ goto out; /* success */
4a4d8108
AM
16243+
16244+ /* copyup the new parent into the branch we process */
16245+ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart);
027c5e7a
AM
16246+ if (err >= 0) {
16247+ if (!dentry->d_inode) {
16248+ au_set_h_dptr(dentry, bstart, NULL);
16249+ au_set_dbstart(dentry, bcpup);
16250+ au_set_dbend(dentry, bcpup);
16251+ }
16252+ AuDebugOn(add_entry && !au_h_dptr(dentry, bcpup));
16253+ }
4a4d8108 16254+
4f0767ce 16255+out:
4a4d8108 16256+ dput(parent);
dece6358
AM
16257+ return err;
16258+}
1facf9fc 16259+
1308ab2a 16260+/* ---------------------------------------------------------------------- */
16261+
4a4d8108 16262+struct dentry *au_pinned_h_parent(struct au_pin *pin)
1308ab2a 16263+{
4a4d8108
AM
16264+ if (pin && pin->parent)
16265+ return au_h_dptr(pin->parent, pin->bindex);
16266+ return NULL;
dece6358 16267+}
1facf9fc 16268+
4a4d8108 16269+void au_unpin(struct au_pin *p)
dece6358 16270+{
e49829fe 16271+ if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE))
b4510431 16272+ vfsub_mnt_drop_write(p->h_mnt);
4a4d8108
AM
16273+ if (!p->hdir)
16274+ return;
1facf9fc 16275+
4a4d8108
AM
16276+ au_hn_imtx_unlock(p->hdir);
16277+ if (!au_ftest_pin(p->flags, DI_LOCKED))
16278+ di_read_unlock(p->parent, AuLock_IR);
16279+ iput(p->hdir->hi_inode);
16280+ dput(p->parent);
16281+ p->parent = NULL;
16282+ p->hdir = NULL;
16283+ p->h_mnt = NULL;
16284+}
1308ab2a 16285+
4a4d8108
AM
16286+int au_do_pin(struct au_pin *p)
16287+{
16288+ int err;
16289+ struct super_block *sb;
16290+ struct dentry *h_dentry, *h_parent;
16291+ struct au_branch *br;
16292+ struct inode *h_dir;
16293+
16294+ err = 0;
16295+ sb = p->dentry->d_sb;
16296+ br = au_sbr(sb, p->bindex);
16297+ if (IS_ROOT(p->dentry)) {
16298+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
16299+ p->h_mnt = br->br_mnt;
b4510431 16300+ err = vfsub_mnt_want_write(p->h_mnt);
4a4d8108
AM
16301+ if (unlikely(err)) {
16302+ au_fclr_pin(p->flags, MNT_WRITE);
16303+ goto out_err;
16304+ }
16305+ }
dece6358 16306+ goto out;
1facf9fc 16307+ }
16308+
4a4d8108
AM
16309+ h_dentry = NULL;
16310+ if (p->bindex <= au_dbend(p->dentry))
16311+ h_dentry = au_h_dptr(p->dentry, p->bindex);
dece6358 16312+
4a4d8108
AM
16313+ p->parent = dget_parent(p->dentry);
16314+ if (!au_ftest_pin(p->flags, DI_LOCKED))
16315+ di_read_lock(p->parent, AuLock_IR, p->lsc_di);
dece6358 16316+
4a4d8108
AM
16317+ h_dir = NULL;
16318+ h_parent = au_h_dptr(p->parent, p->bindex);
16319+ p->hdir = au_hi(p->parent->d_inode, p->bindex);
16320+ if (p->hdir)
16321+ h_dir = p->hdir->hi_inode;
dece6358 16322+
b752ccd1
AM
16323+ /*
16324+ * udba case, or
16325+ * if DI_LOCKED is not set, then p->parent may be different
16326+ * and h_parent can be NULL.
16327+ */
16328+ if (unlikely(!p->hdir || !h_dir || !h_parent)) {
e49829fe 16329+ err = -EBUSY;
4a4d8108
AM
16330+ if (!au_ftest_pin(p->flags, DI_LOCKED))
16331+ di_read_unlock(p->parent, AuLock_IR);
16332+ dput(p->parent);
16333+ p->parent = NULL;
16334+ goto out_err;
16335+ }
1308ab2a 16336+
4a4d8108
AM
16337+ au_igrab(h_dir);
16338+ au_hn_imtx_lock_nested(p->hdir, p->lsc_hi);
1308ab2a 16339+
4a4d8108
AM
16340+ if (unlikely(p->hdir->hi_inode != h_parent->d_inode)) {
16341+ err = -EBUSY;
16342+ goto out_unpin;
16343+ }
16344+ if (h_dentry) {
16345+ err = au_h_verify(h_dentry, p->udba, h_dir, h_parent, br);
16346+ if (unlikely(err)) {
16347+ au_fclr_pin(p->flags, MNT_WRITE);
16348+ goto out_unpin;
16349+ }
1facf9fc 16350+ }
dece6358 16351+
4a4d8108
AM
16352+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
16353+ p->h_mnt = br->br_mnt;
b4510431 16354+ err = vfsub_mnt_want_write(p->h_mnt);
dece6358 16355+ if (unlikely(err)) {
4a4d8108
AM
16356+ au_fclr_pin(p->flags, MNT_WRITE);
16357+ goto out_unpin;
dece6358
AM
16358+ }
16359+ }
4a4d8108
AM
16360+ goto out; /* success */
16361+
4f0767ce 16362+out_unpin:
4a4d8108 16363+ au_unpin(p);
4f0767ce 16364+out_err:
4a4d8108
AM
16365+ pr_err("err %d\n", err);
16366+ err = au_busy_or_stale();
4f0767ce 16367+out:
1facf9fc 16368+ return err;
16369+}
16370+
4a4d8108
AM
16371+void au_pin_init(struct au_pin *p, struct dentry *dentry,
16372+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
16373+ unsigned int udba, unsigned char flags)
16374+{
16375+ p->dentry = dentry;
16376+ p->udba = udba;
16377+ p->lsc_di = lsc_di;
16378+ p->lsc_hi = lsc_hi;
16379+ p->flags = flags;
16380+ p->bindex = bindex;
16381+
16382+ p->parent = NULL;
16383+ p->hdir = NULL;
16384+ p->h_mnt = NULL;
16385+}
16386+
16387+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
16388+ unsigned int udba, unsigned char flags)
16389+{
16390+ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
16391+ udba, flags);
16392+ return au_do_pin(pin);
16393+}
16394+
dece6358
AM
16395+/* ---------------------------------------------------------------------- */
16396+
1308ab2a 16397+/*
4a4d8108
AM
16398+ * ->setattr() and ->getattr() are called in various cases.
16399+ * chmod, stat: dentry is revalidated.
16400+ * fchmod, fstat: file and dentry are not revalidated, additionally they may be
16401+ * unhashed.
16402+ * for ->setattr(), ia->ia_file is passed from ftruncate only.
1308ab2a 16403+ */
027c5e7a 16404+/* todo: consolidate with do_refresh() and simple_reval_dpath() */
4a4d8108 16405+static int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
1facf9fc 16406+{
4a4d8108
AM
16407+ int err;
16408+ struct inode *inode;
16409+ struct dentry *parent;
1facf9fc 16410+
1308ab2a 16411+ err = 0;
4a4d8108 16412+ inode = dentry->d_inode;
027c5e7a 16413+ if (au_digen_test(dentry, sigen)) {
4a4d8108
AM
16414+ parent = dget_parent(dentry);
16415+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 16416+ err = au_refresh_dentry(dentry, parent);
4a4d8108
AM
16417+ di_read_unlock(parent, AuLock_IR);
16418+ dput(parent);
dece6358 16419+ }
1facf9fc 16420+
4a4d8108 16421+ AuTraceErr(err);
1308ab2a 16422+ return err;
16423+}
dece6358 16424+
4a4d8108
AM
16425+#define AuIcpup_DID_CPUP 1
16426+#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
7f207e10
AM
16427+#define au_fset_icpup(flags, name) \
16428+ do { (flags) |= AuIcpup_##name; } while (0)
16429+#define au_fclr_icpup(flags, name) \
16430+ do { (flags) &= ~AuIcpup_##name; } while (0)
1308ab2a 16431+
4a4d8108
AM
16432+struct au_icpup_args {
16433+ unsigned char flags;
16434+ unsigned char pin_flags;
16435+ aufs_bindex_t btgt;
16436+ unsigned int udba;
16437+ struct au_pin pin;
16438+ struct path h_path;
16439+ struct inode *h_inode;
16440+};
1308ab2a 16441+
4a4d8108
AM
16442+static int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
16443+ struct au_icpup_args *a)
1308ab2a 16444+{
16445+ int err;
4a4d8108 16446+ loff_t sz;
e49829fe 16447+ aufs_bindex_t bstart, ibstart;
4a4d8108
AM
16448+ struct dentry *hi_wh, *parent;
16449+ struct inode *inode;
16450+ struct file *h_file;
16451+ struct au_wr_dir_args wr_dir_args = {
16452+ .force_btgt = -1,
16453+ .flags = 0
16454+ };
16455+
16456+ bstart = au_dbstart(dentry);
16457+ inode = dentry->d_inode;
16458+ if (S_ISDIR(inode->i_mode))
16459+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
16460+ /* plink or hi_wh() case */
e49829fe 16461+ ibstart = au_ibstart(inode);
027c5e7a 16462+ if (bstart != ibstart && !au_test_ro(inode->i_sb, ibstart, inode))
e49829fe 16463+ wr_dir_args.force_btgt = ibstart;
4a4d8108
AM
16464+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
16465+ if (unlikely(err < 0))
16466+ goto out;
16467+ a->btgt = err;
16468+ if (err != bstart)
16469+ au_fset_icpup(a->flags, DID_CPUP);
16470+
16471+ err = 0;
16472+ a->pin_flags = AuPin_MNT_WRITE;
16473+ parent = NULL;
16474+ if (!IS_ROOT(dentry)) {
16475+ au_fset_pin(a->pin_flags, DI_LOCKED);
16476+ parent = dget_parent(dentry);
16477+ di_write_lock_parent(parent);
16478+ }
16479+
16480+ err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags);
16481+ if (unlikely(err))
16482+ goto out_parent;
16483+
16484+ a->h_path.dentry = au_h_dptr(dentry, bstart);
16485+ a->h_inode = a->h_path.dentry->d_inode;
16486+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
16487+ sz = -1;
16488+ if ((ia->ia_valid & ATTR_SIZE) && ia->ia_size < i_size_read(a->h_inode))
16489+ sz = ia->ia_size;
16490+
16491+ h_file = NULL;
16492+ hi_wh = NULL;
027c5e7a 16493+ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) {
4a4d8108
AM
16494+ hi_wh = au_hi_wh(inode, a->btgt);
16495+ if (!hi_wh) {
16496+ err = au_sio_cpup_wh(dentry, a->btgt, sz, /*file*/NULL);
16497+ if (unlikely(err))
16498+ goto out_unlock;
16499+ hi_wh = au_hi_wh(inode, a->btgt);
16500+ /* todo: revalidate hi_wh? */
16501+ }
16502+ }
16503+
16504+ if (parent) {
16505+ au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
16506+ di_downgrade_lock(parent, AuLock_IR);
16507+ dput(parent);
16508+ parent = NULL;
16509+ }
16510+ if (!au_ftest_icpup(a->flags, DID_CPUP))
16511+ goto out; /* success */
16512+
16513+ if (!d_unhashed(dentry)) {
16514+ h_file = au_h_open_pre(dentry, bstart);
16515+ if (IS_ERR(h_file)) {
16516+ err = PTR_ERR(h_file);
16517+ h_file = NULL;
16518+ } else
16519+ err = au_sio_cpup_simple(dentry, a->btgt, sz,
16520+ AuCpup_DTIME);
16521+ if (!err)
16522+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
16523+ } else if (!hi_wh)
16524+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
16525+ else
16526+ a->h_path.dentry = hi_wh; /* do not dget here */
1308ab2a 16527+
4f0767ce 16528+out_unlock:
4a4d8108
AM
16529+ mutex_unlock(&a->h_inode->i_mutex);
16530+ au_h_open_post(dentry, bstart, h_file);
16531+ a->h_inode = a->h_path.dentry->d_inode;
dece6358 16532+ if (!err) {
4a4d8108 16533+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
dece6358 16534+ goto out; /* success */
1facf9fc 16535+ }
dece6358 16536+
4a4d8108 16537+ au_unpin(&a->pin);
4f0767ce 16538+out_parent:
4a4d8108
AM
16539+ if (parent) {
16540+ di_write_unlock(parent);
16541+ dput(parent);
16542+ }
4f0767ce 16543+out:
1facf9fc 16544+ return err;
16545+}
16546+
4a4d8108 16547+static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
1facf9fc 16548+{
4a4d8108
AM
16549+ int err;
16550+ struct inode *inode;
16551+ struct super_block *sb;
16552+ struct file *file;
16553+ struct au_icpup_args *a;
1facf9fc 16554+
4a4d8108
AM
16555+ inode = dentry->d_inode;
16556+ IMustLock(inode);
dece6358 16557+
4a4d8108
AM
16558+ err = -ENOMEM;
16559+ a = kzalloc(sizeof(*a), GFP_NOFS);
16560+ if (unlikely(!a))
16561+ goto out;
1facf9fc 16562+
4a4d8108
AM
16563+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
16564+ ia->ia_valid &= ~ATTR_MODE;
dece6358 16565+
4a4d8108
AM
16566+ file = NULL;
16567+ sb = dentry->d_sb;
e49829fe
JR
16568+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
16569+ if (unlikely(err))
16570+ goto out_kfree;
16571+
4a4d8108
AM
16572+ if (ia->ia_valid & ATTR_FILE) {
16573+ /* currently ftruncate(2) only */
16574+ AuDebugOn(!S_ISREG(inode->i_mode));
16575+ file = ia->ia_file;
16576+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
16577+ if (unlikely(err))
16578+ goto out_si;
16579+ ia->ia_file = au_hf_top(file);
16580+ a->udba = AuOpt_UDBA_NONE;
16581+ } else {
16582+ /* fchmod() doesn't pass ia_file */
16583+ a->udba = au_opt_udba(sb);
027c5e7a
AM
16584+ di_write_lock_child(dentry);
16585+ /* no d_unlinked(), to set UDBA_NONE for root */
4a4d8108
AM
16586+ if (d_unhashed(dentry))
16587+ a->udba = AuOpt_UDBA_NONE;
4a4d8108
AM
16588+ if (a->udba != AuOpt_UDBA_NONE) {
16589+ AuDebugOn(IS_ROOT(dentry));
16590+ err = au_reval_for_attr(dentry, au_sigen(sb));
16591+ if (unlikely(err))
16592+ goto out_dentry;
16593+ }
dece6358 16594+ }
dece6358 16595+
4a4d8108
AM
16596+ err = au_pin_and_icpup(dentry, ia, a);
16597+ if (unlikely(err < 0))
16598+ goto out_dentry;
16599+ if (au_ftest_icpup(a->flags, DID_CPUP)) {
16600+ ia->ia_file = NULL;
16601+ ia->ia_valid &= ~ATTR_FILE;
1308ab2a 16602+ }
dece6358 16603+
4a4d8108
AM
16604+ a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
16605+ if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME))
16606+ == (ATTR_MODE | ATTR_CTIME)) {
7eafdf33 16607+ err = security_path_chmod(&a->h_path, ia->ia_mode);
4a4d8108
AM
16608+ if (unlikely(err))
16609+ goto out_unlock;
16610+ } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
16611+ && (ia->ia_valid & ATTR_CTIME)) {
0c3ec466
AM
16612+ err = security_path_chown(&a->h_path, vfsub_ia_uid(ia),
16613+ vfsub_ia_gid(ia));
4a4d8108
AM
16614+ if (unlikely(err))
16615+ goto out_unlock;
16616+ }
dece6358 16617+
4a4d8108
AM
16618+ if (ia->ia_valid & ATTR_SIZE) {
16619+ struct file *f;
1308ab2a 16620+
953406b4 16621+ if (ia->ia_size < i_size_read(inode))
4a4d8108 16622+ /* unmap only */
953406b4 16623+ truncate_setsize(inode, ia->ia_size);
1308ab2a 16624+
4a4d8108
AM
16625+ f = NULL;
16626+ if (ia->ia_valid & ATTR_FILE)
16627+ f = ia->ia_file;
16628+ mutex_unlock(&a->h_inode->i_mutex);
16629+ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
16630+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
16631+ } else
16632+ err = vfsub_notify_change(&a->h_path, ia);
16633+ if (!err)
16634+ au_cpup_attr_changeable(inode);
1308ab2a 16635+
4f0767ce 16636+out_unlock:
4a4d8108
AM
16637+ mutex_unlock(&a->h_inode->i_mutex);
16638+ au_unpin(&a->pin);
027c5e7a
AM
16639+ if (unlikely(err))
16640+ au_update_dbstart(dentry);
4f0767ce 16641+out_dentry:
4a4d8108
AM
16642+ di_write_unlock(dentry);
16643+ if (file) {
16644+ fi_write_unlock(file);
16645+ ia->ia_file = file;
16646+ ia->ia_valid |= ATTR_FILE;
16647+ }
4f0767ce 16648+out_si:
4a4d8108 16649+ si_read_unlock(sb);
e49829fe 16650+out_kfree:
4a4d8108 16651+ kfree(a);
4f0767ce 16652+out:
4a4d8108
AM
16653+ AuTraceErr(err);
16654+ return err;
1facf9fc 16655+}
16656+
4a4d8108
AM
16657+static void au_refresh_iattr(struct inode *inode, struct kstat *st,
16658+ unsigned int nlink)
1facf9fc 16659+{
9dbd164d
AM
16660+ unsigned int n;
16661+
4a4d8108 16662+ inode->i_mode = st->mode;
0c3ec466
AM
16663+ i_uid_write(inode, st->uid);
16664+ i_gid_write(inode, st->gid);
4a4d8108
AM
16665+ inode->i_atime = st->atime;
16666+ inode->i_mtime = st->mtime;
16667+ inode->i_ctime = st->ctime;
1facf9fc 16668+
4a4d8108
AM
16669+ au_cpup_attr_nlink(inode, /*force*/0);
16670+ if (S_ISDIR(inode->i_mode)) {
9dbd164d
AM
16671+ n = inode->i_nlink;
16672+ n -= nlink;
16673+ n += st->nlink;
7eafdf33 16674+ /* 0 can happen */
92d182d2 16675+ set_nlink(inode, n);
4a4d8108 16676+ }
1facf9fc 16677+
4a4d8108
AM
16678+ spin_lock(&inode->i_lock);
16679+ inode->i_blocks = st->blocks;
16680+ i_size_write(inode, st->size);
16681+ spin_unlock(&inode->i_lock);
1facf9fc 16682+}
16683+
4a4d8108
AM
16684+static int aufs_getattr(struct vfsmount *mnt __maybe_unused,
16685+ struct dentry *dentry, struct kstat *st)
1facf9fc 16686+{
4a4d8108
AM
16687+ int err;
16688+ unsigned int mnt_flags;
16689+ aufs_bindex_t bindex;
16690+ unsigned char udba_none, positive;
16691+ struct super_block *sb, *h_sb;
16692+ struct inode *inode;
16693+ struct vfsmount *h_mnt;
16694+ struct dentry *h_dentry;
1facf9fc 16695+
4a4d8108
AM
16696+ sb = dentry->d_sb;
16697+ inode = dentry->d_inode;
7f207e10
AM
16698+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
16699+ if (unlikely(err))
16700+ goto out;
4a4d8108
AM
16701+ mnt_flags = au_mntflags(sb);
16702+ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
1facf9fc 16703+
4a4d8108 16704+ /* support fstat(2) */
027c5e7a 16705+ if (!d_unlinked(dentry) && !udba_none) {
4a4d8108 16706+ unsigned int sigen = au_sigen(sb);
027c5e7a
AM
16707+ err = au_digen_test(dentry, sigen);
16708+ if (!err) {
4a4d8108 16709+ di_read_lock_child(dentry, AuLock_IR);
027c5e7a
AM
16710+ err = au_dbrange_test(dentry);
16711+ if (unlikely(err))
16712+ goto out_unlock;
16713+ } else {
4a4d8108
AM
16714+ AuDebugOn(IS_ROOT(dentry));
16715+ di_write_lock_child(dentry);
027c5e7a
AM
16716+ err = au_dbrange_test(dentry);
16717+ if (!err)
16718+ err = au_reval_for_attr(dentry, sigen);
4a4d8108
AM
16719+ di_downgrade_lock(dentry, AuLock_IR);
16720+ if (unlikely(err))
7f207e10 16721+ goto out_unlock;
4a4d8108
AM
16722+ }
16723+ } else
16724+ di_read_lock_child(dentry, AuLock_IR);
1facf9fc 16725+
4a4d8108
AM
16726+ bindex = au_ibstart(inode);
16727+ h_mnt = au_sbr_mnt(sb, bindex);
16728+ h_sb = h_mnt->mnt_sb;
16729+ if (!au_test_fs_bad_iattr(h_sb) && udba_none)
16730+ goto out_fill; /* success */
1facf9fc 16731+
4a4d8108
AM
16732+ h_dentry = NULL;
16733+ if (au_dbstart(dentry) == bindex)
16734+ h_dentry = dget(au_h_dptr(dentry, bindex));
16735+ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
16736+ h_dentry = au_plink_lkup(inode, bindex);
16737+ if (IS_ERR(h_dentry))
16738+ goto out_fill; /* pretending success */
16739+ }
16740+ /* illegally overlapped or something */
16741+ if (unlikely(!h_dentry))
16742+ goto out_fill; /* pretending success */
16743+
16744+ positive = !!h_dentry->d_inode;
16745+ if (positive)
16746+ err = vfs_getattr(h_mnt, h_dentry, st);
16747+ dput(h_dentry);
16748+ if (!err) {
16749+ if (positive)
16750+ au_refresh_iattr(inode, st, h_dentry->d_inode->i_nlink);
16751+ goto out_fill; /* success */
1facf9fc 16752+ }
7f207e10
AM
16753+ AuTraceErr(err);
16754+ goto out_unlock;
4a4d8108 16755+
4f0767ce 16756+out_fill:
4a4d8108 16757+ generic_fillattr(inode, st);
7f207e10 16758+out_unlock:
4a4d8108
AM
16759+ di_read_unlock(dentry, AuLock_IR);
16760+ si_read_unlock(sb);
7f207e10
AM
16761+out:
16762+ AuTraceErr(err);
4a4d8108 16763+ return err;
1facf9fc 16764+}
16765+
16766+/* ---------------------------------------------------------------------- */
16767+
4a4d8108
AM
16768+static int h_readlink(struct dentry *dentry, int bindex, char __user *buf,
16769+ int bufsiz)
1facf9fc 16770+{
16771+ int err;
4a4d8108
AM
16772+ struct super_block *sb;
16773+ struct dentry *h_dentry;
1facf9fc 16774+
4a4d8108
AM
16775+ err = -EINVAL;
16776+ h_dentry = au_h_dptr(dentry, bindex);
16777+ if (unlikely(!h_dentry->d_inode->i_op->readlink))
16778+ goto out;
1facf9fc 16779+
4a4d8108
AM
16780+ err = security_inode_readlink(h_dentry);
16781+ if (unlikely(err))
dece6358 16782+ goto out;
1facf9fc 16783+
4a4d8108
AM
16784+ sb = dentry->d_sb;
16785+ if (!au_test_ro(sb, bindex, dentry->d_inode)) {
16786+ vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry);
16787+ fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode);
1facf9fc 16788+ }
4a4d8108 16789+ err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz);
1facf9fc 16790+
4f0767ce 16791+out:
4a4d8108
AM
16792+ return err;
16793+}
1facf9fc 16794+
4a4d8108
AM
16795+static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
16796+{
16797+ int err;
1facf9fc 16798+
027c5e7a
AM
16799+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
16800+ if (unlikely(err))
16801+ goto out;
16802+ err = au_d_hashed_positive(dentry);
16803+ if (!err)
16804+ err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz);
4a4d8108 16805+ aufs_read_unlock(dentry, AuLock_IR);
1facf9fc 16806+
027c5e7a 16807+out:
4a4d8108
AM
16808+ return err;
16809+}
1facf9fc 16810+
4a4d8108
AM
16811+static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd)
16812+{
16813+ int err;
4a4d8108 16814+ mm_segment_t old_fs;
b752ccd1
AM
16815+ union {
16816+ char *k;
16817+ char __user *u;
16818+ } buf;
1facf9fc 16819+
4a4d8108 16820+ err = -ENOMEM;
537831f9 16821+ buf.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 16822+ if (unlikely(!buf.k))
4a4d8108 16823+ goto out;
1facf9fc 16824+
027c5e7a
AM
16825+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
16826+ if (unlikely(err))
16827+ goto out_name;
16828+
16829+ err = au_d_hashed_positive(dentry);
16830+ if (!err) {
16831+ old_fs = get_fs();
16832+ set_fs(KERNEL_DS);
16833+ err = h_readlink(dentry, au_dbstart(dentry), buf.u, PATH_MAX);
16834+ set_fs(old_fs);
16835+ }
4a4d8108 16836+ aufs_read_unlock(dentry, AuLock_IR);
1facf9fc 16837+
4a4d8108 16838+ if (err >= 0) {
b752ccd1 16839+ buf.k[err] = 0;
4a4d8108 16840+ /* will be freed by put_link */
b752ccd1 16841+ nd_set_link(nd, buf.k);
4a4d8108 16842+ return NULL; /* success */
1308ab2a 16843+ }
1facf9fc 16844+
027c5e7a 16845+out_name:
537831f9 16846+ free_page((unsigned long)buf.k);
4f0767ce 16847+out:
4a4d8108
AM
16848+ AuTraceErr(err);
16849+ return ERR_PTR(err);
16850+}
1facf9fc 16851+
4a4d8108
AM
16852+static void aufs_put_link(struct dentry *dentry __maybe_unused,
16853+ struct nameidata *nd, void *cookie __maybe_unused)
16854+{
537831f9
AM
16855+ char *p;
16856+
16857+ p = nd_get_link(nd);
16858+ if (!IS_ERR_OR_NULL(p))
16859+ free_page((unsigned long)p);
4a4d8108 16860+}
1facf9fc 16861+
4a4d8108 16862+/* ---------------------------------------------------------------------- */
1facf9fc 16863+
0c3ec466 16864+static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags)
4a4d8108 16865+{
0c3ec466
AM
16866+ int err;
16867+ struct super_block *sb;
16868+ struct inode *h_inode;
16869+
16870+ sb = inode->i_sb;
16871+ /* mmap_sem might be acquired already, cf. aufs_mmap() */
16872+ lockdep_off();
16873+ si_read_lock(sb, AuLock_FLUSH);
16874+ ii_write_lock_child(inode);
16875+ lockdep_on();
16876+ h_inode = au_h_iptr(inode, au_ibstart(inode));
16877+ err = vfsub_update_time(h_inode, ts, flags);
16878+ lockdep_off();
16879+ ii_write_unlock(inode);
16880+ si_read_unlock(sb);
16881+ lockdep_on();
16882+ return err;
4a4d8108 16883+}
1facf9fc 16884+
4a4d8108 16885+/* ---------------------------------------------------------------------- */
1308ab2a 16886+
4a4d8108
AM
16887+struct inode_operations aufs_symlink_iop = {
16888+ .permission = aufs_permission,
16889+ .setattr = aufs_setattr,
16890+ .getattr = aufs_getattr,
0c3ec466 16891+
4a4d8108
AM
16892+ .readlink = aufs_readlink,
16893+ .follow_link = aufs_follow_link,
0c3ec466
AM
16894+ .put_link = aufs_put_link,
16895+
16896+ /* .update_time = aufs_update_time */
4a4d8108
AM
16897+};
16898+
16899+struct inode_operations aufs_dir_iop = {
16900+ .create = aufs_create,
16901+ .lookup = aufs_lookup,
16902+ .link = aufs_link,
16903+ .unlink = aufs_unlink,
16904+ .symlink = aufs_symlink,
16905+ .mkdir = aufs_mkdir,
16906+ .rmdir = aufs_rmdir,
16907+ .mknod = aufs_mknod,
16908+ .rename = aufs_rename,
16909+
16910+ .permission = aufs_permission,
16911+ .setattr = aufs_setattr,
0c3ec466
AM
16912+ .getattr = aufs_getattr,
16913+
16914+ .update_time = aufs_update_time
b4510431 16915+ /* no support for atomic_open() */
4a4d8108
AM
16916+};
16917+
16918+struct inode_operations aufs_iop = {
16919+ .permission = aufs_permission,
16920+ .setattr = aufs_setattr,
16921+ .getattr = aufs_getattr,
0c3ec466
AM
16922+
16923+ .update_time = aufs_update_time
4a4d8108 16924+};
7f207e10
AM
16925diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
16926--- /usr/share/empty/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
1716fcea 16927+++ linux/fs/aufs/i_op_del.c 2013-02-19 08:40:03.950226347 +0100
537831f9 16928@@ -0,0 +1,477 @@
1facf9fc 16929+/*
7a9e40b8 16930+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 16931+ *
16932+ * This program, aufs is free software; you can redistribute it and/or modify
16933+ * it under the terms of the GNU General Public License as published by
16934+ * the Free Software Foundation; either version 2 of the License, or
16935+ * (at your option) any later version.
dece6358
AM
16936+ *
16937+ * This program is distributed in the hope that it will be useful,
16938+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16939+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16940+ * GNU General Public License for more details.
16941+ *
16942+ * You should have received a copy of the GNU General Public License
16943+ * along with this program; if not, write to the Free Software
16944+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 16945+ */
16946+
16947+/*
4a4d8108 16948+ * inode operations (del entry)
1308ab2a 16949+ */
dece6358 16950+
1308ab2a 16951+#include "aufs.h"
dece6358 16952+
4a4d8108
AM
16953+/*
16954+ * decide if a new whiteout for @dentry is necessary or not.
16955+ * when it is necessary, prepare the parent dir for the upper branch whose
16956+ * branch index is @bcpup for creation. the actual creation of the whiteout will
16957+ * be done by caller.
16958+ * return value:
16959+ * 0: wh is unnecessary
16960+ * plus: wh is necessary
16961+ * minus: error
16962+ */
16963+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
1308ab2a 16964+{
4a4d8108
AM
16965+ int need_wh, err;
16966+ aufs_bindex_t bstart;
16967+ struct super_block *sb;
dece6358 16968+
4a4d8108
AM
16969+ sb = dentry->d_sb;
16970+ bstart = au_dbstart(dentry);
16971+ if (*bcpup < 0) {
16972+ *bcpup = bstart;
16973+ if (au_test_ro(sb, bstart, dentry->d_inode)) {
16974+ err = AuWbrCopyup(au_sbi(sb), dentry);
16975+ *bcpup = err;
16976+ if (unlikely(err < 0))
16977+ goto out;
16978+ }
16979+ } else
16980+ AuDebugOn(bstart < *bcpup
16981+ || au_test_ro(sb, *bcpup, dentry->d_inode));
16982+ AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
1308ab2a 16983+
4a4d8108
AM
16984+ if (*bcpup != bstart) {
16985+ err = au_cpup_dirs(dentry, *bcpup);
16986+ if (unlikely(err))
16987+ goto out;
16988+ need_wh = 1;
16989+ } else {
027c5e7a 16990+ struct au_dinfo *dinfo, *tmp;
4a4d8108 16991+
027c5e7a
AM
16992+ need_wh = -ENOMEM;
16993+ dinfo = au_di(dentry);
16994+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
16995+ if (tmp) {
16996+ au_di_cp(tmp, dinfo);
16997+ au_di_swap(tmp, dinfo);
16998+ /* returns the number of positive dentries */
537831f9 16999+ need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0);
027c5e7a
AM
17000+ au_di_swap(tmp, dinfo);
17001+ au_rw_write_unlock(&tmp->di_rwsem);
17002+ au_di_free(tmp);
4a4d8108
AM
17003+ }
17004+ }
17005+ AuDbg("need_wh %d\n", need_wh);
17006+ err = need_wh;
17007+
4f0767ce 17008+out:
4a4d8108 17009+ return err;
1facf9fc 17010+}
17011+
4a4d8108
AM
17012+/*
17013+ * simple tests for the del-entry operations.
17014+ * following the checks in vfs, plus the parent-child relationship.
17015+ */
17016+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
17017+ struct dentry *h_parent, int isdir)
1facf9fc 17018+{
4a4d8108
AM
17019+ int err;
17020+ umode_t h_mode;
17021+ struct dentry *h_dentry, *h_latest;
1308ab2a 17022+ struct inode *h_inode;
1facf9fc 17023+
4a4d8108
AM
17024+ h_dentry = au_h_dptr(dentry, bindex);
17025+ h_inode = h_dentry->d_inode;
17026+ if (dentry->d_inode) {
17027+ err = -ENOENT;
17028+ if (unlikely(!h_inode || !h_inode->i_nlink))
17029+ goto out;
1facf9fc 17030+
4a4d8108
AM
17031+ h_mode = h_inode->i_mode;
17032+ if (!isdir) {
17033+ err = -EISDIR;
17034+ if (unlikely(S_ISDIR(h_mode)))
17035+ goto out;
17036+ } else if (unlikely(!S_ISDIR(h_mode))) {
17037+ err = -ENOTDIR;
17038+ goto out;
17039+ }
17040+ } else {
17041+ /* rename(2) case */
17042+ err = -EIO;
17043+ if (unlikely(h_inode))
17044+ goto out;
17045+ }
1facf9fc 17046+
4a4d8108
AM
17047+ err = -ENOENT;
17048+ /* expected parent dir is locked */
17049+ if (unlikely(h_parent != h_dentry->d_parent))
17050+ goto out;
17051+ err = 0;
17052+
17053+ /*
17054+ * rmdir a dir may break the consistency on some filesystem.
17055+ * let's try heavy test.
17056+ */
17057+ err = -EACCES;
17058+ if (unlikely(au_test_h_perm(h_parent->d_inode, MAY_EXEC | MAY_WRITE)))
17059+ goto out;
17060+
17061+ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent,
17062+ au_sbr(dentry->d_sb, bindex));
17063+ err = -EIO;
17064+ if (IS_ERR(h_latest))
17065+ goto out;
17066+ if (h_latest == h_dentry)
17067+ err = 0;
17068+ dput(h_latest);
17069+
4f0767ce 17070+out:
4a4d8108 17071+ return err;
1308ab2a 17072+}
1facf9fc 17073+
4a4d8108
AM
17074+/*
17075+ * decide the branch where we operate for @dentry. the branch index will be set
17076+ * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
17077+ * dir for reverting.
17078+ * when a new whiteout is necessary, create it.
17079+ */
17080+static struct dentry*
17081+lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
17082+ struct au_dtime *dt, struct au_pin *pin)
1308ab2a 17083+{
4a4d8108
AM
17084+ struct dentry *wh_dentry;
17085+ struct super_block *sb;
17086+ struct path h_path;
17087+ int err, need_wh;
17088+ unsigned int udba;
17089+ aufs_bindex_t bcpup;
dece6358 17090+
4a4d8108
AM
17091+ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
17092+ wh_dentry = ERR_PTR(need_wh);
17093+ if (unlikely(need_wh < 0))
17094+ goto out;
17095+
17096+ sb = dentry->d_sb;
17097+ udba = au_opt_udba(sb);
17098+ bcpup = *rbcpup;
17099+ err = au_pin(pin, dentry, bcpup, udba,
17100+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17101+ wh_dentry = ERR_PTR(err);
17102+ if (unlikely(err))
17103+ goto out;
17104+
17105+ h_path.dentry = au_pinned_h_parent(pin);
17106+ if (udba != AuOpt_UDBA_NONE
17107+ && au_dbstart(dentry) == bcpup) {
17108+ err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
17109+ wh_dentry = ERR_PTR(err);
17110+ if (unlikely(err))
17111+ goto out_unpin;
17112+ }
17113+
17114+ h_path.mnt = au_sbr_mnt(sb, bcpup);
17115+ au_dtime_store(dt, au_pinned_parent(pin), &h_path);
17116+ wh_dentry = NULL;
17117+ if (!need_wh)
17118+ goto out; /* success, no need to create whiteout */
17119+
17120+ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
17121+ if (IS_ERR(wh_dentry))
17122+ goto out_unpin;
17123+
17124+ /* returns with the parent is locked and wh_dentry is dget-ed */
17125+ goto out; /* success */
17126+
4f0767ce 17127+out_unpin:
4a4d8108 17128+ au_unpin(pin);
4f0767ce 17129+out:
4a4d8108 17130+ return wh_dentry;
1facf9fc 17131+}
17132+
4a4d8108
AM
17133+/*
17134+ * when removing a dir, rename it to a unique temporary whiteout-ed name first
17135+ * in order to be revertible and save time for removing many child whiteouts
17136+ * under the dir.
17137+ * returns 1 when there are too many child whiteout and caller should remove
17138+ * them asynchronously. returns 0 when the number of children is enough small to
17139+ * remove now or the branch fs is a remote fs.
17140+ * otherwise return an error.
17141+ */
17142+static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
17143+ struct au_nhash *whlist, struct inode *dir)
1facf9fc 17144+{
4a4d8108
AM
17145+ int rmdir_later, err, dirwh;
17146+ struct dentry *h_dentry;
17147+ struct super_block *sb;
17148+
17149+ sb = dentry->d_sb;
17150+ SiMustAnyLock(sb);
17151+ h_dentry = au_h_dptr(dentry, bindex);
17152+ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
17153+ if (unlikely(err))
17154+ goto out;
17155+
17156+ /* stop monitoring */
17157+ au_hn_free(au_hi(dentry->d_inode, bindex));
17158+
17159+ if (!au_test_fs_remote(h_dentry->d_sb)) {
17160+ dirwh = au_sbi(sb)->si_dirwh;
17161+ rmdir_later = (dirwh <= 1);
17162+ if (!rmdir_later)
17163+ rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
17164+ dirwh);
17165+ if (rmdir_later)
17166+ return rmdir_later;
17167+ }
1facf9fc 17168+
4a4d8108
AM
17169+ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
17170+ if (unlikely(err)) {
17171+ AuIOErr("rmdir %.*s, b%d failed, %d. ignored\n",
17172+ AuDLNPair(h_dentry), bindex, err);
17173+ err = 0;
17174+ }
dece6358 17175+
4f0767ce 17176+out:
4a4d8108
AM
17177+ AuTraceErr(err);
17178+ return err;
17179+}
1308ab2a 17180+
4a4d8108
AM
17181+/*
17182+ * final procedure for deleting a entry.
17183+ * maintain dentry and iattr.
17184+ */
17185+static void epilog(struct inode *dir, struct dentry *dentry,
17186+ aufs_bindex_t bindex)
17187+{
17188+ struct inode *inode;
1308ab2a 17189+
4a4d8108
AM
17190+ inode = dentry->d_inode;
17191+ d_drop(dentry);
17192+ inode->i_ctime = dir->i_ctime;
1308ab2a 17193+
4a4d8108
AM
17194+ if (au_ibstart(dir) == bindex)
17195+ au_cpup_attr_timesizes(dir);
17196+ dir->i_version++;
1facf9fc 17197+}
17198+
4a4d8108
AM
17199+/*
17200+ * when an error happened, remove the created whiteout and revert everything.
17201+ */
7f207e10
AM
17202+static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex,
17203+ aufs_bindex_t bwh, struct dentry *wh_dentry,
17204+ struct dentry *dentry, struct au_dtime *dt)
1facf9fc 17205+{
4a4d8108
AM
17206+ int rerr;
17207+ struct path h_path = {
17208+ .dentry = wh_dentry,
7f207e10 17209+ .mnt = au_sbr_mnt(dir->i_sb, bindex)
4a4d8108 17210+ };
dece6358 17211+
7f207e10 17212+ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
4a4d8108
AM
17213+ if (!rerr) {
17214+ au_set_dbwh(dentry, bwh);
17215+ au_dtime_revert(dt);
17216+ return 0;
17217+ }
dece6358 17218+
4a4d8108
AM
17219+ AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
17220+ AuDLNPair(dentry), err, rerr);
17221+ return -EIO;
1facf9fc 17222+}
17223+
4a4d8108 17224+/* ---------------------------------------------------------------------- */
1facf9fc 17225+
4a4d8108 17226+int aufs_unlink(struct inode *dir, struct dentry *dentry)
1308ab2a 17227+{
4a4d8108
AM
17228+ int err;
17229+ aufs_bindex_t bwh, bindex, bstart;
17230+ struct au_dtime dt;
17231+ struct au_pin pin;
17232+ struct path h_path;
17233+ struct inode *inode, *h_dir;
17234+ struct dentry *parent, *wh_dentry;
1facf9fc 17235+
4a4d8108 17236+ IMustLock(dir);
027c5e7a
AM
17237+
17238+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
17239+ if (unlikely(err))
17240+ goto out;
17241+ err = au_d_hashed_positive(dentry);
17242+ if (unlikely(err))
17243+ goto out_unlock;
4a4d8108 17244+ inode = dentry->d_inode;
4a4d8108 17245+ IMustLock(inode);
027c5e7a
AM
17246+ err = -EISDIR;
17247+ if (unlikely(S_ISDIR(inode->i_mode)))
17248+ goto out_unlock; /* possible? */
1facf9fc 17249+
4a4d8108
AM
17250+ bstart = au_dbstart(dentry);
17251+ bwh = au_dbwh(dentry);
17252+ bindex = -1;
027c5e7a
AM
17253+ parent = dentry->d_parent; /* dir inode is locked */
17254+ di_write_lock_parent(parent);
4a4d8108
AM
17255+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt, &pin);
17256+ err = PTR_ERR(wh_dentry);
17257+ if (IS_ERR(wh_dentry))
027c5e7a 17258+ goto out_parent;
1facf9fc 17259+
4a4d8108
AM
17260+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
17261+ h_path.dentry = au_h_dptr(dentry, bstart);
17262+ dget(h_path.dentry);
17263+ if (bindex == bstart) {
17264+ h_dir = au_pinned_h_dir(&pin);
17265+ err = vfsub_unlink(h_dir, &h_path, /*force*/0);
17266+ } else {
17267+ /* dir inode is locked */
17268+ h_dir = wh_dentry->d_parent->d_inode;
17269+ IMustLock(h_dir);
17270+ err = 0;
17271+ }
dece6358 17272+
4a4d8108 17273+ if (!err) {
7f207e10 17274+ vfsub_drop_nlink(inode);
4a4d8108
AM
17275+ epilog(dir, dentry, bindex);
17276+
17277+ /* update target timestamps */
17278+ if (bindex == bstart) {
17279+ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
17280+ inode->i_ctime = h_path.dentry->d_inode->i_ctime;
17281+ } else
17282+ /* todo: this timestamp may be reverted later */
17283+ inode->i_ctime = h_dir->i_ctime;
027c5e7a 17284+ goto out_unpin; /* success */
1facf9fc 17285+ }
17286+
4a4d8108
AM
17287+ /* revert */
17288+ if (wh_dentry) {
17289+ int rerr;
17290+
7f207e10 17291+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, &dt);
4a4d8108
AM
17292+ if (rerr)
17293+ err = rerr;
dece6358 17294+ }
1facf9fc 17295+
027c5e7a 17296+out_unpin:
4a4d8108
AM
17297+ au_unpin(&pin);
17298+ dput(wh_dentry);
17299+ dput(h_path.dentry);
027c5e7a 17300+out_parent:
4a4d8108 17301+ di_write_unlock(parent);
027c5e7a 17302+out_unlock:
4a4d8108 17303+ aufs_read_unlock(dentry, AuLock_DW);
027c5e7a 17304+out:
4a4d8108 17305+ return err;
dece6358
AM
17306+}
17307+
4a4d8108 17308+int aufs_rmdir(struct inode *dir, struct dentry *dentry)
1308ab2a 17309+{
4a4d8108
AM
17310+ int err, rmdir_later;
17311+ aufs_bindex_t bwh, bindex, bstart;
17312+ struct au_dtime dt;
17313+ struct au_pin pin;
17314+ struct inode *inode;
17315+ struct dentry *parent, *wh_dentry, *h_dentry;
17316+ struct au_whtmp_rmdir *args;
1facf9fc 17317+
4a4d8108 17318+ IMustLock(dir);
027c5e7a
AM
17319+
17320+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
17321+ if (unlikely(err))
4a4d8108 17322+ goto out;
53392da6
AM
17323+ err = au_alive_dir(dentry);
17324+ if (unlikely(err))
027c5e7a 17325+ goto out_unlock;
53392da6 17326+ inode = dentry->d_inode;
4a4d8108 17327+ IMustLock(inode);
027c5e7a
AM
17328+ err = -ENOTDIR;
17329+ if (unlikely(!S_ISDIR(inode->i_mode)))
17330+ goto out_unlock; /* possible? */
dece6358 17331+
4a4d8108
AM
17332+ err = -ENOMEM;
17333+ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
17334+ if (unlikely(!args))
17335+ goto out_unlock;
dece6358 17336+
4a4d8108
AM
17337+ parent = dentry->d_parent; /* dir inode is locked */
17338+ di_write_lock_parent(parent);
17339+ err = au_test_empty(dentry, &args->whlist);
17340+ if (unlikely(err))
027c5e7a 17341+ goto out_parent;
1facf9fc 17342+
4a4d8108
AM
17343+ bstart = au_dbstart(dentry);
17344+ bwh = au_dbwh(dentry);
17345+ bindex = -1;
17346+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &dt, &pin);
17347+ err = PTR_ERR(wh_dentry);
17348+ if (IS_ERR(wh_dentry))
027c5e7a 17349+ goto out_parent;
1facf9fc 17350+
4a4d8108
AM
17351+ h_dentry = au_h_dptr(dentry, bstart);
17352+ dget(h_dentry);
17353+ rmdir_later = 0;
17354+ if (bindex == bstart) {
17355+ err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir);
17356+ if (err > 0) {
17357+ rmdir_later = err;
17358+ err = 0;
17359+ }
17360+ } else {
17361+ /* stop monitoring */
17362+ au_hn_free(au_hi(inode, bstart));
17363+
17364+ /* dir inode is locked */
17365+ IMustLock(wh_dentry->d_parent->d_inode);
1facf9fc 17366+ err = 0;
17367+ }
17368+
4a4d8108 17369+ if (!err) {
027c5e7a 17370+ vfsub_dead_dir(inode);
4a4d8108
AM
17371+ au_set_dbdiropq(dentry, -1);
17372+ epilog(dir, dentry, bindex);
1308ab2a 17373+
4a4d8108
AM
17374+ if (rmdir_later) {
17375+ au_whtmp_kick_rmdir(dir, bstart, h_dentry, args);
17376+ args = NULL;
17377+ }
1308ab2a 17378+
4a4d8108 17379+ goto out_unpin; /* success */
1facf9fc 17380+ }
17381+
4a4d8108
AM
17382+ /* revert */
17383+ AuLabel(revert);
17384+ if (wh_dentry) {
17385+ int rerr;
1308ab2a 17386+
7f207e10 17387+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, &dt);
4a4d8108
AM
17388+ if (rerr)
17389+ err = rerr;
1facf9fc 17390+ }
17391+
4f0767ce 17392+out_unpin:
4a4d8108
AM
17393+ au_unpin(&pin);
17394+ dput(wh_dentry);
17395+ dput(h_dentry);
027c5e7a 17396+out_parent:
4a4d8108
AM
17397+ di_write_unlock(parent);
17398+ if (args)
17399+ au_whtmp_rmdir_free(args);
4f0767ce 17400+out_unlock:
4a4d8108 17401+ aufs_read_unlock(dentry, AuLock_DW);
4f0767ce 17402+out:
4a4d8108
AM
17403+ AuTraceErr(err);
17404+ return err;
dece6358 17405+}
7f207e10
AM
17406diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
17407--- /usr/share/empty/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
1716fcea 17408+++ linux/fs/aufs/i_op_ren.c 2013-02-19 08:40:03.950226347 +0100
7eafdf33 17409@@ -0,0 +1,1026 @@
1facf9fc 17410+/*
7a9e40b8 17411+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 17412+ *
17413+ * This program, aufs is free software; you can redistribute it and/or modify
17414+ * it under the terms of the GNU General Public License as published by
17415+ * the Free Software Foundation; either version 2 of the License, or
17416+ * (at your option) any later version.
dece6358
AM
17417+ *
17418+ * This program is distributed in the hope that it will be useful,
17419+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17420+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17421+ * GNU General Public License for more details.
17422+ *
17423+ * You should have received a copy of the GNU General Public License
17424+ * along with this program; if not, write to the Free Software
17425+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 17426+ */
17427+
17428+/*
4a4d8108
AM
17429+ * inode operation (rename entry)
17430+ * todo: this is crazy monster
1facf9fc 17431+ */
17432+
17433+#include "aufs.h"
17434+
4a4d8108
AM
17435+enum { AuSRC, AuDST, AuSrcDst };
17436+enum { AuPARENT, AuCHILD, AuParentChild };
1facf9fc 17437+
4a4d8108
AM
17438+#define AuRen_ISDIR 1
17439+#define AuRen_ISSAMEDIR (1 << 1)
17440+#define AuRen_WHSRC (1 << 2)
17441+#define AuRen_WHDST (1 << 3)
17442+#define AuRen_MNT_WRITE (1 << 4)
17443+#define AuRen_DT_DSTDIR (1 << 5)
17444+#define AuRen_DIROPQ (1 << 6)
17445+#define AuRen_CPUP (1 << 7)
17446+#define au_ftest_ren(flags, name) ((flags) & AuRen_##name)
7f207e10
AM
17447+#define au_fset_ren(flags, name) \
17448+ do { (flags) |= AuRen_##name; } while (0)
17449+#define au_fclr_ren(flags, name) \
17450+ do { (flags) &= ~AuRen_##name; } while (0)
1facf9fc 17451+
4a4d8108
AM
17452+struct au_ren_args {
17453+ struct {
17454+ struct dentry *dentry, *h_dentry, *parent, *h_parent,
17455+ *wh_dentry;
17456+ struct inode *dir, *inode;
17457+ struct au_hinode *hdir;
17458+ struct au_dtime dt[AuParentChild];
17459+ aufs_bindex_t bstart;
17460+ } sd[AuSrcDst];
1facf9fc 17461+
4a4d8108
AM
17462+#define src_dentry sd[AuSRC].dentry
17463+#define src_dir sd[AuSRC].dir
17464+#define src_inode sd[AuSRC].inode
17465+#define src_h_dentry sd[AuSRC].h_dentry
17466+#define src_parent sd[AuSRC].parent
17467+#define src_h_parent sd[AuSRC].h_parent
17468+#define src_wh_dentry sd[AuSRC].wh_dentry
17469+#define src_hdir sd[AuSRC].hdir
17470+#define src_h_dir sd[AuSRC].hdir->hi_inode
17471+#define src_dt sd[AuSRC].dt
17472+#define src_bstart sd[AuSRC].bstart
1facf9fc 17473+
4a4d8108
AM
17474+#define dst_dentry sd[AuDST].dentry
17475+#define dst_dir sd[AuDST].dir
17476+#define dst_inode sd[AuDST].inode
17477+#define dst_h_dentry sd[AuDST].h_dentry
17478+#define dst_parent sd[AuDST].parent
17479+#define dst_h_parent sd[AuDST].h_parent
17480+#define dst_wh_dentry sd[AuDST].wh_dentry
17481+#define dst_hdir sd[AuDST].hdir
17482+#define dst_h_dir sd[AuDST].hdir->hi_inode
17483+#define dst_dt sd[AuDST].dt
17484+#define dst_bstart sd[AuDST].bstart
17485+
17486+ struct dentry *h_trap;
17487+ struct au_branch *br;
17488+ struct au_hinode *src_hinode;
17489+ struct path h_path;
17490+ struct au_nhash whlist;
027c5e7a 17491+ aufs_bindex_t btgt, src_bwh, src_bdiropq;
1facf9fc 17492+
1308ab2a 17493+ unsigned int flags;
1facf9fc 17494+
4a4d8108
AM
17495+ struct au_whtmp_rmdir *thargs;
17496+ struct dentry *h_dst;
17497+};
1308ab2a 17498+
4a4d8108 17499+/* ---------------------------------------------------------------------- */
1308ab2a 17500+
4a4d8108
AM
17501+/*
17502+ * functions for reverting.
17503+ * when an error happened in a single rename systemcall, we should revert
17504+ * everything as if nothing happend.
17505+ * we don't need to revert the copied-up/down the parent dir since they are
17506+ * harmless.
17507+ */
1facf9fc 17508+
4a4d8108
AM
17509+#define RevertFailure(fmt, ...) do { \
17510+ AuIOErr("revert failure: " fmt " (%d, %d)\n", \
17511+ ##__VA_ARGS__, err, rerr); \
17512+ err = -EIO; \
17513+} while (0)
1facf9fc 17514+
4a4d8108 17515+static void au_ren_rev_diropq(int err, struct au_ren_args *a)
1facf9fc 17516+{
4a4d8108 17517+ int rerr;
1facf9fc 17518+
4a4d8108
AM
17519+ au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
17520+ rerr = au_diropq_remove(a->src_dentry, a->btgt);
17521+ au_hn_imtx_unlock(a->src_hinode);
027c5e7a 17522+ au_set_dbdiropq(a->src_dentry, a->src_bdiropq);
4a4d8108
AM
17523+ if (rerr)
17524+ RevertFailure("remove diropq %.*s", AuDLNPair(a->src_dentry));
17525+}
1facf9fc 17526+
4a4d8108
AM
17527+static void au_ren_rev_rename(int err, struct au_ren_args *a)
17528+{
17529+ int rerr;
1facf9fc 17530+
b4510431
AM
17531+ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name,
17532+ a->src_h_parent);
4a4d8108
AM
17533+ rerr = PTR_ERR(a->h_path.dentry);
17534+ if (IS_ERR(a->h_path.dentry)) {
b4510431 17535+ RevertFailure("lkup one %.*s", AuDLNPair(a->src_dentry));
4a4d8108 17536+ return;
1facf9fc 17537+ }
17538+
4a4d8108
AM
17539+ rerr = vfsub_rename(a->dst_h_dir,
17540+ au_h_dptr(a->src_dentry, a->btgt),
17541+ a->src_h_dir, &a->h_path);
17542+ d_drop(a->h_path.dentry);
17543+ dput(a->h_path.dentry);
17544+ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
17545+ if (rerr)
17546+ RevertFailure("rename %.*s", AuDLNPair(a->src_dentry));
1facf9fc 17547+}
17548+
4a4d8108 17549+static void au_ren_rev_cpup(int err, struct au_ren_args *a)
1facf9fc 17550+{
4a4d8108 17551+ int rerr;
1facf9fc 17552+
4a4d8108
AM
17553+ a->h_path.dentry = a->dst_h_dentry;
17554+ rerr = vfsub_unlink(a->dst_h_dir, &a->h_path, /*force*/0);
17555+ au_set_h_dptr(a->src_dentry, a->btgt, NULL);
17556+ au_set_dbstart(a->src_dentry, a->src_bstart);
17557+ if (rerr)
17558+ RevertFailure("unlink %.*s", AuDLNPair(a->dst_h_dentry));
1facf9fc 17559+}
17560+
4a4d8108 17561+static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
1facf9fc 17562+{
4a4d8108 17563+ int rerr;
dece6358 17564+
b4510431
AM
17565+ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name,
17566+ a->dst_h_parent);
4a4d8108
AM
17567+ rerr = PTR_ERR(a->h_path.dentry);
17568+ if (IS_ERR(a->h_path.dentry)) {
b4510431 17569+ RevertFailure("lkup one %.*s", AuDLNPair(a->dst_dentry));
4a4d8108
AM
17570+ return;
17571+ }
17572+ if (a->h_path.dentry->d_inode) {
17573+ d_drop(a->h_path.dentry);
17574+ dput(a->h_path.dentry);
17575+ return;
dece6358
AM
17576+ }
17577+
4a4d8108
AM
17578+ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path);
17579+ d_drop(a->h_path.dentry);
17580+ dput(a->h_path.dentry);
17581+ if (!rerr)
17582+ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
17583+ else
17584+ RevertFailure("rename %.*s", AuDLNPair(a->h_dst));
17585+}
1308ab2a 17586+
4a4d8108
AM
17587+static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
17588+{
17589+ int rerr;
1308ab2a 17590+
4a4d8108
AM
17591+ a->h_path.dentry = a->src_wh_dentry;
17592+ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
027c5e7a 17593+ au_set_dbwh(a->src_dentry, a->src_bwh);
4a4d8108
AM
17594+ if (rerr)
17595+ RevertFailure("unlink %.*s", AuDLNPair(a->src_wh_dentry));
17596+}
4a4d8108 17597+#undef RevertFailure
1facf9fc 17598+
1308ab2a 17599+/* ---------------------------------------------------------------------- */
17600+
4a4d8108
AM
17601+/*
17602+ * when we have to copyup the renaming entry, do it with the rename-target name
17603+ * in order to minimize the cost (the later actual rename is unnecessary).
17604+ * otherwise rename it on the target branch.
17605+ */
17606+static int au_ren_or_cpup(struct au_ren_args *a)
1facf9fc 17607+{
dece6358 17608+ int err;
4a4d8108 17609+ struct dentry *d;
1facf9fc 17610+
4a4d8108
AM
17611+ d = a->src_dentry;
17612+ if (au_dbstart(d) == a->btgt) {
17613+ a->h_path.dentry = a->dst_h_dentry;
17614+ if (au_ftest_ren(a->flags, DIROPQ)
17615+ && au_dbdiropq(d) == a->btgt)
17616+ au_fclr_ren(a->flags, DIROPQ);
17617+ AuDebugOn(au_dbstart(d) != a->btgt);
17618+ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
17619+ a->dst_h_dir, &a->h_path);
17620+ } else {
17621+ struct mutex *h_mtx = &a->src_h_dentry->d_inode->i_mutex;
17622+ struct file *h_file;
1308ab2a 17623+
4a4d8108
AM
17624+ au_fset_ren(a->flags, CPUP);
17625+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
17626+ au_set_dbstart(d, a->btgt);
17627+ au_set_h_dptr(d, a->btgt, dget(a->dst_h_dentry));
17628+ h_file = au_h_open_pre(d, a->src_bstart);
17629+ if (IS_ERR(h_file)) {
17630+ err = PTR_ERR(h_file);
17631+ h_file = NULL;
17632+ } else
17633+ err = au_sio_cpup_single(d, a->btgt, a->src_bstart, -1,
17634+ !AuCpup_DTIME, a->dst_parent);
17635+ mutex_unlock(h_mtx);
17636+ au_h_open_post(d, a->src_bstart, h_file);
17637+ if (!err) {
17638+ d = a->dst_dentry;
17639+ au_set_h_dptr(d, a->btgt, NULL);
17640+ au_update_dbstart(d);
17641+ } else {
17642+ au_set_h_dptr(d, a->btgt, NULL);
17643+ au_set_dbstart(d, a->src_bstart);
17644+ }
1308ab2a 17645+ }
027c5e7a
AM
17646+ if (!err && a->h_dst)
17647+ /* it will be set to dinfo later */
17648+ dget(a->h_dst);
1facf9fc 17649+
dece6358
AM
17650+ return err;
17651+}
1facf9fc 17652+
4a4d8108
AM
17653+/* cf. aufs_rmdir() */
17654+static int au_ren_del_whtmp(struct au_ren_args *a)
dece6358 17655+{
4a4d8108
AM
17656+ int err;
17657+ struct inode *dir;
1facf9fc 17658+
4a4d8108
AM
17659+ dir = a->dst_dir;
17660+ SiMustAnyLock(dir->i_sb);
17661+ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
17662+ au_sbi(dir->i_sb)->si_dirwh)
17663+ || au_test_fs_remote(a->h_dst->d_sb)) {
17664+ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
17665+ if (unlikely(err))
0c3ec466
AM
17666+ pr_warn("failed removing whtmp dir %.*s (%d), "
17667+ "ignored.\n", AuDLNPair(a->h_dst), err);
4a4d8108
AM
17668+ } else {
17669+ au_nhash_wh_free(&a->thargs->whlist);
17670+ a->thargs->whlist = a->whlist;
17671+ a->whlist.nh_num = 0;
17672+ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
17673+ dput(a->h_dst);
17674+ a->thargs = NULL;
17675+ }
17676+
17677+ return 0;
1308ab2a 17678+}
1facf9fc 17679+
4a4d8108
AM
17680+/* make it 'opaque' dir. */
17681+static int au_ren_diropq(struct au_ren_args *a)
17682+{
17683+ int err;
17684+ struct dentry *diropq;
1facf9fc 17685+
4a4d8108 17686+ err = 0;
027c5e7a 17687+ a->src_bdiropq = au_dbdiropq(a->src_dentry);
4a4d8108
AM
17688+ a->src_hinode = au_hi(a->src_inode, a->btgt);
17689+ au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
17690+ diropq = au_diropq_create(a->src_dentry, a->btgt);
17691+ au_hn_imtx_unlock(a->src_hinode);
17692+ if (IS_ERR(diropq))
17693+ err = PTR_ERR(diropq);
17694+ dput(diropq);
1facf9fc 17695+
4a4d8108
AM
17696+ return err;
17697+}
1facf9fc 17698+
4a4d8108
AM
17699+static int do_rename(struct au_ren_args *a)
17700+{
17701+ int err;
17702+ struct dentry *d, *h_d;
1facf9fc 17703+
4a4d8108
AM
17704+ /* prepare workqueue args for asynchronous rmdir */
17705+ h_d = a->dst_h_dentry;
17706+ if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) {
17707+ err = -ENOMEM;
17708+ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS);
17709+ if (unlikely(!a->thargs))
17710+ goto out;
17711+ a->h_dst = dget(h_d);
17712+ }
1facf9fc 17713+
4a4d8108
AM
17714+ /* create whiteout for src_dentry */
17715+ if (au_ftest_ren(a->flags, WHSRC)) {
027c5e7a
AM
17716+ a->src_bwh = au_dbwh(a->src_dentry);
17717+ AuDebugOn(a->src_bwh >= 0);
4a4d8108
AM
17718+ a->src_wh_dentry
17719+ = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent);
17720+ err = PTR_ERR(a->src_wh_dentry);
17721+ if (IS_ERR(a->src_wh_dentry))
17722+ goto out_thargs;
17723+ }
1facf9fc 17724+
4a4d8108
AM
17725+ /* lookup whiteout for dentry */
17726+ if (au_ftest_ren(a->flags, WHDST)) {
17727+ h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name,
17728+ a->br);
17729+ err = PTR_ERR(h_d);
17730+ if (IS_ERR(h_d))
17731+ goto out_whsrc;
17732+ if (!h_d->d_inode)
17733+ dput(h_d);
17734+ else
17735+ a->dst_wh_dentry = h_d;
17736+ }
1facf9fc 17737+
4a4d8108
AM
17738+ /* rename dentry to tmpwh */
17739+ if (a->thargs) {
17740+ err = au_whtmp_ren(a->dst_h_dentry, a->br);
17741+ if (unlikely(err))
17742+ goto out_whdst;
dece6358 17743+
4a4d8108
AM
17744+ d = a->dst_dentry;
17745+ au_set_h_dptr(d, a->btgt, NULL);
17746+ err = au_lkup_neg(d, a->btgt);
17747+ if (unlikely(err))
17748+ goto out_whtmp;
17749+ a->dst_h_dentry = au_h_dptr(d, a->btgt);
17750+ }
1facf9fc 17751+
4a4d8108
AM
17752+ /* cpup src */
17753+ if (a->dst_h_dentry->d_inode && a->src_bstart != a->btgt) {
17754+ struct mutex *h_mtx = &a->src_h_dentry->d_inode->i_mutex;
17755+ struct file *h_file;
1facf9fc 17756+
4a4d8108
AM
17757+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
17758+ AuDebugOn(au_dbstart(a->src_dentry) != a->src_bstart);
17759+ h_file = au_h_open_pre(a->src_dentry, a->src_bstart);
17760+ if (IS_ERR(h_file)) {
17761+ err = PTR_ERR(h_file);
17762+ h_file = NULL;
17763+ } else
17764+ err = au_sio_cpup_simple(a->src_dentry, a->btgt, -1,
17765+ !AuCpup_DTIME);
17766+ mutex_unlock(h_mtx);
17767+ au_h_open_post(a->src_dentry, a->src_bstart, h_file);
17768+ if (unlikely(err))
17769+ goto out_whtmp;
17770+ }
1facf9fc 17771+
4a4d8108
AM
17772+ /* rename by vfs_rename or cpup */
17773+ d = a->dst_dentry;
17774+ if (au_ftest_ren(a->flags, ISDIR)
17775+ && (a->dst_wh_dentry
17776+ || au_dbdiropq(d) == a->btgt
17777+ /* hide the lower to keep xino */
17778+ || a->btgt < au_dbend(d)
17779+ || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ)))
17780+ au_fset_ren(a->flags, DIROPQ);
17781+ err = au_ren_or_cpup(a);
17782+ if (unlikely(err))
17783+ /* leave the copied-up one */
17784+ goto out_whtmp;
1308ab2a 17785+
4a4d8108
AM
17786+ /* make dir opaque */
17787+ if (au_ftest_ren(a->flags, DIROPQ)) {
17788+ err = au_ren_diropq(a);
17789+ if (unlikely(err))
17790+ goto out_rename;
17791+ }
1308ab2a 17792+
4a4d8108
AM
17793+ /* update target timestamps */
17794+ AuDebugOn(au_dbstart(a->src_dentry) != a->btgt);
17795+ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
17796+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
17797+ a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
1facf9fc 17798+
4a4d8108
AM
17799+ /* remove whiteout for dentry */
17800+ if (a->dst_wh_dentry) {
17801+ a->h_path.dentry = a->dst_wh_dentry;
17802+ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
17803+ a->dst_dentry);
17804+ if (unlikely(err))
17805+ goto out_diropq;
17806+ }
1facf9fc 17807+
4a4d8108
AM
17808+ /* remove whtmp */
17809+ if (a->thargs)
17810+ au_ren_del_whtmp(a); /* ignore this error */
1308ab2a 17811+
4a4d8108
AM
17812+ err = 0;
17813+ goto out_success;
17814+
4f0767ce 17815+out_diropq:
4a4d8108
AM
17816+ if (au_ftest_ren(a->flags, DIROPQ))
17817+ au_ren_rev_diropq(err, a);
4f0767ce 17818+out_rename:
4a4d8108
AM
17819+ if (!au_ftest_ren(a->flags, CPUP))
17820+ au_ren_rev_rename(err, a);
17821+ else
17822+ au_ren_rev_cpup(err, a);
027c5e7a 17823+ dput(a->h_dst);
4f0767ce 17824+out_whtmp:
4a4d8108
AM
17825+ if (a->thargs)
17826+ au_ren_rev_whtmp(err, a);
4f0767ce 17827+out_whdst:
4a4d8108
AM
17828+ dput(a->dst_wh_dentry);
17829+ a->dst_wh_dentry = NULL;
4f0767ce 17830+out_whsrc:
4a4d8108
AM
17831+ if (a->src_wh_dentry)
17832+ au_ren_rev_whsrc(err, a);
4f0767ce 17833+out_success:
4a4d8108
AM
17834+ dput(a->src_wh_dentry);
17835+ dput(a->dst_wh_dentry);
4f0767ce 17836+out_thargs:
4a4d8108
AM
17837+ if (a->thargs) {
17838+ dput(a->h_dst);
17839+ au_whtmp_rmdir_free(a->thargs);
17840+ a->thargs = NULL;
17841+ }
4f0767ce 17842+out:
4a4d8108 17843+ return err;
dece6358 17844+}
1facf9fc 17845+
1308ab2a 17846+/* ---------------------------------------------------------------------- */
1facf9fc 17847+
4a4d8108
AM
17848+/*
17849+ * test if @dentry dir can be rename destination or not.
17850+ * success means, it is a logically empty dir.
17851+ */
17852+static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
1308ab2a 17853+{
4a4d8108 17854+ return au_test_empty(dentry, whlist);
1308ab2a 17855+}
1facf9fc 17856+
4a4d8108
AM
17857+/*
17858+ * test if @dentry dir can be rename source or not.
17859+ * if it can, return 0 and @children is filled.
17860+ * success means,
17861+ * - it is a logically empty dir.
17862+ * - or, it exists on writable branch and has no children including whiteouts
17863+ * on the lower branch.
17864+ */
17865+static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt)
17866+{
17867+ int err;
17868+ unsigned int rdhash;
17869+ aufs_bindex_t bstart;
1facf9fc 17870+
4a4d8108
AM
17871+ bstart = au_dbstart(dentry);
17872+ if (bstart != btgt) {
17873+ struct au_nhash whlist;
dece6358 17874+
4a4d8108
AM
17875+ SiMustAnyLock(dentry->d_sb);
17876+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
17877+ if (!rdhash)
17878+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL,
17879+ dentry));
17880+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
17881+ if (unlikely(err))
17882+ goto out;
17883+ err = au_test_empty(dentry, &whlist);
17884+ au_nhash_wh_free(&whlist);
17885+ goto out;
17886+ }
dece6358 17887+
4a4d8108
AM
17888+ if (bstart == au_dbtaildir(dentry))
17889+ return 0; /* success */
dece6358 17890+
4a4d8108 17891+ err = au_test_empty_lower(dentry);
1facf9fc 17892+
4f0767ce 17893+out:
4a4d8108
AM
17894+ if (err == -ENOTEMPTY) {
17895+ AuWarn1("renaming dir who has child(ren) on multiple branches,"
17896+ " is not supported\n");
17897+ err = -EXDEV;
17898+ }
17899+ return err;
17900+}
1308ab2a 17901+
4a4d8108
AM
17902+/* side effect: sets whlist and h_dentry */
17903+static int au_ren_may_dir(struct au_ren_args *a)
1308ab2a 17904+{
4a4d8108
AM
17905+ int err;
17906+ unsigned int rdhash;
17907+ struct dentry *d;
1facf9fc 17908+
4a4d8108
AM
17909+ d = a->dst_dentry;
17910+ SiMustAnyLock(d->d_sb);
1facf9fc 17911+
4a4d8108
AM
17912+ err = 0;
17913+ if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) {
17914+ rdhash = au_sbi(d->d_sb)->si_rdhash;
17915+ if (!rdhash)
17916+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d));
17917+ err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS);
17918+ if (unlikely(err))
17919+ goto out;
1308ab2a 17920+
4a4d8108
AM
17921+ au_set_dbstart(d, a->dst_bstart);
17922+ err = may_rename_dstdir(d, &a->whlist);
17923+ au_set_dbstart(d, a->btgt);
17924+ }
17925+ a->dst_h_dentry = au_h_dptr(d, au_dbstart(d));
17926+ if (unlikely(err))
17927+ goto out;
17928+
17929+ d = a->src_dentry;
17930+ a->src_h_dentry = au_h_dptr(d, au_dbstart(d));
17931+ if (au_ftest_ren(a->flags, ISDIR)) {
17932+ err = may_rename_srcdir(d, a->btgt);
17933+ if (unlikely(err)) {
17934+ au_nhash_wh_free(&a->whlist);
17935+ a->whlist.nh_num = 0;
17936+ }
17937+ }
4f0767ce 17938+out:
4a4d8108 17939+ return err;
1facf9fc 17940+}
17941+
4a4d8108 17942+/* ---------------------------------------------------------------------- */
1facf9fc 17943+
4a4d8108
AM
17944+/*
17945+ * simple tests for rename.
17946+ * following the checks in vfs, plus the parent-child relationship.
17947+ */
17948+static int au_may_ren(struct au_ren_args *a)
17949+{
17950+ int err, isdir;
17951+ struct inode *h_inode;
1facf9fc 17952+
4a4d8108
AM
17953+ if (a->src_bstart == a->btgt) {
17954+ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
17955+ au_ftest_ren(a->flags, ISDIR));
17956+ if (unlikely(err))
17957+ goto out;
17958+ err = -EINVAL;
17959+ if (unlikely(a->src_h_dentry == a->h_trap))
17960+ goto out;
17961+ }
1facf9fc 17962+
4a4d8108
AM
17963+ err = 0;
17964+ if (a->dst_bstart != a->btgt)
17965+ goto out;
1facf9fc 17966+
027c5e7a
AM
17967+ err = -ENOTEMPTY;
17968+ if (unlikely(a->dst_h_dentry == a->h_trap))
17969+ goto out;
17970+
4a4d8108
AM
17971+ err = -EIO;
17972+ h_inode = a->dst_h_dentry->d_inode;
17973+ isdir = !!au_ftest_ren(a->flags, ISDIR);
17974+ if (!a->dst_dentry->d_inode) {
17975+ if (unlikely(h_inode))
17976+ goto out;
17977+ err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent,
17978+ isdir);
17979+ } else {
17980+ if (unlikely(!h_inode || !h_inode->i_nlink))
17981+ goto out;
17982+ err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent,
17983+ isdir);
17984+ if (unlikely(err))
17985+ goto out;
4a4d8108 17986+ }
1facf9fc 17987+
4f0767ce 17988+out:
4a4d8108
AM
17989+ if (unlikely(err == -ENOENT || err == -EEXIST))
17990+ err = -EIO;
17991+ AuTraceErr(err);
17992+ return err;
17993+}
1facf9fc 17994+
1308ab2a 17995+/* ---------------------------------------------------------------------- */
1facf9fc 17996+
4a4d8108
AM
17997+/*
17998+ * locking order
17999+ * (VFS)
18000+ * - src_dir and dir by lock_rename()
18001+ * - inode if exitsts
18002+ * (aufs)
18003+ * - lock all
18004+ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
18005+ * + si_read_lock
18006+ * + di_write_lock2_child()
18007+ * + di_write_lock_child()
18008+ * + ii_write_lock_child()
18009+ * + di_write_lock_child2()
18010+ * + ii_write_lock_child2()
18011+ * + src_parent and parent
18012+ * + di_write_lock_parent()
18013+ * + ii_write_lock_parent()
18014+ * + di_write_lock_parent2()
18015+ * + ii_write_lock_parent2()
18016+ * + lower src_dir and dir by vfsub_lock_rename()
18017+ * + verify the every relationships between child and parent. if any
18018+ * of them failed, unlock all and return -EBUSY.
18019+ */
18020+static void au_ren_unlock(struct au_ren_args *a)
1308ab2a 18021+{
4a4d8108
AM
18022+ struct super_block *sb;
18023+
18024+ sb = a->dst_dentry->d_sb;
18025+ if (au_ftest_ren(a->flags, MNT_WRITE))
b4510431 18026+ vfsub_mnt_drop_write(a->br->br_mnt);
4a4d8108
AM
18027+ vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
18028+ a->dst_h_parent, a->dst_hdir);
1308ab2a 18029+}
18030+
4a4d8108 18031+static int au_ren_lock(struct au_ren_args *a)
1308ab2a 18032+{
4a4d8108
AM
18033+ int err;
18034+ unsigned int udba;
1308ab2a 18035+
4a4d8108
AM
18036+ err = 0;
18037+ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
18038+ a->src_hdir = au_hi(a->src_dir, a->btgt);
18039+ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
18040+ a->dst_hdir = au_hi(a->dst_dir, a->btgt);
18041+ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
18042+ a->dst_h_parent, a->dst_hdir);
18043+ udba = au_opt_udba(a->src_dentry->d_sb);
18044+ if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode
18045+ || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode))
18046+ err = au_busy_or_stale();
18047+ if (!err && au_dbstart(a->src_dentry) == a->btgt)
18048+ err = au_h_verify(a->src_h_dentry, udba,
18049+ a->src_h_parent->d_inode, a->src_h_parent,
18050+ a->br);
18051+ if (!err && au_dbstart(a->dst_dentry) == a->btgt)
18052+ err = au_h_verify(a->dst_h_dentry, udba,
18053+ a->dst_h_parent->d_inode, a->dst_h_parent,
18054+ a->br);
18055+ if (!err) {
b4510431 18056+ err = vfsub_mnt_want_write(a->br->br_mnt);
4a4d8108
AM
18057+ if (unlikely(err))
18058+ goto out_unlock;
18059+ au_fset_ren(a->flags, MNT_WRITE);
18060+ goto out; /* success */
18061+ }
18062+
18063+ err = au_busy_or_stale();
18064+
4f0767ce 18065+out_unlock:
4a4d8108 18066+ au_ren_unlock(a);
4f0767ce 18067+out:
4a4d8108 18068+ return err;
1facf9fc 18069+}
18070+
18071+/* ---------------------------------------------------------------------- */
18072+
4a4d8108 18073+static void au_ren_refresh_dir(struct au_ren_args *a)
1facf9fc 18074+{
4a4d8108 18075+ struct inode *dir;
dece6358 18076+
4a4d8108
AM
18077+ dir = a->dst_dir;
18078+ dir->i_version++;
18079+ if (au_ftest_ren(a->flags, ISDIR)) {
18080+ /* is this updating defined in POSIX? */
18081+ au_cpup_attr_timesizes(a->src_inode);
18082+ au_cpup_attr_nlink(dir, /*force*/1);
4a4d8108 18083+ }
027c5e7a 18084+
4a4d8108
AM
18085+ if (au_ibstart(dir) == a->btgt)
18086+ au_cpup_attr_timesizes(dir);
dece6358 18087+
4a4d8108
AM
18088+ if (au_ftest_ren(a->flags, ISSAMEDIR))
18089+ return;
dece6358 18090+
4a4d8108
AM
18091+ dir = a->src_dir;
18092+ dir->i_version++;
18093+ if (au_ftest_ren(a->flags, ISDIR))
18094+ au_cpup_attr_nlink(dir, /*force*/1);
18095+ if (au_ibstart(dir) == a->btgt)
18096+ au_cpup_attr_timesizes(dir);
1facf9fc 18097+}
18098+
4a4d8108 18099+static void au_ren_refresh(struct au_ren_args *a)
1facf9fc 18100+{
4a4d8108
AM
18101+ aufs_bindex_t bend, bindex;
18102+ struct dentry *d, *h_d;
18103+ struct inode *i, *h_i;
18104+ struct super_block *sb;
dece6358 18105+
027c5e7a
AM
18106+ d = a->dst_dentry;
18107+ d_drop(d);
18108+ if (a->h_dst)
18109+ /* already dget-ed by au_ren_or_cpup() */
18110+ au_set_h_dptr(d, a->btgt, a->h_dst);
18111+
18112+ i = a->dst_inode;
18113+ if (i) {
18114+ if (!au_ftest_ren(a->flags, ISDIR))
18115+ vfsub_drop_nlink(i);
18116+ else {
18117+ vfsub_dead_dir(i);
18118+ au_cpup_attr_timesizes(i);
18119+ }
18120+ au_update_dbrange(d, /*do_put_zero*/1);
18121+ } else {
18122+ bend = a->btgt;
18123+ for (bindex = au_dbstart(d); bindex < bend; bindex++)
18124+ au_set_h_dptr(d, bindex, NULL);
18125+ bend = au_dbend(d);
18126+ for (bindex = a->btgt + 1; bindex <= bend; bindex++)
18127+ au_set_h_dptr(d, bindex, NULL);
18128+ au_update_dbrange(d, /*do_put_zero*/0);
18129+ }
18130+
4a4d8108
AM
18131+ d = a->src_dentry;
18132+ au_set_dbwh(d, -1);
18133+ bend = au_dbend(d);
18134+ for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
18135+ h_d = au_h_dptr(d, bindex);
18136+ if (h_d)
18137+ au_set_h_dptr(d, bindex, NULL);
18138+ }
18139+ au_set_dbend(d, a->btgt);
18140+
18141+ sb = d->d_sb;
18142+ i = a->src_inode;
18143+ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
18144+ return; /* success */
18145+
18146+ bend = au_ibend(i);
18147+ for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
18148+ h_i = au_h_iptr(i, bindex);
18149+ if (h_i) {
18150+ au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
18151+ /* ignore this error */
18152+ au_set_h_iptr(i, bindex, NULL, 0);
18153+ }
18154+ }
18155+ au_set_ibend(i, a->btgt);
1308ab2a 18156+}
dece6358 18157+
4a4d8108
AM
18158+/* ---------------------------------------------------------------------- */
18159+
18160+/* mainly for link(2) and rename(2) */
18161+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
1308ab2a 18162+{
4a4d8108
AM
18163+ aufs_bindex_t bdiropq, bwh;
18164+ struct dentry *parent;
18165+ struct au_branch *br;
18166+
18167+ parent = dentry->d_parent;
18168+ IMustLock(parent->d_inode); /* dir is locked */
18169+
18170+ bdiropq = au_dbdiropq(parent);
18171+ bwh = au_dbwh(dentry);
18172+ br = au_sbr(dentry->d_sb, btgt);
18173+ if (au_br_rdonly(br)
18174+ || (0 <= bdiropq && bdiropq < btgt)
18175+ || (0 <= bwh && bwh < btgt))
18176+ btgt = -1;
18177+
18178+ AuDbg("btgt %d\n", btgt);
18179+ return btgt;
1facf9fc 18180+}
18181+
4a4d8108
AM
18182+/* sets src_bstart, dst_bstart and btgt */
18183+static int au_ren_wbr(struct au_ren_args *a)
1facf9fc 18184+{
4a4d8108
AM
18185+ int err;
18186+ struct au_wr_dir_args wr_dir_args = {
18187+ /* .force_btgt = -1, */
18188+ .flags = AuWrDir_ADD_ENTRY
18189+ };
dece6358 18190+
4a4d8108
AM
18191+ a->src_bstart = au_dbstart(a->src_dentry);
18192+ a->dst_bstart = au_dbstart(a->dst_dentry);
18193+ if (au_ftest_ren(a->flags, ISDIR))
18194+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
18195+ wr_dir_args.force_btgt = a->src_bstart;
18196+ if (a->dst_inode && a->dst_bstart < a->src_bstart)
18197+ wr_dir_args.force_btgt = a->dst_bstart;
18198+ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
18199+ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
18200+ a->btgt = err;
dece6358 18201+
4a4d8108 18202+ return err;
1facf9fc 18203+}
18204+
4a4d8108 18205+static void au_ren_dt(struct au_ren_args *a)
1facf9fc 18206+{
4a4d8108
AM
18207+ a->h_path.dentry = a->src_h_parent;
18208+ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
18209+ if (!au_ftest_ren(a->flags, ISSAMEDIR)) {
18210+ a->h_path.dentry = a->dst_h_parent;
18211+ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
18212+ }
1facf9fc 18213+
4a4d8108
AM
18214+ au_fclr_ren(a->flags, DT_DSTDIR);
18215+ if (!au_ftest_ren(a->flags, ISDIR))
18216+ return;
dece6358 18217+
4a4d8108
AM
18218+ a->h_path.dentry = a->src_h_dentry;
18219+ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
18220+ if (a->dst_h_dentry->d_inode) {
18221+ au_fset_ren(a->flags, DT_DSTDIR);
18222+ a->h_path.dentry = a->dst_h_dentry;
18223+ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
18224+ }
1308ab2a 18225+}
dece6358 18226+
4a4d8108 18227+static void au_ren_rev_dt(int err, struct au_ren_args *a)
1308ab2a 18228+{
4a4d8108
AM
18229+ struct dentry *h_d;
18230+ struct mutex *h_mtx;
18231+
18232+ au_dtime_revert(a->src_dt + AuPARENT);
18233+ if (!au_ftest_ren(a->flags, ISSAMEDIR))
18234+ au_dtime_revert(a->dst_dt + AuPARENT);
18235+
18236+ if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) {
18237+ h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
18238+ h_mtx = &h_d->d_inode->i_mutex;
18239+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
18240+ au_dtime_revert(a->src_dt + AuCHILD);
18241+ mutex_unlock(h_mtx);
18242+
18243+ if (au_ftest_ren(a->flags, DT_DSTDIR)) {
18244+ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
18245+ h_mtx = &h_d->d_inode->i_mutex;
18246+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
18247+ au_dtime_revert(a->dst_dt + AuCHILD);
18248+ mutex_unlock(h_mtx);
1facf9fc 18249+ }
18250+ }
18251+}
18252+
4a4d8108
AM
18253+/* ---------------------------------------------------------------------- */
18254+
18255+int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
18256+ struct inode *_dst_dir, struct dentry *_dst_dentry)
1facf9fc 18257+{
e49829fe 18258+ int err, flags;
4a4d8108
AM
18259+ /* reduce stack space */
18260+ struct au_ren_args *a;
18261+
18262+ AuDbg("%.*s, %.*s\n", AuDLNPair(_src_dentry), AuDLNPair(_dst_dentry));
18263+ IMustLock(_src_dir);
18264+ IMustLock(_dst_dir);
18265+
18266+ err = -ENOMEM;
18267+ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
18268+ a = kzalloc(sizeof(*a), GFP_NOFS);
18269+ if (unlikely(!a))
18270+ goto out;
18271+
18272+ a->src_dir = _src_dir;
18273+ a->src_dentry = _src_dentry;
18274+ a->src_inode = a->src_dentry->d_inode;
18275+ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
18276+ a->dst_dir = _dst_dir;
18277+ a->dst_dentry = _dst_dentry;
18278+ a->dst_inode = a->dst_dentry->d_inode;
18279+ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
18280+ if (a->dst_inode) {
18281+ IMustLock(a->dst_inode);
18282+ au_igrab(a->dst_inode);
1facf9fc 18283+ }
1facf9fc 18284+
4a4d8108 18285+ err = -ENOTDIR;
027c5e7a 18286+ flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
4a4d8108
AM
18287+ if (S_ISDIR(a->src_inode->i_mode)) {
18288+ au_fset_ren(a->flags, ISDIR);
18289+ if (unlikely(a->dst_inode && !S_ISDIR(a->dst_inode->i_mode)))
18290+ goto out_free;
e49829fe
JR
18291+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
18292+ AuLock_DIR | flags);
4a4d8108 18293+ } else
e49829fe
JR
18294+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
18295+ flags);
18296+ if (unlikely(err))
18297+ goto out_free;
1facf9fc 18298+
027c5e7a
AM
18299+ err = au_d_hashed_positive(a->src_dentry);
18300+ if (unlikely(err))
18301+ goto out_unlock;
18302+ err = -ENOENT;
18303+ if (a->dst_inode) {
18304+ /*
18305+ * If it is a dir, VFS unhash dst_dentry before this
18306+ * function. It means we cannot rely upon d_unhashed().
18307+ */
18308+ if (unlikely(!a->dst_inode->i_nlink))
18309+ goto out_unlock;
18310+ if (!S_ISDIR(a->dst_inode->i_mode)) {
18311+ err = au_d_hashed_positive(a->dst_dentry);
18312+ if (unlikely(err))
18313+ goto out_unlock;
18314+ } else if (unlikely(IS_DEADDIR(a->dst_inode)))
18315+ goto out_unlock;
18316+ } else if (unlikely(d_unhashed(a->dst_dentry)))
18317+ goto out_unlock;
18318+
7eafdf33
AM
18319+ /*
18320+ * is it possible?
18321+ * yes, it happend (in linux-3.3-rcN) but I don't know why.
18322+ * there may exist a problem somewhere else.
18323+ */
18324+ err = -EINVAL;
18325+ if (unlikely(a->dst_parent->d_inode == a->src_dentry->d_inode))
18326+ goto out_unlock;
18327+
4a4d8108
AM
18328+ au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
18329+ di_write_lock_parent(a->dst_parent);
1facf9fc 18330+
4a4d8108
AM
18331+ /* which branch we process */
18332+ err = au_ren_wbr(a);
18333+ if (unlikely(err < 0))
027c5e7a 18334+ goto out_parent;
4a4d8108
AM
18335+ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
18336+ a->h_path.mnt = a->br->br_mnt;
1facf9fc 18337+
4a4d8108
AM
18338+ /* are they available to be renamed */
18339+ err = au_ren_may_dir(a);
18340+ if (unlikely(err))
18341+ goto out_children;
1facf9fc 18342+
4a4d8108
AM
18343+ /* prepare the writable parent dir on the same branch */
18344+ if (a->dst_bstart == a->btgt) {
18345+ au_fset_ren(a->flags, WHDST);
18346+ } else {
18347+ err = au_cpup_dirs(a->dst_dentry, a->btgt);
18348+ if (unlikely(err))
18349+ goto out_children;
18350+ }
1facf9fc 18351+
4a4d8108
AM
18352+ if (a->src_dir != a->dst_dir) {
18353+ /*
18354+ * this temporary unlock is safe,
18355+ * because both dir->i_mutex are locked.
18356+ */
18357+ di_write_unlock(a->dst_parent);
18358+ di_write_lock_parent(a->src_parent);
18359+ err = au_wr_dir_need_wh(a->src_dentry,
18360+ au_ftest_ren(a->flags, ISDIR),
18361+ &a->btgt);
18362+ di_write_unlock(a->src_parent);
18363+ di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1);
18364+ au_fclr_ren(a->flags, ISSAMEDIR);
18365+ } else
18366+ err = au_wr_dir_need_wh(a->src_dentry,
18367+ au_ftest_ren(a->flags, ISDIR),
18368+ &a->btgt);
18369+ if (unlikely(err < 0))
18370+ goto out_children;
18371+ if (err)
18372+ au_fset_ren(a->flags, WHSRC);
1facf9fc 18373+
4a4d8108
AM
18374+ /* lock them all */
18375+ err = au_ren_lock(a);
18376+ if (unlikely(err))
18377+ goto out_children;
1facf9fc 18378+
4a4d8108
AM
18379+ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE))
18380+ err = au_may_ren(a);
18381+ else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN))
18382+ err = -ENAMETOOLONG;
18383+ if (unlikely(err))
18384+ goto out_hdir;
1facf9fc 18385+
4a4d8108
AM
18386+ /* store timestamps to be revertible */
18387+ au_ren_dt(a);
1facf9fc 18388+
4a4d8108
AM
18389+ /* here we go */
18390+ err = do_rename(a);
18391+ if (unlikely(err))
18392+ goto out_dt;
18393+
18394+ /* update dir attributes */
18395+ au_ren_refresh_dir(a);
18396+
18397+ /* dput/iput all lower dentries */
18398+ au_ren_refresh(a);
18399+
18400+ goto out_hdir; /* success */
18401+
4f0767ce 18402+out_dt:
4a4d8108 18403+ au_ren_rev_dt(err, a);
4f0767ce 18404+out_hdir:
4a4d8108 18405+ au_ren_unlock(a);
4f0767ce 18406+out_children:
4a4d8108 18407+ au_nhash_wh_free(&a->whlist);
027c5e7a
AM
18408+ if (err && a->dst_inode && a->dst_bstart != a->btgt) {
18409+ AuDbg("bstart %d, btgt %d\n", a->dst_bstart, a->btgt);
18410+ au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
18411+ au_set_dbstart(a->dst_dentry, a->dst_bstart);
4a4d8108 18412+ }
027c5e7a 18413+out_parent:
4a4d8108
AM
18414+ if (!err)
18415+ d_move(a->src_dentry, a->dst_dentry);
027c5e7a
AM
18416+ else {
18417+ au_update_dbstart(a->dst_dentry);
18418+ if (!a->dst_inode)
18419+ d_drop(a->dst_dentry);
18420+ }
4a4d8108
AM
18421+ if (au_ftest_ren(a->flags, ISSAMEDIR))
18422+ di_write_unlock(a->dst_parent);
18423+ else
18424+ di_write_unlock2(a->src_parent, a->dst_parent);
027c5e7a 18425+out_unlock:
4a4d8108 18426+ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
4f0767ce 18427+out_free:
4a4d8108
AM
18428+ iput(a->dst_inode);
18429+ if (a->thargs)
18430+ au_whtmp_rmdir_free(a->thargs);
18431+ kfree(a);
4f0767ce 18432+out:
4a4d8108
AM
18433+ AuTraceErr(err);
18434+ return err;
1308ab2a 18435+}
7f207e10
AM
18436diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
18437--- /usr/share/empty/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100
a2a7ad62 18438+++ linux/fs/aufs/Kconfig 2013-03-14 20:07:41.038119650 +0100
2cbb1c4b 18439@@ -0,0 +1,203 @@
4a4d8108
AM
18440+config AUFS_FS
18441+ tristate "Aufs (Advanced multi layered unification filesystem) support"
18442+ depends on EXPERIMENTAL
18443+ help
18444+ Aufs is a stackable unification filesystem such as Unionfs,
18445+ which unifies several directories and provides a merged single
18446+ directory.
18447+ In the early days, aufs was entirely re-designed and
18448+ re-implemented Unionfs Version 1.x series. Introducing many
18449+ original ideas, approaches and improvements, it becomes totally
18450+ different from Unionfs while keeping the basic features.
1facf9fc 18451+
4a4d8108
AM
18452+if AUFS_FS
18453+choice
18454+ prompt "Maximum number of branches"
18455+ default AUFS_BRANCH_MAX_127
18456+ help
18457+ Specifies the maximum number of branches (or member directories)
18458+ in a single aufs. The larger value consumes more system
18459+ resources and has a minor impact to performance.
18460+config AUFS_BRANCH_MAX_127
18461+ bool "127"
18462+ help
18463+ Specifies the maximum number of branches (or member directories)
18464+ in a single aufs. The larger value consumes more system
18465+ resources and has a minor impact to performance.
18466+config AUFS_BRANCH_MAX_511
18467+ bool "511"
18468+ help
18469+ Specifies the maximum number of branches (or member directories)
18470+ in a single aufs. The larger value consumes more system
18471+ resources and has a minor impact to performance.
18472+config AUFS_BRANCH_MAX_1023
18473+ bool "1023"
18474+ help
18475+ Specifies the maximum number of branches (or member directories)
18476+ in a single aufs. The larger value consumes more system
18477+ resources and has a minor impact to performance.
18478+config AUFS_BRANCH_MAX_32767
18479+ bool "32767"
18480+ help
18481+ Specifies the maximum number of branches (or member directories)
18482+ in a single aufs. The larger value consumes more system
18483+ resources and has a minor impact to performance.
18484+endchoice
1facf9fc 18485+
e49829fe
JR
18486+config AUFS_SBILIST
18487+ bool
18488+ depends on AUFS_MAGIC_SYSRQ || PROC_FS
18489+ default y
18490+ help
18491+ Automatic configuration for internal use.
18492+ When aufs supports Magic SysRq or /proc, enabled automatically.
18493+
4a4d8108
AM
18494+config AUFS_HNOTIFY
18495+ bool "Detect direct branch access (bypassing aufs)"
18496+ help
18497+ If you want to modify files on branches directly, eg. bypassing aufs,
18498+ and want aufs to detect the changes of them fully, then enable this
18499+ option and use 'udba=notify' mount option.
7f207e10 18500+ Currently there is only one available configuration, "fsnotify".
4a4d8108
AM
18501+ It will have a negative impact to the performance.
18502+ See detail in aufs.5.
dece6358 18503+
4a4d8108
AM
18504+choice
18505+ prompt "method" if AUFS_HNOTIFY
18506+ default AUFS_HFSNOTIFY
18507+config AUFS_HFSNOTIFY
18508+ bool "fsnotify"
18509+ select FSNOTIFY
4a4d8108 18510+endchoice
1facf9fc 18511+
4a4d8108
AM
18512+config AUFS_EXPORT
18513+ bool "NFS-exportable aufs"
2cbb1c4b 18514+ depends on EXPORTFS
4a4d8108
AM
18515+ help
18516+ If you want to export your mounted aufs via NFS, then enable this
18517+ option. There are several requirements for this configuration.
18518+ See detail in aufs.5.
1facf9fc 18519+
4a4d8108
AM
18520+config AUFS_INO_T_64
18521+ bool
18522+ depends on AUFS_EXPORT
18523+ depends on 64BIT && !(ALPHA || S390)
18524+ default y
18525+ help
18526+ Automatic configuration for internal use.
18527+ /* typedef unsigned long/int __kernel_ino_t */
18528+ /* alpha and s390x are int */
1facf9fc 18529+
4a4d8108
AM
18530+config AUFS_RDU
18531+ bool "Readdir in userspace"
18532+ help
18533+ Aufs has two methods to provide a merged view for a directory,
18534+ by a user-space library and by kernel-space natively. The latter
18535+ is always enabled but sometimes large and slow.
18536+ If you enable this option, install the library in aufs2-util
18537+ package, and set some environment variables for your readdir(3),
18538+ then the work will be handled in user-space which generally
18539+ shows better performance in most cases.
18540+ See detail in aufs.5.
1facf9fc 18541+
2cbb1c4b
JR
18542+config AUFS_PROC_MAP
18543+ bool "support for /proc/maps and lsof(1)"
18544+ depends on PROC_FS
18545+ help
18546+ When you issue mmap(2) in aufs, it is actually a direct mmap(2)
18547+ call to the file on the branch fs since the file in aufs is
18548+ purely virtual. And the file path printed in /proc/maps (and
18549+ others) will be the path on the branch fs. In most cases, it
18550+ does no harm. But some utilities like lsof(1) may confuse since
18551+ the utility or user may expect the file path in aufs to be
18552+ printed.
18553+ To address this issue, aufs provides a patch which introduces a
18554+ new member called vm_prfile into struct vm_are_struct. The patch
18555+ is meaningless without enabling this configuration since nobody
18556+ sets the new vm_prfile member.
18557+ If you don't apply the patch, then enabling this configuration
18558+ will cause a compile error.
18559+ This approach is fragile since if someone else make some changes
18560+ around vm_file, then vm_prfile may not work anymore. As a
18561+ workaround such case, aufs provides this configuration. If you
18562+ disable it, then lsof(1) may produce incorrect result but the
18563+ problem will be gone even if the aufs patch is applied (I hope).
18564+
4a4d8108
AM
18565+config AUFS_SP_IATTR
18566+ bool "Respect the attributes (mtime/ctime mainly) of special files"
18567+ help
18568+ When you write something to a special file, some attributes of it
18569+ (mtime/ctime mainly) may be updated. Generally such updates are
18570+ less important (actually some device drivers and NFS ignore
18571+ it). But some applications (such like test program) requires
18572+ such updates. If you need these updates, then enable this
18573+ configuration which introduces some overhead.
18574+ Currently this configuration handles FIFO only.
1facf9fc 18575+
4a4d8108
AM
18576+config AUFS_SHWH
18577+ bool "Show whiteouts"
18578+ help
18579+ If you want to make the whiteouts in aufs visible, then enable
18580+ this option and specify 'shwh' mount option. Although it may
18581+ sounds like philosophy or something, but in technically it
18582+ simply shows the name of whiteout with keeping its behaviour.
1facf9fc 18583+
4a4d8108
AM
18584+config AUFS_BR_RAMFS
18585+ bool "Ramfs (initramfs/rootfs) as an aufs branch"
18586+ help
18587+ If you want to use ramfs as an aufs branch fs, then enable this
18588+ option. Generally tmpfs is recommended.
18589+ Aufs prohibited them to be a branch fs by default, because
18590+ initramfs becomes unusable after switch_root or something
18591+ generally. If you sets initramfs as an aufs branch and boot your
18592+ system by switch_root, you will meet a problem easily since the
18593+ files in initramfs may be inaccessible.
18594+ Unless you are going to use ramfs as an aufs branch fs without
18595+ switch_root or something, leave it N.
1facf9fc 18596+
4a4d8108
AM
18597+config AUFS_BR_FUSE
18598+ bool "Fuse fs as an aufs branch"
18599+ depends on FUSE_FS
18600+ select AUFS_POLL
18601+ help
18602+ If you want to use fuse-based userspace filesystem as an aufs
18603+ branch fs, then enable this option.
18604+ It implements the internal poll(2) operation which is
18605+ implemented by fuse only (curretnly).
1facf9fc 18606+
4a4d8108
AM
18607+config AUFS_POLL
18608+ bool
18609+ help
18610+ Automatic configuration for internal use.
1facf9fc 18611+
4a4d8108
AM
18612+config AUFS_BR_HFSPLUS
18613+ bool "Hfsplus as an aufs branch"
18614+ depends on HFSPLUS_FS
18615+ default y
18616+ help
18617+ If you want to use hfsplus fs as an aufs branch fs, then enable
18618+ this option. This option introduces a small overhead at
18619+ copying-up a file on hfsplus.
1facf9fc 18620+
4a4d8108
AM
18621+config AUFS_BDEV_LOOP
18622+ bool
18623+ depends on BLK_DEV_LOOP
18624+ default y
18625+ help
18626+ Automatic configuration for internal use.
18627+ Convert =[ym] into =y.
1308ab2a 18628+
4a4d8108
AM
18629+config AUFS_DEBUG
18630+ bool "Debug aufs"
18631+ help
18632+ Enable this to compile aufs internal debug code.
18633+ It will have a negative impact to the performance.
18634+
18635+config AUFS_MAGIC_SYSRQ
18636+ bool
18637+ depends on AUFS_DEBUG && MAGIC_SYSRQ
18638+ default y
18639+ help
18640+ Automatic configuration for internal use.
18641+ When aufs supports Magic SysRq, enabled automatically.
18642+endif
7f207e10
AM
18643diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
18644--- /usr/share/empty/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100
a2a7ad62
AM
18645+++ linux/fs/aufs/loop.c 2013-03-14 20:07:18.764260309 +0100
18646@@ -0,0 +1,135 @@
1facf9fc 18647+/*
7a9e40b8 18648+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 18649+ *
18650+ * This program, aufs is free software; you can redistribute it and/or modify
18651+ * it under the terms of the GNU General Public License as published by
18652+ * the Free Software Foundation; either version 2 of the License, or
18653+ * (at your option) any later version.
dece6358
AM
18654+ *
18655+ * This program is distributed in the hope that it will be useful,
18656+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18657+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18658+ * GNU General Public License for more details.
18659+ *
18660+ * You should have received a copy of the GNU General Public License
18661+ * along with this program; if not, write to the Free Software
18662+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 18663+ */
18664+
18665+/*
18666+ * support for loopback block device as a branch
18667+ */
18668+
18669+#include <linux/loop.h>
18670+#include "aufs.h"
18671+
18672+/*
18673+ * test if two lower dentries have overlapping branches.
18674+ */
b752ccd1 18675+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
1facf9fc 18676+{
b752ccd1 18677+ struct super_block *h_sb;
1facf9fc 18678+ struct loop_device *l;
18679+
b752ccd1
AM
18680+ h_sb = h_adding->d_sb;
18681+ if (MAJOR(h_sb->s_dev) != LOOP_MAJOR)
1facf9fc 18682+ return 0;
18683+
b752ccd1
AM
18684+ l = h_sb->s_bdev->bd_disk->private_data;
18685+ h_adding = l->lo_backing_file->f_dentry;
18686+ /*
18687+ * h_adding can be local NFS.
18688+ * in this case aufs cannot detect the loop.
18689+ */
18690+ if (unlikely(h_adding->d_sb == sb))
1facf9fc 18691+ return 1;
b752ccd1 18692+ return !!au_test_subdir(h_adding, sb->s_root);
1facf9fc 18693+}
18694+
18695+/* true if a kernel thread named 'loop[0-9].*' accesses a file */
18696+int au_test_loopback_kthread(void)
18697+{
b752ccd1
AM
18698+ int ret;
18699+ struct task_struct *tsk = current;
a2a7ad62 18700+ char c, comm[sizeof(tsk->comm)];
b752ccd1
AM
18701+
18702+ ret = 0;
18703+ if (tsk->flags & PF_KTHREAD) {
a2a7ad62
AM
18704+ get_task_comm(comm, tsk);
18705+ c = comm[4];
b752ccd1 18706+ ret = ('0' <= c && c <= '9'
a2a7ad62 18707+ && !strncmp(comm, "loop", 4));
b752ccd1 18708+ }
1facf9fc 18709+
b752ccd1 18710+ return ret;
1facf9fc 18711+}
87a755f4
AM
18712+
18713+/* ---------------------------------------------------------------------- */
18714+
18715+#define au_warn_loopback_step 16
18716+static int au_warn_loopback_nelem = au_warn_loopback_step;
18717+static unsigned long *au_warn_loopback_array;
18718+
18719+void au_warn_loopback(struct super_block *h_sb)
18720+{
18721+ int i, new_nelem;
18722+ unsigned long *a, magic;
18723+ static DEFINE_SPINLOCK(spin);
18724+
18725+ magic = h_sb->s_magic;
18726+ spin_lock(&spin);
18727+ a = au_warn_loopback_array;
18728+ for (i = 0; i < au_warn_loopback_nelem && *a; i++)
18729+ if (a[i] == magic) {
18730+ spin_unlock(&spin);
18731+ return;
18732+ }
18733+
18734+ /* h_sb is new to us, print it */
18735+ if (i < au_warn_loopback_nelem) {
18736+ a[i] = magic;
18737+ goto pr;
18738+ }
18739+
18740+ /* expand the array */
18741+ new_nelem = au_warn_loopback_nelem + au_warn_loopback_step;
18742+ a = au_kzrealloc(au_warn_loopback_array,
18743+ au_warn_loopback_nelem * sizeof(unsigned long),
18744+ new_nelem * sizeof(unsigned long), GFP_ATOMIC);
18745+ if (a) {
18746+ au_warn_loopback_nelem = new_nelem;
18747+ au_warn_loopback_array = a;
18748+ a[i] = magic;
18749+ goto pr;
18750+ }
18751+
18752+ spin_unlock(&spin);
18753+ AuWarn1("realloc failed, ignored\n");
18754+ return;
18755+
18756+pr:
18757+ spin_unlock(&spin);
0c3ec466
AM
18758+ pr_warn("you may want to try another patch for loopback file "
18759+ "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic);
87a755f4
AM
18760+}
18761+
18762+int au_loopback_init(void)
18763+{
18764+ int err;
18765+ struct super_block *sb __maybe_unused;
18766+
18767+ AuDebugOn(sizeof(sb->s_magic) != sizeof(unsigned long));
18768+
18769+ err = 0;
18770+ au_warn_loopback_array = kcalloc(au_warn_loopback_step,
18771+ sizeof(unsigned long), GFP_NOFS);
18772+ if (unlikely(!au_warn_loopback_array))
18773+ err = -ENOMEM;
18774+
18775+ return err;
18776+}
18777+
18778+void au_loopback_fin(void)
18779+{
18780+ kfree(au_warn_loopback_array);
18781+}
7f207e10
AM
18782diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
18783--- /usr/share/empty/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
1716fcea 18784+++ linux/fs/aufs/loop.h 2013-02-19 08:40:03.950226347 +0100
87a755f4 18785@@ -0,0 +1,50 @@
1facf9fc 18786+/*
7a9e40b8 18787+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 18788+ *
18789+ * This program, aufs is free software; you can redistribute it and/or modify
18790+ * it under the terms of the GNU General Public License as published by
18791+ * the Free Software Foundation; either version 2 of the License, or
18792+ * (at your option) any later version.
dece6358
AM
18793+ *
18794+ * This program is distributed in the hope that it will be useful,
18795+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18796+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18797+ * GNU General Public License for more details.
18798+ *
18799+ * You should have received a copy of the GNU General Public License
18800+ * along with this program; if not, write to the Free Software
18801+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 18802+ */
18803+
18804+/*
18805+ * support for loopback mount as a branch
18806+ */
18807+
18808+#ifndef __AUFS_LOOP_H__
18809+#define __AUFS_LOOP_H__
18810+
18811+#ifdef __KERNEL__
18812+
dece6358
AM
18813+struct dentry;
18814+struct super_block;
1facf9fc 18815+
18816+#ifdef CONFIG_AUFS_BDEV_LOOP
18817+/* loop.c */
b752ccd1 18818+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding);
1facf9fc 18819+int au_test_loopback_kthread(void);
87a755f4
AM
18820+void au_warn_loopback(struct super_block *h_sb);
18821+
18822+int au_loopback_init(void);
18823+void au_loopback_fin(void);
1facf9fc 18824+#else
4a4d8108 18825+AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
b752ccd1 18826+ struct dentry *h_adding)
4a4d8108 18827+AuStubInt0(au_test_loopback_kthread, void)
87a755f4
AM
18828+AuStubVoid(au_warn_loopback, struct super_block *h_sb)
18829+
18830+AuStubInt0(au_loopback_init, void)
18831+AuStubVoid(au_loopback_fin, void)
1facf9fc 18832+#endif /* BLK_DEV_LOOP */
18833+
18834+#endif /* __KERNEL__ */
18835+#endif /* __AUFS_LOOP_H__ */
7f207e10
AM
18836diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
18837--- /usr/share/empty/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100
7a9e40b8 18838+++ linux/fs/aufs/magic.mk 2012-08-26 08:39:00.760508065 +0200
4a4d8108 18839@@ -0,0 +1,54 @@
1facf9fc 18840+
18841+# defined in ${srctree}/fs/fuse/inode.c
18842+# tristate
18843+ifdef CONFIG_FUSE_FS
18844+ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
18845+endif
18846+
18847+# defined in ${srctree}/fs/ocfs2/ocfs2_fs.h
18848+# tristate
18849+ifdef CONFIG_OCFS2_FS
18850+ccflags-y += -DOCFS2_SUPER_MAGIC=0x7461636f
18851+endif
18852+
18853+# defined in ${srctree}/fs/ocfs2/dlm/userdlm.h
18854+# tristate
18855+ifdef CONFIG_OCFS2_FS_O2CB
18856+ccflags-y += -DDLMFS_MAGIC=0x76a9f425
18857+endif
18858+
1facf9fc 18859+# defined in ${srctree}/fs/cifs/cifsfs.c
18860+# tristate
18861+ifdef CONFIG_CIFS_FS
18862+ccflags-y += -DCIFS_MAGIC_NUMBER=0xFF534D42
18863+endif
18864+
18865+# defined in ${srctree}/fs/xfs/xfs_sb.h
18866+# tristate
18867+ifdef CONFIG_XFS_FS
18868+ccflags-y += -DXFS_SB_MAGIC=0x58465342
18869+endif
18870+
18871+# defined in ${srctree}/fs/configfs/mount.c
18872+# tristate
18873+ifdef CONFIG_CONFIGFS_FS
18874+ccflags-y += -DCONFIGFS_MAGIC=0x62656570
18875+endif
18876+
18877+# defined in ${srctree}/fs/9p/v9fs.h
18878+# tristate
18879+ifdef CONFIG_9P_FS
18880+ccflags-y += -DV9FS_MAGIC=0x01021997
18881+endif
18882+
18883+# defined in ${srctree}/fs/ubifs/ubifs.h
18884+# tristate
18885+ifdef CONFIG_UBIFS_FS
18886+ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
18887+endif
4a4d8108
AM
18888+
18889+# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h
18890+# tristate
18891+ifdef CONFIG_HFSPLUS_FS
18892+ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b
18893+endif
7f207e10
AM
18894diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
18895--- /usr/share/empty/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100
7a9e40b8 18896+++ linux/fs/aufs/Makefile 2012-08-26 08:39:00.757174634 +0200
2dfbb274 18897@@ -0,0 +1,42 @@
4a4d8108
AM
18898+
18899+include ${src}/magic.mk
18900+ifeq (${CONFIG_AUFS_FS},m)
18901+include ${src}/conf.mk
18902+endif
18903+-include ${src}/priv_def.mk
18904+
18905+# cf. include/linux/kernel.h
18906+# enable pr_debug
18907+ccflags-y += -DDEBUG
f6c5ef8b
AM
18908+# sparse requires the full pathname
18909+ifdef M
18910+ccflags-y += -include ${M}/../../include/linux/aufs_type.h
18911+else
18912+ccflags-y += -include ${srctree}/include/linux/aufs_type.h
18913+endif
4a4d8108
AM
18914+
18915+obj-$(CONFIG_AUFS_FS) += aufs.o
18916+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
18917+ wkq.o vfsub.o dcsub.o \
e49829fe 18918+ cpup.o whout.o wbr_policy.o \
4a4d8108
AM
18919+ dinfo.o dentry.o \
18920+ dynop.o \
18921+ finfo.o file.o f_op.o \
18922+ dir.o vdir.o \
18923+ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
18924+ ioctl.o
18925+
18926+# all are boolean
e49829fe 18927+aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
4a4d8108
AM
18928+aufs-$(CONFIG_SYSFS) += sysfs.o
18929+aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
18930+aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
18931+aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
18932+aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
4a4d8108
AM
18933+aufs-$(CONFIG_AUFS_EXPORT) += export.o
18934+aufs-$(CONFIG_AUFS_POLL) += poll.o
18935+aufs-$(CONFIG_AUFS_RDU) += rdu.o
18936+aufs-$(CONFIG_AUFS_SP_IATTR) += f_op_sp.o
18937+aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
18938+aufs-$(CONFIG_AUFS_DEBUG) += debug.o
18939+aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
7f207e10
AM
18940diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
18941--- /usr/share/empty/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100
1716fcea 18942+++ linux/fs/aufs/module.c 2013-02-19 08:40:03.950226347 +0100
537831f9 18943@@ -0,0 +1,202 @@
1facf9fc 18944+/*
7a9e40b8 18945+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 18946+ *
18947+ * This program, aufs is free software; you can redistribute it and/or modify
18948+ * it under the terms of the GNU General Public License as published by
18949+ * the Free Software Foundation; either version 2 of the License, or
18950+ * (at your option) any later version.
dece6358
AM
18951+ *
18952+ * This program is distributed in the hope that it will be useful,
18953+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18954+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18955+ * GNU General Public License for more details.
18956+ *
18957+ * You should have received a copy of the GNU General Public License
18958+ * along with this program; if not, write to the Free Software
18959+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 18960+ */
18961+
18962+/*
18963+ * module global variables and operations
18964+ */
18965+
18966+#include <linux/module.h>
18967+#include <linux/seq_file.h>
18968+#include "aufs.h"
18969+
18970+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp)
18971+{
18972+ if (new_sz <= nused)
18973+ return p;
18974+
18975+ p = krealloc(p, new_sz, gfp);
18976+ if (p)
18977+ memset(p + nused, 0, new_sz - nused);
18978+ return p;
18979+}
18980+
18981+/* ---------------------------------------------------------------------- */
18982+
18983+/*
18984+ * aufs caches
18985+ */
18986+struct kmem_cache *au_cachep[AuCache_Last];
18987+static int __init au_cache_init(void)
18988+{
4a4d8108 18989+ au_cachep[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
1facf9fc 18990+ if (au_cachep[AuCache_DINFO])
027c5e7a 18991+ /* SLAB_DESTROY_BY_RCU */
4a4d8108
AM
18992+ au_cachep[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
18993+ au_icntnr_init_once);
1facf9fc 18994+ if (au_cachep[AuCache_ICNTNR])
4a4d8108
AM
18995+ au_cachep[AuCache_FINFO] = AuCacheCtor(au_finfo,
18996+ au_fi_init_once);
1facf9fc 18997+ if (au_cachep[AuCache_FINFO])
18998+ au_cachep[AuCache_VDIR] = AuCache(au_vdir);
18999+ if (au_cachep[AuCache_VDIR])
19000+ au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
19001+ if (au_cachep[AuCache_DEHSTR])
19002+ return 0;
19003+
19004+ return -ENOMEM;
19005+}
19006+
19007+static void au_cache_fin(void)
19008+{
19009+ int i;
4a4d8108 19010+
537831f9
AM
19011+ /*
19012+ * Make sure all delayed rcu free inodes are flushed before we
19013+ * destroy cache.
19014+ */
19015+ rcu_barrier();
19016+
7eafdf33
AM
19017+ /* excluding AuCache_HNOTIFY */
19018+ BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
19019+ for (i = 0; i < AuCache_HNOTIFY; i++)
1facf9fc 19020+ if (au_cachep[i]) {
19021+ kmem_cache_destroy(au_cachep[i]);
19022+ au_cachep[i] = NULL;
19023+ }
19024+}
19025+
19026+/* ---------------------------------------------------------------------- */
19027+
19028+int au_dir_roflags;
19029+
e49829fe 19030+#ifdef CONFIG_AUFS_SBILIST
1e00d052
AM
19031+/*
19032+ * iterate_supers_type() doesn't protect us from
19033+ * remounting (branch management)
19034+ */
e49829fe
JR
19035+struct au_splhead au_sbilist;
19036+#endif
19037+
9dbd164d
AM
19038+struct lock_class_key au_lc_key[AuLcKey_Last];
19039+
1facf9fc 19040+/*
19041+ * functions for module interface.
19042+ */
19043+MODULE_LICENSE("GPL");
19044+/* MODULE_LICENSE("GPL v2"); */
dece6358 19045+MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
1facf9fc 19046+MODULE_DESCRIPTION(AUFS_NAME
19047+ " -- Advanced multi layered unification filesystem");
19048+MODULE_VERSION(AUFS_VERSION);
19049+
1facf9fc 19050+/* this module parameter has no meaning when SYSFS is disabled */
19051+int sysaufs_brs = 1;
19052+MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
19053+module_param_named(brs, sysaufs_brs, int, S_IRUGO);
19054+
19055+/* ---------------------------------------------------------------------- */
19056+
19057+static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
19058+
19059+int au_seq_path(struct seq_file *seq, struct path *path)
19060+{
19061+ return seq_path(seq, path, au_esc_chars);
19062+}
19063+
19064+/* ---------------------------------------------------------------------- */
19065+
19066+static int __init aufs_init(void)
19067+{
19068+ int err, i;
19069+ char *p;
19070+
19071+ p = au_esc_chars;
19072+ for (i = 1; i <= ' '; i++)
19073+ *p++ = i;
19074+ *p++ = '\\';
19075+ *p++ = '\x7f';
19076+ *p = 0;
19077+
19078+ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
19079+
e49829fe 19080+ au_sbilist_init();
1facf9fc 19081+ sysaufs_brs_init();
19082+ au_debug_init();
4a4d8108 19083+ au_dy_init();
1facf9fc 19084+ err = sysaufs_init();
19085+ if (unlikely(err))
19086+ goto out;
e49829fe 19087+ err = au_procfs_init();
4f0767ce 19088+ if (unlikely(err))
953406b4 19089+ goto out_sysaufs;
e49829fe
JR
19090+ err = au_wkq_init();
19091+ if (unlikely(err))
19092+ goto out_procfs;
87a755f4 19093+ err = au_loopback_init();
1facf9fc 19094+ if (unlikely(err))
19095+ goto out_wkq;
87a755f4
AM
19096+ err = au_hnotify_init();
19097+ if (unlikely(err))
19098+ goto out_loopback;
1facf9fc 19099+ err = au_sysrq_init();
19100+ if (unlikely(err))
19101+ goto out_hin;
19102+ err = au_cache_init();
19103+ if (unlikely(err))
19104+ goto out_sysrq;
19105+ err = register_filesystem(&aufs_fs_type);
19106+ if (unlikely(err))
19107+ goto out_cache;
4a4d8108
AM
19108+ /* since we define pr_fmt, call printk directly */
19109+ printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
1facf9fc 19110+ goto out; /* success */
19111+
4f0767ce 19112+out_cache:
1facf9fc 19113+ au_cache_fin();
4f0767ce 19114+out_sysrq:
1facf9fc 19115+ au_sysrq_fin();
4f0767ce 19116+out_hin:
4a4d8108 19117+ au_hnotify_fin();
87a755f4
AM
19118+out_loopback:
19119+ au_loopback_fin();
4f0767ce 19120+out_wkq:
1facf9fc 19121+ au_wkq_fin();
e49829fe
JR
19122+out_procfs:
19123+ au_procfs_fin();
4f0767ce 19124+out_sysaufs:
1facf9fc 19125+ sysaufs_fin();
4a4d8108 19126+ au_dy_fin();
4f0767ce 19127+out:
1facf9fc 19128+ return err;
19129+}
19130+
19131+static void __exit aufs_exit(void)
19132+{
19133+ unregister_filesystem(&aufs_fs_type);
19134+ au_cache_fin();
19135+ au_sysrq_fin();
4a4d8108 19136+ au_hnotify_fin();
87a755f4 19137+ au_loopback_fin();
1facf9fc 19138+ au_wkq_fin();
e49829fe 19139+ au_procfs_fin();
1facf9fc 19140+ sysaufs_fin();
4a4d8108 19141+ au_dy_fin();
1facf9fc 19142+}
19143+
19144+module_init(aufs_init);
19145+module_exit(aufs_exit);
7f207e10
AM
19146diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
19147--- /usr/share/empty/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100
1716fcea 19148+++ linux/fs/aufs/module.h 2013-02-19 08:40:03.950226347 +0100
7eafdf33 19149@@ -0,0 +1,105 @@
1facf9fc 19150+/*
7a9e40b8 19151+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 19152+ *
19153+ * This program, aufs is free software; you can redistribute it and/or modify
19154+ * it under the terms of the GNU General Public License as published by
19155+ * the Free Software Foundation; either version 2 of the License, or
19156+ * (at your option) any later version.
dece6358
AM
19157+ *
19158+ * This program is distributed in the hope that it will be useful,
19159+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19160+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19161+ * GNU General Public License for more details.
19162+ *
19163+ * You should have received a copy of the GNU General Public License
19164+ * along with this program; if not, write to the Free Software
19165+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 19166+ */
19167+
19168+/*
19169+ * module initialization and module-global
19170+ */
19171+
19172+#ifndef __AUFS_MODULE_H__
19173+#define __AUFS_MODULE_H__
19174+
19175+#ifdef __KERNEL__
19176+
19177+#include <linux/slab.h>
19178+
dece6358
AM
19179+struct path;
19180+struct seq_file;
19181+
1facf9fc 19182+/* module parameters */
1facf9fc 19183+extern int sysaufs_brs;
19184+
19185+/* ---------------------------------------------------------------------- */
19186+
19187+extern int au_dir_roflags;
19188+
9dbd164d
AM
19189+enum {
19190+ AuLcNonDir_FIINFO,
19191+ AuLcNonDir_DIINFO,
19192+ AuLcNonDir_IIINFO,
19193+
19194+ AuLcDir_FIINFO,
19195+ AuLcDir_DIINFO,
19196+ AuLcDir_IIINFO,
19197+
19198+ AuLcSymlink_DIINFO,
19199+ AuLcSymlink_IIINFO,
19200+
19201+ AuLcKey_Last
19202+};
19203+extern struct lock_class_key au_lc_key[AuLcKey_Last];
19204+
1facf9fc 19205+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp);
19206+int au_seq_path(struct seq_file *seq, struct path *path);
19207+
e49829fe
JR
19208+#ifdef CONFIG_PROC_FS
19209+/* procfs.c */
19210+int __init au_procfs_init(void);
19211+void au_procfs_fin(void);
19212+#else
19213+AuStubInt0(au_procfs_init, void);
19214+AuStubVoid(au_procfs_fin, void);
19215+#endif
19216+
4f0767ce
JR
19217+/* ---------------------------------------------------------------------- */
19218+
19219+/* kmem cache */
1facf9fc 19220+enum {
19221+ AuCache_DINFO,
19222+ AuCache_ICNTNR,
19223+ AuCache_FINFO,
19224+ AuCache_VDIR,
19225+ AuCache_DEHSTR,
7eafdf33 19226+ AuCache_HNOTIFY, /* must be last */
1facf9fc 19227+ AuCache_Last
19228+};
19229+
4a4d8108
AM
19230+#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
19231+#define AuCache(type) KMEM_CACHE(type, AuCacheFlags)
19232+#define AuCacheCtor(type, ctor) \
19233+ kmem_cache_create(#type, sizeof(struct type), \
19234+ __alignof__(struct type), AuCacheFlags, ctor)
1facf9fc 19235+
19236+extern struct kmem_cache *au_cachep[];
19237+
19238+#define AuCacheFuncs(name, index) \
4a4d8108 19239+static inline struct au_##name *au_cache_alloc_##name(void) \
1facf9fc 19240+{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \
4a4d8108 19241+static inline void au_cache_free_##name(struct au_##name *p) \
1facf9fc 19242+{ kmem_cache_free(au_cachep[AuCache_##index], p); }
19243+
19244+AuCacheFuncs(dinfo, DINFO);
19245+AuCacheFuncs(icntnr, ICNTNR);
19246+AuCacheFuncs(finfo, FINFO);
19247+AuCacheFuncs(vdir, VDIR);
4a4d8108
AM
19248+AuCacheFuncs(vdir_dehstr, DEHSTR);
19249+#ifdef CONFIG_AUFS_HNOTIFY
19250+AuCacheFuncs(hnotify, HNOTIFY);
19251+#endif
1facf9fc 19252+
4a4d8108
AM
19253+#endif /* __KERNEL__ */
19254+#endif /* __AUFS_MODULE_H__ */
7f207e10
AM
19255diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
19256--- /usr/share/empty/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100
1716fcea 19257+++ linux/fs/aufs/opts.c 2013-02-19 08:40:03.950226347 +0100
f6c5ef8b 19258@@ -0,0 +1,1677 @@
1facf9fc 19259+/*
7a9e40b8 19260+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 19261+ *
19262+ * This program, aufs is free software; you can redistribute it and/or modify
19263+ * it under the terms of the GNU General Public License as published by
19264+ * the Free Software Foundation; either version 2 of the License, or
19265+ * (at your option) any later version.
dece6358
AM
19266+ *
19267+ * This program is distributed in the hope that it will be useful,
19268+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19269+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19270+ * GNU General Public License for more details.
19271+ *
19272+ * You should have received a copy of the GNU General Public License
19273+ * along with this program; if not, write to the Free Software
19274+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 19275+ */
19276+
19277+/*
19278+ * mount options/flags
19279+ */
19280+
dece6358 19281+#include <linux/namei.h>
1facf9fc 19282+#include <linux/types.h> /* a distribution requires */
19283+#include <linux/parser.h>
19284+#include "aufs.h"
19285+
19286+/* ---------------------------------------------------------------------- */
19287+
19288+enum {
19289+ Opt_br,
19290+ Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend,
19291+ Opt_idel, Opt_imod, Opt_ireorder,
19292+ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, Opt_rendir,
dece6358 19293+ Opt_rdblk_def, Opt_rdhash_def,
1facf9fc 19294+ Opt_xino, Opt_zxino, Opt_noxino,
19295+ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
19296+ Opt_trunc_xino_path, Opt_itrunc_xino,
19297+ Opt_trunc_xib, Opt_notrunc_xib,
dece6358 19298+ Opt_shwh, Opt_noshwh,
1facf9fc 19299+ Opt_plink, Opt_noplink, Opt_list_plink,
19300+ Opt_udba,
4a4d8108 19301+ Opt_dio, Opt_nodio,
1facf9fc 19302+ /* Opt_lock, Opt_unlock, */
19303+ Opt_cmd, Opt_cmd_args,
19304+ Opt_diropq_a, Opt_diropq_w,
19305+ Opt_warn_perm, Opt_nowarn_perm,
19306+ Opt_wbr_copyup, Opt_wbr_create,
19307+ Opt_refrof, Opt_norefrof,
19308+ Opt_verbose, Opt_noverbose,
19309+ Opt_sum, Opt_nosum, Opt_wsum,
19310+ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
19311+};
19312+
19313+static match_table_t options = {
19314+ {Opt_br, "br=%s"},
19315+ {Opt_br, "br:%s"},
19316+
19317+ {Opt_add, "add=%d:%s"},
19318+ {Opt_add, "add:%d:%s"},
19319+ {Opt_add, "ins=%d:%s"},
19320+ {Opt_add, "ins:%d:%s"},
19321+ {Opt_append, "append=%s"},
19322+ {Opt_append, "append:%s"},
19323+ {Opt_prepend, "prepend=%s"},
19324+ {Opt_prepend, "prepend:%s"},
19325+
19326+ {Opt_del, "del=%s"},
19327+ {Opt_del, "del:%s"},
19328+ /* {Opt_idel, "idel:%d"}, */
19329+ {Opt_mod, "mod=%s"},
19330+ {Opt_mod, "mod:%s"},
19331+ /* {Opt_imod, "imod:%d:%s"}, */
19332+
19333+ {Opt_dirwh, "dirwh=%d"},
19334+
19335+ {Opt_xino, "xino=%s"},
19336+ {Opt_noxino, "noxino"},
19337+ {Opt_trunc_xino, "trunc_xino"},
19338+ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
19339+ {Opt_notrunc_xino, "notrunc_xino"},
19340+ {Opt_trunc_xino_path, "trunc_xino=%s"},
19341+ {Opt_itrunc_xino, "itrunc_xino=%d"},
19342+ /* {Opt_zxino, "zxino=%s"}, */
19343+ {Opt_trunc_xib, "trunc_xib"},
19344+ {Opt_notrunc_xib, "notrunc_xib"},
19345+
e49829fe 19346+#ifdef CONFIG_PROC_FS
1facf9fc 19347+ {Opt_plink, "plink"},
e49829fe
JR
19348+#else
19349+ {Opt_ignore_silent, "plink"},
19350+#endif
19351+
1facf9fc 19352+ {Opt_noplink, "noplink"},
e49829fe 19353+
1facf9fc 19354+#ifdef CONFIG_AUFS_DEBUG
19355+ {Opt_list_plink, "list_plink"},
19356+#endif
19357+
19358+ {Opt_udba, "udba=%s"},
19359+
4a4d8108
AM
19360+ {Opt_dio, "dio"},
19361+ {Opt_nodio, "nodio"},
19362+
1facf9fc 19363+ {Opt_diropq_a, "diropq=always"},
19364+ {Opt_diropq_a, "diropq=a"},
19365+ {Opt_diropq_w, "diropq=whiteouted"},
19366+ {Opt_diropq_w, "diropq=w"},
19367+
19368+ {Opt_warn_perm, "warn_perm"},
19369+ {Opt_nowarn_perm, "nowarn_perm"},
19370+
19371+ /* keep them temporary */
19372+ {Opt_ignore_silent, "coo=%s"},
19373+ {Opt_ignore_silent, "nodlgt"},
19374+ {Opt_ignore_silent, "nodirperm1"},
1facf9fc 19375+ {Opt_ignore_silent, "clean_plink"},
19376+
dece6358
AM
19377+#ifdef CONFIG_AUFS_SHWH
19378+ {Opt_shwh, "shwh"},
19379+#endif
19380+ {Opt_noshwh, "noshwh"},
19381+
1facf9fc 19382+ {Opt_rendir, "rendir=%d"},
19383+
19384+ {Opt_refrof, "refrof"},
19385+ {Opt_norefrof, "norefrof"},
19386+
19387+ {Opt_verbose, "verbose"},
19388+ {Opt_verbose, "v"},
19389+ {Opt_noverbose, "noverbose"},
19390+ {Opt_noverbose, "quiet"},
19391+ {Opt_noverbose, "q"},
19392+ {Opt_noverbose, "silent"},
19393+
19394+ {Opt_sum, "sum"},
19395+ {Opt_nosum, "nosum"},
19396+ {Opt_wsum, "wsum"},
19397+
19398+ {Opt_rdcache, "rdcache=%d"},
19399+ {Opt_rdblk, "rdblk=%d"},
dece6358 19400+ {Opt_rdblk_def, "rdblk=def"},
1facf9fc 19401+ {Opt_rdhash, "rdhash=%d"},
dece6358 19402+ {Opt_rdhash_def, "rdhash=def"},
1facf9fc 19403+
19404+ {Opt_wbr_create, "create=%s"},
19405+ {Opt_wbr_create, "create_policy=%s"},
19406+ {Opt_wbr_copyup, "cpup=%s"},
19407+ {Opt_wbr_copyup, "copyup=%s"},
19408+ {Opt_wbr_copyup, "copyup_policy=%s"},
19409+
19410+ /* internal use for the scripts */
19411+ {Opt_ignore_silent, "si=%s"},
19412+
19413+ {Opt_br, "dirs=%s"},
19414+ {Opt_ignore, "debug=%d"},
19415+ {Opt_ignore, "delete=whiteout"},
19416+ {Opt_ignore, "delete=all"},
19417+ {Opt_ignore, "imap=%s"},
19418+
1308ab2a 19419+ /* temporary workaround, due to old mount(8)? */
19420+ {Opt_ignore_silent, "relatime"},
19421+
1facf9fc 19422+ {Opt_err, NULL}
19423+};
19424+
19425+/* ---------------------------------------------------------------------- */
19426+
19427+static const char *au_parser_pattern(int val, struct match_token *token)
19428+{
19429+ while (token->pattern) {
19430+ if (token->token == val)
19431+ return token->pattern;
19432+ token++;
19433+ }
19434+ BUG();
19435+ return "??";
19436+}
19437+
19438+/* ---------------------------------------------------------------------- */
19439+
1e00d052 19440+static match_table_t brperm = {
1facf9fc 19441+ {AuBrPerm_RO, AUFS_BRPERM_RO},
19442+ {AuBrPerm_RR, AUFS_BRPERM_RR},
19443+ {AuBrPerm_RW, AUFS_BRPERM_RW},
1e00d052
AM
19444+ {0, NULL}
19445+};
1facf9fc 19446+
1e00d052
AM
19447+static match_table_t brrattr = {
19448+ {AuBrRAttr_WH, AUFS_BRRATTR_WH},
19449+ {0, NULL}
19450+};
1facf9fc 19451+
1e00d052
AM
19452+static match_table_t brwattr = {
19453+ {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
19454+ {0, NULL}
1facf9fc 19455+};
19456+
1e00d052
AM
19457+#define AuBrStr_LONGEST AUFS_BRPERM_RW "+" AUFS_BRWATTR_NLWH
19458+
19459+static int br_attr_val(char *str, match_table_t table, substring_t args[])
19460+{
19461+ int attr, v;
19462+ char *p;
19463+
19464+ attr = 0;
19465+ do {
19466+ p = strchr(str, '+');
19467+ if (p)
19468+ *p = 0;
19469+ v = match_token(str, table, args);
19470+ if (v)
19471+ attr |= v;
19472+ else {
19473+ if (p)
19474+ *p = '+';
0c3ec466 19475+ pr_warn("ignored branch attribute %s\n", str);
1e00d052
AM
19476+ break;
19477+ }
19478+ if (p)
19479+ str = p + 1;
19480+ } while (p);
19481+
19482+ return attr;
19483+}
19484+
4a4d8108 19485+static int noinline_for_stack br_perm_val(char *perm)
1facf9fc 19486+{
19487+ int val;
1e00d052 19488+ char *p;
1facf9fc 19489+ substring_t args[MAX_OPT_ARGS];
19490+
1e00d052
AM
19491+ p = strchr(perm, '+');
19492+ if (p)
19493+ *p = 0;
19494+ val = match_token(perm, brperm, args);
19495+ if (!val) {
19496+ if (p)
19497+ *p = '+';
0c3ec466 19498+ pr_warn("ignored branch permission %s\n", perm);
1e00d052
AM
19499+ val = AuBrPerm_RO;
19500+ goto out;
19501+ }
19502+ if (!p)
19503+ goto out;
19504+
19505+ switch (val) {
19506+ case AuBrPerm_RO:
19507+ case AuBrPerm_RR:
19508+ val |= br_attr_val(p + 1, brrattr, args);
19509+ break;
19510+ case AuBrPerm_RW:
19511+ val |= br_attr_val(p + 1, brwattr, args);
19512+ break;
19513+ }
19514+
19515+out:
1facf9fc 19516+ return val;
19517+}
19518+
1e00d052
AM
19519+/* Caller should free the return value */
19520+char *au_optstr_br_perm(int brperm)
1facf9fc 19521+{
1e00d052
AM
19522+ char *p, a[sizeof(AuBrStr_LONGEST)];
19523+ int sz;
19524+
19525+#define SetPerm(str) do { \
19526+ sz = sizeof(str); \
19527+ memcpy(a, str, sz); \
19528+ p = a + sz - 1; \
19529+ } while (0)
19530+
19531+#define AppendAttr(flag, str) do { \
19532+ if (brperm & flag) { \
19533+ sz = sizeof(str); \
19534+ *p++ = '+'; \
19535+ memcpy(p, str, sz); \
19536+ p += sz - 1; \
19537+ } \
19538+ } while (0)
19539+
19540+ switch (brperm & AuBrPerm_Mask) {
19541+ case AuBrPerm_RO:
19542+ SetPerm(AUFS_BRPERM_RO);
19543+ break;
19544+ case AuBrPerm_RR:
19545+ SetPerm(AUFS_BRPERM_RR);
19546+ break;
19547+ case AuBrPerm_RW:
19548+ SetPerm(AUFS_BRPERM_RW);
19549+ break;
19550+ default:
19551+ AuDebugOn(1);
19552+ }
19553+
19554+ AppendAttr(AuBrRAttr_WH, AUFS_BRRATTR_WH);
19555+ AppendAttr(AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH);
19556+
19557+ AuDebugOn(strlen(a) >= sizeof(a));
19558+ return kstrdup(a, GFP_NOFS);
19559+#undef SetPerm
19560+#undef AppendAttr
1facf9fc 19561+}
19562+
19563+/* ---------------------------------------------------------------------- */
19564+
19565+static match_table_t udbalevel = {
19566+ {AuOpt_UDBA_REVAL, "reval"},
19567+ {AuOpt_UDBA_NONE, "none"},
4a4d8108
AM
19568+#ifdef CONFIG_AUFS_HNOTIFY
19569+ {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
19570+#ifdef CONFIG_AUFS_HFSNOTIFY
19571+ {AuOpt_UDBA_HNOTIFY, "fsnotify"},
4a4d8108 19572+#endif
1facf9fc 19573+#endif
19574+ {-1, NULL}
19575+};
19576+
4a4d8108 19577+static int noinline_for_stack udba_val(char *str)
1facf9fc 19578+{
19579+ substring_t args[MAX_OPT_ARGS];
19580+
7f207e10 19581+ return match_token(str, udbalevel, args);
1facf9fc 19582+}
19583+
19584+const char *au_optstr_udba(int udba)
19585+{
19586+ return au_parser_pattern(udba, (void *)udbalevel);
19587+}
19588+
19589+/* ---------------------------------------------------------------------- */
19590+
19591+static match_table_t au_wbr_create_policy = {
19592+ {AuWbrCreate_TDP, "tdp"},
19593+ {AuWbrCreate_TDP, "top-down-parent"},
19594+ {AuWbrCreate_RR, "rr"},
19595+ {AuWbrCreate_RR, "round-robin"},
19596+ {AuWbrCreate_MFS, "mfs"},
19597+ {AuWbrCreate_MFS, "most-free-space"},
19598+ {AuWbrCreate_MFSV, "mfs:%d"},
19599+ {AuWbrCreate_MFSV, "most-free-space:%d"},
19600+
19601+ {AuWbrCreate_MFSRR, "mfsrr:%d"},
19602+ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
19603+ {AuWbrCreate_PMFS, "pmfs"},
19604+ {AuWbrCreate_PMFSV, "pmfs:%d"},
19605+
19606+ {-1, NULL}
19607+};
19608+
dece6358
AM
19609+/*
19610+ * cf. linux/lib/parser.c and cmdline.c
19611+ * gave up calling memparse() since it uses simple_strtoull() instead of
9dbd164d 19612+ * kstrto...().
dece6358 19613+ */
4a4d8108
AM
19614+static int noinline_for_stack
19615+au_match_ull(substring_t *s, unsigned long long *result)
1facf9fc 19616+{
19617+ int err;
19618+ unsigned int len;
19619+ char a[32];
19620+
19621+ err = -ERANGE;
19622+ len = s->to - s->from;
19623+ if (len + 1 <= sizeof(a)) {
19624+ memcpy(a, s->from, len);
19625+ a[len] = '\0';
9dbd164d 19626+ err = kstrtoull(a, 0, result);
1facf9fc 19627+ }
19628+ return err;
19629+}
19630+
19631+static int au_wbr_mfs_wmark(substring_t *arg, char *str,
19632+ struct au_opt_wbr_create *create)
19633+{
19634+ int err;
19635+ unsigned long long ull;
19636+
19637+ err = 0;
19638+ if (!au_match_ull(arg, &ull))
19639+ create->mfsrr_watermark = ull;
19640+ else {
4a4d8108 19641+ pr_err("bad integer in %s\n", str);
1facf9fc 19642+ err = -EINVAL;
19643+ }
19644+
19645+ return err;
19646+}
19647+
19648+static int au_wbr_mfs_sec(substring_t *arg, char *str,
19649+ struct au_opt_wbr_create *create)
19650+{
19651+ int n, err;
19652+
19653+ err = 0;
027c5e7a 19654+ if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
1facf9fc 19655+ create->mfs_second = n;
19656+ else {
4a4d8108 19657+ pr_err("bad integer in %s\n", str);
1facf9fc 19658+ err = -EINVAL;
19659+ }
19660+
19661+ return err;
19662+}
19663+
4a4d8108
AM
19664+static int noinline_for_stack
19665+au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
1facf9fc 19666+{
19667+ int err, e;
19668+ substring_t args[MAX_OPT_ARGS];
19669+
19670+ err = match_token(str, au_wbr_create_policy, args);
19671+ create->wbr_create = err;
19672+ switch (err) {
19673+ case AuWbrCreate_MFSRRV:
19674+ e = au_wbr_mfs_wmark(&args[0], str, create);
19675+ if (!e)
19676+ e = au_wbr_mfs_sec(&args[1], str, create);
19677+ if (unlikely(e))
19678+ err = e;
19679+ break;
19680+ case AuWbrCreate_MFSRR:
19681+ e = au_wbr_mfs_wmark(&args[0], str, create);
19682+ if (unlikely(e)) {
19683+ err = e;
19684+ break;
19685+ }
19686+ /*FALLTHROUGH*/
19687+ case AuWbrCreate_MFS:
19688+ case AuWbrCreate_PMFS:
027c5e7a 19689+ create->mfs_second = AUFS_MFS_DEF_SEC;
1facf9fc 19690+ break;
19691+ case AuWbrCreate_MFSV:
19692+ case AuWbrCreate_PMFSV:
19693+ e = au_wbr_mfs_sec(&args[0], str, create);
19694+ if (unlikely(e))
19695+ err = e;
19696+ break;
19697+ }
19698+
19699+ return err;
19700+}
19701+
19702+const char *au_optstr_wbr_create(int wbr_create)
19703+{
19704+ return au_parser_pattern(wbr_create, (void *)au_wbr_create_policy);
19705+}
19706+
19707+static match_table_t au_wbr_copyup_policy = {
19708+ {AuWbrCopyup_TDP, "tdp"},
19709+ {AuWbrCopyup_TDP, "top-down-parent"},
19710+ {AuWbrCopyup_BUP, "bup"},
19711+ {AuWbrCopyup_BUP, "bottom-up-parent"},
19712+ {AuWbrCopyup_BU, "bu"},
19713+ {AuWbrCopyup_BU, "bottom-up"},
19714+ {-1, NULL}
19715+};
19716+
4a4d8108 19717+static int noinline_for_stack au_wbr_copyup_val(char *str)
1facf9fc 19718+{
19719+ substring_t args[MAX_OPT_ARGS];
19720+
19721+ return match_token(str, au_wbr_copyup_policy, args);
19722+}
19723+
19724+const char *au_optstr_wbr_copyup(int wbr_copyup)
19725+{
19726+ return au_parser_pattern(wbr_copyup, (void *)au_wbr_copyup_policy);
19727+}
19728+
19729+/* ---------------------------------------------------------------------- */
19730+
19731+static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
19732+
19733+static void dump_opts(struct au_opts *opts)
19734+{
19735+#ifdef CONFIG_AUFS_DEBUG
19736+ /* reduce stack space */
19737+ union {
19738+ struct au_opt_add *add;
19739+ struct au_opt_del *del;
19740+ struct au_opt_mod *mod;
19741+ struct au_opt_xino *xino;
19742+ struct au_opt_xino_itrunc *xino_itrunc;
19743+ struct au_opt_wbr_create *create;
19744+ } u;
19745+ struct au_opt *opt;
19746+
19747+ opt = opts->opt;
19748+ while (opt->type != Opt_tail) {
19749+ switch (opt->type) {
19750+ case Opt_add:
19751+ u.add = &opt->add;
19752+ AuDbg("add {b%d, %s, 0x%x, %p}\n",
19753+ u.add->bindex, u.add->pathname, u.add->perm,
19754+ u.add->path.dentry);
19755+ break;
19756+ case Opt_del:
19757+ case Opt_idel:
19758+ u.del = &opt->del;
19759+ AuDbg("del {%s, %p}\n",
19760+ u.del->pathname, u.del->h_path.dentry);
19761+ break;
19762+ case Opt_mod:
19763+ case Opt_imod:
19764+ u.mod = &opt->mod;
19765+ AuDbg("mod {%s, 0x%x, %p}\n",
19766+ u.mod->path, u.mod->perm, u.mod->h_root);
19767+ break;
19768+ case Opt_append:
19769+ u.add = &opt->add;
19770+ AuDbg("append {b%d, %s, 0x%x, %p}\n",
19771+ u.add->bindex, u.add->pathname, u.add->perm,
19772+ u.add->path.dentry);
19773+ break;
19774+ case Opt_prepend:
19775+ u.add = &opt->add;
19776+ AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
19777+ u.add->bindex, u.add->pathname, u.add->perm,
19778+ u.add->path.dentry);
19779+ break;
19780+ case Opt_dirwh:
19781+ AuDbg("dirwh %d\n", opt->dirwh);
19782+ break;
19783+ case Opt_rdcache:
19784+ AuDbg("rdcache %d\n", opt->rdcache);
19785+ break;
19786+ case Opt_rdblk:
19787+ AuDbg("rdblk %u\n", opt->rdblk);
19788+ break;
dece6358
AM
19789+ case Opt_rdblk_def:
19790+ AuDbg("rdblk_def\n");
19791+ break;
1facf9fc 19792+ case Opt_rdhash:
19793+ AuDbg("rdhash %u\n", opt->rdhash);
19794+ break;
dece6358
AM
19795+ case Opt_rdhash_def:
19796+ AuDbg("rdhash_def\n");
19797+ break;
1facf9fc 19798+ case Opt_xino:
19799+ u.xino = &opt->xino;
19800+ AuDbg("xino {%s %.*s}\n",
19801+ u.xino->path,
19802+ AuDLNPair(u.xino->file->f_dentry));
19803+ break;
19804+ case Opt_trunc_xino:
19805+ AuLabel(trunc_xino);
19806+ break;
19807+ case Opt_notrunc_xino:
19808+ AuLabel(notrunc_xino);
19809+ break;
19810+ case Opt_trunc_xino_path:
19811+ case Opt_itrunc_xino:
19812+ u.xino_itrunc = &opt->xino_itrunc;
19813+ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
19814+ break;
19815+
19816+ case Opt_noxino:
19817+ AuLabel(noxino);
19818+ break;
19819+ case Opt_trunc_xib:
19820+ AuLabel(trunc_xib);
19821+ break;
19822+ case Opt_notrunc_xib:
19823+ AuLabel(notrunc_xib);
19824+ break;
dece6358
AM
19825+ case Opt_shwh:
19826+ AuLabel(shwh);
19827+ break;
19828+ case Opt_noshwh:
19829+ AuLabel(noshwh);
19830+ break;
1facf9fc 19831+ case Opt_plink:
19832+ AuLabel(plink);
19833+ break;
19834+ case Opt_noplink:
19835+ AuLabel(noplink);
19836+ break;
19837+ case Opt_list_plink:
19838+ AuLabel(list_plink);
19839+ break;
19840+ case Opt_udba:
19841+ AuDbg("udba %d, %s\n",
19842+ opt->udba, au_optstr_udba(opt->udba));
19843+ break;
4a4d8108
AM
19844+ case Opt_dio:
19845+ AuLabel(dio);
19846+ break;
19847+ case Opt_nodio:
19848+ AuLabel(nodio);
19849+ break;
1facf9fc 19850+ case Opt_diropq_a:
19851+ AuLabel(diropq_a);
19852+ break;
19853+ case Opt_diropq_w:
19854+ AuLabel(diropq_w);
19855+ break;
19856+ case Opt_warn_perm:
19857+ AuLabel(warn_perm);
19858+ break;
19859+ case Opt_nowarn_perm:
19860+ AuLabel(nowarn_perm);
19861+ break;
19862+ case Opt_refrof:
19863+ AuLabel(refrof);
19864+ break;
19865+ case Opt_norefrof:
19866+ AuLabel(norefrof);
19867+ break;
19868+ case Opt_verbose:
19869+ AuLabel(verbose);
19870+ break;
19871+ case Opt_noverbose:
19872+ AuLabel(noverbose);
19873+ break;
19874+ case Opt_sum:
19875+ AuLabel(sum);
19876+ break;
19877+ case Opt_nosum:
19878+ AuLabel(nosum);
19879+ break;
19880+ case Opt_wsum:
19881+ AuLabel(wsum);
19882+ break;
19883+ case Opt_wbr_create:
19884+ u.create = &opt->wbr_create;
19885+ AuDbg("create %d, %s\n", u.create->wbr_create,
19886+ au_optstr_wbr_create(u.create->wbr_create));
19887+ switch (u.create->wbr_create) {
19888+ case AuWbrCreate_MFSV:
19889+ case AuWbrCreate_PMFSV:
19890+ AuDbg("%d sec\n", u.create->mfs_second);
19891+ break;
19892+ case AuWbrCreate_MFSRR:
19893+ AuDbg("%llu watermark\n",
19894+ u.create->mfsrr_watermark);
19895+ break;
19896+ case AuWbrCreate_MFSRRV:
19897+ AuDbg("%llu watermark, %d sec\n",
19898+ u.create->mfsrr_watermark,
19899+ u.create->mfs_second);
19900+ break;
19901+ }
19902+ break;
19903+ case Opt_wbr_copyup:
19904+ AuDbg("copyup %d, %s\n", opt->wbr_copyup,
19905+ au_optstr_wbr_copyup(opt->wbr_copyup));
19906+ break;
19907+ default:
19908+ BUG();
19909+ }
19910+ opt++;
19911+ }
19912+#endif
19913+}
19914+
19915+void au_opts_free(struct au_opts *opts)
19916+{
19917+ struct au_opt *opt;
19918+
19919+ opt = opts->opt;
19920+ while (opt->type != Opt_tail) {
19921+ switch (opt->type) {
19922+ case Opt_add:
19923+ case Opt_append:
19924+ case Opt_prepend:
19925+ path_put(&opt->add.path);
19926+ break;
19927+ case Opt_del:
19928+ case Opt_idel:
19929+ path_put(&opt->del.h_path);
19930+ break;
19931+ case Opt_mod:
19932+ case Opt_imod:
19933+ dput(opt->mod.h_root);
19934+ break;
19935+ case Opt_xino:
19936+ fput(opt->xino.file);
19937+ break;
19938+ }
19939+ opt++;
19940+ }
19941+}
19942+
19943+static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
19944+ aufs_bindex_t bindex)
19945+{
19946+ int err;
19947+ struct au_opt_add *add = &opt->add;
19948+ char *p;
19949+
19950+ add->bindex = bindex;
1e00d052 19951+ add->perm = AuBrPerm_RO;
1facf9fc 19952+ add->pathname = opt_str;
19953+ p = strchr(opt_str, '=');
19954+ if (p) {
19955+ *p++ = 0;
19956+ if (*p)
19957+ add->perm = br_perm_val(p);
19958+ }
19959+
19960+ err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
19961+ if (!err) {
19962+ if (!p) {
19963+ add->perm = AuBrPerm_RO;
19964+ if (au_test_fs_rr(add->path.dentry->d_sb))
19965+ add->perm = AuBrPerm_RR;
19966+ else if (!bindex && !(sb_flags & MS_RDONLY))
19967+ add->perm = AuBrPerm_RW;
19968+ }
19969+ opt->type = Opt_add;
19970+ goto out;
19971+ }
4a4d8108 19972+ pr_err("lookup failed %s (%d)\n", add->pathname, err);
1facf9fc 19973+ err = -EINVAL;
19974+
4f0767ce 19975+out:
1facf9fc 19976+ return err;
19977+}
19978+
19979+static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
19980+{
19981+ int err;
19982+
19983+ del->pathname = args[0].from;
19984+ AuDbg("del path %s\n", del->pathname);
19985+
19986+ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
19987+ if (unlikely(err))
4a4d8108 19988+ pr_err("lookup failed %s (%d)\n", del->pathname, err);
1facf9fc 19989+
19990+ return err;
19991+}
19992+
19993+#if 0 /* reserved for future use */
19994+static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
19995+ struct au_opt_del *del, substring_t args[])
19996+{
19997+ int err;
19998+ struct dentry *root;
19999+
20000+ err = -EINVAL;
20001+ root = sb->s_root;
20002+ aufs_read_lock(root, AuLock_FLUSH);
20003+ if (bindex < 0 || au_sbend(sb) < bindex) {
4a4d8108 20004+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 20005+ goto out;
20006+ }
20007+
20008+ err = 0;
20009+ del->h_path.dentry = dget(au_h_dptr(root, bindex));
20010+ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
20011+
4f0767ce 20012+out:
1facf9fc 20013+ aufs_read_unlock(root, !AuLock_IR);
20014+ return err;
20015+}
20016+#endif
20017+
4a4d8108
AM
20018+static int noinline_for_stack
20019+au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
1facf9fc 20020+{
20021+ int err;
20022+ struct path path;
20023+ char *p;
20024+
20025+ err = -EINVAL;
20026+ mod->path = args[0].from;
20027+ p = strchr(mod->path, '=');
20028+ if (unlikely(!p)) {
4a4d8108 20029+ pr_err("no permssion %s\n", args[0].from);
1facf9fc 20030+ goto out;
20031+ }
20032+
20033+ *p++ = 0;
20034+ err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
20035+ if (unlikely(err)) {
4a4d8108 20036+ pr_err("lookup failed %s (%d)\n", mod->path, err);
1facf9fc 20037+ goto out;
20038+ }
20039+
20040+ mod->perm = br_perm_val(p);
20041+ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
20042+ mod->h_root = dget(path.dentry);
20043+ path_put(&path);
20044+
4f0767ce 20045+out:
1facf9fc 20046+ return err;
20047+}
20048+
20049+#if 0 /* reserved for future use */
20050+static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
20051+ struct au_opt_mod *mod, substring_t args[])
20052+{
20053+ int err;
20054+ struct dentry *root;
20055+
20056+ err = -EINVAL;
20057+ root = sb->s_root;
20058+ aufs_read_lock(root, AuLock_FLUSH);
20059+ if (bindex < 0 || au_sbend(sb) < bindex) {
4a4d8108 20060+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 20061+ goto out;
20062+ }
20063+
20064+ err = 0;
20065+ mod->perm = br_perm_val(args[1].from);
20066+ AuDbg("mod path %s, perm 0x%x, %s\n",
20067+ mod->path, mod->perm, args[1].from);
20068+ mod->h_root = dget(au_h_dptr(root, bindex));
20069+
4f0767ce 20070+out:
1facf9fc 20071+ aufs_read_unlock(root, !AuLock_IR);
20072+ return err;
20073+}
20074+#endif
20075+
20076+static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
20077+ substring_t args[])
20078+{
20079+ int err;
20080+ struct file *file;
20081+
20082+ file = au_xino_create(sb, args[0].from, /*silent*/0);
20083+ err = PTR_ERR(file);
20084+ if (IS_ERR(file))
20085+ goto out;
20086+
20087+ err = -EINVAL;
20088+ if (unlikely(file->f_dentry->d_sb == sb)) {
20089+ fput(file);
4a4d8108 20090+ pr_err("%s must be outside\n", args[0].from);
1facf9fc 20091+ goto out;
20092+ }
20093+
20094+ err = 0;
20095+ xino->file = file;
20096+ xino->path = args[0].from;
20097+
4f0767ce 20098+out:
1facf9fc 20099+ return err;
20100+}
20101+
4a4d8108
AM
20102+static int noinline_for_stack
20103+au_opts_parse_xino_itrunc_path(struct super_block *sb,
20104+ struct au_opt_xino_itrunc *xino_itrunc,
20105+ substring_t args[])
1facf9fc 20106+{
20107+ int err;
20108+ aufs_bindex_t bend, bindex;
20109+ struct path path;
20110+ struct dentry *root;
20111+
20112+ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
20113+ if (unlikely(err)) {
4a4d8108 20114+ pr_err("lookup failed %s (%d)\n", args[0].from, err);
1facf9fc 20115+ goto out;
20116+ }
20117+
20118+ xino_itrunc->bindex = -1;
20119+ root = sb->s_root;
20120+ aufs_read_lock(root, AuLock_FLUSH);
20121+ bend = au_sbend(sb);
20122+ for (bindex = 0; bindex <= bend; bindex++) {
20123+ if (au_h_dptr(root, bindex) == path.dentry) {
20124+ xino_itrunc->bindex = bindex;
20125+ break;
20126+ }
20127+ }
20128+ aufs_read_unlock(root, !AuLock_IR);
20129+ path_put(&path);
20130+
20131+ if (unlikely(xino_itrunc->bindex < 0)) {
4a4d8108 20132+ pr_err("no such branch %s\n", args[0].from);
1facf9fc 20133+ err = -EINVAL;
20134+ }
20135+
4f0767ce 20136+out:
1facf9fc 20137+ return err;
20138+}
20139+
20140+/* called without aufs lock */
20141+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
20142+{
20143+ int err, n, token;
20144+ aufs_bindex_t bindex;
20145+ unsigned char skipped;
20146+ struct dentry *root;
20147+ struct au_opt *opt, *opt_tail;
20148+ char *opt_str;
20149+ /* reduce the stack space */
20150+ union {
20151+ struct au_opt_xino_itrunc *xino_itrunc;
20152+ struct au_opt_wbr_create *create;
20153+ } u;
20154+ struct {
20155+ substring_t args[MAX_OPT_ARGS];
20156+ } *a;
20157+
20158+ err = -ENOMEM;
20159+ a = kmalloc(sizeof(*a), GFP_NOFS);
20160+ if (unlikely(!a))
20161+ goto out;
20162+
20163+ root = sb->s_root;
20164+ err = 0;
20165+ bindex = 0;
20166+ opt = opts->opt;
20167+ opt_tail = opt + opts->max_opt - 1;
20168+ opt->type = Opt_tail;
20169+ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
20170+ err = -EINVAL;
20171+ skipped = 0;
20172+ token = match_token(opt_str, options, a->args);
20173+ switch (token) {
20174+ case Opt_br:
20175+ err = 0;
20176+ while (!err && (opt_str = strsep(&a->args[0].from, ":"))
20177+ && *opt_str) {
20178+ err = opt_add(opt, opt_str, opts->sb_flags,
20179+ bindex++);
20180+ if (unlikely(!err && ++opt > opt_tail)) {
20181+ err = -E2BIG;
20182+ break;
20183+ }
20184+ opt->type = Opt_tail;
20185+ skipped = 1;
20186+ }
20187+ break;
20188+ case Opt_add:
20189+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 20190+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 20191+ break;
20192+ }
20193+ bindex = n;
20194+ err = opt_add(opt, a->args[1].from, opts->sb_flags,
20195+ bindex);
20196+ if (!err)
20197+ opt->type = token;
20198+ break;
20199+ case Opt_append:
20200+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
20201+ /*dummy bindex*/1);
20202+ if (!err)
20203+ opt->type = token;
20204+ break;
20205+ case Opt_prepend:
20206+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
20207+ /*bindex*/0);
20208+ if (!err)
20209+ opt->type = token;
20210+ break;
20211+ case Opt_del:
20212+ err = au_opts_parse_del(&opt->del, a->args);
20213+ if (!err)
20214+ opt->type = token;
20215+ break;
20216+#if 0 /* reserved for future use */
20217+ case Opt_idel:
20218+ del->pathname = "(indexed)";
20219+ if (unlikely(match_int(&args[0], &n))) {
4a4d8108 20220+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 20221+ break;
20222+ }
20223+ err = au_opts_parse_idel(sb, n, &opt->del, a->args);
20224+ if (!err)
20225+ opt->type = token;
20226+ break;
20227+#endif
20228+ case Opt_mod:
20229+ err = au_opts_parse_mod(&opt->mod, a->args);
20230+ if (!err)
20231+ opt->type = token;
20232+ break;
20233+#ifdef IMOD /* reserved for future use */
20234+ case Opt_imod:
20235+ u.mod->path = "(indexed)";
20236+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 20237+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 20238+ break;
20239+ }
20240+ err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
20241+ if (!err)
20242+ opt->type = token;
20243+ break;
20244+#endif
20245+ case Opt_xino:
20246+ err = au_opts_parse_xino(sb, &opt->xino, a->args);
20247+ if (!err)
20248+ opt->type = token;
20249+ break;
20250+
20251+ case Opt_trunc_xino_path:
20252+ err = au_opts_parse_xino_itrunc_path
20253+ (sb, &opt->xino_itrunc, a->args);
20254+ if (!err)
20255+ opt->type = token;
20256+ break;
20257+
20258+ case Opt_itrunc_xino:
20259+ u.xino_itrunc = &opt->xino_itrunc;
20260+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 20261+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 20262+ break;
20263+ }
20264+ u.xino_itrunc->bindex = n;
20265+ aufs_read_lock(root, AuLock_FLUSH);
20266+ if (n < 0 || au_sbend(sb) < n) {
4a4d8108 20267+ pr_err("out of bounds, %d\n", n);
1facf9fc 20268+ aufs_read_unlock(root, !AuLock_IR);
20269+ break;
20270+ }
20271+ aufs_read_unlock(root, !AuLock_IR);
20272+ err = 0;
20273+ opt->type = token;
20274+ break;
20275+
20276+ case Opt_dirwh:
20277+ if (unlikely(match_int(&a->args[0], &opt->dirwh)))
20278+ break;
20279+ err = 0;
20280+ opt->type = token;
20281+ break;
20282+
20283+ case Opt_rdcache:
027c5e7a
AM
20284+ if (unlikely(match_int(&a->args[0], &n))) {
20285+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 20286+ break;
027c5e7a
AM
20287+ }
20288+ if (unlikely(n > AUFS_RDCACHE_MAX)) {
20289+ pr_err("rdcache must be smaller than %d\n",
20290+ AUFS_RDCACHE_MAX);
20291+ break;
20292+ }
20293+ opt->rdcache = n;
1facf9fc 20294+ err = 0;
20295+ opt->type = token;
20296+ break;
20297+ case Opt_rdblk:
20298+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 20299+ || n < 0
1facf9fc 20300+ || n > KMALLOC_MAX_SIZE)) {
4a4d8108 20301+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 20302+ break;
20303+ }
1308ab2a 20304+ if (unlikely(n && n < NAME_MAX)) {
4a4d8108
AM
20305+ pr_err("rdblk must be larger than %d\n",
20306+ NAME_MAX);
1facf9fc 20307+ break;
20308+ }
20309+ opt->rdblk = n;
20310+ err = 0;
20311+ opt->type = token;
20312+ break;
20313+ case Opt_rdhash:
20314+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 20315+ || n < 0
1facf9fc 20316+ || n * sizeof(struct hlist_head)
20317+ > KMALLOC_MAX_SIZE)) {
4a4d8108 20318+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 20319+ break;
20320+ }
20321+ opt->rdhash = n;
20322+ err = 0;
20323+ opt->type = token;
20324+ break;
20325+
20326+ case Opt_trunc_xino:
20327+ case Opt_notrunc_xino:
20328+ case Opt_noxino:
20329+ case Opt_trunc_xib:
20330+ case Opt_notrunc_xib:
dece6358
AM
20331+ case Opt_shwh:
20332+ case Opt_noshwh:
1facf9fc 20333+ case Opt_plink:
20334+ case Opt_noplink:
20335+ case Opt_list_plink:
4a4d8108
AM
20336+ case Opt_dio:
20337+ case Opt_nodio:
1facf9fc 20338+ case Opt_diropq_a:
20339+ case Opt_diropq_w:
20340+ case Opt_warn_perm:
20341+ case Opt_nowarn_perm:
20342+ case Opt_refrof:
20343+ case Opt_norefrof:
20344+ case Opt_verbose:
20345+ case Opt_noverbose:
20346+ case Opt_sum:
20347+ case Opt_nosum:
20348+ case Opt_wsum:
dece6358
AM
20349+ case Opt_rdblk_def:
20350+ case Opt_rdhash_def:
1facf9fc 20351+ err = 0;
20352+ opt->type = token;
20353+ break;
20354+
20355+ case Opt_udba:
20356+ opt->udba = udba_val(a->args[0].from);
20357+ if (opt->udba >= 0) {
20358+ err = 0;
20359+ opt->type = token;
20360+ } else
4a4d8108 20361+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 20362+ break;
20363+
20364+ case Opt_wbr_create:
20365+ u.create = &opt->wbr_create;
20366+ u.create->wbr_create
20367+ = au_wbr_create_val(a->args[0].from, u.create);
20368+ if (u.create->wbr_create >= 0) {
20369+ err = 0;
20370+ opt->type = token;
20371+ } else
4a4d8108 20372+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 20373+ break;
20374+ case Opt_wbr_copyup:
20375+ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
20376+ if (opt->wbr_copyup >= 0) {
20377+ err = 0;
20378+ opt->type = token;
20379+ } else
4a4d8108 20380+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 20381+ break;
20382+
20383+ case Opt_ignore:
0c3ec466 20384+ pr_warn("ignored %s\n", opt_str);
1facf9fc 20385+ /*FALLTHROUGH*/
20386+ case Opt_ignore_silent:
20387+ skipped = 1;
20388+ err = 0;
20389+ break;
20390+ case Opt_err:
4a4d8108 20391+ pr_err("unknown option %s\n", opt_str);
1facf9fc 20392+ break;
20393+ }
20394+
20395+ if (!err && !skipped) {
20396+ if (unlikely(++opt > opt_tail)) {
20397+ err = -E2BIG;
20398+ opt--;
20399+ opt->type = Opt_tail;
20400+ break;
20401+ }
20402+ opt->type = Opt_tail;
20403+ }
20404+ }
20405+
20406+ kfree(a);
20407+ dump_opts(opts);
20408+ if (unlikely(err))
20409+ au_opts_free(opts);
20410+
4f0767ce 20411+out:
1facf9fc 20412+ return err;
20413+}
20414+
20415+static int au_opt_wbr_create(struct super_block *sb,
20416+ struct au_opt_wbr_create *create)
20417+{
20418+ int err;
20419+ struct au_sbinfo *sbinfo;
20420+
dece6358
AM
20421+ SiMustWriteLock(sb);
20422+
1facf9fc 20423+ err = 1; /* handled */
20424+ sbinfo = au_sbi(sb);
20425+ if (sbinfo->si_wbr_create_ops->fin) {
20426+ err = sbinfo->si_wbr_create_ops->fin(sb);
20427+ if (!err)
20428+ err = 1;
20429+ }
20430+
20431+ sbinfo->si_wbr_create = create->wbr_create;
20432+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
20433+ switch (create->wbr_create) {
20434+ case AuWbrCreate_MFSRRV:
20435+ case AuWbrCreate_MFSRR:
20436+ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
20437+ /*FALLTHROUGH*/
20438+ case AuWbrCreate_MFS:
20439+ case AuWbrCreate_MFSV:
20440+ case AuWbrCreate_PMFS:
20441+ case AuWbrCreate_PMFSV:
e49829fe
JR
20442+ sbinfo->si_wbr_mfs.mfs_expire
20443+ = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
1facf9fc 20444+ break;
20445+ }
20446+
20447+ if (sbinfo->si_wbr_create_ops->init)
20448+ sbinfo->si_wbr_create_ops->init(sb); /* ignore */
20449+
20450+ return err;
20451+}
20452+
20453+/*
20454+ * returns,
20455+ * plus: processed without an error
20456+ * zero: unprocessed
20457+ */
20458+static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
20459+ struct au_opts *opts)
20460+{
20461+ int err;
20462+ struct au_sbinfo *sbinfo;
20463+
dece6358
AM
20464+ SiMustWriteLock(sb);
20465+
1facf9fc 20466+ err = 1; /* handled */
20467+ sbinfo = au_sbi(sb);
20468+ switch (opt->type) {
20469+ case Opt_udba:
20470+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
20471+ sbinfo->si_mntflags |= opt->udba;
20472+ opts->given_udba |= opt->udba;
20473+ break;
20474+
20475+ case Opt_plink:
20476+ au_opt_set(sbinfo->si_mntflags, PLINK);
20477+ break;
20478+ case Opt_noplink:
20479+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
e49829fe 20480+ au_plink_put(sb, /*verbose*/1);
1facf9fc 20481+ au_opt_clr(sbinfo->si_mntflags, PLINK);
20482+ break;
20483+ case Opt_list_plink:
20484+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
20485+ au_plink_list(sb);
20486+ break;
20487+
4a4d8108
AM
20488+ case Opt_dio:
20489+ au_opt_set(sbinfo->si_mntflags, DIO);
20490+ au_fset_opts(opts->flags, REFRESH_DYAOP);
20491+ break;
20492+ case Opt_nodio:
20493+ au_opt_clr(sbinfo->si_mntflags, DIO);
20494+ au_fset_opts(opts->flags, REFRESH_DYAOP);
20495+ break;
20496+
1facf9fc 20497+ case Opt_diropq_a:
20498+ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
20499+ break;
20500+ case Opt_diropq_w:
20501+ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
20502+ break;
20503+
20504+ case Opt_warn_perm:
20505+ au_opt_set(sbinfo->si_mntflags, WARN_PERM);
20506+ break;
20507+ case Opt_nowarn_perm:
20508+ au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
20509+ break;
20510+
20511+ case Opt_refrof:
20512+ au_opt_set(sbinfo->si_mntflags, REFROF);
20513+ break;
20514+ case Opt_norefrof:
20515+ au_opt_clr(sbinfo->si_mntflags, REFROF);
20516+ break;
20517+
20518+ case Opt_verbose:
20519+ au_opt_set(sbinfo->si_mntflags, VERBOSE);
20520+ break;
20521+ case Opt_noverbose:
20522+ au_opt_clr(sbinfo->si_mntflags, VERBOSE);
20523+ break;
20524+
20525+ case Opt_sum:
20526+ au_opt_set(sbinfo->si_mntflags, SUM);
20527+ break;
20528+ case Opt_wsum:
20529+ au_opt_clr(sbinfo->si_mntflags, SUM);
20530+ au_opt_set(sbinfo->si_mntflags, SUM_W);
20531+ case Opt_nosum:
20532+ au_opt_clr(sbinfo->si_mntflags, SUM);
20533+ au_opt_clr(sbinfo->si_mntflags, SUM_W);
20534+ break;
20535+
20536+ case Opt_wbr_create:
20537+ err = au_opt_wbr_create(sb, &opt->wbr_create);
20538+ break;
20539+ case Opt_wbr_copyup:
20540+ sbinfo->si_wbr_copyup = opt->wbr_copyup;
20541+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
20542+ break;
20543+
20544+ case Opt_dirwh:
20545+ sbinfo->si_dirwh = opt->dirwh;
20546+ break;
20547+
20548+ case Opt_rdcache:
e49829fe
JR
20549+ sbinfo->si_rdcache
20550+ = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
1facf9fc 20551+ break;
20552+ case Opt_rdblk:
20553+ sbinfo->si_rdblk = opt->rdblk;
20554+ break;
dece6358
AM
20555+ case Opt_rdblk_def:
20556+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
20557+ break;
1facf9fc 20558+ case Opt_rdhash:
20559+ sbinfo->si_rdhash = opt->rdhash;
20560+ break;
dece6358
AM
20561+ case Opt_rdhash_def:
20562+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
20563+ break;
20564+
20565+ case Opt_shwh:
20566+ au_opt_set(sbinfo->si_mntflags, SHWH);
20567+ break;
20568+ case Opt_noshwh:
20569+ au_opt_clr(sbinfo->si_mntflags, SHWH);
20570+ break;
1facf9fc 20571+
20572+ case Opt_trunc_xino:
20573+ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
20574+ break;
20575+ case Opt_notrunc_xino:
20576+ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
20577+ break;
20578+
20579+ case Opt_trunc_xino_path:
20580+ case Opt_itrunc_xino:
20581+ err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
20582+ if (!err)
20583+ err = 1;
20584+ break;
20585+
20586+ case Opt_trunc_xib:
20587+ au_fset_opts(opts->flags, TRUNC_XIB);
20588+ break;
20589+ case Opt_notrunc_xib:
20590+ au_fclr_opts(opts->flags, TRUNC_XIB);
20591+ break;
20592+
20593+ default:
20594+ err = 0;
20595+ break;
20596+ }
20597+
20598+ return err;
20599+}
20600+
20601+/*
20602+ * returns tri-state.
20603+ * plus: processed without an error
20604+ * zero: unprocessed
20605+ * minus: error
20606+ */
20607+static int au_opt_br(struct super_block *sb, struct au_opt *opt,
20608+ struct au_opts *opts)
20609+{
20610+ int err, do_refresh;
20611+
20612+ err = 0;
20613+ switch (opt->type) {
20614+ case Opt_append:
20615+ opt->add.bindex = au_sbend(sb) + 1;
20616+ if (opt->add.bindex < 0)
20617+ opt->add.bindex = 0;
20618+ goto add;
20619+ case Opt_prepend:
20620+ opt->add.bindex = 0;
20621+ add:
20622+ case Opt_add:
20623+ err = au_br_add(sb, &opt->add,
20624+ au_ftest_opts(opts->flags, REMOUNT));
20625+ if (!err) {
20626+ err = 1;
027c5e7a 20627+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 20628+ }
20629+ break;
20630+
20631+ case Opt_del:
20632+ case Opt_idel:
20633+ err = au_br_del(sb, &opt->del,
20634+ au_ftest_opts(opts->flags, REMOUNT));
20635+ if (!err) {
20636+ err = 1;
20637+ au_fset_opts(opts->flags, TRUNC_XIB);
027c5e7a 20638+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 20639+ }
20640+ break;
20641+
20642+ case Opt_mod:
20643+ case Opt_imod:
20644+ err = au_br_mod(sb, &opt->mod,
20645+ au_ftest_opts(opts->flags, REMOUNT),
20646+ &do_refresh);
20647+ if (!err) {
20648+ err = 1;
027c5e7a
AM
20649+ if (do_refresh)
20650+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 20651+ }
20652+ break;
20653+ }
20654+
20655+ return err;
20656+}
20657+
20658+static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
20659+ struct au_opt_xino **opt_xino,
20660+ struct au_opts *opts)
20661+{
20662+ int err;
20663+ aufs_bindex_t bend, bindex;
20664+ struct dentry *root, *parent, *h_root;
20665+
20666+ err = 0;
20667+ switch (opt->type) {
20668+ case Opt_xino:
20669+ err = au_xino_set(sb, &opt->xino,
20670+ !!au_ftest_opts(opts->flags, REMOUNT));
20671+ if (unlikely(err))
20672+ break;
20673+
20674+ *opt_xino = &opt->xino;
20675+ au_xino_brid_set(sb, -1);
20676+
20677+ /* safe d_parent access */
20678+ parent = opt->xino.file->f_dentry->d_parent;
20679+ root = sb->s_root;
20680+ bend = au_sbend(sb);
20681+ for (bindex = 0; bindex <= bend; bindex++) {
20682+ h_root = au_h_dptr(root, bindex);
20683+ if (h_root == parent) {
20684+ au_xino_brid_set(sb, au_sbr_id(sb, bindex));
20685+ break;
20686+ }
20687+ }
20688+ break;
20689+
20690+ case Opt_noxino:
20691+ au_xino_clr(sb);
20692+ au_xino_brid_set(sb, -1);
20693+ *opt_xino = (void *)-1;
20694+ break;
20695+ }
20696+
20697+ return err;
20698+}
20699+
20700+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
20701+ unsigned int pending)
20702+{
20703+ int err;
20704+ aufs_bindex_t bindex, bend;
20705+ unsigned char do_plink, skip, do_free;
20706+ struct au_branch *br;
20707+ struct au_wbr *wbr;
20708+ struct dentry *root;
20709+ struct inode *dir, *h_dir;
20710+ struct au_sbinfo *sbinfo;
20711+ struct au_hinode *hdir;
20712+
dece6358
AM
20713+ SiMustAnyLock(sb);
20714+
1facf9fc 20715+ sbinfo = au_sbi(sb);
20716+ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
20717+
dece6358
AM
20718+ if (!(sb_flags & MS_RDONLY)) {
20719+ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
0c3ec466 20720+ pr_warn("first branch should be rw\n");
dece6358 20721+ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
0c3ec466 20722+ pr_warn("shwh should be used with ro\n");
dece6358 20723+ }
1facf9fc 20724+
4a4d8108 20725+ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
1facf9fc 20726+ && !au_opt_test(sbinfo->si_mntflags, XINO))
0c3ec466 20727+ pr_warn("udba=*notify requires xino\n");
1facf9fc 20728+
20729+ err = 0;
20730+ root = sb->s_root;
4a4d8108 20731+ dir = root->d_inode;
1facf9fc 20732+ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
20733+ bend = au_sbend(sb);
20734+ for (bindex = 0; !err && bindex <= bend; bindex++) {
20735+ skip = 0;
20736+ h_dir = au_h_iptr(dir, bindex);
20737+ br = au_sbr(sb, bindex);
20738+ do_free = 0;
20739+
20740+ wbr = br->br_wbr;
20741+ if (wbr)
20742+ wbr_wh_read_lock(wbr);
20743+
1e00d052 20744+ if (!au_br_writable(br->br_perm)) {
1facf9fc 20745+ do_free = !!wbr;
20746+ skip = (!wbr
20747+ || (!wbr->wbr_whbase
20748+ && !wbr->wbr_plink
20749+ && !wbr->wbr_orph));
1e00d052 20750+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 20751+ /* skip = (!br->br_whbase && !br->br_orph); */
20752+ skip = (!wbr || !wbr->wbr_whbase);
20753+ if (skip && wbr) {
20754+ if (do_plink)
20755+ skip = !!wbr->wbr_plink;
20756+ else
20757+ skip = !wbr->wbr_plink;
20758+ }
1e00d052 20759+ } else {
1facf9fc 20760+ /* skip = (br->br_whbase && br->br_ohph); */
20761+ skip = (wbr && wbr->wbr_whbase);
20762+ if (skip) {
20763+ if (do_plink)
20764+ skip = !!wbr->wbr_plink;
20765+ else
20766+ skip = !wbr->wbr_plink;
20767+ }
1facf9fc 20768+ }
20769+ if (wbr)
20770+ wbr_wh_read_unlock(wbr);
20771+
20772+ if (skip)
20773+ continue;
20774+
20775+ hdir = au_hi(dir, bindex);
4a4d8108 20776+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 20777+ if (wbr)
20778+ wbr_wh_write_lock(wbr);
20779+ err = au_wh_init(au_h_dptr(root, bindex), br, sb);
20780+ if (wbr)
20781+ wbr_wh_write_unlock(wbr);
4a4d8108 20782+ au_hn_imtx_unlock(hdir);
1facf9fc 20783+
20784+ if (!err && do_free) {
20785+ kfree(wbr);
20786+ br->br_wbr = NULL;
20787+ }
20788+ }
20789+
20790+ return err;
20791+}
20792+
20793+int au_opts_mount(struct super_block *sb, struct au_opts *opts)
20794+{
20795+ int err;
20796+ unsigned int tmp;
027c5e7a 20797+ aufs_bindex_t bindex, bend;
1facf9fc 20798+ struct au_opt *opt;
20799+ struct au_opt_xino *opt_xino, xino;
20800+ struct au_sbinfo *sbinfo;
027c5e7a 20801+ struct au_branch *br;
1facf9fc 20802+
dece6358
AM
20803+ SiMustWriteLock(sb);
20804+
1facf9fc 20805+ err = 0;
20806+ opt_xino = NULL;
20807+ opt = opts->opt;
20808+ while (err >= 0 && opt->type != Opt_tail)
20809+ err = au_opt_simple(sb, opt++, opts);
20810+ if (err > 0)
20811+ err = 0;
20812+ else if (unlikely(err < 0))
20813+ goto out;
20814+
20815+ /* disable xino and udba temporary */
20816+ sbinfo = au_sbi(sb);
20817+ tmp = sbinfo->si_mntflags;
20818+ au_opt_clr(sbinfo->si_mntflags, XINO);
20819+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
20820+
20821+ opt = opts->opt;
20822+ while (err >= 0 && opt->type != Opt_tail)
20823+ err = au_opt_br(sb, opt++, opts);
20824+ if (err > 0)
20825+ err = 0;
20826+ else if (unlikely(err < 0))
20827+ goto out;
20828+
20829+ bend = au_sbend(sb);
20830+ if (unlikely(bend < 0)) {
20831+ err = -EINVAL;
4a4d8108 20832+ pr_err("no branches\n");
1facf9fc 20833+ goto out;
20834+ }
20835+
20836+ if (au_opt_test(tmp, XINO))
20837+ au_opt_set(sbinfo->si_mntflags, XINO);
20838+ opt = opts->opt;
20839+ while (!err && opt->type != Opt_tail)
20840+ err = au_opt_xino(sb, opt++, &opt_xino, opts);
20841+ if (unlikely(err))
20842+ goto out;
20843+
20844+ err = au_opts_verify(sb, sb->s_flags, tmp);
20845+ if (unlikely(err))
20846+ goto out;
20847+
20848+ /* restore xino */
20849+ if (au_opt_test(tmp, XINO) && !opt_xino) {
20850+ xino.file = au_xino_def(sb);
20851+ err = PTR_ERR(xino.file);
20852+ if (IS_ERR(xino.file))
20853+ goto out;
20854+
20855+ err = au_xino_set(sb, &xino, /*remount*/0);
20856+ fput(xino.file);
20857+ if (unlikely(err))
20858+ goto out;
20859+ }
20860+
20861+ /* restore udba */
027c5e7a 20862+ tmp &= AuOptMask_UDBA;
1facf9fc 20863+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
027c5e7a
AM
20864+ sbinfo->si_mntflags |= tmp;
20865+ bend = au_sbend(sb);
20866+ for (bindex = 0; bindex <= bend; bindex++) {
20867+ br = au_sbr(sb, bindex);
20868+ err = au_hnotify_reset_br(tmp, br, br->br_perm);
20869+ if (unlikely(err))
20870+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
20871+ bindex, err);
20872+ /* go on even if err */
20873+ }
4a4d8108 20874+ if (au_opt_test(tmp, UDBA_HNOTIFY)) {
1facf9fc 20875+ struct inode *dir = sb->s_root->d_inode;
4a4d8108 20876+ au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
1facf9fc 20877+ }
20878+
4f0767ce 20879+out:
1facf9fc 20880+ return err;
20881+}
20882+
20883+int au_opts_remount(struct super_block *sb, struct au_opts *opts)
20884+{
20885+ int err, rerr;
20886+ struct inode *dir;
20887+ struct au_opt_xino *opt_xino;
20888+ struct au_opt *opt;
20889+ struct au_sbinfo *sbinfo;
20890+
dece6358
AM
20891+ SiMustWriteLock(sb);
20892+
1facf9fc 20893+ dir = sb->s_root->d_inode;
20894+ sbinfo = au_sbi(sb);
20895+ err = 0;
20896+ opt_xino = NULL;
20897+ opt = opts->opt;
20898+ while (err >= 0 && opt->type != Opt_tail) {
20899+ err = au_opt_simple(sb, opt, opts);
20900+ if (!err)
20901+ err = au_opt_br(sb, opt, opts);
20902+ if (!err)
20903+ err = au_opt_xino(sb, opt, &opt_xino, opts);
20904+ opt++;
20905+ }
20906+ if (err > 0)
20907+ err = 0;
20908+ AuTraceErr(err);
20909+ /* go on even err */
20910+
20911+ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
20912+ if (unlikely(rerr && !err))
20913+ err = rerr;
20914+
20915+ if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
20916+ rerr = au_xib_trunc(sb);
20917+ if (unlikely(rerr && !err))
20918+ err = rerr;
20919+ }
20920+
20921+ /* will be handled by the caller */
027c5e7a 20922+ if (!au_ftest_opts(opts->flags, REFRESH)
1facf9fc 20923+ && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO)))
027c5e7a 20924+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 20925+
20926+ AuDbg("status 0x%x\n", opts->flags);
20927+ return err;
20928+}
20929+
20930+/* ---------------------------------------------------------------------- */
20931+
20932+unsigned int au_opt_udba(struct super_block *sb)
20933+{
20934+ return au_mntflags(sb) & AuOptMask_UDBA;
20935+}
7f207e10
AM
20936diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
20937--- /usr/share/empty/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100
1716fcea 20938+++ linux/fs/aufs/opts.h 2013-02-19 08:40:03.950226347 +0100
f6c5ef8b 20939@@ -0,0 +1,209 @@
1facf9fc 20940+/*
7a9e40b8 20941+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 20942+ *
20943+ * This program, aufs is free software; you can redistribute it and/or modify
20944+ * it under the terms of the GNU General Public License as published by
20945+ * the Free Software Foundation; either version 2 of the License, or
20946+ * (at your option) any later version.
dece6358
AM
20947+ *
20948+ * This program is distributed in the hope that it will be useful,
20949+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20950+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20951+ * GNU General Public License for more details.
20952+ *
20953+ * You should have received a copy of the GNU General Public License
20954+ * along with this program; if not, write to the Free Software
20955+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 20956+ */
20957+
20958+/*
20959+ * mount options/flags
20960+ */
20961+
20962+#ifndef __AUFS_OPTS_H__
20963+#define __AUFS_OPTS_H__
20964+
20965+#ifdef __KERNEL__
20966+
dece6358 20967+#include <linux/path.h>
1facf9fc 20968+
dece6358
AM
20969+struct file;
20970+struct super_block;
20971+
1facf9fc 20972+/* ---------------------------------------------------------------------- */
20973+
20974+/* mount flags */
20975+#define AuOpt_XINO 1 /* external inode number bitmap
20976+ and translation table */
20977+#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */
20978+#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */
20979+#define AuOpt_UDBA_REVAL (1 << 3)
4a4d8108 20980+#define AuOpt_UDBA_HNOTIFY (1 << 4)
dece6358
AM
20981+#define AuOpt_SHWH (1 << 5) /* show whiteout */
20982+#define AuOpt_PLINK (1 << 6) /* pseudo-link */
20983+#define AuOpt_DIRPERM1 (1 << 7) /* unimplemented */
20984+#define AuOpt_REFROF (1 << 8) /* unimplemented */
20985+#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */
20986+#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
20987+#define AuOpt_SUM_W (1 << 11) /* unimplemented */
20988+#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */
20989+#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */
4a4d8108 20990+#define AuOpt_DIO (1 << 14) /* direct io */
1facf9fc 20991+
4a4d8108
AM
20992+#ifndef CONFIG_AUFS_HNOTIFY
20993+#undef AuOpt_UDBA_HNOTIFY
20994+#define AuOpt_UDBA_HNOTIFY 0
1facf9fc 20995+#endif
dece6358
AM
20996+#ifndef CONFIG_AUFS_SHWH
20997+#undef AuOpt_SHWH
20998+#define AuOpt_SHWH 0
20999+#endif
1facf9fc 21000+
21001+#define AuOpt_Def (AuOpt_XINO \
21002+ | AuOpt_UDBA_REVAL \
21003+ | AuOpt_PLINK \
21004+ /* | AuOpt_DIRPERM1 */ \
21005+ | AuOpt_WARN_PERM)
21006+#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
21007+ | AuOpt_UDBA_REVAL \
4a4d8108 21008+ | AuOpt_UDBA_HNOTIFY)
1facf9fc 21009+
21010+#define au_opt_test(flags, name) (flags & AuOpt_##name)
21011+#define au_opt_set(flags, name) do { \
21012+ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
21013+ ((flags) |= AuOpt_##name); \
21014+} while (0)
21015+#define au_opt_set_udba(flags, name) do { \
21016+ (flags) &= ~AuOptMask_UDBA; \
21017+ ((flags) |= AuOpt_##name); \
21018+} while (0)
7f207e10
AM
21019+#define au_opt_clr(flags, name) do { \
21020+ ((flags) &= ~AuOpt_##name); \
21021+} while (0)
1facf9fc 21022+
e49829fe
JR
21023+static inline unsigned int au_opts_plink(unsigned int mntflags)
21024+{
21025+#ifdef CONFIG_PROC_FS
21026+ return mntflags;
21027+#else
21028+ return mntflags & ~AuOpt_PLINK;
21029+#endif
21030+}
21031+
1facf9fc 21032+/* ---------------------------------------------------------------------- */
21033+
21034+/* policies to select one among multiple writable branches */
21035+enum {
21036+ AuWbrCreate_TDP, /* top down parent */
21037+ AuWbrCreate_RR, /* round robin */
21038+ AuWbrCreate_MFS, /* most free space */
21039+ AuWbrCreate_MFSV, /* mfs with seconds */
21040+ AuWbrCreate_MFSRR, /* mfs then rr */
21041+ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */
21042+ AuWbrCreate_PMFS, /* parent and mfs */
21043+ AuWbrCreate_PMFSV, /* parent and mfs with seconds */
21044+
21045+ AuWbrCreate_Def = AuWbrCreate_TDP
21046+};
21047+
21048+enum {
21049+ AuWbrCopyup_TDP, /* top down parent */
21050+ AuWbrCopyup_BUP, /* bottom up parent */
21051+ AuWbrCopyup_BU, /* bottom up */
21052+
21053+ AuWbrCopyup_Def = AuWbrCopyup_TDP
21054+};
21055+
21056+/* ---------------------------------------------------------------------- */
21057+
21058+struct au_opt_add {
21059+ aufs_bindex_t bindex;
21060+ char *pathname;
21061+ int perm;
21062+ struct path path;
21063+};
21064+
21065+struct au_opt_del {
21066+ char *pathname;
21067+ struct path h_path;
21068+};
21069+
21070+struct au_opt_mod {
21071+ char *path;
21072+ int perm;
21073+ struct dentry *h_root;
21074+};
21075+
21076+struct au_opt_xino {
21077+ char *path;
21078+ struct file *file;
21079+};
21080+
21081+struct au_opt_xino_itrunc {
21082+ aufs_bindex_t bindex;
21083+};
21084+
21085+struct au_opt_wbr_create {
21086+ int wbr_create;
21087+ int mfs_second;
21088+ unsigned long long mfsrr_watermark;
21089+};
21090+
21091+struct au_opt {
21092+ int type;
21093+ union {
21094+ struct au_opt_xino xino;
21095+ struct au_opt_xino_itrunc xino_itrunc;
21096+ struct au_opt_add add;
21097+ struct au_opt_del del;
21098+ struct au_opt_mod mod;
21099+ int dirwh;
21100+ int rdcache;
21101+ unsigned int rdblk;
21102+ unsigned int rdhash;
21103+ int udba;
21104+ struct au_opt_wbr_create wbr_create;
21105+ int wbr_copyup;
21106+ };
21107+};
21108+
21109+/* opts flags */
21110+#define AuOpts_REMOUNT 1
027c5e7a
AM
21111+#define AuOpts_REFRESH (1 << 1)
21112+#define AuOpts_TRUNC_XIB (1 << 2)
21113+#define AuOpts_REFRESH_DYAOP (1 << 3)
1facf9fc 21114+#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
7f207e10
AM
21115+#define au_fset_opts(flags, name) \
21116+ do { (flags) |= AuOpts_##name; } while (0)
21117+#define au_fclr_opts(flags, name) \
21118+ do { (flags) &= ~AuOpts_##name; } while (0)
1facf9fc 21119+
21120+struct au_opts {
21121+ struct au_opt *opt;
21122+ int max_opt;
21123+
21124+ unsigned int given_udba;
21125+ unsigned int flags;
21126+ unsigned long sb_flags;
21127+};
21128+
21129+/* ---------------------------------------------------------------------- */
21130+
1e00d052 21131+char *au_optstr_br_perm(int brperm);
1facf9fc 21132+const char *au_optstr_udba(int udba);
21133+const char *au_optstr_wbr_copyup(int wbr_copyup);
21134+const char *au_optstr_wbr_create(int wbr_create);
21135+
21136+void au_opts_free(struct au_opts *opts);
21137+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
21138+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
21139+ unsigned int pending);
21140+int au_opts_mount(struct super_block *sb, struct au_opts *opts);
21141+int au_opts_remount(struct super_block *sb, struct au_opts *opts);
21142+
21143+unsigned int au_opt_udba(struct super_block *sb);
21144+
21145+/* ---------------------------------------------------------------------- */
21146+
21147+#endif /* __KERNEL__ */
21148+#endif /* __AUFS_OPTS_H__ */
7f207e10
AM
21149diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
21150--- /usr/share/empty/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100
1716fcea 21151+++ linux/fs/aufs/plink.c 2013-02-19 08:40:03.950226347 +0100
0c3ec466 21152@@ -0,0 +1,511 @@
1facf9fc 21153+/*
7a9e40b8 21154+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 21155+ *
21156+ * This program, aufs is free software; you can redistribute it and/or modify
21157+ * it under the terms of the GNU General Public License as published by
21158+ * the Free Software Foundation; either version 2 of the License, or
21159+ * (at your option) any later version.
dece6358
AM
21160+ *
21161+ * This program is distributed in the hope that it will be useful,
21162+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21163+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21164+ * GNU General Public License for more details.
21165+ *
21166+ * You should have received a copy of the GNU General Public License
21167+ * along with this program; if not, write to the Free Software
21168+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 21169+ */
21170+
21171+/*
21172+ * pseudo-link
21173+ */
21174+
21175+#include "aufs.h"
21176+
21177+/*
e49829fe 21178+ * the pseudo-link maintenance mode.
1facf9fc 21179+ * during a user process maintains the pseudo-links,
21180+ * prohibit adding a new plink and branch manipulation.
e49829fe
JR
21181+ *
21182+ * Flags
21183+ * NOPLM:
21184+ * For entry functions which will handle plink, and i_mutex is already held
21185+ * in VFS.
21186+ * They cannot wait and should return an error at once.
21187+ * Callers has to check the error.
21188+ * NOPLMW:
21189+ * For entry functions which will handle plink, but i_mutex is not held
21190+ * in VFS.
21191+ * They can wait the plink maintenance mode to finish.
21192+ *
21193+ * They behave like F_SETLK and F_SETLKW.
21194+ * If the caller never handle plink, then both flags are unnecessary.
1facf9fc 21195+ */
e49829fe
JR
21196+
21197+int au_plink_maint(struct super_block *sb, int flags)
1facf9fc 21198+{
e49829fe
JR
21199+ int err;
21200+ pid_t pid, ppid;
21201+ struct au_sbinfo *sbi;
dece6358
AM
21202+
21203+ SiMustAnyLock(sb);
21204+
e49829fe
JR
21205+ err = 0;
21206+ if (!au_opt_test(au_mntflags(sb), PLINK))
21207+ goto out;
21208+
21209+ sbi = au_sbi(sb);
21210+ pid = sbi->si_plink_maint_pid;
21211+ if (!pid || pid == current->pid)
21212+ goto out;
21213+
21214+ /* todo: it highly depends upon /sbin/mount.aufs */
21215+ rcu_read_lock();
21216+ ppid = task_pid_vnr(rcu_dereference(current->real_parent));
21217+ rcu_read_unlock();
21218+ if (pid == ppid)
21219+ goto out;
21220+
21221+ if (au_ftest_lock(flags, NOPLMW)) {
027c5e7a
AM
21222+ /* if there is no i_mutex lock in VFS, we don't need to wait */
21223+ /* AuDebugOn(!lockdep_depth(current)); */
e49829fe
JR
21224+ while (sbi->si_plink_maint_pid) {
21225+ si_read_unlock(sb);
21226+ /* gave up wake_up_bit() */
21227+ wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
21228+
21229+ if (au_ftest_lock(flags, FLUSH))
21230+ au_nwt_flush(&sbi->si_nowait);
21231+ si_noflush_read_lock(sb);
21232+ }
21233+ } else if (au_ftest_lock(flags, NOPLM)) {
21234+ AuDbg("ppid %d, pid %d\n", ppid, pid);
21235+ err = -EAGAIN;
21236+ }
21237+
21238+out:
21239+ return err;
4a4d8108
AM
21240+}
21241+
e49829fe 21242+void au_plink_maint_leave(struct au_sbinfo *sbinfo)
4a4d8108 21243+{
4a4d8108 21244+ spin_lock(&sbinfo->si_plink_maint_lock);
027c5e7a 21245+ sbinfo->si_plink_maint_pid = 0;
4a4d8108 21246+ spin_unlock(&sbinfo->si_plink_maint_lock);
027c5e7a 21247+ wake_up_all(&sbinfo->si_plink_wq);
4a4d8108
AM
21248+}
21249+
e49829fe 21250+int au_plink_maint_enter(struct super_block *sb)
4a4d8108
AM
21251+{
21252+ int err;
4a4d8108
AM
21253+ struct au_sbinfo *sbinfo;
21254+
21255+ err = 0;
4a4d8108
AM
21256+ sbinfo = au_sbi(sb);
21257+ /* make sure i am the only one in this fs */
e49829fe
JR
21258+ si_write_lock(sb, AuLock_FLUSH);
21259+ if (au_opt_test(au_mntflags(sb), PLINK)) {
21260+ spin_lock(&sbinfo->si_plink_maint_lock);
21261+ if (!sbinfo->si_plink_maint_pid)
21262+ sbinfo->si_plink_maint_pid = current->pid;
21263+ else
21264+ err = -EBUSY;
21265+ spin_unlock(&sbinfo->si_plink_maint_lock);
21266+ }
4a4d8108
AM
21267+ si_write_unlock(sb);
21268+
21269+ return err;
1facf9fc 21270+}
21271+
21272+/* ---------------------------------------------------------------------- */
21273+
21274+struct pseudo_link {
4a4d8108
AM
21275+ union {
21276+ struct list_head list;
21277+ struct rcu_head rcu;
21278+ };
1facf9fc 21279+ struct inode *inode;
21280+};
21281+
21282+#ifdef CONFIG_AUFS_DEBUG
21283+void au_plink_list(struct super_block *sb)
21284+{
21285+ struct au_sbinfo *sbinfo;
21286+ struct list_head *plink_list;
21287+ struct pseudo_link *plink;
21288+
dece6358
AM
21289+ SiMustAnyLock(sb);
21290+
1facf9fc 21291+ sbinfo = au_sbi(sb);
21292+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 21293+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 21294+
21295+ plink_list = &sbinfo->si_plink.head;
4a4d8108
AM
21296+ rcu_read_lock();
21297+ list_for_each_entry_rcu(plink, plink_list, list)
1facf9fc 21298+ AuDbg("%lu\n", plink->inode->i_ino);
4a4d8108 21299+ rcu_read_unlock();
1facf9fc 21300+}
21301+#endif
21302+
21303+/* is the inode pseudo-linked? */
21304+int au_plink_test(struct inode *inode)
21305+{
21306+ int found;
21307+ struct au_sbinfo *sbinfo;
21308+ struct list_head *plink_list;
21309+ struct pseudo_link *plink;
21310+
21311+ sbinfo = au_sbi(inode->i_sb);
dece6358 21312+ AuRwMustAnyLock(&sbinfo->si_rwsem);
1facf9fc 21313+ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
e49829fe 21314+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
1facf9fc 21315+
21316+ found = 0;
21317+ plink_list = &sbinfo->si_plink.head;
4a4d8108
AM
21318+ rcu_read_lock();
21319+ list_for_each_entry_rcu(plink, plink_list, list)
1facf9fc 21320+ if (plink->inode == inode) {
21321+ found = 1;
21322+ break;
21323+ }
4a4d8108 21324+ rcu_read_unlock();
1facf9fc 21325+ return found;
21326+}
21327+
21328+/* ---------------------------------------------------------------------- */
21329+
21330+/*
21331+ * generate a name for plink.
21332+ * the file will be stored under AUFS_WH_PLINKDIR.
21333+ */
21334+/* 20 is max digits length of ulong 64 */
21335+#define PLINK_NAME_LEN ((20 + 1) * 2)
21336+
21337+static int plink_name(char *name, int len, struct inode *inode,
21338+ aufs_bindex_t bindex)
21339+{
21340+ int rlen;
21341+ struct inode *h_inode;
21342+
21343+ h_inode = au_h_iptr(inode, bindex);
21344+ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
21345+ return rlen;
21346+}
21347+
7f207e10
AM
21348+struct au_do_plink_lkup_args {
21349+ struct dentry **errp;
21350+ struct qstr *tgtname;
21351+ struct dentry *h_parent;
21352+ struct au_branch *br;
21353+};
21354+
21355+static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
21356+ struct dentry *h_parent,
21357+ struct au_branch *br)
21358+{
21359+ struct dentry *h_dentry;
21360+ struct mutex *h_mtx;
21361+
21362+ h_mtx = &h_parent->d_inode->i_mutex;
21363+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
b4510431 21364+ h_dentry = vfsub_lkup_one(tgtname, h_parent);
7f207e10
AM
21365+ mutex_unlock(h_mtx);
21366+ return h_dentry;
21367+}
21368+
21369+static void au_call_do_plink_lkup(void *args)
21370+{
21371+ struct au_do_plink_lkup_args *a = args;
21372+ *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
21373+}
21374+
1facf9fc 21375+/* lookup the plink-ed @inode under the branch at @bindex */
21376+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
21377+{
21378+ struct dentry *h_dentry, *h_parent;
21379+ struct au_branch *br;
21380+ struct inode *h_dir;
7f207e10 21381+ int wkq_err;
1facf9fc 21382+ char a[PLINK_NAME_LEN];
0c3ec466 21383+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 21384+
e49829fe
JR
21385+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
21386+
1facf9fc 21387+ br = au_sbr(inode->i_sb, bindex);
21388+ h_parent = br->br_wbr->wbr_plink;
21389+ h_dir = h_parent->d_inode;
21390+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
21391+
2dfbb274 21392+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
7f207e10
AM
21393+ struct au_do_plink_lkup_args args = {
21394+ .errp = &h_dentry,
21395+ .tgtname = &tgtname,
21396+ .h_parent = h_parent,
21397+ .br = br
21398+ };
21399+
21400+ wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
21401+ if (unlikely(wkq_err))
21402+ h_dentry = ERR_PTR(wkq_err);
21403+ } else
21404+ h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
21405+
1facf9fc 21406+ return h_dentry;
21407+}
21408+
21409+/* create a pseudo-link */
21410+static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
21411+ struct dentry *h_dentry, struct au_branch *br)
21412+{
21413+ int err;
21414+ struct path h_path = {
21415+ .mnt = br->br_mnt
21416+ };
21417+ struct inode *h_dir;
21418+
21419+ h_dir = h_parent->d_inode;
7f207e10 21420+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
4f0767ce 21421+again:
b4510431 21422+ h_path.dentry = vfsub_lkup_one(tgt, h_parent);
1facf9fc 21423+ err = PTR_ERR(h_path.dentry);
21424+ if (IS_ERR(h_path.dentry))
21425+ goto out;
21426+
21427+ err = 0;
21428+ /* wh.plink dir is not monitored */
7f207e10 21429+ /* todo: is it really safe? */
1facf9fc 21430+ if (h_path.dentry->d_inode
21431+ && h_path.dentry->d_inode != h_dentry->d_inode) {
21432+ err = vfsub_unlink(h_dir, &h_path, /*force*/0);
21433+ dput(h_path.dentry);
21434+ h_path.dentry = NULL;
21435+ if (!err)
21436+ goto again;
21437+ }
21438+ if (!err && !h_path.dentry->d_inode)
21439+ err = vfsub_link(h_dentry, h_dir, &h_path);
21440+ dput(h_path.dentry);
21441+
4f0767ce 21442+out:
7f207e10 21443+ mutex_unlock(&h_dir->i_mutex);
1facf9fc 21444+ return err;
21445+}
21446+
21447+struct do_whplink_args {
21448+ int *errp;
21449+ struct qstr *tgt;
21450+ struct dentry *h_parent;
21451+ struct dentry *h_dentry;
21452+ struct au_branch *br;
21453+};
21454+
21455+static void call_do_whplink(void *args)
21456+{
21457+ struct do_whplink_args *a = args;
21458+ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
21459+}
21460+
21461+static int whplink(struct dentry *h_dentry, struct inode *inode,
21462+ aufs_bindex_t bindex, struct au_branch *br)
21463+{
21464+ int err, wkq_err;
21465+ struct au_wbr *wbr;
21466+ struct dentry *h_parent;
21467+ struct inode *h_dir;
21468+ char a[PLINK_NAME_LEN];
0c3ec466 21469+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 21470+
21471+ wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
21472+ h_parent = wbr->wbr_plink;
21473+ h_dir = h_parent->d_inode;
21474+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
21475+
21476+ /* always superio. */
2dfbb274 21477+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
1facf9fc 21478+ struct do_whplink_args args = {
21479+ .errp = &err,
21480+ .tgt = &tgtname,
21481+ .h_parent = h_parent,
21482+ .h_dentry = h_dentry,
21483+ .br = br
21484+ };
21485+ wkq_err = au_wkq_wait(call_do_whplink, &args);
21486+ if (unlikely(wkq_err))
21487+ err = wkq_err;
21488+ } else
21489+ err = do_whplink(&tgtname, h_parent, h_dentry, br);
1facf9fc 21490+
21491+ return err;
21492+}
21493+
21494+/* free a single plink */
21495+static void do_put_plink(struct pseudo_link *plink, int do_del)
21496+{
1facf9fc 21497+ if (do_del)
21498+ list_del(&plink->list);
4a4d8108
AM
21499+ iput(plink->inode);
21500+ kfree(plink);
21501+}
21502+
21503+static void do_put_plink_rcu(struct rcu_head *rcu)
21504+{
21505+ struct pseudo_link *plink;
21506+
21507+ plink = container_of(rcu, struct pseudo_link, rcu);
21508+ iput(plink->inode);
1facf9fc 21509+ kfree(plink);
21510+}
21511+
21512+/*
21513+ * create a new pseudo-link for @h_dentry on @bindex.
21514+ * the linked inode is held in aufs @inode.
21515+ */
21516+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
21517+ struct dentry *h_dentry)
21518+{
21519+ struct super_block *sb;
21520+ struct au_sbinfo *sbinfo;
21521+ struct list_head *plink_list;
4a4d8108 21522+ struct pseudo_link *plink, *tmp;
1facf9fc 21523+ int found, err, cnt;
21524+
21525+ sb = inode->i_sb;
21526+ sbinfo = au_sbi(sb);
21527+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 21528+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 21529+
1facf9fc 21530+ cnt = 0;
21531+ found = 0;
21532+ plink_list = &sbinfo->si_plink.head;
4a4d8108
AM
21533+ rcu_read_lock();
21534+ list_for_each_entry_rcu(plink, plink_list, list) {
1facf9fc 21535+ cnt++;
21536+ if (plink->inode == inode) {
21537+ found = 1;
21538+ break;
21539+ }
21540+ }
4a4d8108
AM
21541+ rcu_read_unlock();
21542+ if (found)
1facf9fc 21543+ return;
4a4d8108
AM
21544+
21545+ tmp = kmalloc(sizeof(*plink), GFP_NOFS);
21546+ if (tmp)
21547+ tmp->inode = au_igrab(inode);
21548+ else {
21549+ err = -ENOMEM;
21550+ goto out;
1facf9fc 21551+ }
21552+
4a4d8108
AM
21553+ spin_lock(&sbinfo->si_plink.spin);
21554+ list_for_each_entry(plink, plink_list, list) {
21555+ if (plink->inode == inode) {
21556+ found = 1;
21557+ break;
21558+ }
1facf9fc 21559+ }
4a4d8108
AM
21560+ if (!found)
21561+ list_add_rcu(&tmp->list, plink_list);
1facf9fc 21562+ spin_unlock(&sbinfo->si_plink.spin);
4a4d8108
AM
21563+ if (!found) {
21564+ cnt++;
21565+ WARN_ONCE(cnt > AUFS_PLINK_WARN,
21566+ "unexpectedly many pseudo links, %d\n", cnt);
1facf9fc 21567+ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
4a4d8108
AM
21568+ } else {
21569+ do_put_plink(tmp, 0);
21570+ return;
1facf9fc 21571+ }
21572+
4a4d8108 21573+out:
1facf9fc 21574+ if (unlikely(err)) {
0c3ec466 21575+ pr_warn("err %d, damaged pseudo link.\n", err);
4a4d8108
AM
21576+ if (tmp) {
21577+ au_spl_del_rcu(&tmp->list, &sbinfo->si_plink);
21578+ call_rcu(&tmp->rcu, do_put_plink_rcu);
21579+ }
1facf9fc 21580+ }
21581+}
21582+
21583+/* free all plinks */
e49829fe 21584+void au_plink_put(struct super_block *sb, int verbose)
1facf9fc 21585+{
21586+ struct au_sbinfo *sbinfo;
21587+ struct list_head *plink_list;
21588+ struct pseudo_link *plink, *tmp;
21589+
dece6358
AM
21590+ SiMustWriteLock(sb);
21591+
1facf9fc 21592+ sbinfo = au_sbi(sb);
21593+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 21594+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 21595+
21596+ plink_list = &sbinfo->si_plink.head;
21597+ /* no spin_lock since sbinfo is write-locked */
e49829fe 21598+ WARN(verbose && !list_empty(plink_list), "pseudo-link is not flushed");
1facf9fc 21599+ list_for_each_entry_safe(plink, tmp, plink_list, list)
21600+ do_put_plink(plink, 0);
21601+ INIT_LIST_HEAD(plink_list);
21602+}
21603+
e49829fe
JR
21604+void au_plink_clean(struct super_block *sb, int verbose)
21605+{
21606+ struct dentry *root;
21607+
21608+ root = sb->s_root;
21609+ aufs_write_lock(root);
21610+ if (au_opt_test(au_mntflags(sb), PLINK))
21611+ au_plink_put(sb, verbose);
21612+ aufs_write_unlock(root);
21613+}
21614+
1facf9fc 21615+/* free the plinks on a branch specified by @br_id */
21616+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
21617+{
21618+ struct au_sbinfo *sbinfo;
21619+ struct list_head *plink_list;
21620+ struct pseudo_link *plink, *tmp;
21621+ struct inode *inode;
21622+ aufs_bindex_t bstart, bend, bindex;
21623+ unsigned char do_put;
21624+
dece6358
AM
21625+ SiMustWriteLock(sb);
21626+
1facf9fc 21627+ sbinfo = au_sbi(sb);
21628+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 21629+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 21630+
21631+ plink_list = &sbinfo->si_plink.head;
21632+ /* no spin_lock since sbinfo is write-locked */
21633+ list_for_each_entry_safe(plink, tmp, plink_list, list) {
21634+ do_put = 0;
21635+ inode = au_igrab(plink->inode);
21636+ ii_write_lock_child(inode);
21637+ bstart = au_ibstart(inode);
21638+ bend = au_ibend(inode);
21639+ if (bstart >= 0) {
21640+ for (bindex = bstart; bindex <= bend; bindex++) {
21641+ if (!au_h_iptr(inode, bindex)
21642+ || au_ii_br_id(inode, bindex) != br_id)
21643+ continue;
21644+ au_set_h_iptr(inode, bindex, NULL, 0);
21645+ do_put = 1;
21646+ break;
21647+ }
21648+ } else
21649+ do_put_plink(plink, 1);
21650+
dece6358
AM
21651+ if (do_put) {
21652+ for (bindex = bstart; bindex <= bend; bindex++)
21653+ if (au_h_iptr(inode, bindex)) {
21654+ do_put = 0;
21655+ break;
21656+ }
21657+ if (do_put)
21658+ do_put_plink(plink, 1);
21659+ }
21660+ ii_write_unlock(inode);
21661+ iput(inode);
21662+ }
21663+}
7f207e10
AM
21664diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
21665--- /usr/share/empty/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100
1716fcea 21666+++ linux/fs/aufs/poll.c 2013-02-19 08:40:03.950226347 +0100
dece6358
AM
21667@@ -0,0 +1,56 @@
21668+/*
7a9e40b8 21669+ * Copyright (C) 2005-2013 Junjiro R. Okajima
dece6358
AM
21670+ *
21671+ * This program, aufs is free software; you can redistribute it and/or modify
21672+ * it under the terms of the GNU General Public License as published by
21673+ * the Free Software Foundation; either version 2 of the License, or
21674+ * (at your option) any later version.
21675+ *
21676+ * This program is distributed in the hope that it will be useful,
21677+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21678+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21679+ * GNU General Public License for more details.
21680+ *
21681+ * You should have received a copy of the GNU General Public License
21682+ * along with this program; if not, write to the Free Software
21683+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21684+ */
21685+
1308ab2a 21686+/*
21687+ * poll operation
21688+ * There is only one filesystem which implements ->poll operation, currently.
21689+ */
21690+
21691+#include "aufs.h"
21692+
21693+unsigned int aufs_poll(struct file *file, poll_table *wait)
21694+{
21695+ unsigned int mask;
21696+ int err;
21697+ struct file *h_file;
21698+ struct dentry *dentry;
21699+ struct super_block *sb;
21700+
21701+ /* We should pretend an error happened. */
21702+ mask = POLLERR /* | POLLIN | POLLOUT */;
21703+ dentry = file->f_dentry;
21704+ sb = dentry->d_sb;
e49829fe 21705+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
1308ab2a 21706+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
21707+ if (unlikely(err))
21708+ goto out;
21709+
21710+ /* it is not an error if h_file has no operation */
21711+ mask = DEFAULT_POLLMASK;
4a4d8108 21712+ h_file = au_hf_top(file);
1308ab2a 21713+ if (h_file->f_op && h_file->f_op->poll)
21714+ mask = h_file->f_op->poll(h_file, wait);
21715+
21716+ di_read_unlock(dentry, AuLock_IR);
21717+ fi_read_unlock(file);
21718+
4f0767ce 21719+out:
1308ab2a 21720+ si_read_unlock(sb);
21721+ AuTraceErr((int)mask);
21722+ return mask;
21723+}
7f207e10
AM
21724diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
21725--- /usr/share/empty/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100
1716fcea 21726+++ linux/fs/aufs/procfs.c 2013-02-19 08:40:03.950226347 +0100
53392da6 21727@@ -0,0 +1,170 @@
e49829fe 21728+/*
7a9e40b8 21729+ * Copyright (C) 2010-2013 Junjiro R. Okajima
e49829fe
JR
21730+ *
21731+ * This program, aufs is free software; you can redistribute it and/or modify
21732+ * it under the terms of the GNU General Public License as published by
21733+ * the Free Software Foundation; either version 2 of the License, or
21734+ * (at your option) any later version.
21735+ *
21736+ * This program is distributed in the hope that it will be useful,
21737+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21738+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21739+ * GNU General Public License for more details.
21740+ *
21741+ * You should have received a copy of the GNU General Public License
21742+ * along with this program; if not, write to the Free Software
21743+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21744+ */
21745+
21746+/*
21747+ * procfs interfaces
21748+ */
21749+
21750+#include <linux/proc_fs.h>
21751+#include "aufs.h"
21752+
21753+static int au_procfs_plm_release(struct inode *inode, struct file *file)
21754+{
21755+ struct au_sbinfo *sbinfo;
21756+
21757+ sbinfo = file->private_data;
21758+ if (sbinfo) {
21759+ au_plink_maint_leave(sbinfo);
21760+ kobject_put(&sbinfo->si_kobj);
21761+ }
21762+
21763+ return 0;
21764+}
21765+
21766+static void au_procfs_plm_write_clean(struct file *file)
21767+{
21768+ struct au_sbinfo *sbinfo;
21769+
21770+ sbinfo = file->private_data;
21771+ if (sbinfo)
21772+ au_plink_clean(sbinfo->si_sb, /*verbose*/0);
21773+}
21774+
21775+static int au_procfs_plm_write_si(struct file *file, unsigned long id)
21776+{
21777+ int err;
21778+ struct super_block *sb;
21779+ struct au_sbinfo *sbinfo;
21780+
21781+ err = -EBUSY;
21782+ if (unlikely(file->private_data))
21783+ goto out;
21784+
21785+ sb = NULL;
53392da6 21786+ /* don't use au_sbilist_lock() here */
e49829fe
JR
21787+ spin_lock(&au_sbilist.spin);
21788+ list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
21789+ if (id == sysaufs_si_id(sbinfo)) {
21790+ kobject_get(&sbinfo->si_kobj);
21791+ sb = sbinfo->si_sb;
21792+ break;
21793+ }
21794+ spin_unlock(&au_sbilist.spin);
21795+
21796+ err = -EINVAL;
21797+ if (unlikely(!sb))
21798+ goto out;
21799+
21800+ err = au_plink_maint_enter(sb);
21801+ if (!err)
21802+ /* keep kobject_get() */
21803+ file->private_data = sbinfo;
21804+ else
21805+ kobject_put(&sbinfo->si_kobj);
21806+out:
21807+ return err;
21808+}
21809+
21810+/*
21811+ * Accept a valid "si=xxxx" only.
21812+ * Once it is accepted successfully, accept "clean" too.
21813+ */
21814+static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf,
21815+ size_t count, loff_t *ppos)
21816+{
21817+ ssize_t err;
21818+ unsigned long id;
21819+ /* last newline is allowed */
21820+ char buf[3 + sizeof(unsigned long) * 2 + 1];
21821+
21822+ err = -EACCES;
21823+ if (unlikely(!capable(CAP_SYS_ADMIN)))
21824+ goto out;
21825+
21826+ err = -EINVAL;
21827+ if (unlikely(count > sizeof(buf)))
21828+ goto out;
21829+
21830+ err = copy_from_user(buf, ubuf, count);
21831+ if (unlikely(err)) {
21832+ err = -EFAULT;
21833+ goto out;
21834+ }
21835+ buf[count] = 0;
21836+
21837+ err = -EINVAL;
21838+ if (!strcmp("clean", buf)) {
21839+ au_procfs_plm_write_clean(file);
21840+ goto out_success;
21841+ } else if (unlikely(strncmp("si=", buf, 3)))
21842+ goto out;
21843+
9dbd164d 21844+ err = kstrtoul(buf + 3, 16, &id);
e49829fe
JR
21845+ if (unlikely(err))
21846+ goto out;
21847+
21848+ err = au_procfs_plm_write_si(file, id);
21849+ if (unlikely(err))
21850+ goto out;
21851+
21852+out_success:
21853+ err = count; /* success */
21854+out:
21855+ return err;
21856+}
21857+
21858+static const struct file_operations au_procfs_plm_fop = {
21859+ .write = au_procfs_plm_write,
21860+ .release = au_procfs_plm_release,
21861+ .owner = THIS_MODULE
21862+};
21863+
21864+/* ---------------------------------------------------------------------- */
21865+
21866+static struct proc_dir_entry *au_procfs_dir;
21867+
21868+void au_procfs_fin(void)
21869+{
21870+ remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir);
21871+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
21872+}
21873+
21874+int __init au_procfs_init(void)
21875+{
21876+ int err;
21877+ struct proc_dir_entry *entry;
21878+
21879+ err = -ENOMEM;
21880+ au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL);
21881+ if (unlikely(!au_procfs_dir))
21882+ goto out;
21883+
21884+ entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | S_IWUSR,
21885+ au_procfs_dir, &au_procfs_plm_fop);
21886+ if (unlikely(!entry))
21887+ goto out_dir;
21888+
21889+ err = 0;
21890+ goto out; /* success */
21891+
21892+
21893+out_dir:
21894+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
21895+out:
21896+ return err;
21897+}
7f207e10
AM
21898diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
21899--- /usr/share/empty/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100
1716fcea 21900+++ linux/fs/aufs/rdu.c 2013-02-19 08:40:03.950226347 +0100
92d182d2 21901@@ -0,0 +1,384 @@
1308ab2a 21902+/*
7a9e40b8 21903+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1308ab2a 21904+ *
21905+ * This program, aufs is free software; you can redistribute it and/or modify
21906+ * it under the terms of the GNU General Public License as published by
21907+ * the Free Software Foundation; either version 2 of the License, or
21908+ * (at your option) any later version.
21909+ *
21910+ * This program is distributed in the hope that it will be useful,
21911+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21912+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21913+ * GNU General Public License for more details.
21914+ *
21915+ * You should have received a copy of the GNU General Public License
21916+ * along with this program; if not, write to the Free Software
21917+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21918+ */
21919+
21920+/*
21921+ * readdir in userspace.
21922+ */
21923+
b752ccd1 21924+#include <linux/compat.h>
4a4d8108 21925+#include <linux/fs_stack.h>
1308ab2a 21926+#include <linux/security.h>
1308ab2a 21927+#include "aufs.h"
21928+
21929+/* bits for struct aufs_rdu.flags */
21930+#define AuRdu_CALLED 1
21931+#define AuRdu_CONT (1 << 1)
21932+#define AuRdu_FULL (1 << 2)
21933+#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name)
7f207e10
AM
21934+#define au_fset_rdu(flags, name) \
21935+ do { (flags) |= AuRdu_##name; } while (0)
21936+#define au_fclr_rdu(flags, name) \
21937+ do { (flags) &= ~AuRdu_##name; } while (0)
1308ab2a 21938+
21939+struct au_rdu_arg {
21940+ struct aufs_rdu *rdu;
21941+ union au_rdu_ent_ul ent;
21942+ unsigned long end;
21943+
21944+ struct super_block *sb;
21945+ int err;
21946+};
21947+
21948+static int au_rdu_fill(void *__arg, const char *name, int nlen,
21949+ loff_t offset, u64 h_ino, unsigned int d_type)
21950+{
21951+ int err, len;
21952+ struct au_rdu_arg *arg = __arg;
21953+ struct aufs_rdu *rdu = arg->rdu;
21954+ struct au_rdu_ent ent;
21955+
21956+ err = 0;
21957+ arg->err = 0;
21958+ au_fset_rdu(rdu->cookie.flags, CALLED);
21959+ len = au_rdu_len(nlen);
21960+ if (arg->ent.ul + len < arg->end) {
21961+ ent.ino = h_ino;
21962+ ent.bindex = rdu->cookie.bindex;
21963+ ent.type = d_type;
21964+ ent.nlen = nlen;
4a4d8108
AM
21965+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
21966+ ent.type = DT_UNKNOWN;
1308ab2a 21967+
9dbd164d 21968+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 21969+ err = -EFAULT;
21970+ if (copy_to_user(arg->ent.e, &ent, sizeof(ent)))
21971+ goto out;
21972+ if (copy_to_user(arg->ent.e->name, name, nlen))
21973+ goto out;
21974+ /* the terminating NULL */
21975+ if (__put_user(0, arg->ent.e->name + nlen))
21976+ goto out;
21977+ err = 0;
21978+ /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */
21979+ arg->ent.ul += len;
21980+ rdu->rent++;
21981+ } else {
21982+ err = -EFAULT;
21983+ au_fset_rdu(rdu->cookie.flags, FULL);
21984+ rdu->full = 1;
21985+ rdu->tail = arg->ent;
21986+ }
21987+
4f0767ce 21988+out:
1308ab2a 21989+ /* AuTraceErr(err); */
21990+ return err;
21991+}
21992+
21993+static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg)
21994+{
21995+ int err;
21996+ loff_t offset;
21997+ struct au_rdu_cookie *cookie = &arg->rdu->cookie;
21998+
92d182d2 21999+ /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */
1308ab2a 22000+ offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET);
22001+ err = offset;
22002+ if (unlikely(offset != cookie->h_pos))
22003+ goto out;
22004+
22005+ err = 0;
22006+ do {
22007+ arg->err = 0;
22008+ au_fclr_rdu(cookie->flags, CALLED);
22009+ /* smp_mb(); */
22010+ err = vfsub_readdir(h_file, au_rdu_fill, arg);
22011+ if (err >= 0)
22012+ err = arg->err;
22013+ } while (!err
22014+ && au_ftest_rdu(cookie->flags, CALLED)
22015+ && !au_ftest_rdu(cookie->flags, FULL));
22016+ cookie->h_pos = h_file->f_pos;
22017+
4f0767ce 22018+out:
1308ab2a 22019+ AuTraceErr(err);
22020+ return err;
22021+}
22022+
22023+static int au_rdu(struct file *file, struct aufs_rdu *rdu)
22024+{
22025+ int err;
22026+ aufs_bindex_t bend;
22027+ struct au_rdu_arg arg;
22028+ struct dentry *dentry;
22029+ struct inode *inode;
22030+ struct file *h_file;
22031+ struct au_rdu_cookie *cookie = &rdu->cookie;
22032+
22033+ err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz);
22034+ if (unlikely(err)) {
22035+ err = -EFAULT;
22036+ AuTraceErr(err);
22037+ goto out;
22038+ }
22039+ rdu->rent = 0;
22040+ rdu->tail = rdu->ent;
22041+ rdu->full = 0;
22042+ arg.rdu = rdu;
22043+ arg.ent = rdu->ent;
22044+ arg.end = arg.ent.ul;
22045+ arg.end += rdu->sz;
22046+
22047+ err = -ENOTDIR;
22048+ if (unlikely(!file->f_op || !file->f_op->readdir))
22049+ goto out;
22050+
22051+ err = security_file_permission(file, MAY_READ);
22052+ AuTraceErr(err);
22053+ if (unlikely(err))
22054+ goto out;
22055+
22056+ dentry = file->f_dentry;
22057+ inode = dentry->d_inode;
22058+#if 1
22059+ mutex_lock(&inode->i_mutex);
22060+#else
22061+ err = mutex_lock_killable(&inode->i_mutex);
22062+ AuTraceErr(err);
22063+ if (unlikely(err))
22064+ goto out;
22065+#endif
1308ab2a 22066+
22067+ arg.sb = inode->i_sb;
e49829fe
JR
22068+ err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM);
22069+ if (unlikely(err))
22070+ goto out_mtx;
027c5e7a
AM
22071+ err = au_alive_dir(dentry);
22072+ if (unlikely(err))
22073+ goto out_si;
e49829fe 22074+ /* todo: reval? */
1308ab2a 22075+ fi_read_lock(file);
22076+
22077+ err = -EAGAIN;
22078+ if (unlikely(au_ftest_rdu(cookie->flags, CONT)
22079+ && cookie->generation != au_figen(file)))
22080+ goto out_unlock;
22081+
22082+ err = 0;
22083+ if (!rdu->blk) {
22084+ rdu->blk = au_sbi(arg.sb)->si_rdblk;
22085+ if (!rdu->blk)
22086+ rdu->blk = au_dir_size(file, /*dentry*/NULL);
22087+ }
22088+ bend = au_fbstart(file);
22089+ if (cookie->bindex < bend)
22090+ cookie->bindex = bend;
4a4d8108 22091+ bend = au_fbend_dir(file);
1308ab2a 22092+ /* AuDbg("b%d, b%d\n", cookie->bindex, bend); */
22093+ for (; !err && cookie->bindex <= bend;
22094+ cookie->bindex++, cookie->h_pos = 0) {
4a4d8108 22095+ h_file = au_hf_dir(file, cookie->bindex);
1308ab2a 22096+ if (!h_file)
22097+ continue;
22098+
22099+ au_fclr_rdu(cookie->flags, FULL);
22100+ err = au_rdu_do(h_file, &arg);
22101+ AuTraceErr(err);
22102+ if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err))
22103+ break;
22104+ }
22105+ AuDbg("rent %llu\n", rdu->rent);
22106+
22107+ if (!err && !au_ftest_rdu(cookie->flags, CONT)) {
22108+ rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH);
22109+ au_fset_rdu(cookie->flags, CONT);
22110+ cookie->generation = au_figen(file);
22111+ }
22112+
22113+ ii_read_lock_child(inode);
22114+ fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibstart(inode)));
22115+ ii_read_unlock(inode);
22116+
4f0767ce 22117+out_unlock:
1308ab2a 22118+ fi_read_unlock(file);
027c5e7a 22119+out_si:
1308ab2a 22120+ si_read_unlock(arg.sb);
4f0767ce 22121+out_mtx:
1308ab2a 22122+ mutex_unlock(&inode->i_mutex);
4f0767ce 22123+out:
1308ab2a 22124+ AuTraceErr(err);
22125+ return err;
22126+}
22127+
22128+static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu)
22129+{
22130+ int err;
22131+ ino_t ino;
22132+ unsigned long long nent;
22133+ union au_rdu_ent_ul *u;
22134+ struct au_rdu_ent ent;
22135+ struct super_block *sb;
22136+
22137+ err = 0;
22138+ nent = rdu->nent;
22139+ u = &rdu->ent;
22140+ sb = file->f_dentry->d_sb;
22141+ si_read_lock(sb, AuLock_FLUSH);
22142+ while (nent-- > 0) {
9dbd164d 22143+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 22144+ err = copy_from_user(&ent, u->e, sizeof(ent));
4a4d8108
AM
22145+ if (!err)
22146+ err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino));
1308ab2a 22147+ if (unlikely(err)) {
22148+ err = -EFAULT;
22149+ AuTraceErr(err);
22150+ break;
22151+ }
22152+
22153+ /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */
22154+ if (!ent.wh)
22155+ err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino);
22156+ else
22157+ err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type,
22158+ &ino);
22159+ if (unlikely(err)) {
22160+ AuTraceErr(err);
22161+ break;
22162+ }
22163+
22164+ err = __put_user(ino, &u->e->ino);
22165+ if (unlikely(err)) {
22166+ err = -EFAULT;
22167+ AuTraceErr(err);
22168+ break;
22169+ }
22170+ u->ul += au_rdu_len(ent.nlen);
22171+ }
22172+ si_read_unlock(sb);
22173+
22174+ return err;
22175+}
22176+
22177+/* ---------------------------------------------------------------------- */
22178+
22179+static int au_rdu_verify(struct aufs_rdu *rdu)
22180+{
b752ccd1 22181+ AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | "
1308ab2a 22182+ "%llu, b%d, 0x%x, g%u}\n",
b752ccd1 22183+ rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ],
1308ab2a 22184+ rdu->blk,
22185+ rdu->rent, rdu->shwh, rdu->full,
22186+ rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags,
22187+ rdu->cookie.generation);
dece6358 22188+
b752ccd1 22189+ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu))
1308ab2a 22190+ return 0;
dece6358 22191+
b752ccd1
AM
22192+ AuDbg("%u:%u\n",
22193+ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu));
1308ab2a 22194+ return -EINVAL;
22195+}
22196+
22197+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
dece6358 22198+{
1308ab2a 22199+ long err, e;
22200+ struct aufs_rdu rdu;
22201+ void __user *p = (void __user *)arg;
dece6358 22202+
1308ab2a 22203+ err = copy_from_user(&rdu, p, sizeof(rdu));
22204+ if (unlikely(err)) {
22205+ err = -EFAULT;
22206+ AuTraceErr(err);
22207+ goto out;
22208+ }
22209+ err = au_rdu_verify(&rdu);
dece6358
AM
22210+ if (unlikely(err))
22211+ goto out;
22212+
1308ab2a 22213+ switch (cmd) {
22214+ case AUFS_CTL_RDU:
22215+ err = au_rdu(file, &rdu);
22216+ if (unlikely(err))
22217+ break;
dece6358 22218+
1308ab2a 22219+ e = copy_to_user(p, &rdu, sizeof(rdu));
22220+ if (unlikely(e)) {
22221+ err = -EFAULT;
22222+ AuTraceErr(err);
22223+ }
22224+ break;
22225+ case AUFS_CTL_RDU_INO:
22226+ err = au_rdu_ino(file, &rdu);
22227+ break;
22228+
22229+ default:
4a4d8108 22230+ /* err = -ENOTTY; */
1308ab2a 22231+ err = -EINVAL;
22232+ }
dece6358 22233+
4f0767ce 22234+out:
1308ab2a 22235+ AuTraceErr(err);
22236+ return err;
1facf9fc 22237+}
b752ccd1
AM
22238+
22239+#ifdef CONFIG_COMPAT
22240+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
22241+{
22242+ long err, e;
22243+ struct aufs_rdu rdu;
22244+ void __user *p = compat_ptr(arg);
22245+
22246+ /* todo: get_user()? */
22247+ err = copy_from_user(&rdu, p, sizeof(rdu));
22248+ if (unlikely(err)) {
22249+ err = -EFAULT;
22250+ AuTraceErr(err);
22251+ goto out;
22252+ }
22253+ rdu.ent.e = compat_ptr(rdu.ent.ul);
22254+ err = au_rdu_verify(&rdu);
22255+ if (unlikely(err))
22256+ goto out;
22257+
22258+ switch (cmd) {
22259+ case AUFS_CTL_RDU:
22260+ err = au_rdu(file, &rdu);
22261+ if (unlikely(err))
22262+ break;
22263+
22264+ rdu.ent.ul = ptr_to_compat(rdu.ent.e);
22265+ rdu.tail.ul = ptr_to_compat(rdu.tail.e);
22266+ e = copy_to_user(p, &rdu, sizeof(rdu));
22267+ if (unlikely(e)) {
22268+ err = -EFAULT;
22269+ AuTraceErr(err);
22270+ }
22271+ break;
22272+ case AUFS_CTL_RDU_INO:
22273+ err = au_rdu_ino(file, &rdu);
22274+ break;
22275+
22276+ default:
22277+ /* err = -ENOTTY; */
22278+ err = -EINVAL;
22279+ }
22280+
4f0767ce 22281+out:
b752ccd1
AM
22282+ AuTraceErr(err);
22283+ return err;
22284+}
22285+#endif
7f207e10
AM
22286diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h
22287--- /usr/share/empty/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100
1716fcea 22288+++ linux/fs/aufs/rwsem.h 2013-02-19 08:40:03.950226347 +0100
f6c5ef8b 22289@@ -0,0 +1,188 @@
1facf9fc 22290+/*
7a9e40b8 22291+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 22292+ *
22293+ * This program, aufs is free software; you can redistribute it and/or modify
22294+ * it under the terms of the GNU General Public License as published by
22295+ * the Free Software Foundation; either version 2 of the License, or
22296+ * (at your option) any later version.
dece6358
AM
22297+ *
22298+ * This program is distributed in the hope that it will be useful,
22299+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22300+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22301+ * GNU General Public License for more details.
22302+ *
22303+ * You should have received a copy of the GNU General Public License
22304+ * along with this program; if not, write to the Free Software
22305+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 22306+ */
22307+
22308+/*
22309+ * simple read-write semaphore wrappers
22310+ */
22311+
22312+#ifndef __AUFS_RWSEM_H__
22313+#define __AUFS_RWSEM_H__
22314+
22315+#ifdef __KERNEL__
22316+
4a4d8108 22317+#include "debug.h"
dece6358
AM
22318+
22319+struct au_rwsem {
22320+ struct rw_semaphore rwsem;
22321+#ifdef CONFIG_AUFS_DEBUG
22322+ /* just for debugging, not almighty counter */
22323+ atomic_t rcnt, wcnt;
22324+#endif
22325+};
22326+
22327+#ifdef CONFIG_AUFS_DEBUG
22328+#define AuDbgCntInit(rw) do { \
22329+ atomic_set(&(rw)->rcnt, 0); \
22330+ atomic_set(&(rw)->wcnt, 0); \
22331+ smp_mb(); /* atomic set */ \
22332+} while (0)
22333+
e49829fe 22334+#define AuDbgRcntInc(rw) atomic_inc(&(rw)->rcnt)
dece6358 22335+#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0)
e49829fe 22336+#define AuDbgWcntInc(rw) atomic_inc(&(rw)->wcnt)
dece6358
AM
22337+#define AuDbgWcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->wcnt) < 0)
22338+#else
22339+#define AuDbgCntInit(rw) do {} while (0)
22340+#define AuDbgRcntInc(rw) do {} while (0)
22341+#define AuDbgRcntDec(rw) do {} while (0)
22342+#define AuDbgWcntInc(rw) do {} while (0)
22343+#define AuDbgWcntDec(rw) do {} while (0)
22344+#endif /* CONFIG_AUFS_DEBUG */
22345+
22346+/* to debug easier, do not make them inlined functions */
22347+#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->rwsem.wait_list))
22348+/* rwsem_is_locked() is unusable */
22349+#define AuRwMustReadLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0)
22350+#define AuRwMustWriteLock(rw) AuDebugOn(atomic_read(&(rw)->wcnt) <= 0)
22351+#define AuRwMustAnyLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0 \
22352+ && atomic_read(&(rw)->wcnt) <= 0)
22353+#define AuRwDestroy(rw) AuDebugOn(atomic_read(&(rw)->rcnt) \
22354+ || atomic_read(&(rw)->wcnt))
22355+
e49829fe
JR
22356+#define au_rw_class(rw, key) lockdep_set_class(&(rw)->rwsem, key)
22357+
dece6358
AM
22358+static inline void au_rw_init(struct au_rwsem *rw)
22359+{
22360+ AuDbgCntInit(rw);
22361+ init_rwsem(&rw->rwsem);
22362+}
22363+
22364+static inline void au_rw_init_wlock(struct au_rwsem *rw)
22365+{
22366+ au_rw_init(rw);
22367+ down_write(&rw->rwsem);
22368+ AuDbgWcntInc(rw);
22369+}
22370+
22371+static inline void au_rw_init_wlock_nested(struct au_rwsem *rw,
22372+ unsigned int lsc)
22373+{
22374+ au_rw_init(rw);
22375+ down_write_nested(&rw->rwsem, lsc);
22376+ AuDbgWcntInc(rw);
22377+}
22378+
22379+static inline void au_rw_read_lock(struct au_rwsem *rw)
22380+{
22381+ down_read(&rw->rwsem);
22382+ AuDbgRcntInc(rw);
22383+}
22384+
22385+static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc)
22386+{
22387+ down_read_nested(&rw->rwsem, lsc);
22388+ AuDbgRcntInc(rw);
22389+}
22390+
22391+static inline void au_rw_read_unlock(struct au_rwsem *rw)
22392+{
22393+ AuRwMustReadLock(rw);
22394+ AuDbgRcntDec(rw);
22395+ up_read(&rw->rwsem);
22396+}
22397+
22398+static inline void au_rw_dgrade_lock(struct au_rwsem *rw)
22399+{
22400+ AuRwMustWriteLock(rw);
22401+ AuDbgRcntInc(rw);
22402+ AuDbgWcntDec(rw);
22403+ downgrade_write(&rw->rwsem);
22404+}
22405+
22406+static inline void au_rw_write_lock(struct au_rwsem *rw)
22407+{
22408+ down_write(&rw->rwsem);
22409+ AuDbgWcntInc(rw);
22410+}
22411+
22412+static inline void au_rw_write_lock_nested(struct au_rwsem *rw,
22413+ unsigned int lsc)
22414+{
22415+ down_write_nested(&rw->rwsem, lsc);
22416+ AuDbgWcntInc(rw);
22417+}
1facf9fc 22418+
dece6358
AM
22419+static inline void au_rw_write_unlock(struct au_rwsem *rw)
22420+{
22421+ AuRwMustWriteLock(rw);
22422+ AuDbgWcntDec(rw);
22423+ up_write(&rw->rwsem);
22424+}
22425+
22426+/* why is not _nested version defined */
22427+static inline int au_rw_read_trylock(struct au_rwsem *rw)
22428+{
22429+ int ret = down_read_trylock(&rw->rwsem);
22430+ if (ret)
22431+ AuDbgRcntInc(rw);
22432+ return ret;
22433+}
22434+
22435+static inline int au_rw_write_trylock(struct au_rwsem *rw)
22436+{
22437+ int ret = down_write_trylock(&rw->rwsem);
22438+ if (ret)
22439+ AuDbgWcntInc(rw);
22440+ return ret;
22441+}
22442+
22443+#undef AuDbgCntInit
22444+#undef AuDbgRcntInc
22445+#undef AuDbgRcntDec
22446+#undef AuDbgWcntInc
22447+#undef AuDbgWcntDec
1facf9fc 22448+
22449+#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
22450+static inline void prefix##_read_lock(param) \
dece6358 22451+{ au_rw_read_lock(rwsem); } \
1facf9fc 22452+static inline void prefix##_write_lock(param) \
dece6358 22453+{ au_rw_write_lock(rwsem); } \
1facf9fc 22454+static inline int prefix##_read_trylock(param) \
dece6358 22455+{ return au_rw_read_trylock(rwsem); } \
1facf9fc 22456+static inline int prefix##_write_trylock(param) \
dece6358 22457+{ return au_rw_write_trylock(rwsem); }
1facf9fc 22458+/* why is not _nested version defined */
22459+/* static inline void prefix##_read_trylock_nested(param, lsc)
dece6358 22460+{ au_rw_read_trylock_nested(rwsem, lsc)); }
1facf9fc 22461+static inline void prefix##_write_trylock_nestd(param, lsc)
dece6358 22462+{ au_rw_write_trylock_nested(rwsem, lsc); } */
1facf9fc 22463+
22464+#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
22465+static inline void prefix##_read_unlock(param) \
dece6358 22466+{ au_rw_read_unlock(rwsem); } \
1facf9fc 22467+static inline void prefix##_write_unlock(param) \
dece6358 22468+{ au_rw_write_unlock(rwsem); } \
1facf9fc 22469+static inline void prefix##_downgrade_lock(param) \
dece6358 22470+{ au_rw_dgrade_lock(rwsem); }
1facf9fc 22471+
22472+#define AuSimpleRwsemFuncs(prefix, param, rwsem) \
22473+ AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
22474+ AuSimpleUnlockRwsemFuncs(prefix, param, rwsem)
22475+
22476+#endif /* __KERNEL__ */
22477+#endif /* __AUFS_RWSEM_H__ */
7f207e10
AM
22478diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
22479--- /usr/share/empty/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100
1716fcea 22480+++ linux/fs/aufs/sbinfo.c 2013-02-19 08:40:03.950226347 +0100
f6c5ef8b 22481@@ -0,0 +1,343 @@
1facf9fc 22482+/*
7a9e40b8 22483+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 22484+ *
22485+ * This program, aufs is free software; you can redistribute it and/or modify
22486+ * it under the terms of the GNU General Public License as published by
22487+ * the Free Software Foundation; either version 2 of the License, or
22488+ * (at your option) any later version.
dece6358
AM
22489+ *
22490+ * This program is distributed in the hope that it will be useful,
22491+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22492+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22493+ * GNU General Public License for more details.
22494+ *
22495+ * You should have received a copy of the GNU General Public License
22496+ * along with this program; if not, write to the Free Software
22497+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 22498+ */
22499+
22500+/*
22501+ * superblock private data
22502+ */
22503+
22504+#include "aufs.h"
22505+
22506+/*
22507+ * they are necessary regardless sysfs is disabled.
22508+ */
22509+void au_si_free(struct kobject *kobj)
22510+{
22511+ struct au_sbinfo *sbinfo;
b752ccd1 22512+ char *locked __maybe_unused; /* debug only */
1facf9fc 22513+
22514+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
22515+ AuDebugOn(!list_empty(&sbinfo->si_plink.head));
e49829fe 22516+ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
1facf9fc 22517+
e49829fe 22518+ au_rw_write_lock(&sbinfo->si_rwsem);
1facf9fc 22519+ au_br_free(sbinfo);
e49829fe 22520+ au_rw_write_unlock(&sbinfo->si_rwsem);
b752ccd1
AM
22521+
22522+ AuDebugOn(radix_tree_gang_lookup
22523+ (&sbinfo->au_si_pid.tree, (void **)&locked,
22524+ /*first_index*/PID_MAX_DEFAULT - 1,
22525+ /*max_items*/sizeof(locked)/sizeof(*locked)));
22526+
1facf9fc 22527+ kfree(sbinfo->si_branch);
b752ccd1 22528+ kfree(sbinfo->au_si_pid.bitmap);
1facf9fc 22529+ mutex_destroy(&sbinfo->si_xib_mtx);
dece6358 22530+ AuRwDestroy(&sbinfo->si_rwsem);
1facf9fc 22531+
22532+ kfree(sbinfo);
22533+}
22534+
22535+int au_si_alloc(struct super_block *sb)
22536+{
22537+ int err;
22538+ struct au_sbinfo *sbinfo;
e49829fe 22539+ static struct lock_class_key aufs_si;
1facf9fc 22540+
22541+ err = -ENOMEM;
4a4d8108 22542+ sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS);
1facf9fc 22543+ if (unlikely(!sbinfo))
22544+ goto out;
22545+
b752ccd1
AM
22546+ BUILD_BUG_ON(sizeof(unsigned long) !=
22547+ sizeof(*sbinfo->au_si_pid.bitmap));
22548+ sbinfo->au_si_pid.bitmap = kcalloc(BITS_TO_LONGS(PID_MAX_DEFAULT),
22549+ sizeof(*sbinfo->au_si_pid.bitmap),
22550+ GFP_NOFS);
22551+ if (unlikely(!sbinfo->au_si_pid.bitmap))
22552+ goto out_sbinfo;
22553+
1facf9fc 22554+ /* will be reallocated separately */
22555+ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
22556+ if (unlikely(!sbinfo->si_branch))
b752ccd1 22557+ goto out_pidmap;
1facf9fc 22558+
1facf9fc 22559+ err = sysaufs_si_init(sbinfo);
22560+ if (unlikely(err))
22561+ goto out_br;
22562+
22563+ au_nwt_init(&sbinfo->si_nowait);
dece6358 22564+ au_rw_init_wlock(&sbinfo->si_rwsem);
e49829fe 22565+ au_rw_class(&sbinfo->si_rwsem, &aufs_si);
b752ccd1
AM
22566+ spin_lock_init(&sbinfo->au_si_pid.tree_lock);
22567+ INIT_RADIX_TREE(&sbinfo->au_si_pid.tree, GFP_ATOMIC | __GFP_NOFAIL);
22568+
7f207e10 22569+ atomic_long_set(&sbinfo->si_ninodes, 0);
7f207e10
AM
22570+ atomic_long_set(&sbinfo->si_nfiles, 0);
22571+
1facf9fc 22572+ sbinfo->si_bend = -1;
1facf9fc 22573+
22574+ sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
22575+ sbinfo->si_wbr_create = AuWbrCreate_Def;
4a4d8108
AM
22576+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup;
22577+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create;
1facf9fc 22578+
e49829fe 22579+ sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
1facf9fc 22580+
1facf9fc 22581+ mutex_init(&sbinfo->si_xib_mtx);
1facf9fc 22582+ sbinfo->si_xino_brid = -1;
22583+ /* leave si_xib_last_pindex and si_xib_next_bit */
22584+
e49829fe 22585+ sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
1facf9fc 22586+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
22587+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
22588+ sbinfo->si_dirwh = AUFS_DIRWH_DEF;
22589+
22590+ au_spl_init(&sbinfo->si_plink);
22591+ init_waitqueue_head(&sbinfo->si_plink_wq);
4a4d8108 22592+ spin_lock_init(&sbinfo->si_plink_maint_lock);
1facf9fc 22593+
22594+ /* leave other members for sysaufs and si_mnt. */
22595+ sbinfo->si_sb = sb;
22596+ sb->s_fs_info = sbinfo;
b752ccd1 22597+ si_pid_set(sb);
1facf9fc 22598+ au_debug_sbinfo_init(sbinfo);
22599+ return 0; /* success */
22600+
4f0767ce 22601+out_br:
1facf9fc 22602+ kfree(sbinfo->si_branch);
4f0767ce 22603+out_pidmap:
b752ccd1 22604+ kfree(sbinfo->au_si_pid.bitmap);
4f0767ce 22605+out_sbinfo:
1facf9fc 22606+ kfree(sbinfo);
4f0767ce 22607+out:
1facf9fc 22608+ return err;
22609+}
22610+
22611+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr)
22612+{
22613+ int err, sz;
22614+ struct au_branch **brp;
22615+
dece6358
AM
22616+ AuRwMustWriteLock(&sbinfo->si_rwsem);
22617+
1facf9fc 22618+ err = -ENOMEM;
22619+ sz = sizeof(*brp) * (sbinfo->si_bend + 1);
22620+ if (unlikely(!sz))
22621+ sz = sizeof(*brp);
22622+ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS);
22623+ if (brp) {
22624+ sbinfo->si_branch = brp;
22625+ err = 0;
22626+ }
22627+
22628+ return err;
22629+}
22630+
22631+/* ---------------------------------------------------------------------- */
22632+
22633+unsigned int au_sigen_inc(struct super_block *sb)
22634+{
22635+ unsigned int gen;
22636+
dece6358
AM
22637+ SiMustWriteLock(sb);
22638+
1facf9fc 22639+ gen = ++au_sbi(sb)->si_generation;
22640+ au_update_digen(sb->s_root);
537831f9 22641+ au_update_iigen(sb->s_root->d_inode, /*half*/0);
1facf9fc 22642+ sb->s_root->d_inode->i_version++;
22643+ return gen;
22644+}
22645+
22646+aufs_bindex_t au_new_br_id(struct super_block *sb)
22647+{
22648+ aufs_bindex_t br_id;
22649+ int i;
22650+ struct au_sbinfo *sbinfo;
22651+
dece6358
AM
22652+ SiMustWriteLock(sb);
22653+
1facf9fc 22654+ sbinfo = au_sbi(sb);
22655+ for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
22656+ br_id = ++sbinfo->si_last_br_id;
7f207e10 22657+ AuDebugOn(br_id < 0);
1facf9fc 22658+ if (br_id && au_br_index(sb, br_id) < 0)
22659+ return br_id;
22660+ }
22661+
22662+ return -1;
22663+}
22664+
22665+/* ---------------------------------------------------------------------- */
22666+
e49829fe
JR
22667+/* it is ok that new 'nwt' tasks are appended while we are sleeping */
22668+int si_read_lock(struct super_block *sb, int flags)
22669+{
22670+ int err;
22671+
22672+ err = 0;
22673+ if (au_ftest_lock(flags, FLUSH))
22674+ au_nwt_flush(&au_sbi(sb)->si_nowait);
22675+
22676+ si_noflush_read_lock(sb);
22677+ err = au_plink_maint(sb, flags);
22678+ if (unlikely(err))
22679+ si_read_unlock(sb);
22680+
22681+ return err;
22682+}
22683+
22684+int si_write_lock(struct super_block *sb, int flags)
22685+{
22686+ int err;
22687+
22688+ if (au_ftest_lock(flags, FLUSH))
22689+ au_nwt_flush(&au_sbi(sb)->si_nowait);
22690+
22691+ si_noflush_write_lock(sb);
22692+ err = au_plink_maint(sb, flags);
22693+ if (unlikely(err))
22694+ si_write_unlock(sb);
22695+
22696+ return err;
22697+}
22698+
1facf9fc 22699+/* dentry and super_block lock. call at entry point */
e49829fe 22700+int aufs_read_lock(struct dentry *dentry, int flags)
1facf9fc 22701+{
e49829fe 22702+ int err;
027c5e7a 22703+ struct super_block *sb;
e49829fe 22704+
027c5e7a
AM
22705+ sb = dentry->d_sb;
22706+ err = si_read_lock(sb, flags);
22707+ if (unlikely(err))
22708+ goto out;
22709+
22710+ if (au_ftest_lock(flags, DW))
22711+ di_write_lock_child(dentry);
22712+ else
22713+ di_read_lock_child(dentry, flags);
22714+
22715+ if (au_ftest_lock(flags, GEN)) {
22716+ err = au_digen_test(dentry, au_sigen(sb));
22717+ AuDebugOn(!err && au_dbrange_test(dentry));
22718+ if (unlikely(err))
22719+ aufs_read_unlock(dentry, flags);
e49829fe
JR
22720+ }
22721+
027c5e7a 22722+out:
e49829fe 22723+ return err;
1facf9fc 22724+}
22725+
22726+void aufs_read_unlock(struct dentry *dentry, int flags)
22727+{
22728+ if (au_ftest_lock(flags, DW))
22729+ di_write_unlock(dentry);
22730+ else
22731+ di_read_unlock(dentry, flags);
22732+ si_read_unlock(dentry->d_sb);
22733+}
22734+
22735+void aufs_write_lock(struct dentry *dentry)
22736+{
e49829fe 22737+ si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW);
1facf9fc 22738+ di_write_lock_child(dentry);
22739+}
22740+
22741+void aufs_write_unlock(struct dentry *dentry)
22742+{
22743+ di_write_unlock(dentry);
22744+ si_write_unlock(dentry->d_sb);
22745+}
22746+
e49829fe 22747+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
1facf9fc 22748+{
e49829fe 22749+ int err;
027c5e7a
AM
22750+ unsigned int sigen;
22751+ struct super_block *sb;
e49829fe 22752+
027c5e7a
AM
22753+ sb = d1->d_sb;
22754+ err = si_read_lock(sb, flags);
22755+ if (unlikely(err))
22756+ goto out;
22757+
22758+ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR));
22759+
22760+ if (au_ftest_lock(flags, GEN)) {
22761+ sigen = au_sigen(sb);
22762+ err = au_digen_test(d1, sigen);
22763+ AuDebugOn(!err && au_dbrange_test(d1));
22764+ if (!err) {
22765+ err = au_digen_test(d2, sigen);
22766+ AuDebugOn(!err && au_dbrange_test(d2));
22767+ }
22768+ if (unlikely(err))
22769+ aufs_read_and_write_unlock2(d1, d2);
22770+ }
22771+
22772+out:
e49829fe 22773+ return err;
1facf9fc 22774+}
22775+
22776+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
22777+{
22778+ di_write_unlock2(d1, d2);
22779+ si_read_unlock(d1->d_sb);
22780+}
b752ccd1
AM
22781+
22782+/* ---------------------------------------------------------------------- */
22783+
22784+int si_pid_test_slow(struct super_block *sb)
22785+{
22786+ void *p;
22787+
22788+ rcu_read_lock();
22789+ p = radix_tree_lookup(&au_sbi(sb)->au_si_pid.tree, current->pid);
22790+ rcu_read_unlock();
22791+
027c5e7a 22792+ return (long)!!p;
b752ccd1
AM
22793+}
22794+
22795+void si_pid_set_slow(struct super_block *sb)
22796+{
22797+ int err;
22798+ struct au_sbinfo *sbinfo;
22799+
22800+ AuDebugOn(si_pid_test_slow(sb));
22801+
22802+ sbinfo = au_sbi(sb);
22803+ err = radix_tree_preload(GFP_NOFS | __GFP_NOFAIL);
22804+ AuDebugOn(err);
22805+ spin_lock(&sbinfo->au_si_pid.tree_lock);
22806+ err = radix_tree_insert(&sbinfo->au_si_pid.tree, current->pid,
027c5e7a 22807+ /*any valid ptr*/sb);
b752ccd1
AM
22808+ spin_unlock(&sbinfo->au_si_pid.tree_lock);
22809+ AuDebugOn(err);
22810+ radix_tree_preload_end();
22811+}
22812+
22813+void si_pid_clr_slow(struct super_block *sb)
22814+{
22815+ void *p;
22816+ struct au_sbinfo *sbinfo;
22817+
22818+ AuDebugOn(!si_pid_test_slow(sb));
22819+
22820+ sbinfo = au_sbi(sb);
22821+ spin_lock(&sbinfo->au_si_pid.tree_lock);
22822+ p = radix_tree_delete(&sbinfo->au_si_pid.tree, current->pid);
22823+ spin_unlock(&sbinfo->au_si_pid.tree_lock);
b752ccd1 22824+}
7f207e10
AM
22825diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h
22826--- /usr/share/empty/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100
1716fcea 22827+++ linux/fs/aufs/spl.h 2013-02-19 08:40:03.950226347 +0100
f6c5ef8b 22828@@ -0,0 +1,62 @@
1facf9fc 22829+/*
7a9e40b8 22830+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 22831+ *
22832+ * This program, aufs is free software; you can redistribute it and/or modify
22833+ * it under the terms of the GNU General Public License as published by
22834+ * the Free Software Foundation; either version 2 of the License, or
22835+ * (at your option) any later version.
dece6358
AM
22836+ *
22837+ * This program is distributed in the hope that it will be useful,
22838+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22839+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22840+ * GNU General Public License for more details.
22841+ *
22842+ * You should have received a copy of the GNU General Public License
22843+ * along with this program; if not, write to the Free Software
22844+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 22845+ */
22846+
22847+/*
22848+ * simple list protected by a spinlock
22849+ */
22850+
22851+#ifndef __AUFS_SPL_H__
22852+#define __AUFS_SPL_H__
22853+
22854+#ifdef __KERNEL__
22855+
1facf9fc 22856+struct au_splhead {
22857+ spinlock_t spin;
22858+ struct list_head head;
22859+};
22860+
22861+static inline void au_spl_init(struct au_splhead *spl)
22862+{
22863+ spin_lock_init(&spl->spin);
22864+ INIT_LIST_HEAD(&spl->head);
22865+}
22866+
22867+static inline void au_spl_add(struct list_head *list, struct au_splhead *spl)
22868+{
22869+ spin_lock(&spl->spin);
22870+ list_add(list, &spl->head);
22871+ spin_unlock(&spl->spin);
22872+}
22873+
22874+static inline void au_spl_del(struct list_head *list, struct au_splhead *spl)
22875+{
22876+ spin_lock(&spl->spin);
22877+ list_del(list);
22878+ spin_unlock(&spl->spin);
22879+}
22880+
4a4d8108
AM
22881+static inline void au_spl_del_rcu(struct list_head *list,
22882+ struct au_splhead *spl)
22883+{
22884+ spin_lock(&spl->spin);
22885+ list_del_rcu(list);
22886+ spin_unlock(&spl->spin);
22887+}
22888+
1facf9fc 22889+#endif /* __KERNEL__ */
22890+#endif /* __AUFS_SPL_H__ */
7f207e10
AM
22891diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
22892--- /usr/share/empty/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
a2a7ad62 22893+++ linux/fs/aufs/super.c 2013-03-14 20:07:41.221457313 +0100
537831f9 22894@@ -0,0 +1,993 @@
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+ * mount and super_block operations
22915+ */
22916+
f6c5ef8b 22917+#include <linux/mm.h>
dece6358 22918+#include <linux/module.h>
1facf9fc 22919+#include <linux/seq_file.h>
22920+#include <linux/statfs.h>
7f207e10
AM
22921+#include <linux/vmalloc.h>
22922+#include <linux/writeback.h>
1facf9fc 22923+#include "aufs.h"
22924+
22925+/*
22926+ * super_operations
22927+ */
22928+static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
22929+{
22930+ struct au_icntnr *c;
22931+
22932+ c = au_cache_alloc_icntnr();
22933+ if (c) {
027c5e7a 22934+ au_icntnr_init(c);
1facf9fc 22935+ c->vfs_inode.i_version = 1; /* sigen(sb); */
22936+ c->iinfo.ii_hinode = NULL;
22937+ return &c->vfs_inode;
22938+ }
22939+ return NULL;
22940+}
22941+
027c5e7a
AM
22942+static void aufs_destroy_inode_cb(struct rcu_head *head)
22943+{
22944+ struct inode *inode = container_of(head, struct inode, i_rcu);
22945+
b4510431 22946+ INIT_HLIST_HEAD(&inode->i_dentry);
027c5e7a
AM
22947+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
22948+}
22949+
1facf9fc 22950+static void aufs_destroy_inode(struct inode *inode)
22951+{
22952+ au_iinfo_fin(inode);
027c5e7a 22953+ call_rcu(&inode->i_rcu, aufs_destroy_inode_cb);
1facf9fc 22954+}
22955+
22956+struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
22957+{
22958+ struct inode *inode;
22959+ int err;
22960+
22961+ inode = iget_locked(sb, ino);
22962+ if (unlikely(!inode)) {
22963+ inode = ERR_PTR(-ENOMEM);
22964+ goto out;
22965+ }
22966+ if (!(inode->i_state & I_NEW))
22967+ goto out;
22968+
22969+ err = au_xigen_new(inode);
22970+ if (!err)
22971+ err = au_iinfo_init(inode);
22972+ if (!err)
22973+ inode->i_version++;
22974+ else {
22975+ iget_failed(inode);
22976+ inode = ERR_PTR(err);
22977+ }
22978+
4f0767ce 22979+out:
1facf9fc 22980+ /* never return NULL */
22981+ AuDebugOn(!inode);
22982+ AuTraceErrPtr(inode);
22983+ return inode;
22984+}
22985+
22986+/* lock free root dinfo */
22987+static int au_show_brs(struct seq_file *seq, struct super_block *sb)
22988+{
22989+ int err;
22990+ aufs_bindex_t bindex, bend;
22991+ struct path path;
4a4d8108 22992+ struct au_hdentry *hdp;
1facf9fc 22993+ struct au_branch *br;
1e00d052 22994+ char *perm;
1facf9fc 22995+
22996+ err = 0;
22997+ bend = au_sbend(sb);
4a4d8108 22998+ hdp = au_di(sb->s_root)->di_hdentry;
1facf9fc 22999+ for (bindex = 0; !err && bindex <= bend; bindex++) {
23000+ br = au_sbr(sb, bindex);
23001+ path.mnt = br->br_mnt;
4a4d8108 23002+ path.dentry = hdp[bindex].hd_dentry;
1facf9fc 23003+ err = au_seq_path(seq, &path);
1e00d052
AM
23004+ if (err > 0) {
23005+ perm = au_optstr_br_perm(br->br_perm);
23006+ if (perm) {
23007+ err = seq_printf(seq, "=%s", perm);
23008+ kfree(perm);
23009+ if (err == -1)
23010+ err = -E2BIG;
23011+ } else
23012+ err = -ENOMEM;
23013+ }
1facf9fc 23014+ if (!err && bindex != bend)
23015+ err = seq_putc(seq, ':');
23016+ }
23017+
23018+ return err;
23019+}
23020+
23021+static void au_show_wbr_create(struct seq_file *m, int v,
23022+ struct au_sbinfo *sbinfo)
23023+{
23024+ const char *pat;
23025+
dece6358
AM
23026+ AuRwMustAnyLock(&sbinfo->si_rwsem);
23027+
1facf9fc 23028+ seq_printf(m, ",create=");
23029+ pat = au_optstr_wbr_create(v);
23030+ switch (v) {
23031+ case AuWbrCreate_TDP:
23032+ case AuWbrCreate_RR:
23033+ case AuWbrCreate_MFS:
23034+ case AuWbrCreate_PMFS:
23035+ seq_printf(m, pat);
23036+ break;
23037+ case AuWbrCreate_MFSV:
23038+ seq_printf(m, /*pat*/"mfs:%lu",
e49829fe
JR
23039+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
23040+ / MSEC_PER_SEC);
1facf9fc 23041+ break;
23042+ case AuWbrCreate_PMFSV:
23043+ seq_printf(m, /*pat*/"pmfs:%lu",
e49829fe
JR
23044+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
23045+ / MSEC_PER_SEC);
1facf9fc 23046+ break;
23047+ case AuWbrCreate_MFSRR:
23048+ seq_printf(m, /*pat*/"mfsrr:%llu",
23049+ sbinfo->si_wbr_mfs.mfsrr_watermark);
23050+ break;
23051+ case AuWbrCreate_MFSRRV:
23052+ seq_printf(m, /*pat*/"mfsrr:%llu:%lu",
23053+ sbinfo->si_wbr_mfs.mfsrr_watermark,
e49829fe
JR
23054+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
23055+ / MSEC_PER_SEC);
1facf9fc 23056+ break;
23057+ }
23058+}
23059+
7eafdf33 23060+static int au_show_xino(struct seq_file *seq, struct super_block *sb)
1facf9fc 23061+{
23062+#ifdef CONFIG_SYSFS
23063+ return 0;
23064+#else
23065+ int err;
23066+ const int len = sizeof(AUFS_XINO_FNAME) - 1;
23067+ aufs_bindex_t bindex, brid;
1facf9fc 23068+ struct qstr *name;
23069+ struct file *f;
23070+ struct dentry *d, *h_root;
4a4d8108 23071+ struct au_hdentry *hdp;
1facf9fc 23072+
dece6358
AM
23073+ AuRwMustAnyLock(&sbinfo->si_rwsem);
23074+
1facf9fc 23075+ err = 0;
1facf9fc 23076+ f = au_sbi(sb)->si_xib;
23077+ if (!f)
23078+ goto out;
23079+
23080+ /* stop printing the default xino path on the first writable branch */
23081+ h_root = NULL;
23082+ brid = au_xino_brid(sb);
23083+ if (brid >= 0) {
23084+ bindex = au_br_index(sb, brid);
4a4d8108
AM
23085+ hdp = au_di(sb->s_root)->di_hdentry;
23086+ h_root = hdp[0 + bindex].hd_dentry;
1facf9fc 23087+ }
23088+ d = f->f_dentry;
23089+ name = &d->d_name;
23090+ /* safe ->d_parent because the file is unlinked */
23091+ if (d->d_parent == h_root
23092+ && name->len == len
23093+ && !memcmp(name->name, AUFS_XINO_FNAME, len))
23094+ goto out;
23095+
23096+ seq_puts(seq, ",xino=");
23097+ err = au_xino_path(seq, f);
23098+
4f0767ce 23099+out:
1facf9fc 23100+ return err;
23101+#endif
23102+}
23103+
23104+/* seq_file will re-call me in case of too long string */
7eafdf33 23105+static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
1facf9fc 23106+{
027c5e7a 23107+ int err;
1facf9fc 23108+ unsigned int mnt_flags, v;
23109+ struct super_block *sb;
23110+ struct au_sbinfo *sbinfo;
23111+
23112+#define AuBool(name, str) do { \
23113+ v = au_opt_test(mnt_flags, name); \
23114+ if (v != au_opt_test(AuOpt_Def, name)) \
23115+ seq_printf(m, ",%s" #str, v ? "" : "no"); \
23116+} while (0)
23117+
23118+#define AuStr(name, str) do { \
23119+ v = mnt_flags & AuOptMask_##name; \
23120+ if (v != (AuOpt_Def & AuOptMask_##name)) \
23121+ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
23122+} while (0)
23123+
23124+#define AuUInt(name, str, val) do { \
23125+ if (val != AUFS_##name##_DEF) \
23126+ seq_printf(m, "," #str "=%u", val); \
23127+} while (0)
23128+
23129+ /* lock free root dinfo */
7eafdf33 23130+ sb = dentry->d_sb;
1facf9fc 23131+ si_noflush_read_lock(sb);
23132+ sbinfo = au_sbi(sb);
23133+ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
23134+
23135+ mnt_flags = au_mntflags(sb);
23136+ if (au_opt_test(mnt_flags, XINO)) {
7eafdf33 23137+ err = au_show_xino(m, sb);
1facf9fc 23138+ if (unlikely(err))
23139+ goto out;
23140+ } else
23141+ seq_puts(m, ",noxino");
23142+
23143+ AuBool(TRUNC_XINO, trunc_xino);
23144+ AuStr(UDBA, udba);
dece6358 23145+ AuBool(SHWH, shwh);
1facf9fc 23146+ AuBool(PLINK, plink);
4a4d8108 23147+ AuBool(DIO, dio);
1facf9fc 23148+ /* AuBool(DIRPERM1, dirperm1); */
23149+ /* AuBool(REFROF, refrof); */
23150+
23151+ v = sbinfo->si_wbr_create;
23152+ if (v != AuWbrCreate_Def)
23153+ au_show_wbr_create(m, v, sbinfo);
23154+
23155+ v = sbinfo->si_wbr_copyup;
23156+ if (v != AuWbrCopyup_Def)
23157+ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
23158+
23159+ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
23160+ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
23161+ seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
23162+
23163+ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
23164+
027c5e7a
AM
23165+ v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC;
23166+ AuUInt(RDCACHE, rdcache, v);
1facf9fc 23167+
23168+ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
23169+ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
23170+
23171+ AuBool(SUM, sum);
23172+ /* AuBool(SUM_W, wsum); */
23173+ AuBool(WARN_PERM, warn_perm);
23174+ AuBool(VERBOSE, verbose);
23175+
4f0767ce 23176+out:
1facf9fc 23177+ /* be sure to print "br:" last */
23178+ if (!sysaufs_brs) {
23179+ seq_puts(m, ",br:");
23180+ au_show_brs(m, sb);
23181+ }
23182+ si_read_unlock(sb);
23183+ return 0;
23184+
1facf9fc 23185+#undef AuBool
23186+#undef AuStr
4a4d8108 23187+#undef AuUInt
1facf9fc 23188+}
23189+
23190+/* ---------------------------------------------------------------------- */
23191+
23192+/* sum mode which returns the summation for statfs(2) */
23193+
23194+static u64 au_add_till_max(u64 a, u64 b)
23195+{
23196+ u64 old;
23197+
23198+ old = a;
23199+ a += b;
92d182d2
AM
23200+ if (old <= a)
23201+ return a;
23202+ return ULLONG_MAX;
23203+}
23204+
23205+static u64 au_mul_till_max(u64 a, long mul)
23206+{
23207+ u64 old;
23208+
23209+ old = a;
23210+ a *= mul;
23211+ if (old <= a)
1facf9fc 23212+ return a;
23213+ return ULLONG_MAX;
23214+}
23215+
23216+static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
23217+{
23218+ int err;
92d182d2 23219+ long bsize, factor;
1facf9fc 23220+ u64 blocks, bfree, bavail, files, ffree;
23221+ aufs_bindex_t bend, bindex, i;
23222+ unsigned char shared;
7f207e10 23223+ struct path h_path;
1facf9fc 23224+ struct super_block *h_sb;
23225+
92d182d2
AM
23226+ err = 0;
23227+ bsize = LONG_MAX;
23228+ files = 0;
23229+ ffree = 0;
1facf9fc 23230+ blocks = 0;
23231+ bfree = 0;
23232+ bavail = 0;
1facf9fc 23233+ bend = au_sbend(sb);
92d182d2 23234+ for (bindex = 0; bindex <= bend; bindex++) {
7f207e10
AM
23235+ h_path.mnt = au_sbr_mnt(sb, bindex);
23236+ h_sb = h_path.mnt->mnt_sb;
1facf9fc 23237+ shared = 0;
92d182d2 23238+ for (i = 0; !shared && i < bindex; i++)
1facf9fc 23239+ shared = (au_sbr_sb(sb, i) == h_sb);
23240+ if (shared)
23241+ continue;
23242+
23243+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
23244+ h_path.dentry = h_path.mnt->mnt_root;
23245+ err = vfs_statfs(&h_path, buf);
1facf9fc 23246+ if (unlikely(err))
23247+ goto out;
23248+
92d182d2
AM
23249+ if (bsize > buf->f_bsize) {
23250+ /*
23251+ * we will reduce bsize, so we have to expand blocks
23252+ * etc. to match them again
23253+ */
23254+ factor = (bsize / buf->f_bsize);
23255+ blocks = au_mul_till_max(blocks, factor);
23256+ bfree = au_mul_till_max(bfree, factor);
23257+ bavail = au_mul_till_max(bavail, factor);
23258+ bsize = buf->f_bsize;
23259+ }
23260+
23261+ factor = (buf->f_bsize / bsize);
23262+ blocks = au_add_till_max(blocks,
23263+ au_mul_till_max(buf->f_blocks, factor));
23264+ bfree = au_add_till_max(bfree,
23265+ au_mul_till_max(buf->f_bfree, factor));
23266+ bavail = au_add_till_max(bavail,
23267+ au_mul_till_max(buf->f_bavail, factor));
1facf9fc 23268+ files = au_add_till_max(files, buf->f_files);
23269+ ffree = au_add_till_max(ffree, buf->f_ffree);
23270+ }
23271+
92d182d2 23272+ buf->f_bsize = bsize;
1facf9fc 23273+ buf->f_blocks = blocks;
23274+ buf->f_bfree = bfree;
23275+ buf->f_bavail = bavail;
23276+ buf->f_files = files;
23277+ buf->f_ffree = ffree;
92d182d2 23278+ buf->f_frsize = 0;
1facf9fc 23279+
4f0767ce 23280+out:
1facf9fc 23281+ return err;
23282+}
23283+
23284+static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
23285+{
23286+ int err;
7f207e10 23287+ struct path h_path;
1facf9fc 23288+ struct super_block *sb;
23289+
23290+ /* lock free root dinfo */
23291+ sb = dentry->d_sb;
23292+ si_noflush_read_lock(sb);
7f207e10 23293+ if (!au_opt_test(au_mntflags(sb), SUM)) {
1facf9fc 23294+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
23295+ h_path.mnt = au_sbr_mnt(sb, 0);
23296+ h_path.dentry = h_path.mnt->mnt_root;
23297+ err = vfs_statfs(&h_path, buf);
23298+ } else
1facf9fc 23299+ err = au_statfs_sum(sb, buf);
23300+ si_read_unlock(sb);
23301+
23302+ if (!err) {
23303+ buf->f_type = AUFS_SUPER_MAGIC;
4a4d8108 23304+ buf->f_namelen = AUFS_MAX_NAMELEN;
1facf9fc 23305+ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
23306+ }
23307+ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
23308+
23309+ return err;
23310+}
23311+
23312+/* ---------------------------------------------------------------------- */
23313+
537831f9
AM
23314+static int aufs_sync_fs(struct super_block *sb, int wait)
23315+{
23316+ int err, e;
23317+ aufs_bindex_t bend, bindex;
23318+ struct au_branch *br;
23319+ struct super_block *h_sb;
23320+
23321+ err = 0;
23322+ si_noflush_read_lock(sb);
23323+ bend = au_sbend(sb);
23324+ for (bindex = 0; bindex <= bend; bindex++) {
23325+ br = au_sbr(sb, bindex);
23326+ if (!au_br_writable(br->br_perm))
23327+ continue;
23328+
23329+ h_sb = au_sbr_sb(sb, bindex);
23330+ if (h_sb->s_op->sync_fs) {
23331+ e = h_sb->s_op->sync_fs(h_sb, wait);
23332+ if (unlikely(e && !err))
23333+ err = e;
23334+ /* go on even if an error happens */
23335+ }
23336+ }
23337+ si_read_unlock(sb);
23338+
23339+ return err;
23340+}
23341+
23342+/* ---------------------------------------------------------------------- */
23343+
1facf9fc 23344+/* final actions when unmounting a file system */
23345+static void aufs_put_super(struct super_block *sb)
23346+{
23347+ struct au_sbinfo *sbinfo;
23348+
23349+ sbinfo = au_sbi(sb);
23350+ if (!sbinfo)
23351+ return;
23352+
1facf9fc 23353+ dbgaufs_si_fin(sbinfo);
23354+ kobject_put(&sbinfo->si_kobj);
23355+}
23356+
23357+/* ---------------------------------------------------------------------- */
23358+
7f207e10
AM
23359+void au_array_free(void *array)
23360+{
23361+ if (array) {
23362+ if (!is_vmalloc_addr(array))
23363+ kfree(array);
23364+ else
23365+ vfree(array);
23366+ }
23367+}
23368+
23369+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg)
23370+{
23371+ void *array;
23372+ unsigned long long n;
23373+
23374+ array = NULL;
23375+ n = 0;
23376+ if (!*hint)
23377+ goto out;
23378+
23379+ if (*hint > ULLONG_MAX / sizeof(array)) {
23380+ array = ERR_PTR(-EMFILE);
23381+ pr_err("hint %llu\n", *hint);
23382+ goto out;
23383+ }
23384+
23385+ array = kmalloc(sizeof(array) * *hint, GFP_NOFS);
23386+ if (unlikely(!array))
23387+ array = vmalloc(sizeof(array) * *hint);
23388+ if (unlikely(!array)) {
23389+ array = ERR_PTR(-ENOMEM);
23390+ goto out;
23391+ }
23392+
23393+ n = cb(array, *hint, arg);
23394+ AuDebugOn(n > *hint);
23395+
23396+out:
23397+ *hint = n;
23398+ return array;
23399+}
23400+
23401+static unsigned long long au_iarray_cb(void *a,
23402+ unsigned long long max __maybe_unused,
23403+ void *arg)
23404+{
23405+ unsigned long long n;
23406+ struct inode **p, *inode;
23407+ struct list_head *head;
23408+
23409+ n = 0;
23410+ p = a;
23411+ head = arg;
2cbb1c4b 23412+ spin_lock(&inode_sb_list_lock);
7f207e10
AM
23413+ list_for_each_entry(inode, head, i_sb_list) {
23414+ if (!is_bad_inode(inode)
23415+ && au_ii(inode)->ii_bstart >= 0) {
2cbb1c4b
JR
23416+ spin_lock(&inode->i_lock);
23417+ if (atomic_read(&inode->i_count)) {
23418+ au_igrab(inode);
23419+ *p++ = inode;
23420+ n++;
23421+ AuDebugOn(n > max);
23422+ }
23423+ spin_unlock(&inode->i_lock);
7f207e10
AM
23424+ }
23425+ }
2cbb1c4b 23426+ spin_unlock(&inode_sb_list_lock);
7f207e10
AM
23427+
23428+ return n;
23429+}
23430+
23431+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max)
23432+{
23433+ *max = atomic_long_read(&au_sbi(sb)->si_ninodes);
23434+ return au_array_alloc(max, au_iarray_cb, &sb->s_inodes);
23435+}
23436+
23437+void au_iarray_free(struct inode **a, unsigned long long max)
23438+{
23439+ unsigned long long ull;
23440+
23441+ for (ull = 0; ull < max; ull++)
23442+ iput(a[ull]);
23443+ au_array_free(a);
23444+}
23445+
23446+/* ---------------------------------------------------------------------- */
23447+
1facf9fc 23448+/*
23449+ * refresh dentry and inode at remount time.
23450+ */
027c5e7a
AM
23451+/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */
23452+static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags,
23453+ struct dentry *parent)
1facf9fc 23454+{
23455+ int err;
1facf9fc 23456+
23457+ di_write_lock_child(dentry);
1facf9fc 23458+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
23459+ err = au_refresh_dentry(dentry, parent);
23460+ if (!err && dir_flags)
23461+ au_hn_reset(dentry->d_inode, dir_flags);
1facf9fc 23462+ di_read_unlock(parent, AuLock_IR);
1facf9fc 23463+ di_write_unlock(dentry);
23464+
23465+ return err;
23466+}
23467+
027c5e7a
AM
23468+static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
23469+ struct au_sbinfo *sbinfo,
23470+ const unsigned int dir_flags)
1facf9fc 23471+{
027c5e7a
AM
23472+ int err;
23473+ struct dentry *parent;
23474+ struct inode *inode;
23475+
23476+ err = 0;
23477+ parent = dget_parent(dentry);
23478+ if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
23479+ inode = dentry->d_inode;
23480+ if (inode) {
23481+ if (!S_ISDIR(inode->i_mode))
23482+ err = au_do_refresh(dentry, /*dir_flags*/0,
23483+ parent);
23484+ else {
23485+ err = au_do_refresh(dentry, dir_flags, parent);
23486+ if (unlikely(err))
23487+ au_fset_si(sbinfo, FAILED_REFRESH_DIR);
23488+ }
23489+ } else
23490+ err = au_do_refresh(dentry, /*dir_flags*/0, parent);
23491+ AuDbgDentry(dentry);
23492+ }
23493+ dput(parent);
23494+
23495+ AuTraceErr(err);
23496+ return err;
1facf9fc 23497+}
23498+
027c5e7a 23499+static int au_refresh_d(struct super_block *sb)
1facf9fc 23500+{
23501+ int err, i, j, ndentry, e;
027c5e7a 23502+ unsigned int sigen;
1facf9fc 23503+ struct au_dcsub_pages dpages;
23504+ struct au_dpage *dpage;
027c5e7a
AM
23505+ struct dentry **dentries, *d;
23506+ struct au_sbinfo *sbinfo;
23507+ struct dentry *root = sb->s_root;
23508+ const unsigned int dir_flags = au_hi_flags(root->d_inode, /*isdir*/1);
1facf9fc 23509+
027c5e7a
AM
23510+ err = au_dpages_init(&dpages, GFP_NOFS);
23511+ if (unlikely(err))
1facf9fc 23512+ goto out;
027c5e7a
AM
23513+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
23514+ if (unlikely(err))
1facf9fc 23515+ goto out_dpages;
1facf9fc 23516+
027c5e7a
AM
23517+ sigen = au_sigen(sb);
23518+ sbinfo = au_sbi(sb);
23519+ for (i = 0; i < dpages.ndpage; i++) {
1facf9fc 23520+ dpage = dpages.dpages + i;
23521+ dentries = dpage->dentries;
23522+ ndentry = dpage->ndentry;
027c5e7a 23523+ for (j = 0; j < ndentry; j++) {
1facf9fc 23524+ d = dentries[j];
027c5e7a
AM
23525+ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags);
23526+ if (unlikely(e && !err))
23527+ err = e;
23528+ /* go on even err */
1facf9fc 23529+ }
23530+ }
23531+
4f0767ce 23532+out_dpages:
1facf9fc 23533+ au_dpages_free(&dpages);
4f0767ce 23534+out:
1facf9fc 23535+ return err;
23536+}
23537+
027c5e7a 23538+static int au_refresh_i(struct super_block *sb)
1facf9fc 23539+{
027c5e7a
AM
23540+ int err, e;
23541+ unsigned int sigen;
23542+ unsigned long long max, ull;
23543+ struct inode *inode, **array;
1facf9fc 23544+
027c5e7a
AM
23545+ array = au_iarray_alloc(sb, &max);
23546+ err = PTR_ERR(array);
23547+ if (IS_ERR(array))
23548+ goto out;
1facf9fc 23549+
23550+ err = 0;
027c5e7a
AM
23551+ sigen = au_sigen(sb);
23552+ for (ull = 0; ull < max; ull++) {
23553+ inode = array[ull];
537831f9 23554+ if (au_iigen(inode, NULL) != sigen) {
1facf9fc 23555+ ii_write_lock_child(inode);
027c5e7a 23556+ e = au_refresh_hinode_self(inode);
1facf9fc 23557+ ii_write_unlock(inode);
23558+ if (unlikely(e)) {
027c5e7a 23559+ pr_err("error %d, i%lu\n", e, inode->i_ino);
1facf9fc 23560+ if (!err)
23561+ err = e;
23562+ /* go on even if err */
23563+ }
23564+ }
1facf9fc 23565+ }
23566+
027c5e7a 23567+ au_iarray_free(array, max);
1facf9fc 23568+
4f0767ce 23569+out:
1facf9fc 23570+ return err;
23571+}
23572+
027c5e7a 23573+static void au_remount_refresh(struct super_block *sb)
1facf9fc 23574+{
027c5e7a
AM
23575+ int err, e;
23576+ unsigned int udba;
23577+ aufs_bindex_t bindex, bend;
1facf9fc 23578+ struct dentry *root;
23579+ struct inode *inode;
027c5e7a 23580+ struct au_branch *br;
1facf9fc 23581+
23582+ au_sigen_inc(sb);
027c5e7a 23583+ au_fclr_si(au_sbi(sb), FAILED_REFRESH_DIR);
1facf9fc 23584+
23585+ root = sb->s_root;
23586+ DiMustNoWaiters(root);
23587+ inode = root->d_inode;
23588+ IiMustNoWaiters(inode);
1facf9fc 23589+
027c5e7a
AM
23590+ udba = au_opt_udba(sb);
23591+ bend = au_sbend(sb);
23592+ for (bindex = 0; bindex <= bend; bindex++) {
23593+ br = au_sbr(sb, bindex);
23594+ err = au_hnotify_reset_br(udba, br, br->br_perm);
1facf9fc 23595+ if (unlikely(err))
027c5e7a
AM
23596+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
23597+ bindex, err);
23598+ /* go on even if err */
1facf9fc 23599+ }
027c5e7a 23600+ au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
1facf9fc 23601+
027c5e7a
AM
23602+ di_write_unlock(root);
23603+ err = au_refresh_d(sb);
23604+ e = au_refresh_i(sb);
23605+ if (unlikely(e && !err))
23606+ err = e;
1facf9fc 23607+ /* aufs_write_lock() calls ..._child() */
23608+ di_write_lock_child(root);
027c5e7a
AM
23609+
23610+ au_cpup_attr_all(inode, /*force*/1);
23611+
23612+ if (unlikely(err))
23613+ AuIOErr("refresh failed, ignored, %d\n", err);
1facf9fc 23614+}
23615+
23616+/* stop extra interpretation of errno in mount(8), and strange error messages */
23617+static int cvt_err(int err)
23618+{
23619+ AuTraceErr(err);
23620+
23621+ switch (err) {
23622+ case -ENOENT:
23623+ case -ENOTDIR:
23624+ case -EEXIST:
23625+ case -EIO:
23626+ err = -EINVAL;
23627+ }
23628+ return err;
23629+}
23630+
23631+static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
23632+{
4a4d8108
AM
23633+ int err, do_dx;
23634+ unsigned int mntflags;
1facf9fc 23635+ struct au_opts opts;
23636+ struct dentry *root;
23637+ struct inode *inode;
23638+ struct au_sbinfo *sbinfo;
23639+
23640+ err = 0;
23641+ root = sb->s_root;
23642+ if (!data || !*data) {
e49829fe
JR
23643+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
23644+ if (!err) {
23645+ di_write_lock_child(root);
23646+ err = au_opts_verify(sb, *flags, /*pending*/0);
23647+ aufs_write_unlock(root);
23648+ }
1facf9fc 23649+ goto out;
23650+ }
23651+
23652+ err = -ENOMEM;
23653+ memset(&opts, 0, sizeof(opts));
23654+ opts.opt = (void *)__get_free_page(GFP_NOFS);
23655+ if (unlikely(!opts.opt))
23656+ goto out;
23657+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
23658+ opts.flags = AuOpts_REMOUNT;
23659+ opts.sb_flags = *flags;
23660+
23661+ /* parse it before aufs lock */
23662+ err = au_opts_parse(sb, data, &opts);
23663+ if (unlikely(err))
23664+ goto out_opts;
23665+
23666+ sbinfo = au_sbi(sb);
23667+ inode = root->d_inode;
23668+ mutex_lock(&inode->i_mutex);
e49829fe
JR
23669+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
23670+ if (unlikely(err))
23671+ goto out_mtx;
23672+ di_write_lock_child(root);
1facf9fc 23673+
23674+ /* au_opts_remount() may return an error */
23675+ err = au_opts_remount(sb, &opts);
23676+ au_opts_free(&opts);
23677+
027c5e7a
AM
23678+ if (au_ftest_opts(opts.flags, REFRESH))
23679+ au_remount_refresh(sb);
1facf9fc 23680+
4a4d8108
AM
23681+ if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
23682+ mntflags = au_mntflags(sb);
23683+ do_dx = !!au_opt_test(mntflags, DIO);
23684+ au_dy_arefresh(do_dx);
23685+ }
23686+
1facf9fc 23687+ aufs_write_unlock(root);
953406b4 23688+
e49829fe
JR
23689+out_mtx:
23690+ mutex_unlock(&inode->i_mutex);
4f0767ce 23691+out_opts:
1facf9fc 23692+ free_page((unsigned long)opts.opt);
4f0767ce 23693+out:
1facf9fc 23694+ err = cvt_err(err);
23695+ AuTraceErr(err);
23696+ return err;
23697+}
23698+
4a4d8108 23699+static const struct super_operations aufs_sop = {
1facf9fc 23700+ .alloc_inode = aufs_alloc_inode,
23701+ .destroy_inode = aufs_destroy_inode,
b752ccd1 23702+ /* always deleting, no clearing */
1facf9fc 23703+ .drop_inode = generic_delete_inode,
23704+ .show_options = aufs_show_options,
23705+ .statfs = aufs_statfs,
23706+ .put_super = aufs_put_super,
537831f9 23707+ .sync_fs = aufs_sync_fs,
1facf9fc 23708+ .remount_fs = aufs_remount_fs
23709+};
23710+
23711+/* ---------------------------------------------------------------------- */
23712+
23713+static int alloc_root(struct super_block *sb)
23714+{
23715+ int err;
23716+ struct inode *inode;
23717+ struct dentry *root;
23718+
23719+ err = -ENOMEM;
23720+ inode = au_iget_locked(sb, AUFS_ROOT_INO);
23721+ err = PTR_ERR(inode);
23722+ if (IS_ERR(inode))
23723+ goto out;
23724+
23725+ inode->i_op = &aufs_dir_iop;
23726+ inode->i_fop = &aufs_dir_fop;
23727+ inode->i_mode = S_IFDIR;
9dbd164d 23728+ set_nlink(inode, 2);
1facf9fc 23729+ unlock_new_inode(inode);
23730+
92d182d2 23731+ root = d_make_root(inode);
1facf9fc 23732+ if (unlikely(!root))
92d182d2 23733+ goto out;
1facf9fc 23734+ err = PTR_ERR(root);
23735+ if (IS_ERR(root))
92d182d2 23736+ goto out;
1facf9fc 23737+
4a4d8108 23738+ err = au_di_init(root);
1facf9fc 23739+ if (!err) {
23740+ sb->s_root = root;
23741+ return 0; /* success */
23742+ }
23743+ dput(root);
1facf9fc 23744+
4f0767ce 23745+out:
1facf9fc 23746+ return err;
1facf9fc 23747+}
23748+
23749+static int aufs_fill_super(struct super_block *sb, void *raw_data,
23750+ int silent __maybe_unused)
23751+{
23752+ int err;
23753+ struct au_opts opts;
23754+ struct dentry *root;
23755+ struct inode *inode;
23756+ char *arg = raw_data;
23757+
23758+ if (unlikely(!arg || !*arg)) {
23759+ err = -EINVAL;
4a4d8108 23760+ pr_err("no arg\n");
1facf9fc 23761+ goto out;
23762+ }
23763+
23764+ err = -ENOMEM;
23765+ memset(&opts, 0, sizeof(opts));
23766+ opts.opt = (void *)__get_free_page(GFP_NOFS);
23767+ if (unlikely(!opts.opt))
23768+ goto out;
23769+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
23770+ opts.sb_flags = sb->s_flags;
23771+
23772+ err = au_si_alloc(sb);
23773+ if (unlikely(err))
23774+ goto out_opts;
23775+
23776+ /* all timestamps always follow the ones on the branch */
23777+ sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
23778+ sb->s_op = &aufs_sop;
027c5e7a 23779+ sb->s_d_op = &aufs_dop;
1facf9fc 23780+ sb->s_magic = AUFS_SUPER_MAGIC;
23781+ sb->s_maxbytes = 0;
23782+ au_export_init(sb);
23783+
23784+ err = alloc_root(sb);
23785+ if (unlikely(err)) {
23786+ si_write_unlock(sb);
23787+ goto out_info;
23788+ }
23789+ root = sb->s_root;
23790+ inode = root->d_inode;
23791+
23792+ /*
23793+ * actually we can parse options regardless aufs lock here.
23794+ * but at remount time, parsing must be done before aufs lock.
23795+ * so we follow the same rule.
23796+ */
23797+ ii_write_lock_parent(inode);
23798+ aufs_write_unlock(root);
23799+ err = au_opts_parse(sb, arg, &opts);
23800+ if (unlikely(err))
23801+ goto out_root;
23802+
23803+ /* lock vfs_inode first, then aufs. */
23804+ mutex_lock(&inode->i_mutex);
1facf9fc 23805+ aufs_write_lock(root);
23806+ err = au_opts_mount(sb, &opts);
23807+ au_opts_free(&opts);
1facf9fc 23808+ aufs_write_unlock(root);
23809+ mutex_unlock(&inode->i_mutex);
4a4d8108
AM
23810+ if (!err)
23811+ goto out_opts; /* success */
1facf9fc 23812+
4f0767ce 23813+out_root:
1facf9fc 23814+ dput(root);
23815+ sb->s_root = NULL;
4f0767ce 23816+out_info:
2cbb1c4b 23817+ dbgaufs_si_fin(au_sbi(sb));
1facf9fc 23818+ kobject_put(&au_sbi(sb)->si_kobj);
23819+ sb->s_fs_info = NULL;
4f0767ce 23820+out_opts:
1facf9fc 23821+ free_page((unsigned long)opts.opt);
4f0767ce 23822+out:
1facf9fc 23823+ AuTraceErr(err);
23824+ err = cvt_err(err);
23825+ AuTraceErr(err);
23826+ return err;
23827+}
23828+
23829+/* ---------------------------------------------------------------------- */
23830+
027c5e7a
AM
23831+static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags,
23832+ const char *dev_name __maybe_unused,
23833+ void *raw_data)
1facf9fc 23834+{
027c5e7a 23835+ struct dentry *root;
1facf9fc 23836+ struct super_block *sb;
23837+
23838+ /* all timestamps always follow the ones on the branch */
23839+ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
027c5e7a
AM
23840+ root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super);
23841+ if (IS_ERR(root))
23842+ goto out;
23843+
23844+ sb = root->d_sb;
23845+ si_write_lock(sb, !AuLock_FLUSH);
23846+ sysaufs_brs_add(sb, 0);
23847+ si_write_unlock(sb);
23848+ au_sbilist_add(sb);
23849+
23850+out:
23851+ return root;
1facf9fc 23852+}
23853+
e49829fe
JR
23854+static void aufs_kill_sb(struct super_block *sb)
23855+{
23856+ struct au_sbinfo *sbinfo;
23857+
23858+ sbinfo = au_sbi(sb);
23859+ if (sbinfo) {
23860+ au_sbilist_del(sb);
23861+ aufs_write_lock(sb->s_root);
23862+ if (sbinfo->si_wbr_create_ops->fin)
23863+ sbinfo->si_wbr_create_ops->fin(sb);
23864+ if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
23865+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
027c5e7a 23866+ au_remount_refresh(sb);
e49829fe
JR
23867+ }
23868+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
23869+ au_plink_put(sb, /*verbose*/1);
23870+ au_xino_clr(sb);
1e00d052 23871+ sbinfo->si_sb = NULL;
e49829fe 23872+ aufs_write_unlock(sb->s_root);
e49829fe
JR
23873+ au_nwt_flush(&sbinfo->si_nowait);
23874+ }
23875+ generic_shutdown_super(sb);
23876+}
23877+
1facf9fc 23878+struct file_system_type aufs_fs_type = {
23879+ .name = AUFS_FSTYPE,
23880+ .fs_flags =
23881+ FS_RENAME_DOES_D_MOVE /* a race between rename and others */
23882+ | FS_REVAL_DOT, /* for NFS branch and udba */
027c5e7a 23883+ .mount = aufs_mount,
e49829fe 23884+ .kill_sb = aufs_kill_sb,
1facf9fc 23885+ /* no need to __module_get() and module_put(). */
23886+ .owner = THIS_MODULE,
23887+};
7f207e10
AM
23888diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
23889--- /usr/share/empty/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100
a2a7ad62
AM
23890+++ linux/fs/aufs/super.h 2013-03-14 20:07:18.764260309 +0100
23891@@ -0,0 +1,538 @@
1facf9fc 23892+/*
7a9e40b8 23893+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 23894+ *
23895+ * This program, aufs is free software; you can redistribute it and/or modify
23896+ * it under the terms of the GNU General Public License as published by
23897+ * the Free Software Foundation; either version 2 of the License, or
23898+ * (at your option) any later version.
dece6358
AM
23899+ *
23900+ * This program is distributed in the hope that it will be useful,
23901+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23902+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23903+ * GNU General Public License for more details.
23904+ *
23905+ * You should have received a copy of the GNU General Public License
23906+ * along with this program; if not, write to the Free Software
23907+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 23908+ */
23909+
23910+/*
23911+ * super_block operations
23912+ */
23913+
23914+#ifndef __AUFS_SUPER_H__
23915+#define __AUFS_SUPER_H__
23916+
23917+#ifdef __KERNEL__
23918+
23919+#include <linux/fs.h>
1facf9fc 23920+#include "rwsem.h"
23921+#include "spl.h"
23922+#include "wkq.h"
23923+
23924+typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *);
23925+typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t,
23926+ loff_t *);
23927+
23928+/* policies to select one among multiple writable branches */
23929+struct au_wbr_copyup_operations {
23930+ int (*copyup)(struct dentry *dentry);
23931+};
23932+
23933+struct au_wbr_create_operations {
23934+ int (*create)(struct dentry *dentry, int isdir);
23935+ int (*init)(struct super_block *sb);
23936+ int (*fin)(struct super_block *sb);
23937+};
23938+
23939+struct au_wbr_mfs {
23940+ struct mutex mfs_lock; /* protect this structure */
23941+ unsigned long mfs_jiffy;
23942+ unsigned long mfs_expire;
23943+ aufs_bindex_t mfs_bindex;
23944+
23945+ unsigned long long mfsrr_bytes;
23946+ unsigned long long mfsrr_watermark;
23947+};
23948+
1facf9fc 23949+struct au_branch;
23950+struct au_sbinfo {
23951+ /* nowait tasks in the system-wide workqueue */
23952+ struct au_nowait_tasks si_nowait;
23953+
b752ccd1
AM
23954+ /*
23955+ * tried sb->s_umount, but failed due to the dependecy between i_mutex.
23956+ * rwsem for au_sbinfo is necessary.
23957+ */
dece6358 23958+ struct au_rwsem si_rwsem;
1facf9fc 23959+
b752ccd1
AM
23960+ /* prevent recursive locking in deleting inode */
23961+ struct {
23962+ unsigned long *bitmap;
23963+ spinlock_t tree_lock;
23964+ struct radix_tree_root tree;
23965+ } au_si_pid;
23966+
7f207e10
AM
23967+ /*
23968+ * dirty approach to protect sb->sb_inodes and ->s_files from remount.
23969+ */
23970+ atomic_long_t si_ninodes, si_nfiles;
23971+
1facf9fc 23972+ /* branch management */
23973+ unsigned int si_generation;
23974+
23975+ /* see above flags */
23976+ unsigned char au_si_status;
23977+
23978+ aufs_bindex_t si_bend;
7f207e10
AM
23979+
23980+ /* dirty trick to keep br_id plus */
23981+ unsigned int si_last_br_id :
23982+ sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1;
1facf9fc 23983+ struct au_branch **si_branch;
23984+
23985+ /* policy to select a writable branch */
23986+ unsigned char si_wbr_copyup;
23987+ unsigned char si_wbr_create;
23988+ struct au_wbr_copyup_operations *si_wbr_copyup_ops;
23989+ struct au_wbr_create_operations *si_wbr_create_ops;
23990+
23991+ /* round robin */
23992+ atomic_t si_wbr_rr_next;
23993+
23994+ /* most free space */
23995+ struct au_wbr_mfs si_wbr_mfs;
23996+
23997+ /* mount flags */
23998+ /* include/asm-ia64/siginfo.h defines a macro named si_flags */
23999+ unsigned int si_mntflags;
24000+
24001+ /* external inode number (bitmap and translation table) */
24002+ au_readf_t si_xread;
24003+ au_writef_t si_xwrite;
24004+ struct file *si_xib;
24005+ struct mutex si_xib_mtx; /* protect xib members */
24006+ unsigned long *si_xib_buf;
24007+ unsigned long si_xib_last_pindex;
24008+ int si_xib_next_bit;
24009+ aufs_bindex_t si_xino_brid;
24010+ /* reserved for future use */
24011+ /* unsigned long long si_xib_limit; */ /* Max xib file size */
24012+
24013+#ifdef CONFIG_AUFS_EXPORT
24014+ /* i_generation */
24015+ struct file *si_xigen;
24016+ atomic_t si_xigen_next;
24017+#endif
24018+
24019+ /* vdir parameters */
e49829fe 24020+ unsigned long si_rdcache; /* max cache time in jiffies */
1facf9fc 24021+ unsigned int si_rdblk; /* deblk size */
24022+ unsigned int si_rdhash; /* hash size */
24023+
24024+ /*
24025+ * If the number of whiteouts are larger than si_dirwh, leave all of
24026+ * them after au_whtmp_ren to reduce the cost of rmdir(2).
24027+ * future fsck.aufs or kernel thread will remove them later.
24028+ * Otherwise, remove all whiteouts and the dir in rmdir(2).
24029+ */
24030+ unsigned int si_dirwh;
24031+
24032+ /*
24033+ * rename(2) a directory with all children.
24034+ */
24035+ /* reserved for future use */
24036+ /* int si_rendir; */
24037+
24038+ /* pseudo_link list */
24039+ struct au_splhead si_plink;
24040+ wait_queue_head_t si_plink_wq;
4a4d8108 24041+ spinlock_t si_plink_maint_lock;
e49829fe 24042+ pid_t si_plink_maint_pid;
1facf9fc 24043+
24044+ /*
24045+ * sysfs and lifetime management.
24046+ * this is not a small structure and it may be a waste of memory in case
24047+ * of sysfs is disabled, particulary when many aufs-es are mounted.
24048+ * but using sysfs is majority.
24049+ */
24050+ struct kobject si_kobj;
24051+#ifdef CONFIG_DEBUG_FS
24052+ struct dentry *si_dbgaufs, *si_dbgaufs_xib;
24053+#ifdef CONFIG_AUFS_EXPORT
24054+ struct dentry *si_dbgaufs_xigen;
24055+#endif
24056+#endif
24057+
e49829fe
JR
24058+#ifdef CONFIG_AUFS_SBILIST
24059+ struct list_head si_list;
24060+#endif
24061+
1facf9fc 24062+ /* dirty, necessary for unmounting, sysfs and sysrq */
24063+ struct super_block *si_sb;
24064+};
24065+
dece6358
AM
24066+/* sbinfo status flags */
24067+/*
24068+ * set true when refresh_dirs() failed at remount time.
24069+ * then try refreshing dirs at access time again.
24070+ * if it is false, refreshing dirs at access time is unnecesary
24071+ */
027c5e7a 24072+#define AuSi_FAILED_REFRESH_DIR 1
dece6358
AM
24073+static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
24074+ unsigned int flag)
24075+{
24076+ AuRwMustAnyLock(&sbi->si_rwsem);
24077+ return sbi->au_si_status & flag;
24078+}
24079+#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name)
24080+#define au_fset_si(sbinfo, name) do { \
24081+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
24082+ (sbinfo)->au_si_status |= AuSi_##name; \
24083+} while (0)
24084+#define au_fclr_si(sbinfo, name) do { \
24085+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
24086+ (sbinfo)->au_si_status &= ~AuSi_##name; \
24087+} while (0)
24088+
1facf9fc 24089+/* ---------------------------------------------------------------------- */
24090+
24091+/* policy to select one among writable branches */
4a4d8108
AM
24092+#define AuWbrCopyup(sbinfo, ...) \
24093+ ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__))
24094+#define AuWbrCreate(sbinfo, ...) \
24095+ ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__))
1facf9fc 24096+
24097+/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
24098+#define AuLock_DW 1 /* write-lock dentry */
24099+#define AuLock_IR (1 << 1) /* read-lock inode */
24100+#define AuLock_IW (1 << 2) /* write-lock inode */
24101+#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
24102+#define AuLock_DIR (1 << 4) /* target is a dir */
e49829fe
JR
24103+#define AuLock_NOPLM (1 << 5) /* return err in plm mode */
24104+#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */
027c5e7a 24105+#define AuLock_GEN (1 << 7) /* test digen/iigen */
1facf9fc 24106+#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
7f207e10
AM
24107+#define au_fset_lock(flags, name) \
24108+ do { (flags) |= AuLock_##name; } while (0)
24109+#define au_fclr_lock(flags, name) \
24110+ do { (flags) &= ~AuLock_##name; } while (0)
1facf9fc 24111+
24112+/* ---------------------------------------------------------------------- */
24113+
24114+/* super.c */
24115+extern struct file_system_type aufs_fs_type;
24116+struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
7f207e10
AM
24117+typedef unsigned long long (*au_arraycb_t)(void *array, unsigned long long max,
24118+ void *arg);
24119+void au_array_free(void *array);
24120+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg);
24121+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
24122+void au_iarray_free(struct inode **a, unsigned long long max);
1facf9fc 24123+
24124+/* sbinfo.c */
24125+void au_si_free(struct kobject *kobj);
24126+int au_si_alloc(struct super_block *sb);
24127+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr);
24128+
24129+unsigned int au_sigen_inc(struct super_block *sb);
24130+aufs_bindex_t au_new_br_id(struct super_block *sb);
24131+
e49829fe
JR
24132+int si_read_lock(struct super_block *sb, int flags);
24133+int si_write_lock(struct super_block *sb, int flags);
24134+int aufs_read_lock(struct dentry *dentry, int flags);
1facf9fc 24135+void aufs_read_unlock(struct dentry *dentry, int flags);
24136+void aufs_write_lock(struct dentry *dentry);
24137+void aufs_write_unlock(struct dentry *dentry);
e49829fe 24138+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
1facf9fc 24139+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
24140+
b752ccd1
AM
24141+int si_pid_test_slow(struct super_block *sb);
24142+void si_pid_set_slow(struct super_block *sb);
24143+void si_pid_clr_slow(struct super_block *sb);
24144+
1facf9fc 24145+/* wbr_policy.c */
24146+extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
24147+extern struct au_wbr_create_operations au_wbr_create_ops[];
24148+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
24149+
24150+/* ---------------------------------------------------------------------- */
24151+
24152+static inline struct au_sbinfo *au_sbi(struct super_block *sb)
24153+{
24154+ return sb->s_fs_info;
24155+}
24156+
24157+/* ---------------------------------------------------------------------- */
24158+
24159+#ifdef CONFIG_AUFS_EXPORT
a2a7ad62 24160+int au_test_nfsd(void);
1facf9fc 24161+void au_export_init(struct super_block *sb);
b752ccd1 24162+void au_xigen_inc(struct inode *inode);
1facf9fc 24163+int au_xigen_new(struct inode *inode);
24164+int au_xigen_set(struct super_block *sb, struct file *base);
24165+void au_xigen_clr(struct super_block *sb);
24166+
24167+static inline int au_busy_or_stale(void)
24168+{
b752ccd1 24169+ if (!au_test_nfsd())
1facf9fc 24170+ return -EBUSY;
24171+ return -ESTALE;
24172+}
24173+#else
b752ccd1 24174+AuStubInt0(au_test_nfsd, void)
a2a7ad62 24175+AuStubVoid(au_export_init, struct super_block *sb)
b752ccd1 24176+AuStubVoid(au_xigen_inc, struct inode *inode)
4a4d8108
AM
24177+AuStubInt0(au_xigen_new, struct inode *inode)
24178+AuStubInt0(au_xigen_set, struct super_block *sb, struct file *base)
24179+AuStubVoid(au_xigen_clr, struct super_block *sb)
1facf9fc 24180+static inline int au_busy_or_stale(void)
24181+{
24182+ return -EBUSY;
24183+}
24184+#endif /* CONFIG_AUFS_EXPORT */
24185+
24186+/* ---------------------------------------------------------------------- */
24187+
e49829fe
JR
24188+#ifdef CONFIG_AUFS_SBILIST
24189+/* module.c */
24190+extern struct au_splhead au_sbilist;
24191+
24192+static inline void au_sbilist_init(void)
24193+{
24194+ au_spl_init(&au_sbilist);
24195+}
24196+
24197+static inline void au_sbilist_add(struct super_block *sb)
24198+{
24199+ au_spl_add(&au_sbi(sb)->si_list, &au_sbilist);
24200+}
24201+
24202+static inline void au_sbilist_del(struct super_block *sb)
24203+{
24204+ au_spl_del(&au_sbi(sb)->si_list, &au_sbilist);
24205+}
53392da6
AM
24206+
24207+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
24208+static inline void au_sbilist_lock(void)
24209+{
24210+ spin_lock(&au_sbilist.spin);
24211+}
24212+
24213+static inline void au_sbilist_unlock(void)
24214+{
24215+ spin_unlock(&au_sbilist.spin);
24216+}
24217+#define AuGFP_SBILIST GFP_ATOMIC
24218+#else
24219+AuStubVoid(au_sbilist_lock, void)
24220+AuStubVoid(au_sbilist_unlock, void)
24221+#define AuGFP_SBILIST GFP_NOFS
24222+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
e49829fe
JR
24223+#else
24224+AuStubVoid(au_sbilist_init, void)
24225+AuStubVoid(au_sbilist_add, struct super_block*)
24226+AuStubVoid(au_sbilist_del, struct super_block*)
53392da6
AM
24227+AuStubVoid(au_sbilist_lock, void)
24228+AuStubVoid(au_sbilist_unlock, void)
24229+#define AuGFP_SBILIST GFP_NOFS
e49829fe
JR
24230+#endif
24231+
24232+/* ---------------------------------------------------------------------- */
24233+
1facf9fc 24234+static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
24235+{
dece6358
AM
24236+ /*
24237+ * This function is a dynamic '__init' fucntion actually,
24238+ * so the tiny check for si_rwsem is unnecessary.
24239+ */
24240+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
1facf9fc 24241+#ifdef CONFIG_DEBUG_FS
24242+ sbinfo->si_dbgaufs = NULL;
24243+ sbinfo->si_dbgaufs_xib = NULL;
24244+#ifdef CONFIG_AUFS_EXPORT
24245+ sbinfo->si_dbgaufs_xigen = NULL;
24246+#endif
24247+#endif
24248+}
24249+
24250+/* ---------------------------------------------------------------------- */
24251+
b752ccd1
AM
24252+static inline pid_t si_pid_bit(void)
24253+{
24254+ /* the origin of pid is 1, but the bitmap's is 0 */
24255+ return current->pid - 1;
24256+}
24257+
24258+static inline int si_pid_test(struct super_block *sb)
24259+{
24260+ pid_t bit = si_pid_bit();
24261+ if (bit < PID_MAX_DEFAULT)
24262+ return test_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
24263+ else
24264+ return si_pid_test_slow(sb);
24265+}
24266+
24267+static inline void si_pid_set(struct super_block *sb)
24268+{
24269+ pid_t bit = si_pid_bit();
24270+ if (bit < PID_MAX_DEFAULT) {
24271+ AuDebugOn(test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
24272+ set_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
24273+ /* smp_mb(); */
24274+ } else
24275+ si_pid_set_slow(sb);
24276+}
24277+
24278+static inline void si_pid_clr(struct super_block *sb)
24279+{
24280+ pid_t bit = si_pid_bit();
24281+ if (bit < PID_MAX_DEFAULT) {
24282+ AuDebugOn(!test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
24283+ clear_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
24284+ /* smp_mb(); */
24285+ } else
24286+ si_pid_clr_slow(sb);
24287+}
24288+
24289+/* ---------------------------------------------------------------------- */
24290+
1facf9fc 24291+/* lock superblock. mainly for entry point functions */
24292+/*
b752ccd1
AM
24293+ * __si_read_lock, __si_write_lock,
24294+ * __si_read_unlock, __si_write_unlock, __si_downgrade_lock
1facf9fc 24295+ */
b752ccd1 24296+AuSimpleRwsemFuncs(__si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
1facf9fc 24297+
dece6358
AM
24298+#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
24299+#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
24300+#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
24301+
b752ccd1
AM
24302+static inline void si_noflush_read_lock(struct super_block *sb)
24303+{
24304+ __si_read_lock(sb);
24305+ si_pid_set(sb);
24306+}
24307+
24308+static inline int si_noflush_read_trylock(struct super_block *sb)
24309+{
24310+ int locked = __si_read_trylock(sb);
24311+ if (locked)
24312+ si_pid_set(sb);
24313+ return locked;
24314+}
24315+
24316+static inline void si_noflush_write_lock(struct super_block *sb)
24317+{
24318+ __si_write_lock(sb);
24319+ si_pid_set(sb);
24320+}
24321+
24322+static inline int si_noflush_write_trylock(struct super_block *sb)
24323+{
24324+ int locked = __si_write_trylock(sb);
24325+ if (locked)
24326+ si_pid_set(sb);
24327+ return locked;
24328+}
24329+
e49829fe 24330+#if 0 /* unused */
1facf9fc 24331+static inline int si_read_trylock(struct super_block *sb, int flags)
24332+{
24333+ if (au_ftest_lock(flags, FLUSH))
24334+ au_nwt_flush(&au_sbi(sb)->si_nowait);
24335+ return si_noflush_read_trylock(sb);
24336+}
e49829fe 24337+#endif
1facf9fc 24338+
b752ccd1
AM
24339+static inline void si_read_unlock(struct super_block *sb)
24340+{
24341+ si_pid_clr(sb);
24342+ __si_read_unlock(sb);
24343+}
24344+
b752ccd1 24345+#if 0 /* unused */
1facf9fc 24346+static inline int si_write_trylock(struct super_block *sb, int flags)
24347+{
24348+ if (au_ftest_lock(flags, FLUSH))
24349+ au_nwt_flush(&au_sbi(sb)->si_nowait);
24350+ return si_noflush_write_trylock(sb);
24351+}
b752ccd1
AM
24352+#endif
24353+
24354+static inline void si_write_unlock(struct super_block *sb)
24355+{
24356+ si_pid_clr(sb);
24357+ __si_write_unlock(sb);
24358+}
24359+
24360+#if 0 /* unused */
24361+static inline void si_downgrade_lock(struct super_block *sb)
24362+{
24363+ __si_downgrade_lock(sb);
24364+}
24365+#endif
1facf9fc 24366+
24367+/* ---------------------------------------------------------------------- */
24368+
24369+static inline aufs_bindex_t au_sbend(struct super_block *sb)
24370+{
dece6358 24371+ SiMustAnyLock(sb);
1facf9fc 24372+ return au_sbi(sb)->si_bend;
24373+}
24374+
24375+static inline unsigned int au_mntflags(struct super_block *sb)
24376+{
dece6358 24377+ SiMustAnyLock(sb);
1facf9fc 24378+ return au_sbi(sb)->si_mntflags;
24379+}
24380+
24381+static inline unsigned int au_sigen(struct super_block *sb)
24382+{
dece6358 24383+ SiMustAnyLock(sb);
1facf9fc 24384+ return au_sbi(sb)->si_generation;
24385+}
24386+
7f207e10
AM
24387+static inline void au_ninodes_inc(struct super_block *sb)
24388+{
24389+ atomic_long_inc(&au_sbi(sb)->si_ninodes);
24390+}
24391+
24392+static inline void au_ninodes_dec(struct super_block *sb)
24393+{
24394+ AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_ninodes));
24395+ atomic_long_dec(&au_sbi(sb)->si_ninodes);
24396+}
24397+
24398+static inline void au_nfiles_inc(struct super_block *sb)
24399+{
24400+ atomic_long_inc(&au_sbi(sb)->si_nfiles);
24401+}
24402+
24403+static inline void au_nfiles_dec(struct super_block *sb)
24404+{
24405+ AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_nfiles));
24406+ atomic_long_dec(&au_sbi(sb)->si_nfiles);
24407+}
24408+
1facf9fc 24409+static inline struct au_branch *au_sbr(struct super_block *sb,
24410+ aufs_bindex_t bindex)
24411+{
dece6358 24412+ SiMustAnyLock(sb);
1facf9fc 24413+ return au_sbi(sb)->si_branch[0 + bindex];
24414+}
24415+
24416+static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid)
24417+{
dece6358 24418+ SiMustWriteLock(sb);
1facf9fc 24419+ au_sbi(sb)->si_xino_brid = brid;
24420+}
24421+
24422+static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
24423+{
dece6358 24424+ SiMustAnyLock(sb);
1facf9fc 24425+ return au_sbi(sb)->si_xino_brid;
24426+}
24427+
24428+#endif /* __KERNEL__ */
24429+#endif /* __AUFS_SUPER_H__ */
7f207e10
AM
24430diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c
24431--- /usr/share/empty/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
1716fcea 24432+++ linux/fs/aufs/sysaufs.c 2013-02-19 08:40:03.950226347 +0100
f6c5ef8b 24433@@ -0,0 +1,105 @@
1facf9fc 24434+/*
7a9e40b8 24435+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 24436+ *
24437+ * This program, aufs is free software; you can redistribute it and/or modify
24438+ * it under the terms of the GNU General Public License as published by
24439+ * the Free Software Foundation; either version 2 of the License, or
24440+ * (at your option) any later version.
dece6358
AM
24441+ *
24442+ * This program is distributed in the hope that it will be useful,
24443+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24444+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24445+ * GNU General Public License for more details.
24446+ *
24447+ * You should have received a copy of the GNU General Public License
24448+ * along with this program; if not, write to the Free Software
24449+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 24450+ */
24451+
24452+/*
24453+ * sysfs interface and lifetime management
24454+ * they are necessary regardless sysfs is disabled.
24455+ */
24456+
1facf9fc 24457+#include <linux/random.h>
1facf9fc 24458+#include "aufs.h"
24459+
24460+unsigned long sysaufs_si_mask;
e49829fe 24461+struct kset *sysaufs_kset;
1facf9fc 24462+
24463+#define AuSiAttr(_name) { \
24464+ .attr = { .name = __stringify(_name), .mode = 0444 }, \
24465+ .show = sysaufs_si_##_name, \
24466+}
24467+
24468+static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
24469+struct attribute *sysaufs_si_attrs[] = {
24470+ &sysaufs_si_attr_xi_path.attr,
24471+ NULL,
24472+};
24473+
4a4d8108 24474+static const struct sysfs_ops au_sbi_ops = {
1facf9fc 24475+ .show = sysaufs_si_show
24476+};
24477+
24478+static struct kobj_type au_sbi_ktype = {
24479+ .release = au_si_free,
24480+ .sysfs_ops = &au_sbi_ops,
24481+ .default_attrs = sysaufs_si_attrs
24482+};
24483+
24484+/* ---------------------------------------------------------------------- */
24485+
24486+int sysaufs_si_init(struct au_sbinfo *sbinfo)
24487+{
24488+ int err;
24489+
e49829fe 24490+ sbinfo->si_kobj.kset = sysaufs_kset;
1facf9fc 24491+ /* cf. sysaufs_name() */
24492+ err = kobject_init_and_add
e49829fe 24493+ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL,
1facf9fc 24494+ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
24495+
24496+ dbgaufs_si_null(sbinfo);
24497+ if (!err) {
24498+ err = dbgaufs_si_init(sbinfo);
24499+ if (unlikely(err))
24500+ kobject_put(&sbinfo->si_kobj);
24501+ }
24502+ return err;
24503+}
24504+
24505+void sysaufs_fin(void)
24506+{
24507+ dbgaufs_fin();
e49829fe
JR
24508+ sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group);
24509+ kset_unregister(sysaufs_kset);
1facf9fc 24510+}
24511+
24512+int __init sysaufs_init(void)
24513+{
24514+ int err;
24515+
24516+ do {
24517+ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
24518+ } while (!sysaufs_si_mask);
24519+
4a4d8108 24520+ err = -EINVAL;
e49829fe
JR
24521+ sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
24522+ if (unlikely(!sysaufs_kset))
4a4d8108 24523+ goto out;
e49829fe
JR
24524+ err = PTR_ERR(sysaufs_kset);
24525+ if (IS_ERR(sysaufs_kset))
1facf9fc 24526+ goto out;
e49829fe 24527+ err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group);
1facf9fc 24528+ if (unlikely(err)) {
e49829fe 24529+ kset_unregister(sysaufs_kset);
1facf9fc 24530+ goto out;
24531+ }
24532+
24533+ err = dbgaufs_init();
24534+ if (unlikely(err))
24535+ sysaufs_fin();
4f0767ce 24536+out:
1facf9fc 24537+ return err;
24538+}
7f207e10
AM
24539diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h
24540--- /usr/share/empty/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
1716fcea 24541+++ linux/fs/aufs/sysaufs.h 2013-02-19 08:40:03.950226347 +0100
f6c5ef8b 24542@@ -0,0 +1,104 @@
1facf9fc 24543+/*
7a9e40b8 24544+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 24545+ *
24546+ * This program, aufs is free software; you can redistribute it and/or modify
24547+ * it under the terms of the GNU General Public License as published by
24548+ * the Free Software Foundation; either version 2 of the License, or
24549+ * (at your option) any later version.
dece6358
AM
24550+ *
24551+ * This program is distributed in the hope that it will be useful,
24552+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24553+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24554+ * GNU General Public License for more details.
24555+ *
24556+ * You should have received a copy of the GNU General Public License
24557+ * along with this program; if not, write to the Free Software
24558+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 24559+ */
24560+
24561+/*
24562+ * sysfs interface and mount lifetime management
24563+ */
24564+
24565+#ifndef __SYSAUFS_H__
24566+#define __SYSAUFS_H__
24567+
24568+#ifdef __KERNEL__
24569+
1facf9fc 24570+#include <linux/sysfs.h>
1facf9fc 24571+#include "module.h"
24572+
dece6358
AM
24573+struct super_block;
24574+struct au_sbinfo;
24575+
1facf9fc 24576+struct sysaufs_si_attr {
24577+ struct attribute attr;
24578+ int (*show)(struct seq_file *seq, struct super_block *sb);
24579+};
24580+
24581+/* ---------------------------------------------------------------------- */
24582+
24583+/* sysaufs.c */
24584+extern unsigned long sysaufs_si_mask;
e49829fe 24585+extern struct kset *sysaufs_kset;
1facf9fc 24586+extern struct attribute *sysaufs_si_attrs[];
24587+int sysaufs_si_init(struct au_sbinfo *sbinfo);
24588+int __init sysaufs_init(void);
24589+void sysaufs_fin(void);
24590+
24591+/* ---------------------------------------------------------------------- */
24592+
24593+/* some people doesn't like to show a pointer in kernel */
24594+static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
24595+{
24596+ return sysaufs_si_mask ^ (unsigned long)sbinfo;
24597+}
24598+
24599+#define SysaufsSiNamePrefix "si_"
24600+#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16)
24601+static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
24602+{
24603+ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
24604+ sysaufs_si_id(sbinfo));
24605+}
24606+
24607+struct au_branch;
24608+#ifdef CONFIG_SYSFS
24609+/* sysfs.c */
24610+extern struct attribute_group *sysaufs_attr_group;
24611+
24612+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
24613+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
24614+ char *buf);
24615+
24616+void sysaufs_br_init(struct au_branch *br);
24617+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
24618+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
24619+
24620+#define sysaufs_brs_init() do {} while (0)
24621+
24622+#else
24623+#define sysaufs_attr_group NULL
24624+
4a4d8108 24625+AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb)
1facf9fc 24626+
24627+static inline
24628+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
24629+ char *buf)
24630+{
24631+ return 0;
24632+}
24633+
4a4d8108
AM
24634+AuStubVoid(sysaufs_br_init, struct au_branch *br)
24635+AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
24636+AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
1facf9fc 24637+
24638+static inline void sysaufs_brs_init(void)
24639+{
24640+ sysaufs_brs = 0;
24641+}
24642+
24643+#endif /* CONFIG_SYSFS */
24644+
24645+#endif /* __KERNEL__ */
24646+#endif /* __SYSAUFS_H__ */
7f207e10
AM
24647diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
24648--- /usr/share/empty/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100
1716fcea 24649+++ linux/fs/aufs/sysfs.c 2013-02-19 08:40:03.950226347 +0100
f6c5ef8b 24650@@ -0,0 +1,257 @@
1facf9fc 24651+/*
7a9e40b8 24652+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 24653+ *
24654+ * This program, aufs is free software; you can redistribute it and/or modify
24655+ * it under the terms of the GNU General Public License as published by
24656+ * the Free Software Foundation; either version 2 of the License, or
24657+ * (at your option) any later version.
dece6358
AM
24658+ *
24659+ * This program is distributed in the hope that it will be useful,
24660+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24661+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24662+ * GNU General Public License for more details.
24663+ *
24664+ * You should have received a copy of the GNU General Public License
24665+ * along with this program; if not, write to the Free Software
24666+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 24667+ */
24668+
24669+/*
24670+ * sysfs interface
24671+ */
24672+
1facf9fc 24673+#include <linux/seq_file.h>
1facf9fc 24674+#include "aufs.h"
24675+
4a4d8108
AM
24676+#ifdef CONFIG_AUFS_FS_MODULE
24677+/* this entry violates the "one line per file" policy of sysfs */
24678+static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr,
24679+ char *buf)
24680+{
24681+ ssize_t err;
24682+ static char *conf =
24683+/* this file is generated at compiling */
24684+#include "conf.str"
24685+ ;
24686+
24687+ err = snprintf(buf, PAGE_SIZE, conf);
24688+ if (unlikely(err >= PAGE_SIZE))
24689+ err = -EFBIG;
24690+ return err;
24691+}
24692+
24693+static struct kobj_attribute au_config_attr = __ATTR_RO(config);
24694+#endif
24695+
1facf9fc 24696+static struct attribute *au_attr[] = {
4a4d8108
AM
24697+#ifdef CONFIG_AUFS_FS_MODULE
24698+ &au_config_attr.attr,
24699+#endif
1facf9fc 24700+ NULL, /* need to NULL terminate the list of attributes */
24701+};
24702+
24703+static struct attribute_group sysaufs_attr_group_body = {
24704+ .attrs = au_attr
24705+};
24706+
24707+struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
24708+
24709+/* ---------------------------------------------------------------------- */
24710+
24711+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
24712+{
24713+ int err;
24714+
dece6358
AM
24715+ SiMustAnyLock(sb);
24716+
1facf9fc 24717+ err = 0;
24718+ if (au_opt_test(au_mntflags(sb), XINO)) {
24719+ err = au_xino_path(seq, au_sbi(sb)->si_xib);
24720+ seq_putc(seq, '\n');
24721+ }
24722+ return err;
24723+}
24724+
24725+/*
24726+ * the lifetime of branch is independent from the entry under sysfs.
24727+ * sysfs handles the lifetime of the entry, and never call ->show() after it is
24728+ * unlinked.
24729+ */
24730+static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
24731+ aufs_bindex_t bindex)
24732+{
1e00d052 24733+ int err;
1facf9fc 24734+ struct path path;
24735+ struct dentry *root;
24736+ struct au_branch *br;
1e00d052 24737+ char *perm;
1facf9fc 24738+
24739+ AuDbg("b%d\n", bindex);
24740+
1e00d052 24741+ err = 0;
1facf9fc 24742+ root = sb->s_root;
24743+ di_read_lock_parent(root, !AuLock_IR);
24744+ br = au_sbr(sb, bindex);
24745+ path.mnt = br->br_mnt;
24746+ path.dentry = au_h_dptr(root, bindex);
24747+ au_seq_path(seq, &path);
24748+ di_read_unlock(root, !AuLock_IR);
1e00d052
AM
24749+ perm = au_optstr_br_perm(br->br_perm);
24750+ if (perm) {
24751+ err = seq_printf(seq, "=%s\n", perm);
24752+ kfree(perm);
24753+ if (err == -1)
24754+ err = -E2BIG;
24755+ } else
24756+ err = -ENOMEM;
24757+ return err;
1facf9fc 24758+}
24759+
24760+/* ---------------------------------------------------------------------- */
24761+
24762+static struct seq_file *au_seq(char *p, ssize_t len)
24763+{
24764+ struct seq_file *seq;
24765+
24766+ seq = kzalloc(sizeof(*seq), GFP_NOFS);
24767+ if (seq) {
24768+ /* mutex_init(&seq.lock); */
24769+ seq->buf = p;
24770+ seq->size = len;
24771+ return seq; /* success */
24772+ }
24773+
24774+ seq = ERR_PTR(-ENOMEM);
24775+ return seq;
24776+}
24777+
24778+#define SysaufsBr_PREFIX "br"
24779+
24780+/* todo: file size may exceed PAGE_SIZE */
24781+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
1308ab2a 24782+ char *buf)
1facf9fc 24783+{
24784+ ssize_t err;
24785+ long l;
24786+ aufs_bindex_t bend;
24787+ struct au_sbinfo *sbinfo;
24788+ struct super_block *sb;
24789+ struct seq_file *seq;
24790+ char *name;
24791+ struct attribute **cattr;
24792+
24793+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
24794+ sb = sbinfo->si_sb;
1308ab2a 24795+
24796+ /*
24797+ * prevent a race condition between sysfs and aufs.
24798+ * for instance, sysfs_file_read() calls sysfs_get_active_two() which
24799+ * prohibits maintaining the sysfs entries.
24800+ * hew we acquire read lock after sysfs_get_active_two().
24801+ * on the other hand, the remount process may maintain the sysfs/aufs
24802+ * entries after acquiring write lock.
24803+ * it can cause a deadlock.
24804+ * simply we gave up processing read here.
24805+ */
24806+ err = -EBUSY;
24807+ if (unlikely(!si_noflush_read_trylock(sb)))
24808+ goto out;
1facf9fc 24809+
24810+ seq = au_seq(buf, PAGE_SIZE);
24811+ err = PTR_ERR(seq);
24812+ if (IS_ERR(seq))
1308ab2a 24813+ goto out_unlock;
1facf9fc 24814+
24815+ name = (void *)attr->name;
24816+ cattr = sysaufs_si_attrs;
24817+ while (*cattr) {
24818+ if (!strcmp(name, (*cattr)->name)) {
24819+ err = container_of(*cattr, struct sysaufs_si_attr, attr)
24820+ ->show(seq, sb);
24821+ goto out_seq;
24822+ }
24823+ cattr++;
24824+ }
24825+
24826+ bend = au_sbend(sb);
24827+ if (!strncmp(name, SysaufsBr_PREFIX, sizeof(SysaufsBr_PREFIX) - 1)) {
24828+ name += sizeof(SysaufsBr_PREFIX) - 1;
9dbd164d 24829+ err = kstrtol(name, 10, &l);
1facf9fc 24830+ if (!err) {
24831+ if (l <= bend)
24832+ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l);
24833+ else
24834+ err = -ENOENT;
24835+ }
24836+ goto out_seq;
24837+ }
24838+ BUG();
24839+
4f0767ce 24840+out_seq:
1facf9fc 24841+ if (!err) {
24842+ err = seq->count;
24843+ /* sysfs limit */
24844+ if (unlikely(err == PAGE_SIZE))
24845+ err = -EFBIG;
24846+ }
24847+ kfree(seq);
4f0767ce 24848+out_unlock:
1facf9fc 24849+ si_read_unlock(sb);
4f0767ce 24850+out:
1facf9fc 24851+ return err;
24852+}
24853+
24854+/* ---------------------------------------------------------------------- */
24855+
24856+void sysaufs_br_init(struct au_branch *br)
24857+{
4a4d8108
AM
24858+ struct attribute *attr = &br->br_attr;
24859+
24860+ sysfs_attr_init(attr);
24861+ attr->name = br->br_name;
24862+ attr->mode = S_IRUGO;
1facf9fc 24863+}
24864+
24865+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
24866+{
24867+ struct au_branch *br;
24868+ struct kobject *kobj;
24869+ aufs_bindex_t bend;
24870+
24871+ dbgaufs_brs_del(sb, bindex);
24872+
24873+ if (!sysaufs_brs)
24874+ return;
24875+
24876+ kobj = &au_sbi(sb)->si_kobj;
24877+ bend = au_sbend(sb);
24878+ for (; bindex <= bend; bindex++) {
24879+ br = au_sbr(sb, bindex);
24880+ sysfs_remove_file(kobj, &br->br_attr);
24881+ }
24882+}
24883+
24884+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
24885+{
24886+ int err;
24887+ aufs_bindex_t bend;
24888+ struct kobject *kobj;
24889+ struct au_branch *br;
24890+
24891+ dbgaufs_brs_add(sb, bindex);
24892+
24893+ if (!sysaufs_brs)
24894+ return;
24895+
24896+ kobj = &au_sbi(sb)->si_kobj;
24897+ bend = au_sbend(sb);
24898+ for (; bindex <= bend; bindex++) {
24899+ br = au_sbr(sb, bindex);
24900+ snprintf(br->br_name, sizeof(br->br_name), SysaufsBr_PREFIX
24901+ "%d", bindex);
24902+ err = sysfs_create_file(kobj, &br->br_attr);
24903+ if (unlikely(err))
0c3ec466
AM
24904+ pr_warn("failed %s under sysfs(%d)\n",
24905+ br->br_name, err);
1facf9fc 24906+ }
24907+}
7f207e10
AM
24908diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
24909--- /usr/share/empty/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100
a2a7ad62 24910+++ linux/fs/aufs/sysrq.c 2013-03-14 20:07:41.221457313 +0100
f6c5ef8b 24911@@ -0,0 +1,148 @@
1facf9fc 24912+/*
7a9e40b8 24913+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 24914+ *
24915+ * This program, aufs is free software; you can redistribute it and/or modify
24916+ * it under the terms of the GNU General Public License as published by
24917+ * the Free Software Foundation; either version 2 of the License, or
24918+ * (at your option) any later version.
dece6358
AM
24919+ *
24920+ * This program is distributed in the hope that it will be useful,
24921+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24922+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24923+ * GNU General Public License for more details.
24924+ *
24925+ * You should have received a copy of the GNU General Public License
24926+ * along with this program; if not, write to the Free Software
24927+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 24928+ */
24929+
24930+/*
24931+ * magic sysrq hanlder
24932+ */
24933+
1facf9fc 24934+/* #include <linux/sysrq.h> */
027c5e7a 24935+#include <linux/writeback.h>
1facf9fc 24936+#include "aufs.h"
24937+
24938+/* ---------------------------------------------------------------------- */
24939+
24940+static void sysrq_sb(struct super_block *sb)
24941+{
24942+ char *plevel;
24943+ struct au_sbinfo *sbinfo;
24944+ struct file *file;
24945+
24946+ plevel = au_plevel;
24947+ au_plevel = KERN_WARNING;
1facf9fc 24948+
24949+ sbinfo = au_sbi(sb);
4a4d8108
AM
24950+ /* since we define pr_fmt, call printk directly */
24951+ printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo));
24952+ printk(KERN_WARNING AUFS_NAME ": superblock\n");
1facf9fc 24953+ au_dpri_sb(sb);
027c5e7a
AM
24954+
24955+#if 0
4a4d8108 24956+ printk(KERN_WARNING AUFS_NAME ": root dentry\n");
1facf9fc 24957+ au_dpri_dentry(sb->s_root);
4a4d8108 24958+ printk(KERN_WARNING AUFS_NAME ": root inode\n");
1facf9fc 24959+ au_dpri_inode(sb->s_root->d_inode);
027c5e7a
AM
24960+#endif
24961+
1facf9fc 24962+#if 0
027c5e7a
AM
24963+ do {
24964+ int err, i, j, ndentry;
24965+ struct au_dcsub_pages dpages;
24966+ struct au_dpage *dpage;
24967+
24968+ err = au_dpages_init(&dpages, GFP_ATOMIC);
24969+ if (unlikely(err))
24970+ break;
24971+ err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL);
24972+ if (!err)
24973+ for (i = 0; i < dpages.ndpage; i++) {
24974+ dpage = dpages.dpages + i;
24975+ ndentry = dpage->ndentry;
24976+ for (j = 0; j < ndentry; j++)
24977+ au_dpri_dentry(dpage->dentries[j]);
24978+ }
24979+ au_dpages_free(&dpages);
24980+ } while (0);
24981+#endif
24982+
24983+#if 1
24984+ {
24985+ struct inode *i;
24986+ printk(KERN_WARNING AUFS_NAME ": isolated inode\n");
2cbb1c4b
JR
24987+ spin_lock(&inode_sb_list_lock);
24988+ list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
24989+ spin_lock(&i->i_lock);
b4510431 24990+ if (1 || hlist_empty(&i->i_dentry))
027c5e7a 24991+ au_dpri_inode(i);
2cbb1c4b
JR
24992+ spin_unlock(&i->i_lock);
24993+ }
24994+ spin_unlock(&inode_sb_list_lock);
027c5e7a 24995+ }
1facf9fc 24996+#endif
4a4d8108 24997+ printk(KERN_WARNING AUFS_NAME ": files\n");
0c3ec466 24998+ lg_global_lock(&files_lglock);
0c5527e5 24999+ do_file_list_for_each_entry(sb, file) {
4a4d8108
AM
25000+ umode_t mode;
25001+ mode = file->f_dentry->d_inode->i_mode;
25002+ if (!special_file(mode) || au_special_file(mode))
1facf9fc 25003+ au_dpri_file(file);
0c5527e5 25004+ } while_file_list_for_each_entry;
0c3ec466 25005+ lg_global_unlock(&files_lglock);
e49829fe 25006+ printk(KERN_WARNING AUFS_NAME ": done\n");
1facf9fc 25007+
25008+ au_plevel = plevel;
1facf9fc 25009+}
25010+
25011+/* ---------------------------------------------------------------------- */
25012+
25013+/* module parameter */
25014+static char *aufs_sysrq_key = "a";
25015+module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO);
25016+MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
25017+
0c5527e5 25018+static void au_sysrq(int key __maybe_unused)
1facf9fc 25019+{
1facf9fc 25020+ struct au_sbinfo *sbinfo;
25021+
027c5e7a 25022+ lockdep_off();
53392da6 25023+ au_sbilist_lock();
e49829fe 25024+ list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
1facf9fc 25025+ sysrq_sb(sbinfo->si_sb);
53392da6 25026+ au_sbilist_unlock();
027c5e7a 25027+ lockdep_on();
1facf9fc 25028+}
25029+
25030+static struct sysrq_key_op au_sysrq_op = {
25031+ .handler = au_sysrq,
25032+ .help_msg = "Aufs",
25033+ .action_msg = "Aufs",
25034+ .enable_mask = SYSRQ_ENABLE_DUMP
25035+};
25036+
25037+/* ---------------------------------------------------------------------- */
25038+
25039+int __init au_sysrq_init(void)
25040+{
25041+ int err;
25042+ char key;
25043+
25044+ err = -1;
25045+ key = *aufs_sysrq_key;
25046+ if ('a' <= key && key <= 'z')
25047+ err = register_sysrq_key(key, &au_sysrq_op);
25048+ if (unlikely(err))
4a4d8108 25049+ pr_err("err %d, sysrq=%c\n", err, key);
1facf9fc 25050+ return err;
25051+}
25052+
25053+void au_sysrq_fin(void)
25054+{
25055+ int err;
25056+ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
25057+ if (unlikely(err))
4a4d8108 25058+ pr_err("err %d (ignored)\n", err);
1facf9fc 25059+}
7f207e10
AM
25060diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
25061--- /usr/share/empty/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100
a2a7ad62 25062+++ linux/fs/aufs/vdir.c 2013-03-14 20:07:41.221457313 +0100
f6c5ef8b 25063@@ -0,0 +1,885 @@
1facf9fc 25064+/*
7a9e40b8 25065+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 25066+ *
25067+ * This program, aufs is free software; you can redistribute it and/or modify
25068+ * it under the terms of the GNU General Public License as published by
25069+ * the Free Software Foundation; either version 2 of the License, or
25070+ * (at your option) any later version.
dece6358
AM
25071+ *
25072+ * This program is distributed in the hope that it will be useful,
25073+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25074+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25075+ * GNU General Public License for more details.
25076+ *
25077+ * You should have received a copy of the GNU General Public License
25078+ * along with this program; if not, write to the Free Software
25079+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 25080+ */
25081+
25082+/*
25083+ * virtual or vertical directory
25084+ */
25085+
25086+#include "aufs.h"
25087+
dece6358 25088+static unsigned int calc_size(int nlen)
1facf9fc 25089+{
dece6358 25090+ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
1facf9fc 25091+}
25092+
25093+static int set_deblk_end(union au_vdir_deblk_p *p,
25094+ union au_vdir_deblk_p *deblk_end)
25095+{
25096+ if (calc_size(0) <= deblk_end->deblk - p->deblk) {
25097+ p->de->de_str.len = 0;
25098+ /* smp_mb(); */
25099+ return 0;
25100+ }
25101+ return -1; /* error */
25102+}
25103+
25104+/* returns true or false */
25105+static int is_deblk_end(union au_vdir_deblk_p *p,
25106+ union au_vdir_deblk_p *deblk_end)
25107+{
25108+ if (calc_size(0) <= deblk_end->deblk - p->deblk)
25109+ return !p->de->de_str.len;
25110+ return 1;
25111+}
25112+
25113+static unsigned char *last_deblk(struct au_vdir *vdir)
25114+{
25115+ return vdir->vd_deblk[vdir->vd_nblk - 1];
25116+}
25117+
25118+/* ---------------------------------------------------------------------- */
25119+
1308ab2a 25120+/* estimate the apropriate size for name hash table */
25121+unsigned int au_rdhash_est(loff_t sz)
25122+{
25123+ unsigned int n;
25124+
25125+ n = UINT_MAX;
25126+ sz >>= 10;
25127+ if (sz < n)
25128+ n = sz;
25129+ if (sz < AUFS_RDHASH_DEF)
25130+ n = AUFS_RDHASH_DEF;
4a4d8108 25131+ /* pr_info("n %u\n", n); */
1308ab2a 25132+ return n;
25133+}
25134+
1facf9fc 25135+/*
25136+ * the allocated memory has to be freed by
dece6358 25137+ * au_nhash_wh_free() or au_nhash_de_free().
1facf9fc 25138+ */
dece6358 25139+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
1facf9fc 25140+{
1facf9fc 25141+ struct hlist_head *head;
dece6358 25142+ unsigned int u;
1facf9fc 25143+
dece6358
AM
25144+ head = kmalloc(sizeof(*nhash->nh_head) * num_hash, gfp);
25145+ if (head) {
25146+ nhash->nh_num = num_hash;
25147+ nhash->nh_head = head;
25148+ for (u = 0; u < num_hash; u++)
1facf9fc 25149+ INIT_HLIST_HEAD(head++);
dece6358 25150+ return 0; /* success */
1facf9fc 25151+ }
1facf9fc 25152+
dece6358 25153+ return -ENOMEM;
1facf9fc 25154+}
25155+
dece6358
AM
25156+static void nhash_count(struct hlist_head *head)
25157+{
25158+#if 0
25159+ unsigned long n;
25160+ struct hlist_node *pos;
25161+
25162+ n = 0;
25163+ hlist_for_each(pos, head)
25164+ n++;
4a4d8108 25165+ pr_info("%lu\n", n);
dece6358
AM
25166+#endif
25167+}
25168+
25169+static void au_nhash_wh_do_free(struct hlist_head *head)
1facf9fc 25170+{
1facf9fc 25171+ struct au_vdir_wh *tpos;
25172+ struct hlist_node *pos, *node;
25173+
dece6358
AM
25174+ hlist_for_each_entry_safe(tpos, pos, node, head, wh_hash) {
25175+ /* hlist_del(pos); */
25176+ kfree(tpos);
1facf9fc 25177+ }
25178+}
25179+
dece6358 25180+static void au_nhash_de_do_free(struct hlist_head *head)
1facf9fc 25181+{
dece6358
AM
25182+ struct au_vdir_dehstr *tpos;
25183+ struct hlist_node *pos, *node;
1facf9fc 25184+
dece6358
AM
25185+ hlist_for_each_entry_safe(tpos, pos, node, head, hash) {
25186+ /* hlist_del(pos); */
4a4d8108 25187+ au_cache_free_vdir_dehstr(tpos);
1facf9fc 25188+ }
1facf9fc 25189+}
25190+
dece6358
AM
25191+static void au_nhash_do_free(struct au_nhash *nhash,
25192+ void (*free)(struct hlist_head *head))
1facf9fc 25193+{
1308ab2a 25194+ unsigned int n;
1facf9fc 25195+ struct hlist_head *head;
1facf9fc 25196+
dece6358 25197+ n = nhash->nh_num;
1308ab2a 25198+ if (!n)
25199+ return;
25200+
dece6358 25201+ head = nhash->nh_head;
1308ab2a 25202+ while (n-- > 0) {
dece6358
AM
25203+ nhash_count(head);
25204+ free(head++);
1facf9fc 25205+ }
dece6358 25206+ kfree(nhash->nh_head);
1facf9fc 25207+}
25208+
dece6358 25209+void au_nhash_wh_free(struct au_nhash *whlist)
1facf9fc 25210+{
dece6358
AM
25211+ au_nhash_do_free(whlist, au_nhash_wh_do_free);
25212+}
1facf9fc 25213+
dece6358
AM
25214+static void au_nhash_de_free(struct au_nhash *delist)
25215+{
25216+ au_nhash_do_free(delist, au_nhash_de_do_free);
1facf9fc 25217+}
25218+
25219+/* ---------------------------------------------------------------------- */
25220+
25221+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
25222+ int limit)
25223+{
25224+ int num;
25225+ unsigned int u, n;
25226+ struct hlist_head *head;
25227+ struct au_vdir_wh *tpos;
25228+ struct hlist_node *pos;
25229+
25230+ num = 0;
25231+ n = whlist->nh_num;
25232+ head = whlist->nh_head;
1308ab2a 25233+ for (u = 0; u < n; u++, head++)
1facf9fc 25234+ hlist_for_each_entry(tpos, pos, head, wh_hash)
25235+ if (tpos->wh_bindex == btgt && ++num > limit)
25236+ return 1;
1facf9fc 25237+ return 0;
25238+}
25239+
25240+static struct hlist_head *au_name_hash(struct au_nhash *nhash,
dece6358 25241+ unsigned char *name,
1facf9fc 25242+ unsigned int len)
25243+{
dece6358
AM
25244+ unsigned int v;
25245+ /* const unsigned int magic_bit = 12; */
25246+
1308ab2a 25247+ AuDebugOn(!nhash->nh_num || !nhash->nh_head);
25248+
dece6358
AM
25249+ v = 0;
25250+ while (len--)
25251+ v += *name++;
25252+ /* v = hash_long(v, magic_bit); */
25253+ v %= nhash->nh_num;
25254+ return nhash->nh_head + v;
25255+}
25256+
25257+static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
25258+ int nlen)
25259+{
25260+ return str->len == nlen && !memcmp(str->name, name, nlen);
1facf9fc 25261+}
25262+
25263+/* returns found or not */
dece6358 25264+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
1facf9fc 25265+{
25266+ struct hlist_head *head;
25267+ struct au_vdir_wh *tpos;
25268+ struct hlist_node *pos;
25269+ struct au_vdir_destr *str;
25270+
dece6358 25271+ head = au_name_hash(whlist, name, nlen);
1facf9fc 25272+ hlist_for_each_entry(tpos, pos, head, wh_hash) {
25273+ str = &tpos->wh_str;
25274+ AuDbg("%.*s\n", str->len, str->name);
dece6358
AM
25275+ if (au_nhash_test_name(str, name, nlen))
25276+ return 1;
25277+ }
25278+ return 0;
25279+}
25280+
25281+/* returns found(true) or not */
25282+static int test_known(struct au_nhash *delist, char *name, int nlen)
25283+{
25284+ struct hlist_head *head;
25285+ struct au_vdir_dehstr *tpos;
25286+ struct hlist_node *pos;
25287+ struct au_vdir_destr *str;
25288+
25289+ head = au_name_hash(delist, name, nlen);
25290+ hlist_for_each_entry(tpos, pos, head, hash) {
25291+ str = tpos->str;
25292+ AuDbg("%.*s\n", str->len, str->name);
25293+ if (au_nhash_test_name(str, name, nlen))
1facf9fc 25294+ return 1;
25295+ }
25296+ return 0;
25297+}
25298+
dece6358
AM
25299+static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
25300+ unsigned char d_type)
25301+{
25302+#ifdef CONFIG_AUFS_SHWH
25303+ wh->wh_ino = ino;
25304+ wh->wh_type = d_type;
25305+#endif
25306+}
25307+
25308+/* ---------------------------------------------------------------------- */
25309+
25310+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
25311+ unsigned int d_type, aufs_bindex_t bindex,
25312+ unsigned char shwh)
1facf9fc 25313+{
25314+ int err;
25315+ struct au_vdir_destr *str;
25316+ struct au_vdir_wh *wh;
25317+
dece6358 25318+ AuDbg("%.*s\n", nlen, name);
1308ab2a 25319+ AuDebugOn(!whlist->nh_num || !whlist->nh_head);
25320+
1facf9fc 25321+ err = -ENOMEM;
dece6358 25322+ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
1facf9fc 25323+ if (unlikely(!wh))
25324+ goto out;
25325+
25326+ err = 0;
25327+ wh->wh_bindex = bindex;
dece6358
AM
25328+ if (shwh)
25329+ au_shwh_init_wh(wh, ino, d_type);
1facf9fc 25330+ str = &wh->wh_str;
dece6358
AM
25331+ str->len = nlen;
25332+ memcpy(str->name, name, nlen);
25333+ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
1facf9fc 25334+ /* smp_mb(); */
25335+
4f0767ce 25336+out:
1facf9fc 25337+ return err;
25338+}
25339+
1facf9fc 25340+static int append_deblk(struct au_vdir *vdir)
25341+{
25342+ int err;
dece6358 25343+ unsigned long ul;
1facf9fc 25344+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
25345+ union au_vdir_deblk_p p, deblk_end;
25346+ unsigned char **o;
25347+
25348+ err = -ENOMEM;
dece6358
AM
25349+ o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
25350+ GFP_NOFS);
1facf9fc 25351+ if (unlikely(!o))
25352+ goto out;
25353+
25354+ vdir->vd_deblk = o;
25355+ p.deblk = kmalloc(deblk_sz, GFP_NOFS);
25356+ if (p.deblk) {
25357+ ul = vdir->vd_nblk++;
25358+ vdir->vd_deblk[ul] = p.deblk;
25359+ vdir->vd_last.ul = ul;
25360+ vdir->vd_last.p.deblk = p.deblk;
25361+ deblk_end.deblk = p.deblk + deblk_sz;
25362+ err = set_deblk_end(&p, &deblk_end);
25363+ }
25364+
4f0767ce 25365+out:
1facf9fc 25366+ return err;
25367+}
25368+
dece6358
AM
25369+static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
25370+ unsigned int d_type, struct au_nhash *delist)
25371+{
25372+ int err;
25373+ unsigned int sz;
25374+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
25375+ union au_vdir_deblk_p p, *room, deblk_end;
25376+ struct au_vdir_dehstr *dehstr;
25377+
25378+ p.deblk = last_deblk(vdir);
25379+ deblk_end.deblk = p.deblk + deblk_sz;
25380+ room = &vdir->vd_last.p;
25381+ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
25382+ || !is_deblk_end(room, &deblk_end));
25383+
25384+ sz = calc_size(nlen);
25385+ if (unlikely(sz > deblk_end.deblk - room->deblk)) {
25386+ err = append_deblk(vdir);
25387+ if (unlikely(err))
25388+ goto out;
25389+
25390+ p.deblk = last_deblk(vdir);
25391+ deblk_end.deblk = p.deblk + deblk_sz;
25392+ /* smp_mb(); */
25393+ AuDebugOn(room->deblk != p.deblk);
25394+ }
25395+
25396+ err = -ENOMEM;
4a4d8108 25397+ dehstr = au_cache_alloc_vdir_dehstr();
dece6358
AM
25398+ if (unlikely(!dehstr))
25399+ goto out;
25400+
25401+ dehstr->str = &room->de->de_str;
25402+ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
25403+ room->de->de_ino = ino;
25404+ room->de->de_type = d_type;
25405+ room->de->de_str.len = nlen;
25406+ memcpy(room->de->de_str.name, name, nlen);
25407+
25408+ err = 0;
25409+ room->deblk += sz;
25410+ if (unlikely(set_deblk_end(room, &deblk_end)))
25411+ err = append_deblk(vdir);
25412+ /* smp_mb(); */
25413+
4f0767ce 25414+out:
dece6358
AM
25415+ return err;
25416+}
25417+
25418+/* ---------------------------------------------------------------------- */
25419+
25420+void au_vdir_free(struct au_vdir *vdir)
25421+{
25422+ unsigned char **deblk;
25423+
25424+ deblk = vdir->vd_deblk;
25425+ while (vdir->vd_nblk--)
25426+ kfree(*deblk++);
25427+ kfree(vdir->vd_deblk);
25428+ au_cache_free_vdir(vdir);
25429+}
25430+
1308ab2a 25431+static struct au_vdir *alloc_vdir(struct file *file)
1facf9fc 25432+{
25433+ struct au_vdir *vdir;
1308ab2a 25434+ struct super_block *sb;
1facf9fc 25435+ int err;
25436+
1308ab2a 25437+ sb = file->f_dentry->d_sb;
dece6358
AM
25438+ SiMustAnyLock(sb);
25439+
1facf9fc 25440+ err = -ENOMEM;
25441+ vdir = au_cache_alloc_vdir();
25442+ if (unlikely(!vdir))
25443+ goto out;
25444+
25445+ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
25446+ if (unlikely(!vdir->vd_deblk))
25447+ goto out_free;
25448+
25449+ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
1308ab2a 25450+ if (!vdir->vd_deblk_sz) {
25451+ /* estimate the apropriate size for deblk */
25452+ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
4a4d8108 25453+ /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
1308ab2a 25454+ }
1facf9fc 25455+ vdir->vd_nblk = 0;
25456+ vdir->vd_version = 0;
25457+ vdir->vd_jiffy = 0;
25458+ err = append_deblk(vdir);
25459+ if (!err)
25460+ return vdir; /* success */
25461+
25462+ kfree(vdir->vd_deblk);
25463+
4f0767ce 25464+out_free:
1facf9fc 25465+ au_cache_free_vdir(vdir);
4f0767ce 25466+out:
1facf9fc 25467+ vdir = ERR_PTR(err);
25468+ return vdir;
25469+}
25470+
25471+static int reinit_vdir(struct au_vdir *vdir)
25472+{
25473+ int err;
25474+ union au_vdir_deblk_p p, deblk_end;
25475+
25476+ while (vdir->vd_nblk > 1) {
25477+ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
25478+ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
25479+ vdir->vd_nblk--;
25480+ }
25481+ p.deblk = vdir->vd_deblk[0];
25482+ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
25483+ err = set_deblk_end(&p, &deblk_end);
25484+ /* keep vd_dblk_sz */
25485+ vdir->vd_last.ul = 0;
25486+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
25487+ vdir->vd_version = 0;
25488+ vdir->vd_jiffy = 0;
25489+ /* smp_mb(); */
25490+ return err;
25491+}
25492+
25493+/* ---------------------------------------------------------------------- */
25494+
1facf9fc 25495+#define AuFillVdir_CALLED 1
25496+#define AuFillVdir_WHABLE (1 << 1)
dece6358 25497+#define AuFillVdir_SHWH (1 << 2)
1facf9fc 25498+#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
7f207e10
AM
25499+#define au_fset_fillvdir(flags, name) \
25500+ do { (flags) |= AuFillVdir_##name; } while (0)
25501+#define au_fclr_fillvdir(flags, name) \
25502+ do { (flags) &= ~AuFillVdir_##name; } while (0)
1facf9fc 25503+
dece6358
AM
25504+#ifndef CONFIG_AUFS_SHWH
25505+#undef AuFillVdir_SHWH
25506+#define AuFillVdir_SHWH 0
25507+#endif
25508+
1facf9fc 25509+struct fillvdir_arg {
25510+ struct file *file;
25511+ struct au_vdir *vdir;
dece6358
AM
25512+ struct au_nhash delist;
25513+ struct au_nhash whlist;
1facf9fc 25514+ aufs_bindex_t bindex;
25515+ unsigned int flags;
25516+ int err;
25517+};
25518+
dece6358 25519+static int fillvdir(void *__arg, const char *__name, int nlen,
1facf9fc 25520+ loff_t offset __maybe_unused, u64 h_ino,
25521+ unsigned int d_type)
25522+{
25523+ struct fillvdir_arg *arg = __arg;
25524+ char *name = (void *)__name;
25525+ struct super_block *sb;
1facf9fc 25526+ ino_t ino;
dece6358 25527+ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
1facf9fc 25528+
1facf9fc 25529+ arg->err = 0;
dece6358 25530+ sb = arg->file->f_dentry->d_sb;
1facf9fc 25531+ au_fset_fillvdir(arg->flags, CALLED);
25532+ /* smp_mb(); */
dece6358 25533+ if (nlen <= AUFS_WH_PFX_LEN
1facf9fc 25534+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
dece6358
AM
25535+ if (test_known(&arg->delist, name, nlen)
25536+ || au_nhash_test_known_wh(&arg->whlist, name, nlen))
25537+ goto out; /* already exists or whiteouted */
1facf9fc 25538+
25539+ sb = arg->file->f_dentry->d_sb;
dece6358 25540+ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
4a4d8108
AM
25541+ if (!arg->err) {
25542+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
25543+ d_type = DT_UNKNOWN;
dece6358
AM
25544+ arg->err = append_de(arg->vdir, name, nlen, ino,
25545+ d_type, &arg->delist);
4a4d8108 25546+ }
1facf9fc 25547+ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
25548+ name += AUFS_WH_PFX_LEN;
dece6358
AM
25549+ nlen -= AUFS_WH_PFX_LEN;
25550+ if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
25551+ goto out; /* already whiteouted */
1facf9fc 25552+
dece6358
AM
25553+ if (shwh)
25554+ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
25555+ &ino);
4a4d8108
AM
25556+ if (!arg->err) {
25557+ if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
25558+ d_type = DT_UNKNOWN;
1facf9fc 25559+ arg->err = au_nhash_append_wh
dece6358
AM
25560+ (&arg->whlist, name, nlen, ino, d_type,
25561+ arg->bindex, shwh);
4a4d8108 25562+ }
1facf9fc 25563+ }
25564+
4f0767ce 25565+out:
1facf9fc 25566+ if (!arg->err)
25567+ arg->vdir->vd_jiffy = jiffies;
25568+ /* smp_mb(); */
25569+ AuTraceErr(arg->err);
25570+ return arg->err;
25571+}
25572+
dece6358
AM
25573+static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
25574+ struct au_nhash *whlist, struct au_nhash *delist)
25575+{
25576+#ifdef CONFIG_AUFS_SHWH
25577+ int err;
25578+ unsigned int nh, u;
25579+ struct hlist_head *head;
25580+ struct au_vdir_wh *tpos;
25581+ struct hlist_node *pos, *n;
25582+ char *p, *o;
25583+ struct au_vdir_destr *destr;
25584+
25585+ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
25586+
25587+ err = -ENOMEM;
537831f9 25588+ o = p = (void *)__get_free_page(GFP_NOFS);
dece6358
AM
25589+ if (unlikely(!p))
25590+ goto out;
25591+
25592+ err = 0;
25593+ nh = whlist->nh_num;
25594+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
25595+ p += AUFS_WH_PFX_LEN;
25596+ for (u = 0; u < nh; u++) {
25597+ head = whlist->nh_head + u;
25598+ hlist_for_each_entry_safe(tpos, pos, n, head, wh_hash) {
25599+ destr = &tpos->wh_str;
25600+ memcpy(p, destr->name, destr->len);
25601+ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
25602+ tpos->wh_ino, tpos->wh_type, delist);
25603+ if (unlikely(err))
25604+ break;
25605+ }
25606+ }
25607+
537831f9 25608+ free_page((unsigned long)o);
dece6358 25609+
4f0767ce 25610+out:
dece6358
AM
25611+ AuTraceErr(err);
25612+ return err;
25613+#else
25614+ return 0;
25615+#endif
25616+}
25617+
1facf9fc 25618+static int au_do_read_vdir(struct fillvdir_arg *arg)
25619+{
25620+ int err;
dece6358 25621+ unsigned int rdhash;
1facf9fc 25622+ loff_t offset;
dece6358
AM
25623+ aufs_bindex_t bend, bindex, bstart;
25624+ unsigned char shwh;
1facf9fc 25625+ struct file *hf, *file;
25626+ struct super_block *sb;
25627+
1facf9fc 25628+ file = arg->file;
25629+ sb = file->f_dentry->d_sb;
dece6358
AM
25630+ SiMustAnyLock(sb);
25631+
25632+ rdhash = au_sbi(sb)->si_rdhash;
1308ab2a 25633+ if (!rdhash)
25634+ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
dece6358
AM
25635+ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
25636+ if (unlikely(err))
1facf9fc 25637+ goto out;
dece6358
AM
25638+ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
25639+ if (unlikely(err))
1facf9fc 25640+ goto out_delist;
25641+
25642+ err = 0;
25643+ arg->flags = 0;
dece6358
AM
25644+ shwh = 0;
25645+ if (au_opt_test(au_mntflags(sb), SHWH)) {
25646+ shwh = 1;
25647+ au_fset_fillvdir(arg->flags, SHWH);
25648+ }
25649+ bstart = au_fbstart(file);
4a4d8108 25650+ bend = au_fbend_dir(file);
dece6358 25651+ for (bindex = bstart; !err && bindex <= bend; bindex++) {
4a4d8108 25652+ hf = au_hf_dir(file, bindex);
1facf9fc 25653+ if (!hf)
25654+ continue;
25655+
25656+ offset = vfsub_llseek(hf, 0, SEEK_SET);
25657+ err = offset;
25658+ if (unlikely(offset))
25659+ break;
25660+
25661+ arg->bindex = bindex;
25662+ au_fclr_fillvdir(arg->flags, WHABLE);
dece6358
AM
25663+ if (shwh
25664+ || (bindex != bend
25665+ && au_br_whable(au_sbr_perm(sb, bindex))))
1facf9fc 25666+ au_fset_fillvdir(arg->flags, WHABLE);
25667+ do {
25668+ arg->err = 0;
25669+ au_fclr_fillvdir(arg->flags, CALLED);
25670+ /* smp_mb(); */
25671+ err = vfsub_readdir(hf, fillvdir, arg);
25672+ if (err >= 0)
25673+ err = arg->err;
25674+ } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
25675+ }
dece6358
AM
25676+
25677+ if (!err && shwh)
25678+ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
25679+
25680+ au_nhash_wh_free(&arg->whlist);
1facf9fc 25681+
4f0767ce 25682+out_delist:
dece6358 25683+ au_nhash_de_free(&arg->delist);
4f0767ce 25684+out:
1facf9fc 25685+ return err;
25686+}
25687+
25688+static int read_vdir(struct file *file, int may_read)
25689+{
25690+ int err;
25691+ unsigned long expire;
25692+ unsigned char do_read;
25693+ struct fillvdir_arg arg;
25694+ struct inode *inode;
25695+ struct au_vdir *vdir, *allocated;
25696+
25697+ err = 0;
25698+ inode = file->f_dentry->d_inode;
25699+ IMustLock(inode);
dece6358
AM
25700+ SiMustAnyLock(inode->i_sb);
25701+
1facf9fc 25702+ allocated = NULL;
25703+ do_read = 0;
25704+ expire = au_sbi(inode->i_sb)->si_rdcache;
25705+ vdir = au_ivdir(inode);
25706+ if (!vdir) {
25707+ do_read = 1;
1308ab2a 25708+ vdir = alloc_vdir(file);
1facf9fc 25709+ err = PTR_ERR(vdir);
25710+ if (IS_ERR(vdir))
25711+ goto out;
25712+ err = 0;
25713+ allocated = vdir;
25714+ } else if (may_read
25715+ && (inode->i_version != vdir->vd_version
25716+ || time_after(jiffies, vdir->vd_jiffy + expire))) {
25717+ do_read = 1;
25718+ err = reinit_vdir(vdir);
25719+ if (unlikely(err))
25720+ goto out;
25721+ }
25722+
25723+ if (!do_read)
25724+ return 0; /* success */
25725+
25726+ arg.file = file;
25727+ arg.vdir = vdir;
25728+ err = au_do_read_vdir(&arg);
25729+ if (!err) {
25730+ /* file->f_pos = 0; */
25731+ vdir->vd_version = inode->i_version;
25732+ vdir->vd_last.ul = 0;
25733+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
25734+ if (allocated)
25735+ au_set_ivdir(inode, allocated);
25736+ } else if (allocated)
25737+ au_vdir_free(allocated);
25738+
4f0767ce 25739+out:
1facf9fc 25740+ return err;
25741+}
25742+
25743+static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
25744+{
25745+ int err, rerr;
25746+ unsigned long ul, n;
25747+ const unsigned int deblk_sz = src->vd_deblk_sz;
25748+
25749+ AuDebugOn(tgt->vd_nblk != 1);
25750+
25751+ err = -ENOMEM;
25752+ if (tgt->vd_nblk < src->vd_nblk) {
25753+ unsigned char **p;
25754+
dece6358
AM
25755+ p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
25756+ GFP_NOFS);
1facf9fc 25757+ if (unlikely(!p))
25758+ goto out;
25759+ tgt->vd_deblk = p;
25760+ }
25761+
1308ab2a 25762+ if (tgt->vd_deblk_sz != deblk_sz) {
25763+ unsigned char *p;
25764+
25765+ tgt->vd_deblk_sz = deblk_sz;
25766+ p = krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS);
25767+ if (unlikely(!p))
25768+ goto out;
25769+ tgt->vd_deblk[0] = p;
25770+ }
1facf9fc 25771+ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
1facf9fc 25772+ tgt->vd_version = src->vd_version;
25773+ tgt->vd_jiffy = src->vd_jiffy;
25774+
25775+ n = src->vd_nblk;
25776+ for (ul = 1; ul < n; ul++) {
dece6358
AM
25777+ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
25778+ GFP_NOFS);
25779+ if (unlikely(!tgt->vd_deblk[ul]))
1facf9fc 25780+ goto out;
1308ab2a 25781+ tgt->vd_nblk++;
1facf9fc 25782+ }
1308ab2a 25783+ tgt->vd_nblk = n;
25784+ tgt->vd_last.ul = tgt->vd_last.ul;
25785+ tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul];
25786+ tgt->vd_last.p.deblk += src->vd_last.p.deblk
25787+ - src->vd_deblk[src->vd_last.ul];
1facf9fc 25788+ /* smp_mb(); */
25789+ return 0; /* success */
25790+
4f0767ce 25791+out:
1facf9fc 25792+ rerr = reinit_vdir(tgt);
25793+ BUG_ON(rerr);
25794+ return err;
25795+}
25796+
25797+int au_vdir_init(struct file *file)
25798+{
25799+ int err;
25800+ struct inode *inode;
25801+ struct au_vdir *vdir_cache, *allocated;
25802+
25803+ err = read_vdir(file, !file->f_pos);
25804+ if (unlikely(err))
25805+ goto out;
25806+
25807+ allocated = NULL;
25808+ vdir_cache = au_fvdir_cache(file);
25809+ if (!vdir_cache) {
1308ab2a 25810+ vdir_cache = alloc_vdir(file);
1facf9fc 25811+ err = PTR_ERR(vdir_cache);
25812+ if (IS_ERR(vdir_cache))
25813+ goto out;
25814+ allocated = vdir_cache;
25815+ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
25816+ err = reinit_vdir(vdir_cache);
25817+ if (unlikely(err))
25818+ goto out;
25819+ } else
25820+ return 0; /* success */
25821+
25822+ inode = file->f_dentry->d_inode;
25823+ err = copy_vdir(vdir_cache, au_ivdir(inode));
25824+ if (!err) {
25825+ file->f_version = inode->i_version;
25826+ if (allocated)
25827+ au_set_fvdir_cache(file, allocated);
25828+ } else if (allocated)
25829+ au_vdir_free(allocated);
25830+
4f0767ce 25831+out:
1facf9fc 25832+ return err;
25833+}
25834+
25835+static loff_t calc_offset(struct au_vdir *vdir)
25836+{
25837+ loff_t offset;
25838+ union au_vdir_deblk_p p;
25839+
25840+ p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
25841+ offset = vdir->vd_last.p.deblk - p.deblk;
25842+ offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
25843+ return offset;
25844+}
25845+
25846+/* returns true or false */
25847+static int seek_vdir(struct file *file)
25848+{
25849+ int valid;
25850+ unsigned int deblk_sz;
25851+ unsigned long ul, n;
25852+ loff_t offset;
25853+ union au_vdir_deblk_p p, deblk_end;
25854+ struct au_vdir *vdir_cache;
25855+
25856+ valid = 1;
25857+ vdir_cache = au_fvdir_cache(file);
25858+ offset = calc_offset(vdir_cache);
25859+ AuDbg("offset %lld\n", offset);
25860+ if (file->f_pos == offset)
25861+ goto out;
25862+
25863+ vdir_cache->vd_last.ul = 0;
25864+ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
25865+ if (!file->f_pos)
25866+ goto out;
25867+
25868+ valid = 0;
25869+ deblk_sz = vdir_cache->vd_deblk_sz;
25870+ ul = div64_u64(file->f_pos, deblk_sz);
25871+ AuDbg("ul %lu\n", ul);
25872+ if (ul >= vdir_cache->vd_nblk)
25873+ goto out;
25874+
25875+ n = vdir_cache->vd_nblk;
25876+ for (; ul < n; ul++) {
25877+ p.deblk = vdir_cache->vd_deblk[ul];
25878+ deblk_end.deblk = p.deblk + deblk_sz;
25879+ offset = ul;
25880+ offset *= deblk_sz;
25881+ while (!is_deblk_end(&p, &deblk_end) && offset < file->f_pos) {
25882+ unsigned int l;
25883+
25884+ l = calc_size(p.de->de_str.len);
25885+ offset += l;
25886+ p.deblk += l;
25887+ }
25888+ if (!is_deblk_end(&p, &deblk_end)) {
25889+ valid = 1;
25890+ vdir_cache->vd_last.ul = ul;
25891+ vdir_cache->vd_last.p = p;
25892+ break;
25893+ }
25894+ }
25895+
4f0767ce 25896+out:
1facf9fc 25897+ /* smp_mb(); */
25898+ AuTraceErr(!valid);
25899+ return valid;
25900+}
25901+
25902+int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir)
25903+{
25904+ int err;
25905+ unsigned int l, deblk_sz;
25906+ union au_vdir_deblk_p deblk_end;
25907+ struct au_vdir *vdir_cache;
25908+ struct au_vdir_de *de;
25909+
25910+ vdir_cache = au_fvdir_cache(file);
25911+ if (!seek_vdir(file))
25912+ return 0;
25913+
25914+ deblk_sz = vdir_cache->vd_deblk_sz;
25915+ while (1) {
25916+ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
25917+ deblk_end.deblk += deblk_sz;
25918+ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
25919+ de = vdir_cache->vd_last.p.de;
25920+ AuDbg("%.*s, off%lld, i%lu, dt%d\n",
25921+ de->de_str.len, de->de_str.name, file->f_pos,
25922+ (unsigned long)de->de_ino, de->de_type);
25923+ err = filldir(dirent, de->de_str.name, de->de_str.len,
25924+ file->f_pos, de->de_ino, de->de_type);
25925+ if (unlikely(err)) {
25926+ AuTraceErr(err);
25927+ /* todo: ignore the error caused by udba? */
25928+ /* return err; */
25929+ return 0;
25930+ }
25931+
25932+ l = calc_size(de->de_str.len);
25933+ vdir_cache->vd_last.p.deblk += l;
25934+ file->f_pos += l;
25935+ }
25936+ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
25937+ vdir_cache->vd_last.ul++;
25938+ vdir_cache->vd_last.p.deblk
25939+ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
25940+ file->f_pos = deblk_sz * vdir_cache->vd_last.ul;
25941+ continue;
25942+ }
25943+ break;
25944+ }
25945+
25946+ /* smp_mb(); */
25947+ return 0;
25948+}
7f207e10
AM
25949diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
25950--- /usr/share/empty/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100
a2a7ad62 25951+++ linux/fs/aufs/vfsub.c 2013-03-14 20:07:41.221457313 +0100
b4510431 25952@@ -0,0 +1,777 @@
1facf9fc 25953+/*
7a9e40b8 25954+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 25955+ *
25956+ * This program, aufs is free software; you can redistribute it and/or modify
25957+ * it under the terms of the GNU General Public License as published by
25958+ * the Free Software Foundation; either version 2 of the License, or
25959+ * (at your option) any later version.
dece6358
AM
25960+ *
25961+ * This program is distributed in the hope that it will be useful,
25962+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25963+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25964+ * GNU General Public License for more details.
25965+ *
25966+ * You should have received a copy of the GNU General Public License
25967+ * along with this program; if not, write to the Free Software
25968+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 25969+ */
25970+
25971+/*
25972+ * sub-routines for VFS
25973+ */
25974+
1308ab2a 25975+#include <linux/ima.h>
dece6358
AM
25976+#include <linux/namei.h>
25977+#include <linux/security.h>
25978+#include <linux/splice.h>
1facf9fc 25979+#include "aufs.h"
25980+
25981+int vfsub_update_h_iattr(struct path *h_path, int *did)
25982+{
25983+ int err;
25984+ struct kstat st;
25985+ struct super_block *h_sb;
25986+
25987+ /* for remote fs, leave work for its getattr or d_revalidate */
25988+ /* for bad i_attr fs, handle them in aufs_getattr() */
25989+ /* still some fs may acquire i_mutex. we need to skip them */
25990+ err = 0;
25991+ if (!did)
25992+ did = &err;
25993+ h_sb = h_path->dentry->d_sb;
25994+ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
25995+ if (*did)
25996+ err = vfs_getattr(h_path->mnt, h_path->dentry, &st);
25997+
25998+ return err;
25999+}
26000+
26001+/* ---------------------------------------------------------------------- */
26002+
4a4d8108 26003+struct file *vfsub_dentry_open(struct path *path, int flags)
1308ab2a 26004+{
26005+ struct file *file;
26006+
b4510431 26007+ file = dentry_open(path, flags /* | __FMODE_NONOTIFY */,
7f207e10 26008+ current_cred());
2cbb1c4b
JR
26009+ if (!IS_ERR_OR_NULL(file)
26010+ && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
26011+ i_readcount_inc(path->dentry->d_inode);
4a4d8108 26012+
1308ab2a 26013+ return file;
26014+}
26015+
1facf9fc 26016+struct file *vfsub_filp_open(const char *path, int oflags, int mode)
26017+{
26018+ struct file *file;
26019+
2cbb1c4b 26020+ lockdep_off();
7f207e10 26021+ file = filp_open(path,
2cbb1c4b 26022+ oflags /* | __FMODE_NONOTIFY */,
7f207e10 26023+ mode);
2cbb1c4b 26024+ lockdep_on();
1facf9fc 26025+ if (IS_ERR(file))
26026+ goto out;
26027+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
26028+
4f0767ce 26029+out:
1facf9fc 26030+ return file;
26031+}
26032+
26033+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
26034+{
26035+ int err;
26036+
1facf9fc 26037+ err = kern_path(name, flags, path);
1facf9fc 26038+ if (!err && path->dentry->d_inode)
26039+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
26040+ return err;
26041+}
26042+
26043+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
26044+ int len)
26045+{
26046+ struct path path = {
26047+ .mnt = NULL
26048+ };
26049+
1308ab2a 26050+ /* VFS checks it too, but by WARN_ON_ONCE() */
1facf9fc 26051+ IMustLock(parent->d_inode);
26052+
26053+ path.dentry = lookup_one_len(name, parent, len);
26054+ if (IS_ERR(path.dentry))
26055+ goto out;
26056+ if (path.dentry->d_inode)
26057+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
26058+
4f0767ce 26059+out:
4a4d8108 26060+ AuTraceErrPtr(path.dentry);
1facf9fc 26061+ return path.dentry;
26062+}
26063+
b4510431 26064+void vfsub_call_lkup_one(void *args)
2cbb1c4b 26065+{
b4510431
AM
26066+ struct vfsub_lkup_one_args *a = args;
26067+ *a->errp = vfsub_lkup_one(a->name, a->parent);
2cbb1c4b
JR
26068+}
26069+
1facf9fc 26070+/* ---------------------------------------------------------------------- */
26071+
26072+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
26073+ struct dentry *d2, struct au_hinode *hdir2)
26074+{
26075+ struct dentry *d;
26076+
2cbb1c4b 26077+ lockdep_off();
1facf9fc 26078+ d = lock_rename(d1, d2);
2cbb1c4b 26079+ lockdep_on();
4a4d8108 26080+ au_hn_suspend(hdir1);
1facf9fc 26081+ if (hdir1 != hdir2)
4a4d8108 26082+ au_hn_suspend(hdir2);
1facf9fc 26083+
26084+ return d;
26085+}
26086+
26087+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
26088+ struct dentry *d2, struct au_hinode *hdir2)
26089+{
4a4d8108 26090+ au_hn_resume(hdir1);
1facf9fc 26091+ if (hdir1 != hdir2)
4a4d8108 26092+ au_hn_resume(hdir2);
2cbb1c4b 26093+ lockdep_off();
1facf9fc 26094+ unlock_rename(d1, d2);
2cbb1c4b 26095+ lockdep_on();
1facf9fc 26096+}
26097+
26098+/* ---------------------------------------------------------------------- */
26099+
b4510431 26100+int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl)
1facf9fc 26101+{
26102+ int err;
26103+ struct dentry *d;
26104+
26105+ IMustLock(dir);
26106+
26107+ d = path->dentry;
26108+ path->dentry = d->d_parent;
b752ccd1 26109+ err = security_path_mknod(path, d, mode, 0);
1facf9fc 26110+ path->dentry = d;
26111+ if (unlikely(err))
26112+ goto out;
26113+
b4510431 26114+ err = vfs_create(dir, path->dentry, mode, want_excl);
1facf9fc 26115+ if (!err) {
26116+ struct path tmp = *path;
26117+ int did;
26118+
26119+ vfsub_update_h_iattr(&tmp, &did);
26120+ if (did) {
26121+ tmp.dentry = path->dentry->d_parent;
26122+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
26123+ }
26124+ /*ignore*/
26125+ }
26126+
4f0767ce 26127+out:
1facf9fc 26128+ return err;
26129+}
26130+
26131+int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
26132+{
26133+ int err;
26134+ struct dentry *d;
26135+
26136+ IMustLock(dir);
26137+
26138+ d = path->dentry;
26139+ path->dentry = d->d_parent;
b752ccd1 26140+ err = security_path_symlink(path, d, symname);
1facf9fc 26141+ path->dentry = d;
26142+ if (unlikely(err))
26143+ goto out;
26144+
26145+ err = vfs_symlink(dir, path->dentry, symname);
26146+ if (!err) {
26147+ struct path tmp = *path;
26148+ int did;
26149+
26150+ vfsub_update_h_iattr(&tmp, &did);
26151+ if (did) {
26152+ tmp.dentry = path->dentry->d_parent;
26153+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
26154+ }
26155+ /*ignore*/
26156+ }
26157+
4f0767ce 26158+out:
1facf9fc 26159+ return err;
26160+}
26161+
26162+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
26163+{
26164+ int err;
26165+ struct dentry *d;
26166+
26167+ IMustLock(dir);
26168+
26169+ d = path->dentry;
26170+ path->dentry = d->d_parent;
027c5e7a 26171+ err = security_path_mknod(path, d, mode, new_encode_dev(dev));
1facf9fc 26172+ path->dentry = d;
26173+ if (unlikely(err))
26174+ goto out;
26175+
26176+ err = vfs_mknod(dir, path->dentry, mode, dev);
26177+ if (!err) {
26178+ struct path tmp = *path;
26179+ int did;
26180+
26181+ vfsub_update_h_iattr(&tmp, &did);
26182+ if (did) {
26183+ tmp.dentry = path->dentry->d_parent;
26184+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
26185+ }
26186+ /*ignore*/
26187+ }
26188+
4f0767ce 26189+out:
1facf9fc 26190+ return err;
26191+}
26192+
26193+static int au_test_nlink(struct inode *inode)
26194+{
26195+ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
26196+
26197+ if (!au_test_fs_no_limit_nlink(inode->i_sb)
26198+ || inode->i_nlink < link_max)
26199+ return 0;
26200+ return -EMLINK;
26201+}
26202+
26203+int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path)
26204+{
26205+ int err;
26206+ struct dentry *d;
26207+
26208+ IMustLock(dir);
26209+
26210+ err = au_test_nlink(src_dentry->d_inode);
26211+ if (unlikely(err))
26212+ return err;
26213+
b4510431 26214+ /* we don't call may_linkat() */
1facf9fc 26215+ d = path->dentry;
26216+ path->dentry = d->d_parent;
b752ccd1 26217+ err = security_path_link(src_dentry, path, d);
1facf9fc 26218+ path->dentry = d;
26219+ if (unlikely(err))
26220+ goto out;
26221+
2cbb1c4b 26222+ lockdep_off();
1facf9fc 26223+ err = vfs_link(src_dentry, dir, path->dentry);
2cbb1c4b 26224+ lockdep_on();
1facf9fc 26225+ if (!err) {
26226+ struct path tmp = *path;
26227+ int did;
26228+
26229+ /* fuse has different memory inode for the same inumber */
26230+ vfsub_update_h_iattr(&tmp, &did);
26231+ if (did) {
26232+ tmp.dentry = path->dentry->d_parent;
26233+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
26234+ tmp.dentry = src_dentry;
26235+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
26236+ }
26237+ /*ignore*/
26238+ }
26239+
4f0767ce 26240+out:
1facf9fc 26241+ return err;
26242+}
26243+
26244+int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
26245+ struct inode *dir, struct path *path)
26246+{
26247+ int err;
26248+ struct path tmp = {
26249+ .mnt = path->mnt
26250+ };
26251+ struct dentry *d;
26252+
26253+ IMustLock(dir);
26254+ IMustLock(src_dir);
26255+
26256+ d = path->dentry;
26257+ path->dentry = d->d_parent;
26258+ tmp.dentry = src_dentry->d_parent;
b752ccd1 26259+ err = security_path_rename(&tmp, src_dentry, path, d);
1facf9fc 26260+ path->dentry = d;
26261+ if (unlikely(err))
26262+ goto out;
26263+
2cbb1c4b 26264+ lockdep_off();
1facf9fc 26265+ err = vfs_rename(src_dir, src_dentry, dir, path->dentry);
2cbb1c4b 26266+ lockdep_on();
1facf9fc 26267+ if (!err) {
26268+ int did;
26269+
26270+ tmp.dentry = d->d_parent;
26271+ vfsub_update_h_iattr(&tmp, &did);
26272+ if (did) {
26273+ tmp.dentry = src_dentry;
26274+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
26275+ tmp.dentry = src_dentry->d_parent;
26276+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
26277+ }
26278+ /*ignore*/
26279+ }
26280+
4f0767ce 26281+out:
1facf9fc 26282+ return err;
26283+}
26284+
26285+int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
26286+{
26287+ int err;
26288+ struct dentry *d;
26289+
26290+ IMustLock(dir);
26291+
26292+ d = path->dentry;
26293+ path->dentry = d->d_parent;
b752ccd1 26294+ err = security_path_mkdir(path, d, mode);
1facf9fc 26295+ path->dentry = d;
26296+ if (unlikely(err))
26297+ goto out;
26298+
26299+ err = vfs_mkdir(dir, path->dentry, mode);
26300+ if (!err) {
26301+ struct path tmp = *path;
26302+ int did;
26303+
26304+ vfsub_update_h_iattr(&tmp, &did);
26305+ if (did) {
26306+ tmp.dentry = path->dentry->d_parent;
26307+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
26308+ }
26309+ /*ignore*/
26310+ }
26311+
4f0767ce 26312+out:
1facf9fc 26313+ return err;
26314+}
26315+
26316+int vfsub_rmdir(struct inode *dir, struct path *path)
26317+{
26318+ int err;
26319+ struct dentry *d;
26320+
26321+ IMustLock(dir);
26322+
26323+ d = path->dentry;
26324+ path->dentry = d->d_parent;
b752ccd1 26325+ err = security_path_rmdir(path, d);
1facf9fc 26326+ path->dentry = d;
26327+ if (unlikely(err))
26328+ goto out;
26329+
2cbb1c4b 26330+ lockdep_off();
1facf9fc 26331+ err = vfs_rmdir(dir, path->dentry);
2cbb1c4b 26332+ lockdep_on();
1facf9fc 26333+ if (!err) {
26334+ struct path tmp = {
26335+ .dentry = path->dentry->d_parent,
26336+ .mnt = path->mnt
26337+ };
26338+
26339+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
26340+ }
26341+
4f0767ce 26342+out:
1facf9fc 26343+ return err;
26344+}
26345+
26346+/* ---------------------------------------------------------------------- */
26347+
9dbd164d 26348+/* todo: support mmap_sem? */
1facf9fc 26349+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
26350+ loff_t *ppos)
26351+{
26352+ ssize_t err;
26353+
2cbb1c4b 26354+ lockdep_off();
1facf9fc 26355+ err = vfs_read(file, ubuf, count, ppos);
2cbb1c4b 26356+ lockdep_on();
1facf9fc 26357+ if (err >= 0)
26358+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
26359+ return err;
26360+}
26361+
26362+/* todo: kernel_read()? */
26363+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
26364+ loff_t *ppos)
26365+{
26366+ ssize_t err;
26367+ mm_segment_t oldfs;
b752ccd1
AM
26368+ union {
26369+ void *k;
26370+ char __user *u;
26371+ } buf;
1facf9fc 26372+
b752ccd1 26373+ buf.k = kbuf;
1facf9fc 26374+ oldfs = get_fs();
26375+ set_fs(KERNEL_DS);
b752ccd1 26376+ err = vfsub_read_u(file, buf.u, count, ppos);
1facf9fc 26377+ set_fs(oldfs);
26378+ return err;
26379+}
26380+
26381+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
26382+ loff_t *ppos)
26383+{
26384+ ssize_t err;
26385+
2cbb1c4b 26386+ lockdep_off();
1facf9fc 26387+ err = vfs_write(file, ubuf, count, ppos);
2cbb1c4b 26388+ lockdep_on();
1facf9fc 26389+ if (err >= 0)
26390+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
26391+ return err;
26392+}
26393+
26394+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
26395+{
26396+ ssize_t err;
26397+ mm_segment_t oldfs;
b752ccd1
AM
26398+ union {
26399+ void *k;
26400+ const char __user *u;
26401+ } buf;
1facf9fc 26402+
b752ccd1 26403+ buf.k = kbuf;
1facf9fc 26404+ oldfs = get_fs();
26405+ set_fs(KERNEL_DS);
b752ccd1 26406+ err = vfsub_write_u(file, buf.u, count, ppos);
1facf9fc 26407+ set_fs(oldfs);
26408+ return err;
26409+}
26410+
4a4d8108
AM
26411+int vfsub_flush(struct file *file, fl_owner_t id)
26412+{
26413+ int err;
26414+
26415+ err = 0;
26416+ if (file->f_op && file->f_op->flush) {
2cbb1c4b
JR
26417+ if (!au_test_nfs(file->f_dentry->d_sb))
26418+ err = file->f_op->flush(file, id);
26419+ else {
26420+ lockdep_off();
26421+ err = file->f_op->flush(file, id);
26422+ lockdep_on();
26423+ }
4a4d8108
AM
26424+ if (!err)
26425+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
26426+ /*ignore*/
26427+ }
26428+ return err;
26429+}
26430+
1facf9fc 26431+int vfsub_readdir(struct file *file, filldir_t filldir, void *arg)
26432+{
26433+ int err;
26434+
2cbb1c4b 26435+ lockdep_off();
1facf9fc 26436+ err = vfs_readdir(file, filldir, arg);
2cbb1c4b 26437+ lockdep_on();
1facf9fc 26438+ if (err >= 0)
26439+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
26440+ return err;
26441+}
26442+
26443+long vfsub_splice_to(struct file *in, loff_t *ppos,
26444+ struct pipe_inode_info *pipe, size_t len,
26445+ unsigned int flags)
26446+{
26447+ long err;
26448+
2cbb1c4b 26449+ lockdep_off();
0fc653ad 26450+ err = do_splice_to(in, ppos, pipe, len, flags);
2cbb1c4b 26451+ lockdep_on();
4a4d8108 26452+ file_accessed(in);
1facf9fc 26453+ if (err >= 0)
26454+ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
26455+ return err;
26456+}
26457+
26458+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
26459+ loff_t *ppos, size_t len, unsigned int flags)
26460+{
26461+ long err;
26462+
2cbb1c4b 26463+ lockdep_off();
0fc653ad 26464+ err = do_splice_from(pipe, out, ppos, len, flags);
2cbb1c4b 26465+ lockdep_on();
1facf9fc 26466+ if (err >= 0)
26467+ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
26468+ return err;
26469+}
26470+
53392da6
AM
26471+int vfsub_fsync(struct file *file, struct path *path, int datasync)
26472+{
26473+ int err;
26474+
26475+ /* file can be NULL */
26476+ lockdep_off();
26477+ err = vfs_fsync(file, datasync);
26478+ lockdep_on();
26479+ if (!err) {
26480+ if (!path) {
26481+ AuDebugOn(!file);
26482+ path = &file->f_path;
26483+ }
26484+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
26485+ }
26486+ return err;
26487+}
26488+
1facf9fc 26489+/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
26490+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
26491+ struct file *h_file)
26492+{
26493+ int err;
26494+ struct inode *h_inode;
26495+
26496+ h_inode = h_path->dentry->d_inode;
26497+ if (!h_file) {
b4510431 26498+ err = vfsub_mnt_want_write(h_path->mnt);
1facf9fc 26499+ if (err)
26500+ goto out;
26501+ err = inode_permission(h_inode, MAY_WRITE);
26502+ if (err)
26503+ goto out_mnt;
26504+ err = get_write_access(h_inode);
26505+ if (err)
26506+ goto out_mnt;
4a4d8108 26507+ err = break_lease(h_inode, O_WRONLY);
1facf9fc 26508+ if (err)
26509+ goto out_inode;
26510+ }
26511+
26512+ err = locks_verify_truncate(h_inode, h_file, length);
26513+ if (!err)
953406b4 26514+ err = security_path_truncate(h_path);
2cbb1c4b
JR
26515+ if (!err) {
26516+ lockdep_off();
1facf9fc 26517+ err = do_truncate(h_path->dentry, length, attr, h_file);
2cbb1c4b
JR
26518+ lockdep_on();
26519+ }
1facf9fc 26520+
4f0767ce 26521+out_inode:
1facf9fc 26522+ if (!h_file)
26523+ put_write_access(h_inode);
4f0767ce 26524+out_mnt:
1facf9fc 26525+ if (!h_file)
b4510431 26526+ vfsub_mnt_drop_write(h_path->mnt);
4f0767ce 26527+out:
1facf9fc 26528+ return err;
26529+}
26530+
26531+/* ---------------------------------------------------------------------- */
26532+
26533+struct au_vfsub_mkdir_args {
26534+ int *errp;
26535+ struct inode *dir;
26536+ struct path *path;
26537+ int mode;
26538+};
26539+
26540+static void au_call_vfsub_mkdir(void *args)
26541+{
26542+ struct au_vfsub_mkdir_args *a = args;
26543+ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
26544+}
26545+
26546+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
26547+{
26548+ int err, do_sio, wkq_err;
26549+
26550+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
26551+ if (!do_sio)
26552+ err = vfsub_mkdir(dir, path, mode);
26553+ else {
26554+ struct au_vfsub_mkdir_args args = {
26555+ .errp = &err,
26556+ .dir = dir,
26557+ .path = path,
26558+ .mode = mode
26559+ };
26560+ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
26561+ if (unlikely(wkq_err))
26562+ err = wkq_err;
26563+ }
26564+
26565+ return err;
26566+}
26567+
26568+struct au_vfsub_rmdir_args {
26569+ int *errp;
26570+ struct inode *dir;
26571+ struct path *path;
26572+};
26573+
26574+static void au_call_vfsub_rmdir(void *args)
26575+{
26576+ struct au_vfsub_rmdir_args *a = args;
26577+ *a->errp = vfsub_rmdir(a->dir, a->path);
26578+}
26579+
26580+int vfsub_sio_rmdir(struct inode *dir, struct path *path)
26581+{
26582+ int err, do_sio, wkq_err;
26583+
26584+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
26585+ if (!do_sio)
26586+ err = vfsub_rmdir(dir, path);
26587+ else {
26588+ struct au_vfsub_rmdir_args args = {
26589+ .errp = &err,
26590+ .dir = dir,
26591+ .path = path
26592+ };
26593+ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
26594+ if (unlikely(wkq_err))
26595+ err = wkq_err;
26596+ }
26597+
26598+ return err;
26599+}
26600+
26601+/* ---------------------------------------------------------------------- */
26602+
26603+struct notify_change_args {
26604+ int *errp;
26605+ struct path *path;
26606+ struct iattr *ia;
26607+};
26608+
26609+static void call_notify_change(void *args)
26610+{
26611+ struct notify_change_args *a = args;
26612+ struct inode *h_inode;
26613+
26614+ h_inode = a->path->dentry->d_inode;
26615+ IMustLock(h_inode);
26616+
26617+ *a->errp = -EPERM;
26618+ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
1facf9fc 26619+ *a->errp = notify_change(a->path->dentry, a->ia);
1facf9fc 26620+ if (!*a->errp)
26621+ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
26622+ }
26623+ AuTraceErr(*a->errp);
26624+}
26625+
26626+int vfsub_notify_change(struct path *path, struct iattr *ia)
26627+{
26628+ int err;
26629+ struct notify_change_args args = {
26630+ .errp = &err,
26631+ .path = path,
26632+ .ia = ia
26633+ };
26634+
26635+ call_notify_change(&args);
26636+
26637+ return err;
26638+}
26639+
26640+int vfsub_sio_notify_change(struct path *path, struct iattr *ia)
26641+{
26642+ int err, wkq_err;
26643+ struct notify_change_args args = {
26644+ .errp = &err,
26645+ .path = path,
26646+ .ia = ia
26647+ };
26648+
26649+ wkq_err = au_wkq_wait(call_notify_change, &args);
26650+ if (unlikely(wkq_err))
26651+ err = wkq_err;
26652+
26653+ return err;
26654+}
26655+
26656+/* ---------------------------------------------------------------------- */
26657+
26658+struct unlink_args {
26659+ int *errp;
26660+ struct inode *dir;
26661+ struct path *path;
26662+};
26663+
26664+static void call_unlink(void *args)
26665+{
26666+ struct unlink_args *a = args;
26667+ struct dentry *d = a->path->dentry;
26668+ struct inode *h_inode;
26669+ const int stop_sillyrename = (au_test_nfs(d->d_sb)
027c5e7a 26670+ && d->d_count == 1);
1facf9fc 26671+
26672+ IMustLock(a->dir);
26673+
26674+ a->path->dentry = d->d_parent;
26675+ *a->errp = security_path_unlink(a->path, d);
26676+ a->path->dentry = d;
26677+ if (unlikely(*a->errp))
26678+ return;
26679+
26680+ if (!stop_sillyrename)
26681+ dget(d);
26682+ h_inode = d->d_inode;
26683+ if (h_inode)
027c5e7a 26684+ ihold(h_inode);
1facf9fc 26685+
2cbb1c4b 26686+ lockdep_off();
1facf9fc 26687+ *a->errp = vfs_unlink(a->dir, d);
2cbb1c4b 26688+ lockdep_on();
1facf9fc 26689+ if (!*a->errp) {
26690+ struct path tmp = {
26691+ .dentry = d->d_parent,
26692+ .mnt = a->path->mnt
26693+ };
26694+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
26695+ }
26696+
26697+ if (!stop_sillyrename)
26698+ dput(d);
26699+ if (h_inode)
26700+ iput(h_inode);
26701+
26702+ AuTraceErr(*a->errp);
26703+}
26704+
26705+/*
26706+ * @dir: must be locked.
26707+ * @dentry: target dentry.
26708+ */
26709+int vfsub_unlink(struct inode *dir, struct path *path, int force)
26710+{
26711+ int err;
26712+ struct unlink_args args = {
26713+ .errp = &err,
26714+ .dir = dir,
26715+ .path = path
26716+ };
26717+
26718+ if (!force)
26719+ call_unlink(&args);
26720+ else {
26721+ int wkq_err;
26722+
26723+ wkq_err = au_wkq_wait(call_unlink, &args);
26724+ if (unlikely(wkq_err))
26725+ err = wkq_err;
26726+ }
26727+
26728+ return err;
26729+}
7f207e10
AM
26730diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
26731--- /usr/share/empty/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
a2a7ad62 26732+++ linux/fs/aufs/vfsub.h 2013-03-14 20:07:41.224790724 +0100
537831f9 26733@@ -0,0 +1,284 @@
1facf9fc 26734+/*
7a9e40b8 26735+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 26736+ *
26737+ * This program, aufs is free software; you can redistribute it and/or modify
26738+ * it under the terms of the GNU General Public License as published by
26739+ * the Free Software Foundation; either version 2 of the License, or
26740+ * (at your option) any later version.
dece6358
AM
26741+ *
26742+ * This program is distributed in the hope that it will be useful,
26743+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26744+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26745+ * GNU General Public License for more details.
26746+ *
26747+ * You should have received a copy of the GNU General Public License
26748+ * along with this program; if not, write to the Free Software
26749+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 26750+ */
26751+
26752+/*
26753+ * sub-routines for VFS
26754+ */
26755+
26756+#ifndef __AUFS_VFSUB_H__
26757+#define __AUFS_VFSUB_H__
26758+
26759+#ifdef __KERNEL__
26760+
26761+#include <linux/fs.h>
0c5527e5 26762+#include <linux/lglock.h>
b4510431 26763+#include <linux/mount.h>
7f207e10 26764+#include "debug.h"
1facf9fc 26765+
7f207e10 26766+/* copied from linux/fs/internal.h */
2cbb1c4b 26767+/* todo: BAD approach!! */
0c3ec466 26768+extern struct lglock vfsmount_lock;
2cbb1c4b 26769+extern spinlock_t inode_sb_list_lock;
0c5527e5 26770+
7f207e10 26771+/* copied from linux/fs/file_table.c */
0c3ec466 26772+extern struct lglock files_lglock;
0c5527e5
AM
26773+#ifdef CONFIG_SMP
26774+/*
26775+ * These macros iterate all files on all CPUs for a given superblock.
26776+ * files_lglock must be held globally.
26777+ */
26778+#define do_file_list_for_each_entry(__sb, __file) \
26779+{ \
26780+ int i; \
26781+ for_each_possible_cpu(i) { \
26782+ struct list_head *list; \
26783+ list = per_cpu_ptr((__sb)->s_files, i); \
26784+ list_for_each_entry((__file), list, f_u.fu_list)
26785+
26786+#define while_file_list_for_each_entry \
26787+ } \
26788+}
26789+
26790+#else
26791+
26792+#define do_file_list_for_each_entry(__sb, __file) \
26793+{ \
26794+ struct list_head *list; \
26795+ list = &(sb)->s_files; \
26796+ list_for_each_entry((__file), list, f_u.fu_list)
26797+
26798+#define while_file_list_for_each_entry \
26799+}
7f207e10
AM
26800+#endif
26801+
26802+/* ---------------------------------------------------------------------- */
1facf9fc 26803+
26804+/* lock subclass for lower inode */
26805+/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
26806+/* reduce? gave up. */
26807+enum {
26808+ AuLsc_I_Begin = I_MUTEX_QUOTA, /* 4 */
26809+ AuLsc_I_PARENT, /* lower inode, parent first */
26810+ AuLsc_I_PARENT2, /* copyup dirs */
dece6358 26811+ AuLsc_I_PARENT3, /* copyup wh */
1facf9fc 26812+ AuLsc_I_CHILD,
26813+ AuLsc_I_CHILD2,
26814+ AuLsc_I_End
26815+};
26816+
26817+/* to debug easier, do not make them inlined functions */
26818+#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
26819+#define IMustLock(i) MtxMustLock(&(i)->i_mutex)
26820+
26821+/* ---------------------------------------------------------------------- */
26822+
7f207e10
AM
26823+static inline void vfsub_drop_nlink(struct inode *inode)
26824+{
26825+ AuDebugOn(!inode->i_nlink);
26826+ drop_nlink(inode);
26827+}
26828+
027c5e7a
AM
26829+static inline void vfsub_dead_dir(struct inode *inode)
26830+{
26831+ AuDebugOn(!S_ISDIR(inode->i_mode));
26832+ inode->i_flags |= S_DEAD;
26833+ clear_nlink(inode);
26834+}
26835+
7f207e10
AM
26836+/* ---------------------------------------------------------------------- */
26837+
0c3ec466
AM
26838+/* cf. i_[ug]id_read() in linux/include/fs.h */
26839+static inline uid_t vfsub_ia_uid(struct iattr *ia)
26840+{
26841+ return from_kuid(&init_user_ns, ia->ia_uid);
26842+}
26843+
26844+static inline gid_t vfsub_ia_gid(struct iattr *ia)
26845+{
26846+ return from_kgid(&init_user_ns, ia->ia_gid);
26847+}
26848+
26849+/* ---------------------------------------------------------------------- */
26850+
7f207e10
AM
26851+int vfsub_update_h_iattr(struct path *h_path, int *did);
26852+struct file *vfsub_dentry_open(struct path *path, int flags);
26853+struct file *vfsub_filp_open(const char *path, int oflags, int mode);
1facf9fc 26854+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
b4510431 26855+
1facf9fc 26856+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
26857+ int len);
b4510431
AM
26858+
26859+struct vfsub_lkup_one_args {
26860+ struct dentry **errp;
26861+ struct qstr *name;
26862+ struct dentry *parent;
26863+};
26864+
26865+static inline struct dentry *vfsub_lkup_one(struct qstr *name,
26866+ struct dentry *parent)
26867+{
26868+ return vfsub_lookup_one_len(name->name, parent, name->len);
26869+}
26870+
26871+void vfsub_call_lkup_one(void *args);
26872+
26873+/* ---------------------------------------------------------------------- */
26874+
26875+static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
26876+{
26877+ int err;
26878+ lockdep_off();
26879+ err = mnt_want_write(mnt);
26880+ lockdep_on();
26881+ return err;
26882+}
26883+
26884+static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
26885+{
26886+ lockdep_off();
26887+ mnt_drop_write(mnt);
26888+ lockdep_on();
26889+}
1facf9fc 26890+
26891+/* ---------------------------------------------------------------------- */
26892+
26893+struct au_hinode;
26894+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
26895+ struct dentry *d2, struct au_hinode *hdir2);
26896+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
26897+ struct dentry *d2, struct au_hinode *hdir2);
26898+
537831f9
AM
26899+int vfsub_create(struct inode *dir, struct path *path, int mode,
26900+ bool want_excl);
1facf9fc 26901+int vfsub_symlink(struct inode *dir, struct path *path,
26902+ const char *symname);
26903+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
26904+int vfsub_link(struct dentry *src_dentry, struct inode *dir,
26905+ struct path *path);
26906+int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
26907+ struct inode *hdir, struct path *path);
26908+int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
26909+int vfsub_rmdir(struct inode *dir, struct path *path);
26910+
26911+/* ---------------------------------------------------------------------- */
26912+
26913+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
26914+ loff_t *ppos);
26915+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
26916+ loff_t *ppos);
26917+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
26918+ loff_t *ppos);
26919+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
26920+ loff_t *ppos);
4a4d8108 26921+int vfsub_flush(struct file *file, fl_owner_t id);
1facf9fc 26922+int vfsub_readdir(struct file *file, filldir_t filldir, void *arg);
26923+
4a4d8108
AM
26924+static inline unsigned int vfsub_file_flags(struct file *file)
26925+{
26926+ unsigned int flags;
26927+
26928+ spin_lock(&file->f_lock);
26929+ flags = file->f_flags;
26930+ spin_unlock(&file->f_lock);
26931+
26932+ return flags;
26933+}
1308ab2a 26934+
1facf9fc 26935+static inline void vfsub_file_accessed(struct file *h_file)
26936+{
26937+ file_accessed(h_file);
26938+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
26939+}
26940+
26941+static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
26942+ struct dentry *h_dentry)
26943+{
26944+ struct path h_path = {
26945+ .dentry = h_dentry,
26946+ .mnt = h_mnt
26947+ };
92d182d2 26948+ touch_atime(&h_path);
1facf9fc 26949+ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
26950+}
26951+
0c3ec466
AM
26952+static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts,
26953+ int flags)
26954+{
26955+ return update_time(h_inode, ts, flags);
26956+ /* no vfsub_update_h_iattr() since we don't have struct path */
26957+}
26958+
4a4d8108
AM
26959+long vfsub_splice_to(struct file *in, loff_t *ppos,
26960+ struct pipe_inode_info *pipe, size_t len,
26961+ unsigned int flags);
26962+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
26963+ loff_t *ppos, size_t len, unsigned int flags);
26964+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
26965+ struct file *h_file);
53392da6 26966+int vfsub_fsync(struct file *file, struct path *path, int datasync);
4a4d8108 26967+
1facf9fc 26968+/* ---------------------------------------------------------------------- */
26969+
26970+static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
26971+{
26972+ loff_t err;
26973+
2cbb1c4b 26974+ lockdep_off();
1facf9fc 26975+ err = vfs_llseek(file, offset, origin);
2cbb1c4b 26976+ lockdep_on();
1facf9fc 26977+ return err;
26978+}
26979+
26980+/* ---------------------------------------------------------------------- */
26981+
26982+/* dirty workaround for strict type of fmode_t */
26983+union vfsub_fmu {
26984+ fmode_t fm;
26985+ unsigned int ui;
26986+};
26987+
26988+static inline unsigned int vfsub_fmode_to_uint(fmode_t fm)
26989+{
26990+ union vfsub_fmu u = {
26991+ .fm = fm
26992+ };
26993+
26994+ BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui));
26995+
26996+ return u.ui;
26997+}
26998+
26999+static inline fmode_t vfsub_uint_to_fmode(unsigned int ui)
27000+{
27001+ union vfsub_fmu u = {
27002+ .ui = ui
27003+ };
27004+
27005+ return u.fm;
27006+}
27007+
4a4d8108
AM
27008+/* ---------------------------------------------------------------------- */
27009+
27010+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
27011+int vfsub_sio_rmdir(struct inode *dir, struct path *path);
27012+int vfsub_sio_notify_change(struct path *path, struct iattr *ia);
27013+int vfsub_notify_change(struct path *path, struct iattr *ia);
27014+int vfsub_unlink(struct inode *dir, struct path *path, int force);
27015+
1facf9fc 27016+#endif /* __KERNEL__ */
27017+#endif /* __AUFS_VFSUB_H__ */
7f207e10
AM
27018diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
27019--- /usr/share/empty/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100
1716fcea 27020+++ linux/fs/aufs/wbr_policy.c 2013-02-19 08:40:03.953559833 +0100
027c5e7a 27021@@ -0,0 +1,700 @@
1facf9fc 27022+/*
7a9e40b8 27023+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 27024+ *
27025+ * This program, aufs is free software; you can redistribute it and/or modify
27026+ * it under the terms of the GNU General Public License as published by
27027+ * the Free Software Foundation; either version 2 of the License, or
27028+ * (at your option) any later version.
dece6358
AM
27029+ *
27030+ * This program is distributed in the hope that it will be useful,
27031+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27032+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27033+ * GNU General Public License for more details.
27034+ *
27035+ * You should have received a copy of the GNU General Public License
27036+ * along with this program; if not, write to the Free Software
27037+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 27038+ */
27039+
27040+/*
27041+ * policies for selecting one among multiple writable branches
27042+ */
27043+
27044+#include <linux/statfs.h>
27045+#include "aufs.h"
27046+
27047+/* subset of cpup_attr() */
27048+static noinline_for_stack
27049+int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
27050+{
27051+ int err, sbits;
27052+ struct iattr ia;
27053+ struct inode *h_isrc;
27054+
27055+ h_isrc = h_src->d_inode;
27056+ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
27057+ ia.ia_mode = h_isrc->i_mode;
27058+ ia.ia_uid = h_isrc->i_uid;
27059+ ia.ia_gid = h_isrc->i_gid;
27060+ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
27061+ au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc);
27062+ err = vfsub_sio_notify_change(h_path, &ia);
27063+
27064+ /* is this nfs only? */
27065+ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
27066+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
27067+ ia.ia_mode = h_isrc->i_mode;
27068+ err = vfsub_sio_notify_change(h_path, &ia);
27069+ }
27070+
27071+ return err;
27072+}
27073+
27074+#define AuCpdown_PARENT_OPQ 1
27075+#define AuCpdown_WHED (1 << 1)
27076+#define AuCpdown_MADE_DIR (1 << 2)
27077+#define AuCpdown_DIROPQ (1 << 3)
27078+#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name)
7f207e10
AM
27079+#define au_fset_cpdown(flags, name) \
27080+ do { (flags) |= AuCpdown_##name; } while (0)
27081+#define au_fclr_cpdown(flags, name) \
27082+ do { (flags) &= ~AuCpdown_##name; } while (0)
1facf9fc 27083+
27084+struct au_cpdown_dir_args {
27085+ struct dentry *parent;
27086+ unsigned int flags;
27087+};
27088+
27089+static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
27090+ struct au_cpdown_dir_args *a)
27091+{
27092+ int err;
27093+ struct dentry *opq_dentry;
27094+
27095+ opq_dentry = au_diropq_create(dentry, bdst);
27096+ err = PTR_ERR(opq_dentry);
27097+ if (IS_ERR(opq_dentry))
27098+ goto out;
27099+ dput(opq_dentry);
27100+ au_fset_cpdown(a->flags, DIROPQ);
27101+
4f0767ce 27102+out:
1facf9fc 27103+ return err;
27104+}
27105+
27106+static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
27107+ struct inode *dir, aufs_bindex_t bdst)
27108+{
27109+ int err;
27110+ struct path h_path;
27111+ struct au_branch *br;
27112+
27113+ br = au_sbr(dentry->d_sb, bdst);
27114+ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
27115+ err = PTR_ERR(h_path.dentry);
27116+ if (IS_ERR(h_path.dentry))
27117+ goto out;
27118+
27119+ err = 0;
27120+ if (h_path.dentry->d_inode) {
27121+ h_path.mnt = br->br_mnt;
27122+ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
27123+ dentry);
27124+ }
27125+ dput(h_path.dentry);
27126+
4f0767ce 27127+out:
1facf9fc 27128+ return err;
27129+}
27130+
27131+static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
27132+ struct dentry *h_parent, void *arg)
27133+{
27134+ int err, rerr;
4a4d8108 27135+ aufs_bindex_t bopq, bstart;
1facf9fc 27136+ struct path h_path;
27137+ struct dentry *parent;
27138+ struct inode *h_dir, *h_inode, *inode, *dir;
27139+ struct au_cpdown_dir_args *args = arg;
27140+
27141+ bstart = au_dbstart(dentry);
27142+ /* dentry is di-locked */
27143+ parent = dget_parent(dentry);
27144+ dir = parent->d_inode;
27145+ h_dir = h_parent->d_inode;
27146+ AuDebugOn(h_dir != au_h_iptr(dir, bdst));
27147+ IMustLock(h_dir);
27148+
27149+ err = au_lkup_neg(dentry, bdst);
27150+ if (unlikely(err < 0))
27151+ goto out;
27152+ h_path.dentry = au_h_dptr(dentry, bdst);
27153+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
27154+ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path,
27155+ S_IRWXU | S_IRUGO | S_IXUGO);
27156+ if (unlikely(err))
27157+ goto out_put;
27158+ au_fset_cpdown(args->flags, MADE_DIR);
27159+
1facf9fc 27160+ bopq = au_dbdiropq(dentry);
27161+ au_fclr_cpdown(args->flags, WHED);
27162+ au_fclr_cpdown(args->flags, DIROPQ);
27163+ if (au_dbwh(dentry) == bdst)
27164+ au_fset_cpdown(args->flags, WHED);
27165+ if (!au_ftest_cpdown(args->flags, PARENT_OPQ) && bopq <= bdst)
27166+ au_fset_cpdown(args->flags, PARENT_OPQ);
1facf9fc 27167+ h_inode = h_path.dentry->d_inode;
27168+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
27169+ if (au_ftest_cpdown(args->flags, WHED)) {
27170+ err = au_cpdown_dir_opq(dentry, bdst, args);
27171+ if (unlikely(err)) {
27172+ mutex_unlock(&h_inode->i_mutex);
27173+ goto out_dir;
27174+ }
27175+ }
27176+
27177+ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart));
27178+ mutex_unlock(&h_inode->i_mutex);
27179+ if (unlikely(err))
27180+ goto out_opq;
27181+
27182+ if (au_ftest_cpdown(args->flags, WHED)) {
27183+ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
27184+ if (unlikely(err))
27185+ goto out_opq;
27186+ }
27187+
27188+ inode = dentry->d_inode;
27189+ if (au_ibend(inode) < bdst)
27190+ au_set_ibend(inode, bdst);
27191+ au_set_h_iptr(inode, bdst, au_igrab(h_inode),
27192+ au_hi_flags(inode, /*isdir*/1));
27193+ goto out; /* success */
27194+
27195+ /* revert */
4f0767ce 27196+out_opq:
1facf9fc 27197+ if (au_ftest_cpdown(args->flags, DIROPQ)) {
27198+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
27199+ rerr = au_diropq_remove(dentry, bdst);
27200+ mutex_unlock(&h_inode->i_mutex);
27201+ if (unlikely(rerr)) {
27202+ AuIOErr("failed removing diropq for %.*s b%d (%d)\n",
27203+ AuDLNPair(dentry), bdst, rerr);
27204+ err = -EIO;
27205+ goto out;
27206+ }
27207+ }
4f0767ce 27208+out_dir:
1facf9fc 27209+ if (au_ftest_cpdown(args->flags, MADE_DIR)) {
27210+ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
27211+ if (unlikely(rerr)) {
27212+ AuIOErr("failed removing %.*s b%d (%d)\n",
27213+ AuDLNPair(dentry), bdst, rerr);
27214+ err = -EIO;
27215+ }
27216+ }
4f0767ce 27217+out_put:
1facf9fc 27218+ au_set_h_dptr(dentry, bdst, NULL);
27219+ if (au_dbend(dentry) == bdst)
27220+ au_update_dbend(dentry);
4f0767ce 27221+out:
1facf9fc 27222+ dput(parent);
27223+ return err;
27224+}
27225+
27226+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
27227+{
27228+ int err;
27229+ struct au_cpdown_dir_args args = {
27230+ .parent = dget_parent(dentry),
27231+ .flags = 0
27232+ };
27233+
27234+ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &args);
27235+ dput(args.parent);
27236+
27237+ return err;
27238+}
27239+
27240+/* ---------------------------------------------------------------------- */
27241+
27242+/* policies for create */
27243+
4a4d8108
AM
27244+static int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex)
27245+{
27246+ int err, i, j, ndentry;
27247+ aufs_bindex_t bopq;
27248+ struct au_dcsub_pages dpages;
27249+ struct au_dpage *dpage;
27250+ struct dentry **dentries, *parent, *d;
27251+
27252+ err = au_dpages_init(&dpages, GFP_NOFS);
27253+ if (unlikely(err))
27254+ goto out;
27255+ parent = dget_parent(dentry);
027c5e7a 27256+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0);
4a4d8108
AM
27257+ if (unlikely(err))
27258+ goto out_free;
27259+
27260+ err = bindex;
27261+ for (i = 0; i < dpages.ndpage; i++) {
27262+ dpage = dpages.dpages + i;
27263+ dentries = dpage->dentries;
27264+ ndentry = dpage->ndentry;
27265+ for (j = 0; j < ndentry; j++) {
27266+ d = dentries[j];
27267+ di_read_lock_parent2(d, !AuLock_IR);
27268+ bopq = au_dbdiropq(d);
27269+ di_read_unlock(d, !AuLock_IR);
27270+ if (bopq >= 0 && bopq < err)
27271+ err = bopq;
27272+ }
27273+ }
27274+
27275+out_free:
27276+ dput(parent);
27277+ au_dpages_free(&dpages);
27278+out:
27279+ return err;
27280+}
27281+
1facf9fc 27282+static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
27283+{
27284+ for (; bindex >= 0; bindex--)
27285+ if (!au_br_rdonly(au_sbr(sb, bindex)))
27286+ return bindex;
27287+ return -EROFS;
27288+}
27289+
27290+/* top down parent */
27291+static int au_wbr_create_tdp(struct dentry *dentry, int isdir __maybe_unused)
27292+{
27293+ int err;
27294+ aufs_bindex_t bstart, bindex;
27295+ struct super_block *sb;
27296+ struct dentry *parent, *h_parent;
27297+
27298+ sb = dentry->d_sb;
27299+ bstart = au_dbstart(dentry);
27300+ err = bstart;
27301+ if (!au_br_rdonly(au_sbr(sb, bstart)))
27302+ goto out;
27303+
27304+ err = -EROFS;
27305+ parent = dget_parent(dentry);
27306+ for (bindex = au_dbstart(parent); bindex < bstart; bindex++) {
27307+ h_parent = au_h_dptr(parent, bindex);
27308+ if (!h_parent || !h_parent->d_inode)
27309+ continue;
27310+
27311+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
27312+ err = bindex;
27313+ break;
27314+ }
27315+ }
27316+ dput(parent);
27317+
27318+ /* bottom up here */
4a4d8108 27319+ if (unlikely(err < 0)) {
1facf9fc 27320+ err = au_wbr_bu(sb, bstart - 1);
4a4d8108
AM
27321+ if (err >= 0)
27322+ err = au_wbr_nonopq(dentry, err);
27323+ }
1facf9fc 27324+
4f0767ce 27325+out:
1facf9fc 27326+ AuDbg("b%d\n", err);
27327+ return err;
27328+}
27329+
27330+/* ---------------------------------------------------------------------- */
27331+
27332+/* an exception for the policy other than tdp */
27333+static int au_wbr_create_exp(struct dentry *dentry)
27334+{
27335+ int err;
27336+ aufs_bindex_t bwh, bdiropq;
27337+ struct dentry *parent;
27338+
27339+ err = -1;
27340+ bwh = au_dbwh(dentry);
27341+ parent = dget_parent(dentry);
27342+ bdiropq = au_dbdiropq(parent);
27343+ if (bwh >= 0) {
27344+ if (bdiropq >= 0)
27345+ err = min(bdiropq, bwh);
27346+ else
27347+ err = bwh;
27348+ AuDbg("%d\n", err);
27349+ } else if (bdiropq >= 0) {
27350+ err = bdiropq;
27351+ AuDbg("%d\n", err);
27352+ }
27353+ dput(parent);
27354+
4a4d8108
AM
27355+ if (err >= 0)
27356+ err = au_wbr_nonopq(dentry, err);
27357+
1facf9fc 27358+ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
27359+ err = -1;
27360+
27361+ AuDbg("%d\n", err);
27362+ return err;
27363+}
27364+
27365+/* ---------------------------------------------------------------------- */
27366+
27367+/* round robin */
27368+static int au_wbr_create_init_rr(struct super_block *sb)
27369+{
27370+ int err;
27371+
27372+ err = au_wbr_bu(sb, au_sbend(sb));
27373+ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
dece6358 27374+ /* smp_mb(); */
1facf9fc 27375+
27376+ AuDbg("b%d\n", err);
27377+ return err;
27378+}
27379+
27380+static int au_wbr_create_rr(struct dentry *dentry, int isdir)
27381+{
27382+ int err, nbr;
27383+ unsigned int u;
27384+ aufs_bindex_t bindex, bend;
27385+ struct super_block *sb;
27386+ atomic_t *next;
27387+
27388+ err = au_wbr_create_exp(dentry);
27389+ if (err >= 0)
27390+ goto out;
27391+
27392+ sb = dentry->d_sb;
27393+ next = &au_sbi(sb)->si_wbr_rr_next;
27394+ bend = au_sbend(sb);
27395+ nbr = bend + 1;
27396+ for (bindex = 0; bindex <= bend; bindex++) {
27397+ if (!isdir) {
27398+ err = atomic_dec_return(next) + 1;
27399+ /* modulo for 0 is meaningless */
27400+ if (unlikely(!err))
27401+ err = atomic_dec_return(next) + 1;
27402+ } else
27403+ err = atomic_read(next);
27404+ AuDbg("%d\n", err);
27405+ u = err;
27406+ err = u % nbr;
27407+ AuDbg("%d\n", err);
27408+ if (!au_br_rdonly(au_sbr(sb, err)))
27409+ break;
27410+ err = -EROFS;
27411+ }
27412+
4a4d8108
AM
27413+ if (err >= 0)
27414+ err = au_wbr_nonopq(dentry, err);
27415+
4f0767ce 27416+out:
1facf9fc 27417+ AuDbg("%d\n", err);
27418+ return err;
27419+}
27420+
27421+/* ---------------------------------------------------------------------- */
27422+
27423+/* most free space */
27424+static void au_mfs(struct dentry *dentry)
27425+{
27426+ struct super_block *sb;
27427+ struct au_branch *br;
27428+ struct au_wbr_mfs *mfs;
27429+ aufs_bindex_t bindex, bend;
27430+ int err;
27431+ unsigned long long b, bavail;
7f207e10 27432+ struct path h_path;
1facf9fc 27433+ /* reduce the stack usage */
27434+ struct kstatfs *st;
27435+
27436+ st = kmalloc(sizeof(*st), GFP_NOFS);
27437+ if (unlikely(!st)) {
27438+ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
27439+ return;
27440+ }
27441+
27442+ bavail = 0;
27443+ sb = dentry->d_sb;
27444+ mfs = &au_sbi(sb)->si_wbr_mfs;
dece6358 27445+ MtxMustLock(&mfs->mfs_lock);
1facf9fc 27446+ mfs->mfs_bindex = -EROFS;
27447+ mfs->mfsrr_bytes = 0;
27448+ bend = au_sbend(sb);
27449+ for (bindex = 0; bindex <= bend; bindex++) {
27450+ br = au_sbr(sb, bindex);
27451+ if (au_br_rdonly(br))
27452+ continue;
27453+
27454+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
27455+ h_path.mnt = br->br_mnt;
27456+ h_path.dentry = h_path.mnt->mnt_root;
27457+ err = vfs_statfs(&h_path, st);
1facf9fc 27458+ if (unlikely(err)) {
27459+ AuWarn1("failed statfs, b%d, %d\n", bindex, err);
27460+ continue;
27461+ }
27462+
27463+ /* when the available size is equal, select the lower one */
27464+ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
27465+ || sizeof(b) < sizeof(st->f_bsize));
27466+ b = st->f_bavail * st->f_bsize;
27467+ br->br_wbr->wbr_bytes = b;
27468+ if (b >= bavail) {
27469+ bavail = b;
27470+ mfs->mfs_bindex = bindex;
27471+ mfs->mfs_jiffy = jiffies;
27472+ }
27473+ }
27474+
27475+ mfs->mfsrr_bytes = bavail;
27476+ AuDbg("b%d\n", mfs->mfs_bindex);
27477+ kfree(st);
27478+}
27479+
27480+static int au_wbr_create_mfs(struct dentry *dentry, int isdir __maybe_unused)
27481+{
27482+ int err;
27483+ struct super_block *sb;
27484+ struct au_wbr_mfs *mfs;
27485+
27486+ err = au_wbr_create_exp(dentry);
27487+ if (err >= 0)
27488+ goto out;
27489+
27490+ sb = dentry->d_sb;
27491+ mfs = &au_sbi(sb)->si_wbr_mfs;
27492+ mutex_lock(&mfs->mfs_lock);
27493+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
27494+ || mfs->mfs_bindex < 0
27495+ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
27496+ au_mfs(dentry);
27497+ mutex_unlock(&mfs->mfs_lock);
27498+ err = mfs->mfs_bindex;
27499+
4a4d8108
AM
27500+ if (err >= 0)
27501+ err = au_wbr_nonopq(dentry, err);
27502+
4f0767ce 27503+out:
1facf9fc 27504+ AuDbg("b%d\n", err);
27505+ return err;
27506+}
27507+
27508+static int au_wbr_create_init_mfs(struct super_block *sb)
27509+{
27510+ struct au_wbr_mfs *mfs;
27511+
27512+ mfs = &au_sbi(sb)->si_wbr_mfs;
27513+ mutex_init(&mfs->mfs_lock);
27514+ mfs->mfs_jiffy = 0;
27515+ mfs->mfs_bindex = -EROFS;
27516+
27517+ return 0;
27518+}
27519+
27520+static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
27521+{
27522+ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
27523+ return 0;
27524+}
27525+
27526+/* ---------------------------------------------------------------------- */
27527+
27528+/* most free space and then round robin */
27529+static int au_wbr_create_mfsrr(struct dentry *dentry, int isdir)
27530+{
27531+ int err;
27532+ struct au_wbr_mfs *mfs;
27533+
27534+ err = au_wbr_create_mfs(dentry, isdir);
27535+ if (err >= 0) {
27536+ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
dece6358 27537+ mutex_lock(&mfs->mfs_lock);
1facf9fc 27538+ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
27539+ err = au_wbr_create_rr(dentry, isdir);
dece6358 27540+ mutex_unlock(&mfs->mfs_lock);
1facf9fc 27541+ }
27542+
27543+ AuDbg("b%d\n", err);
27544+ return err;
27545+}
27546+
27547+static int au_wbr_create_init_mfsrr(struct super_block *sb)
27548+{
27549+ int err;
27550+
27551+ au_wbr_create_init_mfs(sb); /* ignore */
27552+ err = au_wbr_create_init_rr(sb);
27553+
27554+ return err;
27555+}
27556+
27557+/* ---------------------------------------------------------------------- */
27558+
27559+/* top down parent and most free space */
27560+static int au_wbr_create_pmfs(struct dentry *dentry, int isdir)
27561+{
27562+ int err, e2;
27563+ unsigned long long b;
27564+ aufs_bindex_t bindex, bstart, bend;
27565+ struct super_block *sb;
27566+ struct dentry *parent, *h_parent;
27567+ struct au_branch *br;
27568+
27569+ err = au_wbr_create_tdp(dentry, isdir);
27570+ if (unlikely(err < 0))
27571+ goto out;
27572+ parent = dget_parent(dentry);
27573+ bstart = au_dbstart(parent);
27574+ bend = au_dbtaildir(parent);
27575+ if (bstart == bend)
27576+ goto out_parent; /* success */
27577+
27578+ e2 = au_wbr_create_mfs(dentry, isdir);
27579+ if (e2 < 0)
27580+ goto out_parent; /* success */
27581+
27582+ /* when the available size is equal, select upper one */
27583+ sb = dentry->d_sb;
27584+ br = au_sbr(sb, err);
27585+ b = br->br_wbr->wbr_bytes;
27586+ AuDbg("b%d, %llu\n", err, b);
27587+
27588+ for (bindex = bstart; bindex <= bend; bindex++) {
27589+ h_parent = au_h_dptr(parent, bindex);
27590+ if (!h_parent || !h_parent->d_inode)
27591+ continue;
27592+
27593+ br = au_sbr(sb, bindex);
27594+ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
27595+ b = br->br_wbr->wbr_bytes;
27596+ err = bindex;
27597+ AuDbg("b%d, %llu\n", err, b);
27598+ }
27599+ }
27600+
4a4d8108
AM
27601+ if (err >= 0)
27602+ err = au_wbr_nonopq(dentry, err);
27603+
4f0767ce 27604+out_parent:
1facf9fc 27605+ dput(parent);
4f0767ce 27606+out:
1facf9fc 27607+ AuDbg("b%d\n", err);
27608+ return err;
27609+}
27610+
27611+/* ---------------------------------------------------------------------- */
27612+
27613+/* policies for copyup */
27614+
27615+/* top down parent */
27616+static int au_wbr_copyup_tdp(struct dentry *dentry)
27617+{
27618+ return au_wbr_create_tdp(dentry, /*isdir, anything is ok*/0);
27619+}
27620+
27621+/* bottom up parent */
27622+static int au_wbr_copyup_bup(struct dentry *dentry)
27623+{
27624+ int err;
27625+ aufs_bindex_t bindex, bstart;
27626+ struct dentry *parent, *h_parent;
27627+ struct super_block *sb;
27628+
27629+ err = -EROFS;
27630+ sb = dentry->d_sb;
27631+ parent = dget_parent(dentry);
27632+ bstart = au_dbstart(parent);
27633+ for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) {
27634+ h_parent = au_h_dptr(parent, bindex);
27635+ if (!h_parent || !h_parent->d_inode)
27636+ continue;
27637+
27638+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
27639+ err = bindex;
27640+ break;
27641+ }
27642+ }
27643+ dput(parent);
27644+
27645+ /* bottom up here */
27646+ if (unlikely(err < 0))
27647+ err = au_wbr_bu(sb, bstart - 1);
27648+
27649+ AuDbg("b%d\n", err);
27650+ return err;
27651+}
27652+
27653+/* bottom up */
27654+static int au_wbr_copyup_bu(struct dentry *dentry)
27655+{
27656+ int err;
4a4d8108 27657+ aufs_bindex_t bstart;
1facf9fc 27658+
4a4d8108
AM
27659+ bstart = au_dbstart(dentry);
27660+ err = au_wbr_bu(dentry->d_sb, bstart);
27661+ AuDbg("b%d\n", err);
27662+ if (err > bstart)
27663+ err = au_wbr_nonopq(dentry, err);
1facf9fc 27664+
27665+ AuDbg("b%d\n", err);
27666+ return err;
27667+}
27668+
27669+/* ---------------------------------------------------------------------- */
27670+
27671+struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
27672+ [AuWbrCopyup_TDP] = {
27673+ .copyup = au_wbr_copyup_tdp
27674+ },
27675+ [AuWbrCopyup_BUP] = {
27676+ .copyup = au_wbr_copyup_bup
27677+ },
27678+ [AuWbrCopyup_BU] = {
27679+ .copyup = au_wbr_copyup_bu
27680+ }
27681+};
27682+
27683+struct au_wbr_create_operations au_wbr_create_ops[] = {
27684+ [AuWbrCreate_TDP] = {
27685+ .create = au_wbr_create_tdp
27686+ },
27687+ [AuWbrCreate_RR] = {
27688+ .create = au_wbr_create_rr,
27689+ .init = au_wbr_create_init_rr
27690+ },
27691+ [AuWbrCreate_MFS] = {
27692+ .create = au_wbr_create_mfs,
27693+ .init = au_wbr_create_init_mfs,
27694+ .fin = au_wbr_create_fin_mfs
27695+ },
27696+ [AuWbrCreate_MFSV] = {
27697+ .create = au_wbr_create_mfs,
27698+ .init = au_wbr_create_init_mfs,
27699+ .fin = au_wbr_create_fin_mfs
27700+ },
27701+ [AuWbrCreate_MFSRR] = {
27702+ .create = au_wbr_create_mfsrr,
27703+ .init = au_wbr_create_init_mfsrr,
27704+ .fin = au_wbr_create_fin_mfs
27705+ },
27706+ [AuWbrCreate_MFSRRV] = {
27707+ .create = au_wbr_create_mfsrr,
27708+ .init = au_wbr_create_init_mfsrr,
27709+ .fin = au_wbr_create_fin_mfs
27710+ },
27711+ [AuWbrCreate_PMFS] = {
27712+ .create = au_wbr_create_pmfs,
27713+ .init = au_wbr_create_init_mfs,
27714+ .fin = au_wbr_create_fin_mfs
27715+ },
27716+ [AuWbrCreate_PMFSV] = {
27717+ .create = au_wbr_create_pmfs,
27718+ .init = au_wbr_create_init_mfs,
27719+ .fin = au_wbr_create_fin_mfs
27720+ }
27721+};
7f207e10
AM
27722diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
27723--- /usr/share/empty/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100
a2a7ad62 27724+++ linux/fs/aufs/whout.c 2013-03-14 20:07:41.224790724 +0100
b4510431 27725@@ -0,0 +1,1042 @@
1facf9fc 27726+/*
7a9e40b8 27727+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 27728+ *
27729+ * This program, aufs is free software; you can redistribute it and/or modify
27730+ * it under the terms of the GNU General Public License as published by
27731+ * the Free Software Foundation; either version 2 of the License, or
27732+ * (at your option) any later version.
dece6358
AM
27733+ *
27734+ * This program is distributed in the hope that it will be useful,
27735+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27736+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27737+ * GNU General Public License for more details.
27738+ *
27739+ * You should have received a copy of the GNU General Public License
27740+ * along with this program; if not, write to the Free Software
27741+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 27742+ */
27743+
27744+/*
27745+ * whiteout for logical deletion and opaque directory
27746+ */
27747+
1facf9fc 27748+#include "aufs.h"
27749+
27750+#define WH_MASK S_IRUGO
27751+
27752+/*
27753+ * If a directory contains this file, then it is opaque. We start with the
27754+ * .wh. flag so that it is blocked by lookup.
27755+ */
0c3ec466
AM
27756+static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ,
27757+ sizeof(AUFS_WH_DIROPQ) - 1);
1facf9fc 27758+
27759+/*
27760+ * generate whiteout name, which is NOT terminated by NULL.
27761+ * @name: original d_name.name
27762+ * @len: original d_name.len
27763+ * @wh: whiteout qstr
27764+ * returns zero when succeeds, otherwise error.
27765+ * succeeded value as wh->name should be freed by kfree().
27766+ */
27767+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
27768+{
27769+ char *p;
27770+
27771+ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
27772+ return -ENAMETOOLONG;
27773+
27774+ wh->len = name->len + AUFS_WH_PFX_LEN;
27775+ p = kmalloc(wh->len, GFP_NOFS);
27776+ wh->name = p;
27777+ if (p) {
27778+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
27779+ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
27780+ /* smp_mb(); */
27781+ return 0;
27782+ }
27783+ return -ENOMEM;
27784+}
27785+
27786+/* ---------------------------------------------------------------------- */
27787+
27788+/*
27789+ * test if the @wh_name exists under @h_parent.
27790+ * @try_sio specifies the necessary of super-io.
27791+ */
27792+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
27793+ struct au_branch *br, int try_sio)
27794+{
27795+ int err;
27796+ struct dentry *wh_dentry;
1facf9fc 27797+
1facf9fc 27798+ if (!try_sio)
b4510431 27799+ wh_dentry = vfsub_lkup_one(wh_name, h_parent);
1facf9fc 27800+ else
27801+ wh_dentry = au_sio_lkup_one(wh_name, h_parent, br);
27802+ err = PTR_ERR(wh_dentry);
27803+ if (IS_ERR(wh_dentry))
27804+ goto out;
27805+
27806+ err = 0;
27807+ if (!wh_dentry->d_inode)
27808+ goto out_wh; /* success */
27809+
27810+ err = 1;
27811+ if (S_ISREG(wh_dentry->d_inode->i_mode))
27812+ goto out_wh; /* success */
27813+
27814+ err = -EIO;
27815+ AuIOErr("%.*s Invalid whiteout entry type 0%o.\n",
27816+ AuDLNPair(wh_dentry), wh_dentry->d_inode->i_mode);
27817+
4f0767ce 27818+out_wh:
1facf9fc 27819+ dput(wh_dentry);
4f0767ce 27820+out:
1facf9fc 27821+ return err;
27822+}
27823+
27824+/*
27825+ * test if the @h_dentry sets opaque or not.
27826+ */
27827+int au_diropq_test(struct dentry *h_dentry, struct au_branch *br)
27828+{
27829+ int err;
27830+ struct inode *h_dir;
27831+
27832+ h_dir = h_dentry->d_inode;
27833+ err = au_wh_test(h_dentry, &diropq_name, br,
27834+ au_test_h_perm_sio(h_dir, MAY_EXEC));
27835+ return err;
27836+}
27837+
27838+/*
27839+ * returns a negative dentry whose name is unique and temporary.
27840+ */
27841+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
27842+ struct qstr *prefix)
27843+{
1facf9fc 27844+ struct dentry *dentry;
27845+ int i;
027c5e7a 27846+ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
4a4d8108 27847+ *name, *p;
027c5e7a 27848+ /* strict atomic_t is unnecessary here */
1facf9fc 27849+ static unsigned short cnt;
27850+ struct qstr qs;
27851+
4a4d8108
AM
27852+ BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
27853+
1facf9fc 27854+ name = defname;
027c5e7a
AM
27855+ qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
27856+ if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
1facf9fc 27857+ dentry = ERR_PTR(-ENAMETOOLONG);
4a4d8108 27858+ if (unlikely(qs.len > NAME_MAX))
1facf9fc 27859+ goto out;
27860+ dentry = ERR_PTR(-ENOMEM);
27861+ name = kmalloc(qs.len + 1, GFP_NOFS);
27862+ if (unlikely(!name))
27863+ goto out;
27864+ }
27865+
27866+ /* doubly whiteout-ed */
27867+ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
27868+ p = name + AUFS_WH_PFX_LEN * 2;
27869+ memcpy(p, prefix->name, prefix->len);
27870+ p += prefix->len;
27871+ *p++ = '.';
4a4d8108 27872+ AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
1facf9fc 27873+
27874+ qs.name = name;
27875+ for (i = 0; i < 3; i++) {
b752ccd1 27876+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
1facf9fc 27877+ dentry = au_sio_lkup_one(&qs, h_parent, br);
27878+ if (IS_ERR(dentry) || !dentry->d_inode)
27879+ goto out_name;
27880+ dput(dentry);
27881+ }
0c3ec466 27882+ /* pr_warn("could not get random name\n"); */
1facf9fc 27883+ dentry = ERR_PTR(-EEXIST);
27884+ AuDbg("%.*s\n", AuLNPair(&qs));
27885+ BUG();
27886+
4f0767ce 27887+out_name:
1facf9fc 27888+ if (name != defname)
27889+ kfree(name);
4f0767ce 27890+out:
4a4d8108 27891+ AuTraceErrPtr(dentry);
1facf9fc 27892+ return dentry;
1facf9fc 27893+}
27894+
27895+/*
27896+ * rename the @h_dentry on @br to the whiteouted temporary name.
27897+ */
27898+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
27899+{
27900+ int err;
27901+ struct path h_path = {
27902+ .mnt = br->br_mnt
27903+ };
27904+ struct inode *h_dir;
27905+ struct dentry *h_parent;
27906+
27907+ h_parent = h_dentry->d_parent; /* dir inode is locked */
27908+ h_dir = h_parent->d_inode;
27909+ IMustLock(h_dir);
27910+
27911+ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
27912+ err = PTR_ERR(h_path.dentry);
27913+ if (IS_ERR(h_path.dentry))
27914+ goto out;
27915+
27916+ /* under the same dir, no need to lock_rename() */
27917+ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path);
27918+ AuTraceErr(err);
27919+ dput(h_path.dentry);
27920+
4f0767ce 27921+out:
4a4d8108 27922+ AuTraceErr(err);
1facf9fc 27923+ return err;
27924+}
27925+
27926+/* ---------------------------------------------------------------------- */
27927+/*
27928+ * functions for removing a whiteout
27929+ */
27930+
27931+static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
27932+{
27933+ int force;
27934+
27935+ /*
27936+ * forces superio when the dir has a sticky bit.
27937+ * this may be a violation of unix fs semantics.
27938+ */
27939+ force = (h_dir->i_mode & S_ISVTX)
0c3ec466 27940+ && !uid_eq(current_fsuid(), h_path->dentry->d_inode->i_uid);
1facf9fc 27941+ return vfsub_unlink(h_dir, h_path, force);
27942+}
27943+
27944+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
27945+ struct dentry *dentry)
27946+{
27947+ int err;
27948+
27949+ err = do_unlink_wh(h_dir, h_path);
27950+ if (!err && dentry)
27951+ au_set_dbwh(dentry, -1);
27952+
27953+ return err;
27954+}
27955+
27956+static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
27957+ struct au_branch *br)
27958+{
27959+ int err;
27960+ struct path h_path = {
27961+ .mnt = br->br_mnt
27962+ };
27963+
27964+ err = 0;
b4510431 27965+ h_path.dentry = vfsub_lkup_one(wh, h_parent);
1facf9fc 27966+ if (IS_ERR(h_path.dentry))
27967+ err = PTR_ERR(h_path.dentry);
27968+ else {
27969+ if (h_path.dentry->d_inode
27970+ && S_ISREG(h_path.dentry->d_inode->i_mode))
27971+ err = do_unlink_wh(h_parent->d_inode, &h_path);
27972+ dput(h_path.dentry);
27973+ }
27974+
27975+ return err;
27976+}
27977+
27978+/* ---------------------------------------------------------------------- */
27979+/*
27980+ * initialize/clean whiteout for a branch
27981+ */
27982+
27983+static void au_wh_clean(struct inode *h_dir, struct path *whpath,
27984+ const int isdir)
27985+{
27986+ int err;
27987+
27988+ if (!whpath->dentry->d_inode)
27989+ return;
27990+
b4510431 27991+ err = vfsub_mnt_want_write(whpath->mnt);
1facf9fc 27992+ if (!err) {
27993+ if (isdir)
27994+ err = vfsub_rmdir(h_dir, whpath);
27995+ else
27996+ err = vfsub_unlink(h_dir, whpath, /*force*/0);
b4510431 27997+ vfsub_mnt_drop_write(whpath->mnt);
1facf9fc 27998+ }
27999+ if (unlikely(err))
0c3ec466
AM
28000+ pr_warn("failed removing %.*s (%d), ignored.\n",
28001+ AuDLNPair(whpath->dentry), err);
1facf9fc 28002+}
28003+
28004+static int test_linkable(struct dentry *h_root)
28005+{
28006+ struct inode *h_dir = h_root->d_inode;
28007+
28008+ if (h_dir->i_op->link)
28009+ return 0;
28010+
4a4d8108
AM
28011+ pr_err("%.*s (%s) doesn't support link(2), use noplink and rw+nolwh\n",
28012+ AuDLNPair(h_root), au_sbtype(h_root->d_sb));
1facf9fc 28013+ return -ENOSYS;
28014+}
28015+
28016+/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
28017+static int au_whdir(struct inode *h_dir, struct path *path)
28018+{
28019+ int err;
28020+
28021+ err = -EEXIST;
28022+ if (!path->dentry->d_inode) {
28023+ int mode = S_IRWXU;
28024+
28025+ if (au_test_nfs(path->dentry->d_sb))
28026+ mode |= S_IXUGO;
b4510431 28027+ err = vfsub_mnt_want_write(path->mnt);
1facf9fc 28028+ if (!err) {
28029+ err = vfsub_mkdir(h_dir, path, mode);
b4510431 28030+ vfsub_mnt_drop_write(path->mnt);
1facf9fc 28031+ }
28032+ } else if (S_ISDIR(path->dentry->d_inode->i_mode))
28033+ err = 0;
28034+ else
4a4d8108 28035+ pr_err("unknown %.*s exists\n", AuDLNPair(path->dentry));
1facf9fc 28036+
28037+ return err;
28038+}
28039+
28040+struct au_wh_base {
28041+ const struct qstr *name;
28042+ struct dentry *dentry;
28043+};
28044+
28045+static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
28046+ struct path *h_path)
28047+{
28048+ h_path->dentry = base[AuBrWh_BASE].dentry;
28049+ au_wh_clean(h_dir, h_path, /*isdir*/0);
28050+ h_path->dentry = base[AuBrWh_PLINK].dentry;
28051+ au_wh_clean(h_dir, h_path, /*isdir*/1);
28052+ h_path->dentry = base[AuBrWh_ORPH].dentry;
28053+ au_wh_clean(h_dir, h_path, /*isdir*/1);
28054+}
28055+
28056+/*
28057+ * returns tri-state,
28058+ * minus: error, caller should print the mesage
28059+ * zero: succuess
28060+ * plus: error, caller should NOT print the mesage
28061+ */
28062+static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
28063+ int do_plink, struct au_wh_base base[],
28064+ struct path *h_path)
28065+{
28066+ int err;
28067+ struct inode *h_dir;
28068+
28069+ h_dir = h_root->d_inode;
28070+ h_path->dentry = base[AuBrWh_BASE].dentry;
28071+ au_wh_clean(h_dir, h_path, /*isdir*/0);
28072+ h_path->dentry = base[AuBrWh_PLINK].dentry;
28073+ if (do_plink) {
28074+ err = test_linkable(h_root);
28075+ if (unlikely(err)) {
28076+ err = 1;
28077+ goto out;
28078+ }
28079+
28080+ err = au_whdir(h_dir, h_path);
28081+ if (unlikely(err))
28082+ goto out;
28083+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
28084+ } else
28085+ au_wh_clean(h_dir, h_path, /*isdir*/1);
28086+ h_path->dentry = base[AuBrWh_ORPH].dentry;
28087+ err = au_whdir(h_dir, h_path);
28088+ if (unlikely(err))
28089+ goto out;
28090+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
28091+
4f0767ce 28092+out:
1facf9fc 28093+ return err;
28094+}
28095+
28096+/*
28097+ * for the moment, aufs supports the branch filesystem which does not support
28098+ * link(2). testing on FAT which does not support i_op->setattr() fully either,
28099+ * copyup failed. finally, such filesystem will not be used as the writable
28100+ * branch.
28101+ *
28102+ * returns tri-state, see above.
28103+ */
28104+static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
28105+ int do_plink, struct au_wh_base base[],
28106+ struct path *h_path)
28107+{
28108+ int err;
28109+ struct inode *h_dir;
28110+
1308ab2a 28111+ WbrWhMustWriteLock(wbr);
28112+
1facf9fc 28113+ err = test_linkable(h_root);
28114+ if (unlikely(err)) {
28115+ err = 1;
28116+ goto out;
28117+ }
28118+
28119+ /*
28120+ * todo: should this create be done in /sbin/mount.aufs helper?
28121+ */
28122+ err = -EEXIST;
28123+ h_dir = h_root->d_inode;
28124+ if (!base[AuBrWh_BASE].dentry->d_inode) {
b4510431 28125+ err = vfsub_mnt_want_write(h_path->mnt);
1facf9fc 28126+ if (!err) {
28127+ h_path->dentry = base[AuBrWh_BASE].dentry;
b4510431
AM
28128+ err = vfsub_create(h_dir, h_path, WH_MASK,
28129+ /*want_excl*/true);
28130+ vfsub_mnt_drop_write(h_path->mnt);
1facf9fc 28131+ }
28132+ } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode))
28133+ err = 0;
28134+ else
4a4d8108
AM
28135+ pr_err("unknown %.*s/%.*s exists\n",
28136+ AuDLNPair(h_root), AuDLNPair(base[AuBrWh_BASE].dentry));
1facf9fc 28137+ if (unlikely(err))
28138+ goto out;
28139+
28140+ h_path->dentry = base[AuBrWh_PLINK].dentry;
28141+ if (do_plink) {
28142+ err = au_whdir(h_dir, h_path);
28143+ if (unlikely(err))
28144+ goto out;
28145+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
28146+ } else
28147+ au_wh_clean(h_dir, h_path, /*isdir*/1);
28148+ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
28149+
28150+ h_path->dentry = base[AuBrWh_ORPH].dentry;
28151+ err = au_whdir(h_dir, h_path);
28152+ if (unlikely(err))
28153+ goto out;
28154+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
28155+
4f0767ce 28156+out:
1facf9fc 28157+ return err;
28158+}
28159+
28160+/*
28161+ * initialize the whiteout base file/dir for @br.
28162+ */
28163+int au_wh_init(struct dentry *h_root, struct au_branch *br,
28164+ struct super_block *sb)
28165+{
28166+ int err, i;
28167+ const unsigned char do_plink
28168+ = !!au_opt_test(au_mntflags(sb), PLINK);
28169+ struct path path = {
28170+ .mnt = br->br_mnt
28171+ };
28172+ struct inode *h_dir;
28173+ struct au_wbr *wbr = br->br_wbr;
28174+ static const struct qstr base_name[] = {
0c3ec466
AM
28175+ [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME,
28176+ sizeof(AUFS_BASE_NAME) - 1),
28177+ [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME,
28178+ sizeof(AUFS_PLINKDIR_NAME) - 1),
28179+ [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME,
28180+ sizeof(AUFS_ORPHDIR_NAME) - 1)
1facf9fc 28181+ };
28182+ struct au_wh_base base[] = {
28183+ [AuBrWh_BASE] = {
28184+ .name = base_name + AuBrWh_BASE,
28185+ .dentry = NULL
28186+ },
28187+ [AuBrWh_PLINK] = {
28188+ .name = base_name + AuBrWh_PLINK,
28189+ .dentry = NULL
28190+ },
28191+ [AuBrWh_ORPH] = {
28192+ .name = base_name + AuBrWh_ORPH,
28193+ .dentry = NULL
28194+ }
28195+ };
28196+
1308ab2a 28197+ if (wbr)
28198+ WbrWhMustWriteLock(wbr);
1facf9fc 28199+
1facf9fc 28200+ for (i = 0; i < AuBrWh_Last; i++) {
28201+ /* doubly whiteouted */
28202+ struct dentry *d;
28203+
28204+ d = au_wh_lkup(h_root, (void *)base[i].name, br);
28205+ err = PTR_ERR(d);
28206+ if (IS_ERR(d))
28207+ goto out;
28208+
28209+ base[i].dentry = d;
28210+ AuDebugOn(wbr
28211+ && wbr->wbr_wh[i]
28212+ && wbr->wbr_wh[i] != base[i].dentry);
28213+ }
28214+
28215+ if (wbr)
28216+ for (i = 0; i < AuBrWh_Last; i++) {
28217+ dput(wbr->wbr_wh[i]);
28218+ wbr->wbr_wh[i] = NULL;
28219+ }
28220+
28221+ err = 0;
1e00d052 28222+ if (!au_br_writable(br->br_perm)) {
4a4d8108 28223+ h_dir = h_root->d_inode;
1facf9fc 28224+ au_wh_init_ro(h_dir, base, &path);
1e00d052 28225+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 28226+ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
28227+ if (err > 0)
28228+ goto out;
28229+ else if (err)
28230+ goto out_err;
1e00d052 28231+ } else {
1facf9fc 28232+ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
28233+ if (err > 0)
28234+ goto out;
28235+ else if (err)
28236+ goto out_err;
1facf9fc 28237+ }
28238+ goto out; /* success */
28239+
4f0767ce 28240+out_err:
4a4d8108
AM
28241+ pr_err("an error(%d) on the writable branch %.*s(%s)\n",
28242+ err, AuDLNPair(h_root), au_sbtype(h_root->d_sb));
4f0767ce 28243+out:
1facf9fc 28244+ for (i = 0; i < AuBrWh_Last; i++)
28245+ dput(base[i].dentry);
28246+ return err;
28247+}
28248+
28249+/* ---------------------------------------------------------------------- */
28250+/*
28251+ * whiteouts are all hard-linked usually.
28252+ * when its link count reaches a ceiling, we create a new whiteout base
28253+ * asynchronously.
28254+ */
28255+
28256+struct reinit_br_wh {
28257+ struct super_block *sb;
28258+ struct au_branch *br;
28259+};
28260+
28261+static void reinit_br_wh(void *arg)
28262+{
28263+ int err;
28264+ aufs_bindex_t bindex;
28265+ struct path h_path;
28266+ struct reinit_br_wh *a = arg;
28267+ struct au_wbr *wbr;
28268+ struct inode *dir;
28269+ struct dentry *h_root;
28270+ struct au_hinode *hdir;
28271+
28272+ err = 0;
28273+ wbr = a->br->br_wbr;
28274+ /* big aufs lock */
28275+ si_noflush_write_lock(a->sb);
28276+ if (!au_br_writable(a->br->br_perm))
28277+ goto out;
28278+ bindex = au_br_index(a->sb, a->br->br_id);
28279+ if (unlikely(bindex < 0))
28280+ goto out;
28281+
1308ab2a 28282+ di_read_lock_parent(a->sb->s_root, AuLock_IR);
1facf9fc 28283+ dir = a->sb->s_root->d_inode;
1facf9fc 28284+ hdir = au_hi(dir, bindex);
28285+ h_root = au_h_dptr(a->sb->s_root, bindex);
28286+
4a4d8108 28287+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 28288+ wbr_wh_write_lock(wbr);
28289+ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
28290+ h_root, a->br);
28291+ if (!err) {
b4510431 28292+ err = vfsub_mnt_want_write(a->br->br_mnt);
1facf9fc 28293+ if (!err) {
28294+ h_path.dentry = wbr->wbr_whbase;
28295+ h_path.mnt = a->br->br_mnt;
28296+ err = vfsub_unlink(hdir->hi_inode, &h_path, /*force*/0);
b4510431 28297+ vfsub_mnt_drop_write(a->br->br_mnt);
1facf9fc 28298+ }
28299+ } else {
0c3ec466
AM
28300+ pr_warn("%.*s is moved, ignored\n",
28301+ AuDLNPair(wbr->wbr_whbase));
1facf9fc 28302+ err = 0;
28303+ }
28304+ dput(wbr->wbr_whbase);
28305+ wbr->wbr_whbase = NULL;
28306+ if (!err)
28307+ err = au_wh_init(h_root, a->br, a->sb);
28308+ wbr_wh_write_unlock(wbr);
4a4d8108 28309+ au_hn_imtx_unlock(hdir);
1308ab2a 28310+ di_read_unlock(a->sb->s_root, AuLock_IR);
1facf9fc 28311+
4f0767ce 28312+out:
1facf9fc 28313+ if (wbr)
28314+ atomic_dec(&wbr->wbr_wh_running);
28315+ atomic_dec(&a->br->br_count);
1facf9fc 28316+ si_write_unlock(a->sb);
027c5e7a 28317+ au_nwt_done(&au_sbi(a->sb)->si_nowait);
1facf9fc 28318+ kfree(arg);
28319+ if (unlikely(err))
28320+ AuIOErr("err %d\n", err);
28321+}
28322+
28323+static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
28324+{
28325+ int do_dec, wkq_err;
28326+ struct reinit_br_wh *arg;
28327+
28328+ do_dec = 1;
28329+ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
28330+ goto out;
28331+
28332+ /* ignore ENOMEM */
28333+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
28334+ if (arg) {
28335+ /*
28336+ * dec(wh_running), kfree(arg) and dec(br_count)
28337+ * in reinit function
28338+ */
28339+ arg->sb = sb;
28340+ arg->br = br;
28341+ atomic_inc(&br->br_count);
53392da6 28342+ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0);
1facf9fc 28343+ if (unlikely(wkq_err)) {
28344+ atomic_dec(&br->br_wbr->wbr_wh_running);
28345+ atomic_dec(&br->br_count);
28346+ kfree(arg);
28347+ }
28348+ do_dec = 0;
28349+ }
28350+
4f0767ce 28351+out:
1facf9fc 28352+ if (do_dec)
28353+ atomic_dec(&br->br_wbr->wbr_wh_running);
28354+}
28355+
28356+/* ---------------------------------------------------------------------- */
28357+
28358+/*
28359+ * create the whiteout @wh.
28360+ */
28361+static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
28362+ struct dentry *wh)
28363+{
28364+ int err;
28365+ struct path h_path = {
28366+ .dentry = wh
28367+ };
28368+ struct au_branch *br;
28369+ struct au_wbr *wbr;
28370+ struct dentry *h_parent;
28371+ struct inode *h_dir;
28372+
28373+ h_parent = wh->d_parent; /* dir inode is locked */
28374+ h_dir = h_parent->d_inode;
28375+ IMustLock(h_dir);
28376+
28377+ br = au_sbr(sb, bindex);
28378+ h_path.mnt = br->br_mnt;
28379+ wbr = br->br_wbr;
28380+ wbr_wh_read_lock(wbr);
28381+ if (wbr->wbr_whbase) {
28382+ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path);
28383+ if (!err || err != -EMLINK)
28384+ goto out;
28385+
28386+ /* link count full. re-initialize br_whbase. */
28387+ kick_reinit_br_wh(sb, br);
28388+ }
28389+
28390+ /* return this error in this context */
b4510431 28391+ err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true);
1facf9fc 28392+
4f0767ce 28393+out:
1facf9fc 28394+ wbr_wh_read_unlock(wbr);
28395+ return err;
28396+}
28397+
28398+/* ---------------------------------------------------------------------- */
28399+
28400+/*
28401+ * create or remove the diropq.
28402+ */
28403+static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
28404+ unsigned int flags)
28405+{
28406+ struct dentry *opq_dentry, *h_dentry;
28407+ struct super_block *sb;
28408+ struct au_branch *br;
28409+ int err;
28410+
28411+ sb = dentry->d_sb;
28412+ br = au_sbr(sb, bindex);
28413+ h_dentry = au_h_dptr(dentry, bindex);
b4510431 28414+ opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry);
1facf9fc 28415+ if (IS_ERR(opq_dentry))
28416+ goto out;
28417+
28418+ if (au_ftest_diropq(flags, CREATE)) {
28419+ err = link_or_create_wh(sb, bindex, opq_dentry);
28420+ if (!err) {
28421+ au_set_dbdiropq(dentry, bindex);
28422+ goto out; /* success */
28423+ }
28424+ } else {
28425+ struct path tmp = {
28426+ .dentry = opq_dentry,
28427+ .mnt = br->br_mnt
28428+ };
28429+ err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp);
28430+ if (!err)
28431+ au_set_dbdiropq(dentry, -1);
28432+ }
28433+ dput(opq_dentry);
28434+ opq_dentry = ERR_PTR(err);
28435+
4f0767ce 28436+out:
1facf9fc 28437+ return opq_dentry;
28438+}
28439+
28440+struct do_diropq_args {
28441+ struct dentry **errp;
28442+ struct dentry *dentry;
28443+ aufs_bindex_t bindex;
28444+ unsigned int flags;
28445+};
28446+
28447+static void call_do_diropq(void *args)
28448+{
28449+ struct do_diropq_args *a = args;
28450+ *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
28451+}
28452+
28453+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
28454+ unsigned int flags)
28455+{
28456+ struct dentry *diropq, *h_dentry;
28457+
28458+ h_dentry = au_h_dptr(dentry, bindex);
28459+ if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE))
28460+ diropq = do_diropq(dentry, bindex, flags);
28461+ else {
28462+ int wkq_err;
28463+ struct do_diropq_args args = {
28464+ .errp = &diropq,
28465+ .dentry = dentry,
28466+ .bindex = bindex,
28467+ .flags = flags
28468+ };
28469+
28470+ wkq_err = au_wkq_wait(call_do_diropq, &args);
28471+ if (unlikely(wkq_err))
28472+ diropq = ERR_PTR(wkq_err);
28473+ }
28474+
28475+ return diropq;
28476+}
28477+
28478+/* ---------------------------------------------------------------------- */
28479+
28480+/*
28481+ * lookup whiteout dentry.
28482+ * @h_parent: lower parent dentry which must exist and be locked
28483+ * @base_name: name of dentry which will be whiteouted
28484+ * returns dentry for whiteout.
28485+ */
28486+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
28487+ struct au_branch *br)
28488+{
28489+ int err;
28490+ struct qstr wh_name;
28491+ struct dentry *wh_dentry;
28492+
28493+ err = au_wh_name_alloc(&wh_name, base_name);
28494+ wh_dentry = ERR_PTR(err);
28495+ if (!err) {
b4510431 28496+ wh_dentry = vfsub_lkup_one(&wh_name, h_parent);
1facf9fc 28497+ kfree(wh_name.name);
28498+ }
28499+ return wh_dentry;
28500+}
28501+
28502+/*
28503+ * link/create a whiteout for @dentry on @bindex.
28504+ */
28505+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
28506+ struct dentry *h_parent)
28507+{
28508+ struct dentry *wh_dentry;
28509+ struct super_block *sb;
28510+ int err;
28511+
28512+ sb = dentry->d_sb;
28513+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
28514+ if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) {
28515+ err = link_or_create_wh(sb, bindex, wh_dentry);
28516+ if (!err)
28517+ au_set_dbwh(dentry, bindex);
28518+ else {
28519+ dput(wh_dentry);
28520+ wh_dentry = ERR_PTR(err);
28521+ }
28522+ }
28523+
28524+ return wh_dentry;
28525+}
28526+
28527+/* ---------------------------------------------------------------------- */
28528+
28529+/* Delete all whiteouts in this directory on branch bindex. */
28530+static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
28531+ aufs_bindex_t bindex, struct au_branch *br)
28532+{
28533+ int err;
28534+ unsigned long ul, n;
28535+ struct qstr wh_name;
28536+ char *p;
28537+ struct hlist_head *head;
28538+ struct au_vdir_wh *tpos;
28539+ struct hlist_node *pos;
28540+ struct au_vdir_destr *str;
28541+
28542+ err = -ENOMEM;
537831f9 28543+ p = (void *)__get_free_page(GFP_NOFS);
1facf9fc 28544+ wh_name.name = p;
28545+ if (unlikely(!wh_name.name))
28546+ goto out;
28547+
28548+ err = 0;
28549+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
28550+ p += AUFS_WH_PFX_LEN;
28551+ n = whlist->nh_num;
28552+ head = whlist->nh_head;
28553+ for (ul = 0; !err && ul < n; ul++, head++) {
28554+ hlist_for_each_entry(tpos, pos, head, wh_hash) {
28555+ if (tpos->wh_bindex != bindex)
28556+ continue;
28557+
28558+ str = &tpos->wh_str;
28559+ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
28560+ memcpy(p, str->name, str->len);
28561+ wh_name.len = AUFS_WH_PFX_LEN + str->len;
28562+ err = unlink_wh_name(h_dentry, &wh_name, br);
28563+ if (!err)
28564+ continue;
28565+ break;
28566+ }
28567+ AuIOErr("whiteout name too long %.*s\n",
28568+ str->len, str->name);
28569+ err = -EIO;
28570+ break;
28571+ }
28572+ }
537831f9 28573+ free_page((unsigned long)wh_name.name);
1facf9fc 28574+
4f0767ce 28575+out:
1facf9fc 28576+ return err;
28577+}
28578+
28579+struct del_wh_children_args {
28580+ int *errp;
28581+ struct dentry *h_dentry;
1308ab2a 28582+ struct au_nhash *whlist;
1facf9fc 28583+ aufs_bindex_t bindex;
28584+ struct au_branch *br;
28585+};
28586+
28587+static void call_del_wh_children(void *args)
28588+{
28589+ struct del_wh_children_args *a = args;
1308ab2a 28590+ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
1facf9fc 28591+}
28592+
28593+/* ---------------------------------------------------------------------- */
28594+
28595+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
28596+{
28597+ struct au_whtmp_rmdir *whtmp;
dece6358 28598+ int err;
1308ab2a 28599+ unsigned int rdhash;
dece6358
AM
28600+
28601+ SiMustAnyLock(sb);
1facf9fc 28602+
28603+ whtmp = kmalloc(sizeof(*whtmp), gfp);
dece6358
AM
28604+ if (unlikely(!whtmp)) {
28605+ whtmp = ERR_PTR(-ENOMEM);
1facf9fc 28606+ goto out;
dece6358 28607+ }
1facf9fc 28608+
28609+ whtmp->dir = NULL;
027c5e7a 28610+ whtmp->br = NULL;
1facf9fc 28611+ whtmp->wh_dentry = NULL;
1308ab2a 28612+ /* no estimation for dir size */
28613+ rdhash = au_sbi(sb)->si_rdhash;
28614+ if (!rdhash)
28615+ rdhash = AUFS_RDHASH_DEF;
28616+ err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
28617+ if (unlikely(err)) {
28618+ kfree(whtmp);
28619+ whtmp = ERR_PTR(err);
28620+ }
dece6358 28621+
4f0767ce 28622+out:
dece6358 28623+ return whtmp;
1facf9fc 28624+}
28625+
28626+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
28627+{
027c5e7a
AM
28628+ if (whtmp->br)
28629+ atomic_dec(&whtmp->br->br_count);
1facf9fc 28630+ dput(whtmp->wh_dentry);
28631+ iput(whtmp->dir);
dece6358 28632+ au_nhash_wh_free(&whtmp->whlist);
1facf9fc 28633+ kfree(whtmp);
28634+}
28635+
28636+/*
28637+ * rmdir the whiteouted temporary named dir @h_dentry.
28638+ * @whlist: whiteouted children.
28639+ */
28640+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
28641+ struct dentry *wh_dentry, struct au_nhash *whlist)
28642+{
28643+ int err;
28644+ struct path h_tmp;
28645+ struct inode *wh_inode, *h_dir;
28646+ struct au_branch *br;
28647+
28648+ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
28649+ IMustLock(h_dir);
28650+
28651+ br = au_sbr(dir->i_sb, bindex);
28652+ wh_inode = wh_dentry->d_inode;
28653+ mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
28654+
28655+ /*
28656+ * someone else might change some whiteouts while we were sleeping.
28657+ * it means this whlist may have an obsoleted entry.
28658+ */
28659+ if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
28660+ err = del_wh_children(wh_dentry, whlist, bindex, br);
28661+ else {
28662+ int wkq_err;
28663+ struct del_wh_children_args args = {
28664+ .errp = &err,
28665+ .h_dentry = wh_dentry,
1308ab2a 28666+ .whlist = whlist,
1facf9fc 28667+ .bindex = bindex,
28668+ .br = br
28669+ };
28670+
28671+ wkq_err = au_wkq_wait(call_del_wh_children, &args);
28672+ if (unlikely(wkq_err))
28673+ err = wkq_err;
28674+ }
28675+ mutex_unlock(&wh_inode->i_mutex);
28676+
28677+ if (!err) {
28678+ h_tmp.dentry = wh_dentry;
28679+ h_tmp.mnt = br->br_mnt;
28680+ err = vfsub_rmdir(h_dir, &h_tmp);
1facf9fc 28681+ }
28682+
28683+ if (!err) {
28684+ if (au_ibstart(dir) == bindex) {
7f207e10 28685+ /* todo: dir->i_mutex is necessary */
1facf9fc 28686+ au_cpup_attr_timesizes(dir);
7f207e10 28687+ vfsub_drop_nlink(dir);
1facf9fc 28688+ }
28689+ return 0; /* success */
28690+ }
28691+
0c3ec466
AM
28692+ pr_warn("failed removing %.*s(%d), ignored\n",
28693+ AuDLNPair(wh_dentry), err);
1facf9fc 28694+ return err;
28695+}
28696+
28697+static void call_rmdir_whtmp(void *args)
28698+{
28699+ int err;
e49829fe 28700+ aufs_bindex_t bindex;
1facf9fc 28701+ struct au_whtmp_rmdir *a = args;
28702+ struct super_block *sb;
28703+ struct dentry *h_parent;
28704+ struct inode *h_dir;
1facf9fc 28705+ struct au_hinode *hdir;
28706+
28707+ /* rmdir by nfsd may cause deadlock with this i_mutex */
28708+ /* mutex_lock(&a->dir->i_mutex); */
e49829fe 28709+ err = -EROFS;
1facf9fc 28710+ sb = a->dir->i_sb;
e49829fe
JR
28711+ si_read_lock(sb, !AuLock_FLUSH);
28712+ if (!au_br_writable(a->br->br_perm))
28713+ goto out;
28714+ bindex = au_br_index(sb, a->br->br_id);
28715+ if (unlikely(bindex < 0))
1facf9fc 28716+ goto out;
28717+
28718+ err = -EIO;
1facf9fc 28719+ ii_write_lock_parent(a->dir);
28720+ h_parent = dget_parent(a->wh_dentry);
28721+ h_dir = h_parent->d_inode;
e49829fe 28722+ hdir = au_hi(a->dir, bindex);
4a4d8108 28723+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
e49829fe
JR
28724+ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
28725+ a->br);
1facf9fc 28726+ if (!err) {
b4510431 28727+ err = vfsub_mnt_want_write(a->br->br_mnt);
1facf9fc 28728+ if (!err) {
e49829fe 28729+ err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry,
dece6358 28730+ &a->whlist);
b4510431 28731+ vfsub_mnt_drop_write(a->br->br_mnt);
1facf9fc 28732+ }
28733+ }
4a4d8108 28734+ au_hn_imtx_unlock(hdir);
1facf9fc 28735+ dput(h_parent);
28736+ ii_write_unlock(a->dir);
28737+
4f0767ce 28738+out:
1facf9fc 28739+ /* mutex_unlock(&a->dir->i_mutex); */
1facf9fc 28740+ au_whtmp_rmdir_free(a);
027c5e7a
AM
28741+ si_read_unlock(sb);
28742+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 28743+ if (unlikely(err))
28744+ AuIOErr("err %d\n", err);
28745+}
28746+
28747+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
28748+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
28749+{
28750+ int wkq_err;
e49829fe 28751+ struct super_block *sb;
1facf9fc 28752+
28753+ IMustLock(dir);
28754+
28755+ /* all post-process will be done in do_rmdir_whtmp(). */
e49829fe 28756+ sb = dir->i_sb;
1facf9fc 28757+ args->dir = au_igrab(dir);
e49829fe
JR
28758+ args->br = au_sbr(sb, bindex);
28759+ atomic_inc(&args->br->br_count);
1facf9fc 28760+ args->wh_dentry = dget(wh_dentry);
53392da6 28761+ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0);
1facf9fc 28762+ if (unlikely(wkq_err)) {
0c3ec466
AM
28763+ pr_warn("rmdir error %.*s (%d), ignored\n",
28764+ AuDLNPair(wh_dentry), wkq_err);
1facf9fc 28765+ au_whtmp_rmdir_free(args);
28766+ }
28767+}
7f207e10
AM
28768diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h
28769--- /usr/share/empty/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100
1716fcea 28770+++ linux/fs/aufs/whout.h 2013-02-19 08:40:03.953559833 +0100
f6c5ef8b 28771@@ -0,0 +1,88 @@
1facf9fc 28772+/*
7a9e40b8 28773+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 28774+ *
28775+ * This program, aufs is free software; you can redistribute it and/or modify
28776+ * it under the terms of the GNU General Public License as published by
28777+ * the Free Software Foundation; either version 2 of the License, or
28778+ * (at your option) any later version.
dece6358
AM
28779+ *
28780+ * This program is distributed in the hope that it will be useful,
28781+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28782+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28783+ * GNU General Public License for more details.
28784+ *
28785+ * You should have received a copy of the GNU General Public License
28786+ * along with this program; if not, write to the Free Software
28787+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 28788+ */
28789+
28790+/*
28791+ * whiteout for logical deletion and opaque directory
28792+ */
28793+
28794+#ifndef __AUFS_WHOUT_H__
28795+#define __AUFS_WHOUT_H__
28796+
28797+#ifdef __KERNEL__
28798+
1facf9fc 28799+#include "dir.h"
28800+
28801+/* whout.c */
28802+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
28803+struct au_branch;
28804+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
28805+ struct au_branch *br, int try_sio);
28806+int au_diropq_test(struct dentry *h_dentry, struct au_branch *br);
28807+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
28808+ struct qstr *prefix);
28809+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
28810+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
28811+ struct dentry *dentry);
28812+int au_wh_init(struct dentry *h_parent, struct au_branch *br,
28813+ struct super_block *sb);
28814+
28815+/* diropq flags */
28816+#define AuDiropq_CREATE 1
28817+#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name)
7f207e10
AM
28818+#define au_fset_diropq(flags, name) \
28819+ do { (flags) |= AuDiropq_##name; } while (0)
28820+#define au_fclr_diropq(flags, name) \
28821+ do { (flags) &= ~AuDiropq_##name; } while (0)
1facf9fc 28822+
28823+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
28824+ unsigned int flags);
28825+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
28826+ struct au_branch *br);
28827+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
28828+ struct dentry *h_parent);
28829+
28830+/* real rmdir for the whiteout-ed dir */
28831+struct au_whtmp_rmdir {
28832+ struct inode *dir;
e49829fe 28833+ struct au_branch *br;
1facf9fc 28834+ struct dentry *wh_dentry;
dece6358 28835+ struct au_nhash whlist;
1facf9fc 28836+};
28837+
28838+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
28839+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
28840+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
28841+ struct dentry *wh_dentry, struct au_nhash *whlist);
28842+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
28843+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
28844+
28845+/* ---------------------------------------------------------------------- */
28846+
28847+static inline struct dentry *au_diropq_create(struct dentry *dentry,
28848+ aufs_bindex_t bindex)
28849+{
28850+ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
28851+}
28852+
28853+static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
28854+{
28855+ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
28856+}
28857+
28858+#endif /* __KERNEL__ */
28859+#endif /* __AUFS_WHOUT_H__ */
7f207e10
AM
28860diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
28861--- /usr/share/empty/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100
1716fcea 28862+++ linux/fs/aufs/wkq.c 2013-02-19 08:40:03.953559833 +0100
9dbd164d 28863@@ -0,0 +1,214 @@
1facf9fc 28864+/*
7a9e40b8 28865+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 28866+ *
28867+ * This program, aufs is free software; you can redistribute it and/or modify
28868+ * it under the terms of the GNU General Public License as published by
28869+ * the Free Software Foundation; either version 2 of the License, or
28870+ * (at your option) any later version.
dece6358
AM
28871+ *
28872+ * This program is distributed in the hope that it will be useful,
28873+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28874+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28875+ * GNU General Public License for more details.
28876+ *
28877+ * You should have received a copy of the GNU General Public License
28878+ * along with this program; if not, write to the Free Software
28879+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 28880+ */
28881+
28882+/*
28883+ * workqueue for asynchronous/super-io operations
28884+ * todo: try new dredential scheme
28885+ */
28886+
dece6358 28887+#include <linux/module.h>
1facf9fc 28888+#include "aufs.h"
28889+
9dbd164d 28890+/* internal workqueue named AUFS_WKQ_NAME */
b752ccd1 28891+
9dbd164d 28892+static struct workqueue_struct *au_wkq;
1facf9fc 28893+
28894+struct au_wkinfo {
28895+ struct work_struct wk;
7f207e10 28896+ struct kobject *kobj;
1facf9fc 28897+
28898+ unsigned int flags; /* see wkq.h */
28899+
28900+ au_wkq_func_t func;
28901+ void *args;
28902+
1facf9fc 28903+ struct completion *comp;
28904+};
28905+
28906+/* ---------------------------------------------------------------------- */
28907+
1facf9fc 28908+static void wkq_func(struct work_struct *wk)
28909+{
28910+ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
28911+
2dfbb274 28912+ AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID));
7f207e10
AM
28913+ AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY);
28914+
1facf9fc 28915+ wkinfo->func(wkinfo->args);
1facf9fc 28916+ if (au_ftest_wkq(wkinfo->flags, WAIT))
28917+ complete(wkinfo->comp);
28918+ else {
7f207e10 28919+ kobject_put(wkinfo->kobj);
9dbd164d 28920+ module_put(THIS_MODULE); /* todo: ?? */
1facf9fc 28921+ kfree(wkinfo);
28922+ }
28923+}
28924+
28925+/*
28926+ * Since struct completion is large, try allocating it dynamically.
28927+ */
28928+#if defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS)
28929+#define AuWkqCompDeclare(name) struct completion *comp = NULL
28930+
28931+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
28932+{
28933+ *comp = kmalloc(sizeof(**comp), GFP_NOFS);
28934+ if (*comp) {
28935+ init_completion(*comp);
28936+ wkinfo->comp = *comp;
28937+ return 0;
28938+ }
28939+ return -ENOMEM;
28940+}
28941+
28942+static void au_wkq_comp_free(struct completion *comp)
28943+{
28944+ kfree(comp);
28945+}
28946+
28947+#else
28948+
28949+/* no braces */
28950+#define AuWkqCompDeclare(name) \
28951+ DECLARE_COMPLETION_ONSTACK(_ ## name); \
28952+ struct completion *comp = &_ ## name
28953+
28954+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
28955+{
28956+ wkinfo->comp = *comp;
28957+ return 0;
28958+}
28959+
28960+static void au_wkq_comp_free(struct completion *comp __maybe_unused)
28961+{
28962+ /* empty */
28963+}
28964+#endif /* 4KSTACKS */
28965+
53392da6 28966+static void au_wkq_run(struct au_wkinfo *wkinfo)
1facf9fc 28967+{
53392da6
AM
28968+ if (au_ftest_wkq(wkinfo->flags, NEST)) {
28969+ if (au_wkq_test()) {
28970+ AuWarn1("wkq from wkq, due to a dead dir by UDBA?\n");
28971+ AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT));
28972+ }
28973+ } else
28974+ au_dbg_verify_kthread();
28975+
28976+ if (au_ftest_wkq(wkinfo->flags, WAIT)) {
a1f66529 28977+ INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func);
9dbd164d 28978+ queue_work(au_wkq, &wkinfo->wk);
4a4d8108
AM
28979+ } else {
28980+ INIT_WORK(&wkinfo->wk, wkq_func);
28981+ schedule_work(&wkinfo->wk);
28982+ }
1facf9fc 28983+}
28984+
7f207e10
AM
28985+/*
28986+ * Be careful. It is easy to make deadlock happen.
28987+ * processA: lock, wkq and wait
28988+ * processB: wkq and wait, lock in wkq
28989+ * --> deadlock
28990+ */
b752ccd1 28991+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args)
1facf9fc 28992+{
28993+ int err;
28994+ AuWkqCompDeclare(comp);
28995+ struct au_wkinfo wkinfo = {
b752ccd1 28996+ .flags = flags,
1facf9fc 28997+ .func = func,
28998+ .args = args
28999+ };
29000+
29001+ err = au_wkq_comp_alloc(&wkinfo, &comp);
29002+ if (!err) {
53392da6 29003+ au_wkq_run(&wkinfo);
1facf9fc 29004+ /* no timeout, no interrupt */
29005+ wait_for_completion(wkinfo.comp);
29006+ au_wkq_comp_free(comp);
4a4d8108 29007+ destroy_work_on_stack(&wkinfo.wk);
1facf9fc 29008+ }
29009+
29010+ return err;
29011+
29012+}
29013+
027c5e7a
AM
29014+/*
29015+ * Note: dget/dput() in func for aufs dentries are not supported. It will be a
29016+ * problem in a concurrent umounting.
29017+ */
53392da6
AM
29018+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
29019+ unsigned int flags)
1facf9fc 29020+{
29021+ int err;
29022+ struct au_wkinfo *wkinfo;
29023+
29024+ atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
29025+
29026+ /*
29027+ * wkq_func() must free this wkinfo.
29028+ * it highly depends upon the implementation of workqueue.
29029+ */
29030+ err = 0;
29031+ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
29032+ if (wkinfo) {
7f207e10 29033+ wkinfo->kobj = &au_sbi(sb)->si_kobj;
53392da6 29034+ wkinfo->flags = flags & ~AuWkq_WAIT;
1facf9fc 29035+ wkinfo->func = func;
29036+ wkinfo->args = args;
29037+ wkinfo->comp = NULL;
7f207e10 29038+ kobject_get(wkinfo->kobj);
9dbd164d 29039+ __module_get(THIS_MODULE); /* todo: ?? */
1facf9fc 29040+
53392da6 29041+ au_wkq_run(wkinfo);
1facf9fc 29042+ } else {
29043+ err = -ENOMEM;
e49829fe 29044+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 29045+ }
29046+
29047+ return err;
29048+}
29049+
29050+/* ---------------------------------------------------------------------- */
29051+
29052+void au_nwt_init(struct au_nowait_tasks *nwt)
29053+{
29054+ atomic_set(&nwt->nw_len, 0);
4a4d8108 29055+ /* smp_mb(); */ /* atomic_set */
1facf9fc 29056+ init_waitqueue_head(&nwt->nw_wq);
29057+}
29058+
29059+void au_wkq_fin(void)
29060+{
9dbd164d 29061+ destroy_workqueue(au_wkq);
1facf9fc 29062+}
29063+
29064+int __init au_wkq_init(void)
29065+{
9dbd164d 29066+ int err;
b752ccd1
AM
29067+
29068+ err = 0;
9dbd164d
AM
29069+ BUILD_BUG_ON(!WQ_RESCUER);
29070+ au_wkq = alloc_workqueue(AUFS_WKQ_NAME, !WQ_RESCUER, WQ_DFL_ACTIVE);
29071+ if (IS_ERR(au_wkq))
29072+ err = PTR_ERR(au_wkq);
29073+ else if (!au_wkq)
29074+ err = -ENOMEM;
b752ccd1
AM
29075+
29076+ return err;
1facf9fc 29077+}
7f207e10
AM
29078diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
29079--- /usr/share/empty/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100
1716fcea 29080+++ linux/fs/aufs/wkq.h 2013-02-19 08:40:03.953559833 +0100
f6c5ef8b 29081@@ -0,0 +1,92 @@
1facf9fc 29082+/*
7a9e40b8 29083+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 29084+ *
29085+ * This program, aufs is free software; you can redistribute it and/or modify
29086+ * it under the terms of the GNU General Public License as published by
29087+ * the Free Software Foundation; either version 2 of the License, or
29088+ * (at your option) any later version.
dece6358
AM
29089+ *
29090+ * This program is distributed in the hope that it will be useful,
29091+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29092+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29093+ * GNU General Public License for more details.
29094+ *
29095+ * You should have received a copy of the GNU General Public License
29096+ * along with this program; if not, write to the Free Software
29097+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 29098+ */
29099+
29100+/*
29101+ * workqueue for asynchronous/super-io operations
29102+ * todo: try new credentials management scheme
29103+ */
29104+
29105+#ifndef __AUFS_WKQ_H__
29106+#define __AUFS_WKQ_H__
29107+
29108+#ifdef __KERNEL__
29109+
dece6358
AM
29110+struct super_block;
29111+
1facf9fc 29112+/* ---------------------------------------------------------------------- */
29113+
29114+/*
29115+ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
29116+ */
29117+struct au_nowait_tasks {
29118+ atomic_t nw_len;
29119+ wait_queue_head_t nw_wq;
29120+};
29121+
29122+/* ---------------------------------------------------------------------- */
29123+
29124+typedef void (*au_wkq_func_t)(void *args);
29125+
29126+/* wkq flags */
29127+#define AuWkq_WAIT 1
9dbd164d 29128+#define AuWkq_NEST (1 << 1)
1facf9fc 29129+#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name)
7f207e10
AM
29130+#define au_fset_wkq(flags, name) \
29131+ do { (flags) |= AuWkq_##name; } while (0)
29132+#define au_fclr_wkq(flags, name) \
29133+ do { (flags) &= ~AuWkq_##name; } while (0)
1facf9fc 29134+
9dbd164d
AM
29135+#ifndef CONFIG_AUFS_HNOTIFY
29136+#undef AuWkq_NEST
29137+#define AuWkq_NEST 0
29138+#endif
29139+
1facf9fc 29140+/* wkq.c */
b752ccd1 29141+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args);
53392da6
AM
29142+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
29143+ unsigned int flags);
1facf9fc 29144+void au_nwt_init(struct au_nowait_tasks *nwt);
29145+int __init au_wkq_init(void);
29146+void au_wkq_fin(void);
29147+
29148+/* ---------------------------------------------------------------------- */
29149+
53392da6
AM
29150+static inline int au_wkq_test(void)
29151+{
29152+ return current->flags & PF_WQ_WORKER;
29153+}
29154+
b752ccd1 29155+static inline int au_wkq_wait(au_wkq_func_t func, void *args)
1facf9fc 29156+{
b752ccd1 29157+ return au_wkq_do_wait(AuWkq_WAIT, func, args);
1facf9fc 29158+}
29159+
29160+static inline void au_nwt_done(struct au_nowait_tasks *nwt)
29161+{
e49829fe 29162+ if (atomic_dec_and_test(&nwt->nw_len))
1facf9fc 29163+ wake_up_all(&nwt->nw_wq);
29164+}
29165+
29166+static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
29167+{
29168+ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
29169+ return 0;
29170+}
29171+
29172+#endif /* __KERNEL__ */
29173+#endif /* __AUFS_WKQ_H__ */
7f207e10
AM
29174diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
29175--- /usr/share/empty/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100
a2a7ad62 29176+++ linux/fs/aufs/xino.c 2013-03-14 20:07:41.224790724 +0100
1716fcea 29177@@ -0,0 +1,1265 @@
1facf9fc 29178+/*
7a9e40b8 29179+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 29180+ *
29181+ * This program, aufs is free software; you can redistribute it and/or modify
29182+ * it under the terms of the GNU General Public License as published by
29183+ * the Free Software Foundation; either version 2 of the License, or
29184+ * (at your option) any later version.
dece6358
AM
29185+ *
29186+ * This program is distributed in the hope that it will be useful,
29187+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29188+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29189+ * GNU General Public License for more details.
29190+ *
29191+ * You should have received a copy of the GNU General Public License
29192+ * along with this program; if not, write to the Free Software
29193+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 29194+ */
29195+
29196+/*
29197+ * external inode number translation table and bitmap
29198+ */
29199+
29200+#include <linux/seq_file.h>
1facf9fc 29201+#include "aufs.h"
29202+
9dbd164d 29203+/* todo: unnecessary to support mmap_sem since kernel-space? */
b752ccd1 29204+ssize_t xino_fread(au_readf_t func, struct file *file, void *kbuf, size_t size,
1facf9fc 29205+ loff_t *pos)
29206+{
29207+ ssize_t err;
29208+ mm_segment_t oldfs;
b752ccd1
AM
29209+ union {
29210+ void *k;
29211+ char __user *u;
29212+ } buf;
1facf9fc 29213+
b752ccd1 29214+ buf.k = kbuf;
1facf9fc 29215+ oldfs = get_fs();
29216+ set_fs(KERNEL_DS);
29217+ do {
29218+ /* todo: signal_pending? */
b752ccd1 29219+ err = func(file, buf.u, size, pos);
1facf9fc 29220+ } while (err == -EAGAIN || err == -EINTR);
29221+ set_fs(oldfs);
29222+
29223+#if 0 /* reserved for future use */
29224+ if (err > 0)
29225+ fsnotify_access(file->f_dentry);
29226+#endif
29227+
29228+ return err;
29229+}
29230+
29231+/* ---------------------------------------------------------------------- */
29232+
b752ccd1 29233+static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *kbuf,
1facf9fc 29234+ size_t size, loff_t *pos)
29235+{
29236+ ssize_t err;
29237+ mm_segment_t oldfs;
b752ccd1
AM
29238+ union {
29239+ void *k;
29240+ const char __user *u;
29241+ } buf;
1facf9fc 29242+
b752ccd1 29243+ buf.k = kbuf;
1facf9fc 29244+ oldfs = get_fs();
29245+ set_fs(KERNEL_DS);
1facf9fc 29246+ do {
29247+ /* todo: signal_pending? */
b752ccd1 29248+ err = func(file, buf.u, size, pos);
1facf9fc 29249+ } while (err == -EAGAIN || err == -EINTR);
1facf9fc 29250+ set_fs(oldfs);
29251+
29252+#if 0 /* reserved for future use */
29253+ if (err > 0)
29254+ fsnotify_modify(file->f_dentry);
29255+#endif
29256+
29257+ return err;
29258+}
29259+
29260+struct do_xino_fwrite_args {
29261+ ssize_t *errp;
29262+ au_writef_t func;
29263+ struct file *file;
29264+ void *buf;
29265+ size_t size;
29266+ loff_t *pos;
29267+};
29268+
29269+static void call_do_xino_fwrite(void *args)
29270+{
29271+ struct do_xino_fwrite_args *a = args;
29272+ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
29273+}
29274+
29275+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
29276+ loff_t *pos)
29277+{
29278+ ssize_t err;
29279+
29280+ /* todo: signal block and no wkq? */
b752ccd1
AM
29281+ if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
29282+ lockdep_off();
29283+ err = do_xino_fwrite(func, file, buf, size, pos);
29284+ lockdep_on();
29285+ } else {
29286+ /*
29287+ * it breaks RLIMIT_FSIZE and normal user's limit,
29288+ * users should care about quota and real 'filesystem full.'
29289+ */
1facf9fc 29290+ int wkq_err;
29291+ struct do_xino_fwrite_args args = {
29292+ .errp = &err,
29293+ .func = func,
29294+ .file = file,
29295+ .buf = buf,
29296+ .size = size,
29297+ .pos = pos
29298+ };
29299+
29300+ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
29301+ if (unlikely(wkq_err))
29302+ err = wkq_err;
b752ccd1 29303+ }
1facf9fc 29304+
29305+ return err;
29306+}
29307+
29308+/* ---------------------------------------------------------------------- */
29309+
29310+/*
29311+ * create a new xinofile at the same place/path as @base_file.
29312+ */
29313+struct file *au_xino_create2(struct file *base_file, struct file *copy_src)
29314+{
29315+ struct file *file;
4a4d8108 29316+ struct dentry *base, *parent;
1facf9fc 29317+ struct inode *dir;
29318+ struct qstr *name;
1308ab2a 29319+ struct path path;
4a4d8108 29320+ int err;
1facf9fc 29321+
29322+ base = base_file->f_dentry;
29323+ parent = base->d_parent; /* dir inode is locked */
29324+ dir = parent->d_inode;
29325+ IMustLock(dir);
29326+
29327+ file = ERR_PTR(-EINVAL);
29328+ name = &base->d_name;
4a4d8108
AM
29329+ path.dentry = vfsub_lookup_one_len(name->name, parent, name->len);
29330+ if (IS_ERR(path.dentry)) {
29331+ file = (void *)path.dentry;
29332+ pr_err("%.*s lookup err %ld\n",
29333+ AuLNPair(name), PTR_ERR(path.dentry));
1facf9fc 29334+ goto out;
29335+ }
29336+
29337+ /* no need to mnt_want_write() since we call dentry_open() later */
4a4d8108 29338+ err = vfs_create(dir, path.dentry, S_IRUGO | S_IWUGO, NULL);
1facf9fc 29339+ if (unlikely(err)) {
29340+ file = ERR_PTR(err);
4a4d8108 29341+ pr_err("%.*s create err %d\n", AuLNPair(name), err);
1facf9fc 29342+ goto out_dput;
29343+ }
29344+
1308ab2a 29345+ path.mnt = base_file->f_vfsmnt;
4a4d8108 29346+ file = vfsub_dentry_open(&path,
7f207e10 29347+ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 29348+ /* | __FMODE_NONOTIFY */);
1facf9fc 29349+ if (IS_ERR(file)) {
4a4d8108 29350+ pr_err("%.*s open err %ld\n", AuLNPair(name), PTR_ERR(file));
1facf9fc 29351+ goto out_dput;
29352+ }
29353+
29354+ err = vfsub_unlink(dir, &file->f_path, /*force*/0);
29355+ if (unlikely(err)) {
4a4d8108 29356+ pr_err("%.*s unlink err %d\n", AuLNPair(name), err);
1facf9fc 29357+ goto out_fput;
29358+ }
29359+
29360+ if (copy_src) {
29361+ /* no one can touch copy_src xino */
29362+ err = au_copy_file(file, copy_src,
29363+ i_size_read(copy_src->f_dentry->d_inode));
29364+ if (unlikely(err)) {
4a4d8108 29365+ pr_err("%.*s copy err %d\n", AuLNPair(name), err);
1facf9fc 29366+ goto out_fput;
29367+ }
29368+ }
29369+ goto out_dput; /* success */
29370+
4f0767ce 29371+out_fput:
1facf9fc 29372+ fput(file);
29373+ file = ERR_PTR(err);
4f0767ce 29374+out_dput:
4a4d8108 29375+ dput(path.dentry);
4f0767ce 29376+out:
1facf9fc 29377+ return file;
29378+}
29379+
29380+struct au_xino_lock_dir {
29381+ struct au_hinode *hdir;
29382+ struct dentry *parent;
29383+ struct mutex *mtx;
29384+};
29385+
29386+static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
29387+ struct au_xino_lock_dir *ldir)
29388+{
29389+ aufs_bindex_t brid, bindex;
29390+
29391+ ldir->hdir = NULL;
29392+ bindex = -1;
29393+ brid = au_xino_brid(sb);
29394+ if (brid >= 0)
29395+ bindex = au_br_index(sb, brid);
29396+ if (bindex >= 0) {
29397+ ldir->hdir = au_hi(sb->s_root->d_inode, bindex);
4a4d8108 29398+ au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
1facf9fc 29399+ } else {
29400+ ldir->parent = dget_parent(xino->f_dentry);
29401+ ldir->mtx = &ldir->parent->d_inode->i_mutex;
29402+ mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT);
29403+ }
29404+}
29405+
29406+static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
29407+{
29408+ if (ldir->hdir)
4a4d8108 29409+ au_hn_imtx_unlock(ldir->hdir);
1facf9fc 29410+ else {
29411+ mutex_unlock(ldir->mtx);
29412+ dput(ldir->parent);
29413+ }
29414+}
29415+
29416+/* ---------------------------------------------------------------------- */
29417+
29418+/* trucate xino files asynchronously */
29419+
29420+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex)
29421+{
29422+ int err;
29423+ aufs_bindex_t bi, bend;
29424+ struct au_branch *br;
29425+ struct file *new_xino, *file;
29426+ struct super_block *h_sb;
29427+ struct au_xino_lock_dir ldir;
29428+
29429+ err = -EINVAL;
29430+ bend = au_sbend(sb);
29431+ if (unlikely(bindex < 0 || bend < bindex))
29432+ goto out;
29433+ br = au_sbr(sb, bindex);
29434+ file = br->br_xino.xi_file;
29435+ if (!file)
29436+ goto out;
29437+
29438+ au_xino_lock_dir(sb, file, &ldir);
29439+ /* mnt_want_write() is unnecessary here */
29440+ new_xino = au_xino_create2(file, file);
29441+ au_xino_unlock_dir(&ldir);
29442+ err = PTR_ERR(new_xino);
29443+ if (IS_ERR(new_xino))
29444+ goto out;
29445+ err = 0;
29446+ fput(file);
29447+ br->br_xino.xi_file = new_xino;
29448+
29449+ h_sb = br->br_mnt->mnt_sb;
29450+ for (bi = 0; bi <= bend; bi++) {
29451+ if (unlikely(bi == bindex))
29452+ continue;
29453+ br = au_sbr(sb, bi);
29454+ if (br->br_mnt->mnt_sb != h_sb)
29455+ continue;
29456+
29457+ fput(br->br_xino.xi_file);
29458+ br->br_xino.xi_file = new_xino;
29459+ get_file(new_xino);
29460+ }
29461+
4f0767ce 29462+out:
1facf9fc 29463+ return err;
29464+}
29465+
29466+struct xino_do_trunc_args {
29467+ struct super_block *sb;
29468+ struct au_branch *br;
29469+};
29470+
29471+static void xino_do_trunc(void *_args)
29472+{
29473+ struct xino_do_trunc_args *args = _args;
29474+ struct super_block *sb;
29475+ struct au_branch *br;
29476+ struct inode *dir;
29477+ int err;
29478+ aufs_bindex_t bindex;
29479+
29480+ err = 0;
29481+ sb = args->sb;
29482+ dir = sb->s_root->d_inode;
29483+ br = args->br;
29484+
29485+ si_noflush_write_lock(sb);
29486+ ii_read_lock_parent(dir);
29487+ bindex = au_br_index(sb, br->br_id);
29488+ err = au_xino_trunc(sb, bindex);
dece6358
AM
29489+ if (!err
29490+ && br->br_xino.xi_file->f_dentry->d_inode->i_blocks
1facf9fc 29491+ >= br->br_xino_upper)
29492+ br->br_xino_upper += AUFS_XINO_TRUNC_STEP;
29493+
1facf9fc 29494+ ii_read_unlock(dir);
29495+ if (unlikely(err))
1716fcea
AM
29496+ pr_warn("err b%d, upper %llu, (%d)\n",
29497+ bindex, (unsigned long long)br->br_xino_upper, err);
1facf9fc 29498+ atomic_dec(&br->br_xino_running);
29499+ atomic_dec(&br->br_count);
1facf9fc 29500+ si_write_unlock(sb);
027c5e7a 29501+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 29502+ kfree(args);
29503+}
29504+
29505+static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
29506+{
29507+ struct xino_do_trunc_args *args;
29508+ int wkq_err;
29509+
29510+ if (br->br_xino.xi_file->f_dentry->d_inode->i_blocks
29511+ < br->br_xino_upper)
29512+ return;
29513+
29514+ if (atomic_inc_return(&br->br_xino_running) > 1)
29515+ goto out;
29516+
29517+ /* lock and kfree() will be called in trunc_xino() */
29518+ args = kmalloc(sizeof(*args), GFP_NOFS);
29519+ if (unlikely(!args)) {
29520+ AuErr1("no memory\n");
29521+ goto out_args;
29522+ }
29523+
e49829fe 29524+ atomic_inc(&br->br_count);
1facf9fc 29525+ args->sb = sb;
29526+ args->br = br;
53392da6 29527+ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0);
1facf9fc 29528+ if (!wkq_err)
29529+ return; /* success */
29530+
4a4d8108 29531+ pr_err("wkq %d\n", wkq_err);
e49829fe 29532+ atomic_dec(&br->br_count);
1facf9fc 29533+
4f0767ce 29534+out_args:
1facf9fc 29535+ kfree(args);
4f0767ce 29536+out:
e49829fe 29537+ atomic_dec(&br->br_xino_running);
1facf9fc 29538+}
29539+
29540+/* ---------------------------------------------------------------------- */
29541+
29542+static int au_xino_do_write(au_writef_t write, struct file *file,
29543+ ino_t h_ino, ino_t ino)
29544+{
29545+ loff_t pos;
29546+ ssize_t sz;
29547+
29548+ pos = h_ino;
29549+ if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) {
29550+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
29551+ return -EFBIG;
29552+ }
29553+ pos *= sizeof(ino);
29554+ sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos);
29555+ if (sz == sizeof(ino))
29556+ return 0; /* success */
29557+
29558+ AuIOErr("write failed (%zd)\n", sz);
29559+ return -EIO;
29560+}
29561+
29562+/*
29563+ * write @ino to the xinofile for the specified branch{@sb, @bindex}
29564+ * at the position of @h_ino.
29565+ * even if @ino is zero, it is written to the xinofile and means no entry.
29566+ * if the size of the xino file on a specific filesystem exceeds the watermark,
29567+ * try truncating it.
29568+ */
29569+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
29570+ ino_t ino)
29571+{
29572+ int err;
29573+ unsigned int mnt_flags;
29574+ struct au_branch *br;
29575+
29576+ BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max)
29577+ || ((loff_t)-1) > 0);
dece6358 29578+ SiMustAnyLock(sb);
1facf9fc 29579+
29580+ mnt_flags = au_mntflags(sb);
29581+ if (!au_opt_test(mnt_flags, XINO))
29582+ return 0;
29583+
29584+ br = au_sbr(sb, bindex);
29585+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
29586+ h_ino, ino);
29587+ if (!err) {
29588+ if (au_opt_test(mnt_flags, TRUNC_XINO)
29589+ && au_test_fs_trunc_xino(br->br_mnt->mnt_sb))
29590+ xino_try_trunc(sb, br);
29591+ return 0; /* success */
29592+ }
29593+
29594+ AuIOErr("write failed (%d)\n", err);
29595+ return -EIO;
29596+}
29597+
29598+/* ---------------------------------------------------------------------- */
29599+
29600+/* aufs inode number bitmap */
29601+
29602+static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
29603+static ino_t xib_calc_ino(unsigned long pindex, int bit)
29604+{
29605+ ino_t ino;
29606+
29607+ AuDebugOn(bit < 0 || page_bits <= bit);
29608+ ino = AUFS_FIRST_INO + pindex * page_bits + bit;
29609+ return ino;
29610+}
29611+
29612+static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
29613+{
29614+ AuDebugOn(ino < AUFS_FIRST_INO);
29615+ ino -= AUFS_FIRST_INO;
29616+ *pindex = ino / page_bits;
29617+ *bit = ino % page_bits;
29618+}
29619+
29620+static int xib_pindex(struct super_block *sb, unsigned long pindex)
29621+{
29622+ int err;
29623+ loff_t pos;
29624+ ssize_t sz;
29625+ struct au_sbinfo *sbinfo;
29626+ struct file *xib;
29627+ unsigned long *p;
29628+
29629+ sbinfo = au_sbi(sb);
29630+ MtxMustLock(&sbinfo->si_xib_mtx);
29631+ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
29632+ || !au_opt_test(sbinfo->si_mntflags, XINO));
29633+
29634+ if (pindex == sbinfo->si_xib_last_pindex)
29635+ return 0;
29636+
29637+ xib = sbinfo->si_xib;
29638+ p = sbinfo->si_xib_buf;
29639+ pos = sbinfo->si_xib_last_pindex;
29640+ pos *= PAGE_SIZE;
29641+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
29642+ if (unlikely(sz != PAGE_SIZE))
29643+ goto out;
29644+
29645+ pos = pindex;
29646+ pos *= PAGE_SIZE;
29647+ if (i_size_read(xib->f_dentry->d_inode) >= pos + PAGE_SIZE)
29648+ sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
29649+ else {
29650+ memset(p, 0, PAGE_SIZE);
29651+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
29652+ }
29653+ if (sz == PAGE_SIZE) {
29654+ sbinfo->si_xib_last_pindex = pindex;
29655+ return 0; /* success */
29656+ }
29657+
4f0767ce 29658+out:
b752ccd1
AM
29659+ AuIOErr1("write failed (%zd)\n", sz);
29660+ err = sz;
29661+ if (sz >= 0)
29662+ err = -EIO;
29663+ return err;
29664+}
29665+
29666+/* ---------------------------------------------------------------------- */
29667+
29668+static void au_xib_clear_bit(struct inode *inode)
29669+{
29670+ int err, bit;
29671+ unsigned long pindex;
29672+ struct super_block *sb;
29673+ struct au_sbinfo *sbinfo;
29674+
29675+ AuDebugOn(inode->i_nlink);
29676+
29677+ sb = inode->i_sb;
29678+ xib_calc_bit(inode->i_ino, &pindex, &bit);
29679+ AuDebugOn(page_bits <= bit);
29680+ sbinfo = au_sbi(sb);
29681+ mutex_lock(&sbinfo->si_xib_mtx);
29682+ err = xib_pindex(sb, pindex);
29683+ if (!err) {
29684+ clear_bit(bit, sbinfo->si_xib_buf);
29685+ sbinfo->si_xib_next_bit = bit;
29686+ }
29687+ mutex_unlock(&sbinfo->si_xib_mtx);
29688+}
29689+
29690+/* for s_op->delete_inode() */
29691+void au_xino_delete_inode(struct inode *inode, const int unlinked)
29692+{
29693+ int err;
29694+ unsigned int mnt_flags;
29695+ aufs_bindex_t bindex, bend, bi;
29696+ unsigned char try_trunc;
29697+ struct au_iinfo *iinfo;
29698+ struct super_block *sb;
29699+ struct au_hinode *hi;
29700+ struct inode *h_inode;
29701+ struct au_branch *br;
29702+ au_writef_t xwrite;
29703+
29704+ sb = inode->i_sb;
29705+ mnt_flags = au_mntflags(sb);
29706+ if (!au_opt_test(mnt_flags, XINO)
29707+ || inode->i_ino == AUFS_ROOT_INO)
29708+ return;
29709+
29710+ if (unlinked) {
29711+ au_xigen_inc(inode);
29712+ au_xib_clear_bit(inode);
29713+ }
29714+
29715+ iinfo = au_ii(inode);
29716+ if (!iinfo)
29717+ return;
1facf9fc 29718+
b752ccd1
AM
29719+ bindex = iinfo->ii_bstart;
29720+ if (bindex < 0)
29721+ return;
1facf9fc 29722+
b752ccd1
AM
29723+ xwrite = au_sbi(sb)->si_xwrite;
29724+ try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO);
29725+ hi = iinfo->ii_hinode + bindex;
29726+ bend = iinfo->ii_bend;
29727+ for (; bindex <= bend; bindex++, hi++) {
29728+ h_inode = hi->hi_inode;
29729+ if (!h_inode
29730+ || (!unlinked && h_inode->i_nlink))
29731+ continue;
1facf9fc 29732+
b752ccd1
AM
29733+ /* inode may not be revalidated */
29734+ bi = au_br_index(sb, hi->hi_id);
29735+ if (bi < 0)
29736+ continue;
1facf9fc 29737+
b752ccd1
AM
29738+ br = au_sbr(sb, bi);
29739+ err = au_xino_do_write(xwrite, br->br_xino.xi_file,
29740+ h_inode->i_ino, /*ino*/0);
29741+ if (!err && try_trunc
29742+ && au_test_fs_trunc_xino(br->br_mnt->mnt_sb))
29743+ xino_try_trunc(sb, br);
1facf9fc 29744+ }
1facf9fc 29745+}
29746+
29747+/* get an unused inode number from bitmap */
29748+ino_t au_xino_new_ino(struct super_block *sb)
29749+{
29750+ ino_t ino;
29751+ unsigned long *p, pindex, ul, pend;
29752+ struct au_sbinfo *sbinfo;
29753+ struct file *file;
29754+ int free_bit, err;
29755+
29756+ if (!au_opt_test(au_mntflags(sb), XINO))
29757+ return iunique(sb, AUFS_FIRST_INO);
29758+
29759+ sbinfo = au_sbi(sb);
29760+ mutex_lock(&sbinfo->si_xib_mtx);
29761+ p = sbinfo->si_xib_buf;
29762+ free_bit = sbinfo->si_xib_next_bit;
29763+ if (free_bit < page_bits && !test_bit(free_bit, p))
29764+ goto out; /* success */
29765+ free_bit = find_first_zero_bit(p, page_bits);
29766+ if (free_bit < page_bits)
29767+ goto out; /* success */
29768+
29769+ pindex = sbinfo->si_xib_last_pindex;
29770+ for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
29771+ err = xib_pindex(sb, ul);
29772+ if (unlikely(err))
29773+ goto out_err;
29774+ free_bit = find_first_zero_bit(p, page_bits);
29775+ if (free_bit < page_bits)
29776+ goto out; /* success */
29777+ }
29778+
29779+ file = sbinfo->si_xib;
29780+ pend = i_size_read(file->f_dentry->d_inode) / PAGE_SIZE;
29781+ for (ul = pindex + 1; ul <= pend; ul++) {
29782+ err = xib_pindex(sb, ul);
29783+ if (unlikely(err))
29784+ goto out_err;
29785+ free_bit = find_first_zero_bit(p, page_bits);
29786+ if (free_bit < page_bits)
29787+ goto out; /* success */
29788+ }
29789+ BUG();
29790+
4f0767ce 29791+out:
1facf9fc 29792+ set_bit(free_bit, p);
7f207e10 29793+ sbinfo->si_xib_next_bit = free_bit + 1;
1facf9fc 29794+ pindex = sbinfo->si_xib_last_pindex;
29795+ mutex_unlock(&sbinfo->si_xib_mtx);
29796+ ino = xib_calc_ino(pindex, free_bit);
29797+ AuDbg("i%lu\n", (unsigned long)ino);
29798+ return ino;
4f0767ce 29799+out_err:
1facf9fc 29800+ mutex_unlock(&sbinfo->si_xib_mtx);
29801+ AuDbg("i0\n");
29802+ return 0;
29803+}
29804+
29805+/*
29806+ * read @ino from xinofile for the specified branch{@sb, @bindex}
29807+ * at the position of @h_ino.
29808+ * if @ino does not exist and @do_new is true, get new one.
29809+ */
29810+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
29811+ ino_t *ino)
29812+{
29813+ int err;
29814+ ssize_t sz;
29815+ loff_t pos;
29816+ struct file *file;
29817+ struct au_sbinfo *sbinfo;
29818+
29819+ *ino = 0;
29820+ if (!au_opt_test(au_mntflags(sb), XINO))
29821+ return 0; /* no xino */
29822+
29823+ err = 0;
29824+ sbinfo = au_sbi(sb);
29825+ pos = h_ino;
29826+ if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) {
29827+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
29828+ return -EFBIG;
29829+ }
29830+ pos *= sizeof(*ino);
29831+
29832+ file = au_sbr(sb, bindex)->br_xino.xi_file;
29833+ if (i_size_read(file->f_dentry->d_inode) < pos + sizeof(*ino))
29834+ return 0; /* no ino */
29835+
29836+ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos);
29837+ if (sz == sizeof(*ino))
29838+ return 0; /* success */
29839+
29840+ err = sz;
29841+ if (unlikely(sz >= 0)) {
29842+ err = -EIO;
29843+ AuIOErr("xino read error (%zd)\n", sz);
29844+ }
29845+
29846+ return err;
29847+}
29848+
29849+/* ---------------------------------------------------------------------- */
29850+
29851+/* create and set a new xino file */
29852+
29853+struct file *au_xino_create(struct super_block *sb, char *fname, int silent)
29854+{
29855+ struct file *file;
29856+ struct dentry *h_parent, *d;
29857+ struct inode *h_dir;
29858+ int err;
29859+
29860+ /*
29861+ * at mount-time, and the xino file is the default path,
4a4d8108 29862+ * hnotify is disabled so we have no notify events to ignore.
1facf9fc 29863+ * when a user specified the xino, we cannot get au_hdir to be ignored.
29864+ */
7f207e10 29865+ file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 29866+ /* | __FMODE_NONOTIFY */,
1facf9fc 29867+ S_IRUGO | S_IWUGO);
29868+ if (IS_ERR(file)) {
29869+ if (!silent)
4a4d8108 29870+ pr_err("open %s(%ld)\n", fname, PTR_ERR(file));
1facf9fc 29871+ return file;
29872+ }
29873+
29874+ /* keep file count */
29875+ h_parent = dget_parent(file->f_dentry);
29876+ h_dir = h_parent->d_inode;
29877+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
29878+ /* mnt_want_write() is unnecessary here */
29879+ err = vfsub_unlink(h_dir, &file->f_path, /*force*/0);
29880+ mutex_unlock(&h_dir->i_mutex);
29881+ dput(h_parent);
29882+ if (unlikely(err)) {
29883+ if (!silent)
4a4d8108 29884+ pr_err("unlink %s(%d)\n", fname, err);
1facf9fc 29885+ goto out;
29886+ }
29887+
29888+ err = -EINVAL;
29889+ d = file->f_dentry;
29890+ if (unlikely(sb == d->d_sb)) {
29891+ if (!silent)
4a4d8108 29892+ pr_err("%s must be outside\n", fname);
1facf9fc 29893+ goto out;
29894+ }
29895+ if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
29896+ if (!silent)
4a4d8108
AM
29897+ pr_err("xino doesn't support %s(%s)\n",
29898+ fname, au_sbtype(d->d_sb));
1facf9fc 29899+ goto out;
29900+ }
29901+ return file; /* success */
29902+
4f0767ce 29903+out:
1facf9fc 29904+ fput(file);
29905+ file = ERR_PTR(err);
29906+ return file;
29907+}
29908+
29909+/*
29910+ * find another branch who is on the same filesystem of the specified
29911+ * branch{@btgt}. search until @bend.
29912+ */
29913+static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
29914+ aufs_bindex_t bend)
29915+{
29916+ aufs_bindex_t bindex;
29917+ struct super_block *tgt_sb = au_sbr_sb(sb, btgt);
29918+
29919+ for (bindex = 0; bindex < btgt; bindex++)
29920+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
29921+ return bindex;
29922+ for (bindex++; bindex <= bend; bindex++)
29923+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
29924+ return bindex;
29925+ return -1;
29926+}
29927+
29928+/* ---------------------------------------------------------------------- */
29929+
29930+/*
29931+ * initialize the xinofile for the specified branch @br
29932+ * at the place/path where @base_file indicates.
29933+ * test whether another branch is on the same filesystem or not,
29934+ * if @do_test is true.
29935+ */
29936+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
29937+ struct file *base_file, int do_test)
29938+{
29939+ int err;
29940+ ino_t ino;
29941+ aufs_bindex_t bend, bindex;
29942+ struct au_branch *shared_br, *b;
29943+ struct file *file;
29944+ struct super_block *tgt_sb;
29945+
29946+ shared_br = NULL;
29947+ bend = au_sbend(sb);
29948+ if (do_test) {
29949+ tgt_sb = br->br_mnt->mnt_sb;
29950+ for (bindex = 0; bindex <= bend; bindex++) {
29951+ b = au_sbr(sb, bindex);
29952+ if (tgt_sb == b->br_mnt->mnt_sb) {
29953+ shared_br = b;
29954+ break;
29955+ }
29956+ }
29957+ }
29958+
29959+ if (!shared_br || !shared_br->br_xino.xi_file) {
29960+ struct au_xino_lock_dir ldir;
29961+
29962+ au_xino_lock_dir(sb, base_file, &ldir);
29963+ /* mnt_want_write() is unnecessary here */
29964+ file = au_xino_create2(base_file, NULL);
29965+ au_xino_unlock_dir(&ldir);
29966+ err = PTR_ERR(file);
29967+ if (IS_ERR(file))
29968+ goto out;
29969+ br->br_xino.xi_file = file;
29970+ } else {
29971+ br->br_xino.xi_file = shared_br->br_xino.xi_file;
29972+ get_file(br->br_xino.xi_file);
29973+ }
29974+
29975+ ino = AUFS_ROOT_INO;
29976+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
29977+ h_ino, ino);
b752ccd1
AM
29978+ if (unlikely(err)) {
29979+ fput(br->br_xino.xi_file);
29980+ br->br_xino.xi_file = NULL;
29981+ }
1facf9fc 29982+
4f0767ce 29983+out:
1facf9fc 29984+ return err;
29985+}
29986+
29987+/* ---------------------------------------------------------------------- */
29988+
29989+/* trucate a xino bitmap file */
29990+
29991+/* todo: slow */
29992+static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
29993+{
29994+ int err, bit;
29995+ ssize_t sz;
29996+ unsigned long pindex;
29997+ loff_t pos, pend;
29998+ struct au_sbinfo *sbinfo;
29999+ au_readf_t func;
30000+ ino_t *ino;
30001+ unsigned long *p;
30002+
30003+ err = 0;
30004+ sbinfo = au_sbi(sb);
dece6358 30005+ MtxMustLock(&sbinfo->si_xib_mtx);
1facf9fc 30006+ p = sbinfo->si_xib_buf;
30007+ func = sbinfo->si_xread;
30008+ pend = i_size_read(file->f_dentry->d_inode);
30009+ pos = 0;
30010+ while (pos < pend) {
30011+ sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
30012+ err = sz;
30013+ if (unlikely(sz <= 0))
30014+ goto out;
30015+
30016+ err = 0;
30017+ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
30018+ if (unlikely(*ino < AUFS_FIRST_INO))
30019+ continue;
30020+
30021+ xib_calc_bit(*ino, &pindex, &bit);
30022+ AuDebugOn(page_bits <= bit);
30023+ err = xib_pindex(sb, pindex);
30024+ if (!err)
30025+ set_bit(bit, p);
30026+ else
30027+ goto out;
30028+ }
30029+ }
30030+
4f0767ce 30031+out:
1facf9fc 30032+ return err;
30033+}
30034+
30035+static int xib_restore(struct super_block *sb)
30036+{
30037+ int err;
30038+ aufs_bindex_t bindex, bend;
30039+ void *page;
30040+
30041+ err = -ENOMEM;
30042+ page = (void *)__get_free_page(GFP_NOFS);
30043+ if (unlikely(!page))
30044+ goto out;
30045+
30046+ err = 0;
30047+ bend = au_sbend(sb);
30048+ for (bindex = 0; !err && bindex <= bend; bindex++)
30049+ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0)
30050+ err = do_xib_restore
30051+ (sb, au_sbr(sb, bindex)->br_xino.xi_file, page);
30052+ else
30053+ AuDbg("b%d\n", bindex);
30054+ free_page((unsigned long)page);
30055+
4f0767ce 30056+out:
1facf9fc 30057+ return err;
30058+}
30059+
30060+int au_xib_trunc(struct super_block *sb)
30061+{
30062+ int err;
30063+ ssize_t sz;
30064+ loff_t pos;
30065+ struct au_xino_lock_dir ldir;
30066+ struct au_sbinfo *sbinfo;
30067+ unsigned long *p;
30068+ struct file *file;
30069+
dece6358
AM
30070+ SiMustWriteLock(sb);
30071+
1facf9fc 30072+ err = 0;
30073+ sbinfo = au_sbi(sb);
30074+ if (!au_opt_test(sbinfo->si_mntflags, XINO))
30075+ goto out;
30076+
30077+ file = sbinfo->si_xib;
30078+ if (i_size_read(file->f_dentry->d_inode) <= PAGE_SIZE)
30079+ goto out;
30080+
30081+ au_xino_lock_dir(sb, file, &ldir);
30082+ /* mnt_want_write() is unnecessary here */
30083+ file = au_xino_create2(sbinfo->si_xib, NULL);
30084+ au_xino_unlock_dir(&ldir);
30085+ err = PTR_ERR(file);
30086+ if (IS_ERR(file))
30087+ goto out;
30088+ fput(sbinfo->si_xib);
30089+ sbinfo->si_xib = file;
30090+
30091+ p = sbinfo->si_xib_buf;
30092+ memset(p, 0, PAGE_SIZE);
30093+ pos = 0;
30094+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
30095+ if (unlikely(sz != PAGE_SIZE)) {
30096+ err = sz;
30097+ AuIOErr("err %d\n", err);
30098+ if (sz >= 0)
30099+ err = -EIO;
30100+ goto out;
30101+ }
30102+
30103+ mutex_lock(&sbinfo->si_xib_mtx);
30104+ /* mnt_want_write() is unnecessary here */
30105+ err = xib_restore(sb);
30106+ mutex_unlock(&sbinfo->si_xib_mtx);
30107+
30108+out:
30109+ return err;
30110+}
30111+
30112+/* ---------------------------------------------------------------------- */
30113+
30114+/*
30115+ * xino mount option handlers
30116+ */
30117+static au_readf_t find_readf(struct file *h_file)
30118+{
30119+ const struct file_operations *fop = h_file->f_op;
30120+
30121+ if (fop) {
30122+ if (fop->read)
30123+ return fop->read;
30124+ if (fop->aio_read)
30125+ return do_sync_read;
30126+ }
30127+ return ERR_PTR(-ENOSYS);
30128+}
30129+
30130+static au_writef_t find_writef(struct file *h_file)
30131+{
30132+ const struct file_operations *fop = h_file->f_op;
30133+
30134+ if (fop) {
30135+ if (fop->write)
30136+ return fop->write;
30137+ if (fop->aio_write)
30138+ return do_sync_write;
30139+ }
30140+ return ERR_PTR(-ENOSYS);
30141+}
30142+
30143+/* xino bitmap */
30144+static void xino_clear_xib(struct super_block *sb)
30145+{
30146+ struct au_sbinfo *sbinfo;
30147+
dece6358
AM
30148+ SiMustWriteLock(sb);
30149+
1facf9fc 30150+ sbinfo = au_sbi(sb);
30151+ sbinfo->si_xread = NULL;
30152+ sbinfo->si_xwrite = NULL;
30153+ if (sbinfo->si_xib)
30154+ fput(sbinfo->si_xib);
30155+ sbinfo->si_xib = NULL;
30156+ free_page((unsigned long)sbinfo->si_xib_buf);
30157+ sbinfo->si_xib_buf = NULL;
30158+}
30159+
30160+static int au_xino_set_xib(struct super_block *sb, struct file *base)
30161+{
30162+ int err;
30163+ loff_t pos;
30164+ struct au_sbinfo *sbinfo;
30165+ struct file *file;
30166+
dece6358
AM
30167+ SiMustWriteLock(sb);
30168+
1facf9fc 30169+ sbinfo = au_sbi(sb);
30170+ file = au_xino_create2(base, sbinfo->si_xib);
30171+ err = PTR_ERR(file);
30172+ if (IS_ERR(file))
30173+ goto out;
30174+ if (sbinfo->si_xib)
30175+ fput(sbinfo->si_xib);
30176+ sbinfo->si_xib = file;
30177+ sbinfo->si_xread = find_readf(file);
30178+ sbinfo->si_xwrite = find_writef(file);
30179+
30180+ err = -ENOMEM;
30181+ if (!sbinfo->si_xib_buf)
30182+ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
30183+ if (unlikely(!sbinfo->si_xib_buf))
30184+ goto out_unset;
30185+
30186+ sbinfo->si_xib_last_pindex = 0;
30187+ sbinfo->si_xib_next_bit = 0;
30188+ if (i_size_read(file->f_dentry->d_inode) < PAGE_SIZE) {
30189+ pos = 0;
30190+ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
30191+ PAGE_SIZE, &pos);
30192+ if (unlikely(err != PAGE_SIZE))
30193+ goto out_free;
30194+ }
30195+ err = 0;
30196+ goto out; /* success */
30197+
4f0767ce 30198+out_free:
1facf9fc 30199+ free_page((unsigned long)sbinfo->si_xib_buf);
b752ccd1
AM
30200+ sbinfo->si_xib_buf = NULL;
30201+ if (err >= 0)
30202+ err = -EIO;
4f0767ce 30203+out_unset:
b752ccd1
AM
30204+ fput(sbinfo->si_xib);
30205+ sbinfo->si_xib = NULL;
30206+ sbinfo->si_xread = NULL;
30207+ sbinfo->si_xwrite = NULL;
4f0767ce 30208+out:
b752ccd1 30209+ return err;
1facf9fc 30210+}
30211+
b752ccd1
AM
30212+/* xino for each branch */
30213+static void xino_clear_br(struct super_block *sb)
30214+{
30215+ aufs_bindex_t bindex, bend;
30216+ struct au_branch *br;
1facf9fc 30217+
b752ccd1
AM
30218+ bend = au_sbend(sb);
30219+ for (bindex = 0; bindex <= bend; bindex++) {
30220+ br = au_sbr(sb, bindex);
30221+ if (!br || !br->br_xino.xi_file)
30222+ continue;
30223+
30224+ fput(br->br_xino.xi_file);
30225+ br->br_xino.xi_file = NULL;
30226+ }
30227+}
30228+
30229+static int au_xino_set_br(struct super_block *sb, struct file *base)
1facf9fc 30230+{
30231+ int err;
b752ccd1
AM
30232+ ino_t ino;
30233+ aufs_bindex_t bindex, bend, bshared;
30234+ struct {
30235+ struct file *old, *new;
30236+ } *fpair, *p;
30237+ struct au_branch *br;
30238+ struct inode *inode;
30239+ au_writef_t writef;
1facf9fc 30240+
b752ccd1
AM
30241+ SiMustWriteLock(sb);
30242+
30243+ err = -ENOMEM;
30244+ bend = au_sbend(sb);
30245+ fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS);
30246+ if (unlikely(!fpair))
1facf9fc 30247+ goto out;
30248+
b752ccd1
AM
30249+ inode = sb->s_root->d_inode;
30250+ ino = AUFS_ROOT_INO;
30251+ writef = au_sbi(sb)->si_xwrite;
30252+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
30253+ br = au_sbr(sb, bindex);
30254+ bshared = is_sb_shared(sb, bindex, bindex - 1);
30255+ if (bshared >= 0) {
30256+ /* shared xino */
30257+ *p = fpair[bshared];
30258+ get_file(p->new);
30259+ }
30260+
30261+ if (!p->new) {
30262+ /* new xino */
30263+ p->old = br->br_xino.xi_file;
30264+ p->new = au_xino_create2(base, br->br_xino.xi_file);
30265+ err = PTR_ERR(p->new);
30266+ if (IS_ERR(p->new)) {
30267+ p->new = NULL;
30268+ goto out_pair;
30269+ }
30270+ }
30271+
30272+ err = au_xino_do_write(writef, p->new,
30273+ au_h_iptr(inode, bindex)->i_ino, ino);
30274+ if (unlikely(err))
30275+ goto out_pair;
30276+ }
30277+
30278+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
30279+ br = au_sbr(sb, bindex);
30280+ if (br->br_xino.xi_file)
30281+ fput(br->br_xino.xi_file);
30282+ get_file(p->new);
30283+ br->br_xino.xi_file = p->new;
30284+ }
1facf9fc 30285+
4f0767ce 30286+out_pair:
b752ccd1
AM
30287+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++)
30288+ if (p->new)
30289+ fput(p->new);
30290+ else
30291+ break;
30292+ kfree(fpair);
4f0767ce 30293+out:
1facf9fc 30294+ return err;
30295+}
b752ccd1
AM
30296+
30297+void au_xino_clr(struct super_block *sb)
30298+{
30299+ struct au_sbinfo *sbinfo;
30300+
30301+ au_xigen_clr(sb);
30302+ xino_clear_xib(sb);
30303+ xino_clear_br(sb);
30304+ sbinfo = au_sbi(sb);
30305+ /* lvalue, do not call au_mntflags() */
30306+ au_opt_clr(sbinfo->si_mntflags, XINO);
30307+}
30308+
30309+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount)
30310+{
30311+ int err, skip;
30312+ struct dentry *parent, *cur_parent;
30313+ struct qstr *dname, *cur_name;
30314+ struct file *cur_xino;
30315+ struct inode *dir;
30316+ struct au_sbinfo *sbinfo;
30317+
30318+ SiMustWriteLock(sb);
30319+
30320+ err = 0;
30321+ sbinfo = au_sbi(sb);
30322+ parent = dget_parent(xino->file->f_dentry);
30323+ if (remount) {
30324+ skip = 0;
30325+ dname = &xino->file->f_dentry->d_name;
30326+ cur_xino = sbinfo->si_xib;
30327+ if (cur_xino) {
30328+ cur_parent = dget_parent(cur_xino->f_dentry);
30329+ cur_name = &cur_xino->f_dentry->d_name;
30330+ skip = (cur_parent == parent
30331+ && dname->len == cur_name->len
30332+ && !memcmp(dname->name, cur_name->name,
30333+ dname->len));
30334+ dput(cur_parent);
30335+ }
30336+ if (skip)
30337+ goto out;
30338+ }
30339+
30340+ au_opt_set(sbinfo->si_mntflags, XINO);
30341+ dir = parent->d_inode;
30342+ mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT);
30343+ /* mnt_want_write() is unnecessary here */
30344+ err = au_xino_set_xib(sb, xino->file);
30345+ if (!err)
30346+ err = au_xigen_set(sb, xino->file);
30347+ if (!err)
30348+ err = au_xino_set_br(sb, xino->file);
30349+ mutex_unlock(&dir->i_mutex);
30350+ if (!err)
30351+ goto out; /* success */
30352+
30353+ /* reset all */
30354+ AuIOErr("failed creating xino(%d).\n", err);
30355+
4f0767ce 30356+out:
b752ccd1
AM
30357+ dput(parent);
30358+ return err;
30359+}
30360+
30361+/* ---------------------------------------------------------------------- */
30362+
30363+/*
30364+ * create a xinofile at the default place/path.
30365+ */
30366+struct file *au_xino_def(struct super_block *sb)
30367+{
30368+ struct file *file;
30369+ char *page, *p;
30370+ struct au_branch *br;
30371+ struct super_block *h_sb;
30372+ struct path path;
30373+ aufs_bindex_t bend, bindex, bwr;
30374+
30375+ br = NULL;
30376+ bend = au_sbend(sb);
30377+ bwr = -1;
30378+ for (bindex = 0; bindex <= bend; bindex++) {
30379+ br = au_sbr(sb, bindex);
30380+ if (au_br_writable(br->br_perm)
30381+ && !au_test_fs_bad_xino(br->br_mnt->mnt_sb)) {
30382+ bwr = bindex;
30383+ break;
30384+ }
30385+ }
30386+
7f207e10
AM
30387+ if (bwr >= 0) {
30388+ file = ERR_PTR(-ENOMEM);
537831f9 30389+ page = (void *)__get_free_page(GFP_NOFS);
7f207e10
AM
30390+ if (unlikely(!page))
30391+ goto out;
30392+ path.mnt = br->br_mnt;
30393+ path.dentry = au_h_dptr(sb->s_root, bwr);
30394+ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
30395+ file = (void *)p;
30396+ if (!IS_ERR(p)) {
30397+ strcat(p, "/" AUFS_XINO_FNAME);
30398+ AuDbg("%s\n", p);
30399+ file = au_xino_create(sb, p, /*silent*/0);
30400+ if (!IS_ERR(file))
30401+ au_xino_brid_set(sb, br->br_id);
30402+ }
537831f9 30403+ free_page((unsigned long)page);
7f207e10
AM
30404+ } else {
30405+ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
30406+ if (IS_ERR(file))
30407+ goto out;
30408+ h_sb = file->f_dentry->d_sb;
30409+ if (unlikely(au_test_fs_bad_xino(h_sb))) {
30410+ pr_err("xino doesn't support %s(%s)\n",
30411+ AUFS_XINO_DEFPATH, au_sbtype(h_sb));
30412+ fput(file);
30413+ file = ERR_PTR(-EINVAL);
30414+ }
30415+ if (!IS_ERR(file))
30416+ au_xino_brid_set(sb, -1);
30417+ }
0c5527e5 30418+
7f207e10
AM
30419+out:
30420+ return file;
30421+}
30422+
30423+/* ---------------------------------------------------------------------- */
30424+
30425+int au_xino_path(struct seq_file *seq, struct file *file)
30426+{
30427+ int err;
30428+
30429+ err = au_seq_path(seq, &file->f_path);
30430+ if (unlikely(err < 0))
30431+ goto out;
30432+
30433+ err = 0;
30434+#define Deleted "\\040(deleted)"
30435+ seq->count -= sizeof(Deleted) - 1;
30436+ AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
30437+ sizeof(Deleted) - 1));
30438+#undef Deleted
30439+
30440+out:
30441+ return err;
30442+}
30443diff -urN /usr/share/empty/include/linux/aufs_type.h linux/include/linux/aufs_type.h
30444--- /usr/share/empty/include/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
1716fcea 30445+++ linux/include/linux/aufs_type.h 2013-02-19 08:40:03.953559833 +0100
537831f9
AM
30446@@ -0,0 +1,19 @@
30447+/*
7a9e40b8 30448+ * Copyright (C) 2012-2013 Junjiro R. Okajima
537831f9
AM
30449+ *
30450+ * This program, aufs is free software; you can redistribute it and/or modify
30451+ * it under the terms of the GNU General Public License as published by
30452+ * the Free Software Foundation; either version 2 of the License, or
30453+ * (at your option) any later version.
30454+ *
30455+ * This program is distributed in the hope that it will be useful,
30456+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30457+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30458+ * GNU General Public License for more details.
30459+ *
30460+ * You should have received a copy of the GNU General Public License
30461+ * along with this program; if not, write to the Free Software
30462+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30463+ */
30464+
30465+#include <uapi/linux/aufs_type.h>
30466diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h
30467--- /usr/share/empty/include/uapi/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
a2a7ad62
AM
30468+++ linux/include/uapi/linux/aufs_type.h 2013-03-14 20:07:41.224790724 +0100
30469@@ -0,0 +1,234 @@
7f207e10 30470+/*
7a9e40b8 30471+ * Copyright (C) 2005-2013 Junjiro R. Okajima
7f207e10
AM
30472+ *
30473+ * This program, aufs is free software; you can redistribute it and/or modify
30474+ * it under the terms of the GNU General Public License as published by
30475+ * the Free Software Foundation; either version 2 of the License, or
30476+ * (at your option) any later version.
30477+ *
30478+ * This program is distributed in the hope that it will be useful,
30479+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30480+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30481+ * GNU General Public License for more details.
30482+ *
30483+ * You should have received a copy of the GNU General Public License
30484+ * along with this program; if not, write to the Free Software
30485+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30486+ */
30487+
30488+#ifndef __AUFS_TYPE_H__
30489+#define __AUFS_TYPE_H__
30490+
f6c5ef8b
AM
30491+#define AUFS_NAME "aufs"
30492+
9dbd164d 30493+#ifdef __KERNEL__
f6c5ef8b
AM
30494+/*
30495+ * define it before including all other headers.
30496+ * sched.h may use pr_* macros before defining "current", so define the
30497+ * no-current version first, and re-define later.
30498+ */
30499+#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__
30500+#include <linux/sched.h>
30501+#undef pr_fmt
a2a7ad62
AM
30502+#define pr_fmt(fmt) \
30503+ AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \
30504+ (int)sizeof(current->comm), current->comm, current->pid
9dbd164d
AM
30505+#else
30506+#include <stdint.h>
30507+#include <sys/types.h>
f6c5ef8b 30508+#endif /* __KERNEL__ */
7f207e10 30509+
f6c5ef8b
AM
30510+#include <linux/limits.h>
30511+
a2a7ad62 30512+#define AUFS_VERSION "3.8-20130311"
7f207e10
AM
30513+
30514+/* todo? move this to linux-2.6.19/include/magic.h */
30515+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
30516+
30517+/* ---------------------------------------------------------------------- */
30518+
30519+#ifdef CONFIG_AUFS_BRANCH_MAX_127
9dbd164d 30520+typedef int8_t aufs_bindex_t;
7f207e10
AM
30521+#define AUFS_BRANCH_MAX 127
30522+#else
9dbd164d 30523+typedef int16_t aufs_bindex_t;
7f207e10
AM
30524+#ifdef CONFIG_AUFS_BRANCH_MAX_511
30525+#define AUFS_BRANCH_MAX 511
30526+#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
30527+#define AUFS_BRANCH_MAX 1023
30528+#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
30529+#define AUFS_BRANCH_MAX 32767
30530+#endif
30531+#endif
30532+
30533+#ifdef __KERNEL__
30534+#ifndef AUFS_BRANCH_MAX
30535+#error unknown CONFIG_AUFS_BRANCH_MAX value
30536+#endif
30537+#endif /* __KERNEL__ */
30538+
30539+/* ---------------------------------------------------------------------- */
30540+
7f207e10
AM
30541+#define AUFS_FSTYPE AUFS_NAME
30542+
30543+#define AUFS_ROOT_INO 2
30544+#define AUFS_FIRST_INO 11
30545+
30546+#define AUFS_WH_PFX ".wh."
30547+#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1)
30548+#define AUFS_WH_TMP_LEN 4
30549+/* a limit for rmdir/rename a dir */
30550+#define AUFS_MAX_NAMELEN (NAME_MAX \
30551+ - AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\
30552+ - 1 /* dot */\
30553+ - AUFS_WH_TMP_LEN) /* hex */
30554+#define AUFS_XINO_FNAME "." AUFS_NAME ".xino"
30555+#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME
30556+#define AUFS_XINO_TRUNC_INIT 64 /* blocks */
30557+#define AUFS_XINO_TRUNC_STEP 4 /* blocks */
30558+#define AUFS_DIRWH_DEF 3
30559+#define AUFS_RDCACHE_DEF 10 /* seconds */
027c5e7a 30560+#define AUFS_RDCACHE_MAX 3600 /* seconds */
7f207e10
AM
30561+#define AUFS_RDBLK_DEF 512 /* bytes */
30562+#define AUFS_RDHASH_DEF 32
30563+#define AUFS_WKQ_NAME AUFS_NAME "d"
027c5e7a
AM
30564+#define AUFS_MFS_DEF_SEC 30 /* seconds */
30565+#define AUFS_MFS_MAX_SEC 3600 /* seconds */
7f207e10
AM
30566+#define AUFS_PLINK_WARN 100 /* number of plinks */
30567+
30568+/* pseudo-link maintenace under /proc */
30569+#define AUFS_PLINK_MAINT_NAME "plink_maint"
30570+#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME
30571+#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME
30572+
30573+#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */
30574+#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME
30575+
30576+#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME
30577+#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk"
30578+#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph"
30579+
30580+/* doubly whiteouted */
30581+#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME
30582+#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME
30583+#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME
30584+
1e00d052 30585+/* branch permissions and attributes */
7f207e10
AM
30586+#define AUFS_BRPERM_RW "rw"
30587+#define AUFS_BRPERM_RO "ro"
30588+#define AUFS_BRPERM_RR "rr"
1e00d052
AM
30589+#define AUFS_BRRATTR_WH "wh"
30590+#define AUFS_BRWATTR_NLWH "nolwh"
7f207e10
AM
30591+
30592+/* ---------------------------------------------------------------------- */
30593+
30594+/* ioctl */
30595+enum {
30596+ /* readdir in userspace */
30597+ AuCtl_RDU,
30598+ AuCtl_RDU_INO,
30599+
30600+ /* pathconf wrapper */
027c5e7a
AM
30601+ AuCtl_WBR_FD,
30602+
30603+ /* busy inode */
30604+ AuCtl_IBUSY
7f207e10
AM
30605+};
30606+
30607+/* borrowed from linux/include/linux/kernel.h */
30608+#ifndef ALIGN
30609+#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1)
30610+#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
30611+#endif
30612+
30613+/* borrowed from linux/include/linux/compiler-gcc3.h */
30614+#ifndef __aligned
30615+#define __aligned(x) __attribute__((aligned(x)))
53392da6
AM
30616+#endif
30617+
30618+#ifdef __KERNEL__
30619+#ifndef __packed
7f207e10
AM
30620+#define __packed __attribute__((packed))
30621+#endif
53392da6 30622+#endif
7f207e10
AM
30623+
30624+struct au_rdu_cookie {
9dbd164d
AM
30625+ uint64_t h_pos;
30626+ int16_t bindex;
30627+ uint8_t flags;
30628+ uint8_t pad;
30629+ uint32_t generation;
7f207e10
AM
30630+} __aligned(8);
30631+
30632+struct au_rdu_ent {
9dbd164d
AM
30633+ uint64_t ino;
30634+ int16_t bindex;
30635+ uint8_t type;
30636+ uint8_t nlen;
30637+ uint8_t wh;
7f207e10
AM
30638+ char name[0];
30639+} __aligned(8);
30640+
30641+static inline int au_rdu_len(int nlen)
30642+{
30643+ /* include the terminating NULL */
30644+ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1,
9dbd164d 30645+ sizeof(uint64_t));
7f207e10
AM
30646+}
30647+
30648+union au_rdu_ent_ul {
30649+ struct au_rdu_ent __user *e;
9dbd164d 30650+ uint64_t ul;
7f207e10
AM
30651+};
30652+
30653+enum {
30654+ AufsCtlRduV_SZ,
30655+ AufsCtlRduV_End
30656+};
30657+
30658+struct aufs_rdu {
30659+ /* input */
30660+ union {
9dbd164d
AM
30661+ uint64_t sz; /* AuCtl_RDU */
30662+ uint64_t nent; /* AuCtl_RDU_INO */
7f207e10
AM
30663+ };
30664+ union au_rdu_ent_ul ent;
9dbd164d 30665+ uint16_t verify[AufsCtlRduV_End];
7f207e10
AM
30666+
30667+ /* input/output */
9dbd164d 30668+ uint32_t blk;
7f207e10
AM
30669+
30670+ /* output */
30671+ union au_rdu_ent_ul tail;
30672+ /* number of entries which were added in a single call */
9dbd164d
AM
30673+ uint64_t rent;
30674+ uint8_t full;
30675+ uint8_t shwh;
7f207e10
AM
30676+
30677+ struct au_rdu_cookie cookie;
30678+} __aligned(8);
30679+
1e00d052
AM
30680+/* ---------------------------------------------------------------------- */
30681+
30682+struct aufs_wbr_fd {
9dbd164d
AM
30683+ uint32_t oflags;
30684+ int16_t brid;
1e00d052
AM
30685+} __aligned(8);
30686+
30687+/* ---------------------------------------------------------------------- */
30688+
027c5e7a 30689+struct aufs_ibusy {
9dbd164d
AM
30690+ uint64_t ino, h_ino;
30691+ int16_t bindex;
027c5e7a
AM
30692+} __aligned(8);
30693+
1e00d052
AM
30694+/* ---------------------------------------------------------------------- */
30695+
7f207e10
AM
30696+#define AuCtlType 'A'
30697+#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu)
30698+#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu)
1e00d052
AM
30699+#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \
30700+ struct aufs_wbr_fd)
027c5e7a 30701+#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
7f207e10
AM
30702+
30703+#endif /* __AUFS_TYPE_H__ */
7a9e40b8 30704
This page took 5.316254 seconds and 4 git commands to generate.