]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-aufs3.patch
- added versuffix macro for easy future branching
[packages/kernel.git] / kernel-aufs3.patch
CommitLineData
f6b6e03d 1aufs3.13 kbuild patch
7f207e10
AM
2
3diff --git a/fs/Kconfig b/fs/Kconfig
86dc4139 4index c229f82..397b473 100644
7f207e10
AM
5--- a/fs/Kconfig
6+++ b/fs/Kconfig
86dc4139 7@@ -212,6 +212,7 @@ source "fs/ufs/Kconfig"
7f207e10 8 source "fs/exofs/Kconfig"
1716fcea 9 source "fs/f2fs/Kconfig"
c06a8ce3 10 source "fs/efivarfs/Kconfig"
7f207e10
AM
11+source "fs/aufs/Kconfig"
12
13 endif # MISC_FILESYSTEMS
14
15diff --git a/fs/Makefile b/fs/Makefile
86dc4139 16index 4fe6df3..4a57676 100644
7f207e10
AM
17--- a/fs/Makefile
18+++ b/fs/Makefile
86dc4139 19@@ -126,3 +126,4 @@ obj-y += exofs/ # Multiple modules
7f207e10 20 obj-$(CONFIG_CEPH_FS) += ceph/
bf0370f2 21 obj-$(CONFIG_PSTORE) += pstore/
c06a8ce3 22 obj-$(CONFIG_EFIVAR_FS) += efivarfs/
86dc4139 23+obj-$(CONFIG_AUFS_FS) += aufs/
c06a8ce3 24diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
523b37e3 25index 33d2b8f..b55eeb9 100644
c06a8ce3
AM
26--- a/include/uapi/linux/Kbuild
27+++ b/include/uapi/linux/Kbuild
28@@ -56,6 +56,7 @@ header-y += atmppp.h
29 header-y += atmsap.h
30 header-y += atmsvc.h
31 header-y += audit.h
32+header-y += aufs_type.h
33 header-y += auto_fs.h
34 header-y += auto_fs4.h
35 header-y += auxvec.h
f6b6e03d 36aufs3.13 base patch
7f207e10 37
392086de 38diff --git a/drivers/block/loop.c b/drivers/block/loop.c
523b37e3 39index c8dac73..2e229ac 100644
392086de
AM
40--- a/drivers/block/loop.c
41+++ b/drivers/block/loop.c
42@@ -691,6 +691,24 @@ static inline int is_loop_device(struct file *file)
43 return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
44 }
45
46+/*
47+ * for AUFS
48+ * no get/put for file.
49+ */
50+struct file *loop_backing_file(struct super_block *sb)
51+{
52+ struct file *ret;
53+ struct loop_device *l;
54+
55+ ret = NULL;
56+ if (MAJOR(sb->s_dev) == LOOP_MAJOR) {
57+ l = sb->s_bdev->bd_disk->private_data;
58+ ret = l->lo_backing_file;
59+ }
60+ return ret;
61+}
62+EXPORT_SYMBOL(loop_backing_file);
63+
64 /* loop sysfs attributes */
65
66 static ssize_t loop_attr_show(struct device *dev, char *page,
0c3ec466 67diff --git a/fs/inode.c b/fs/inode.c
523b37e3 68index 4bcdad3..bc83168 100644
0c3ec466
AM
69--- a/fs/inode.c
70+++ b/fs/inode.c
523b37e3 71@@ -1497,7 +1497,7 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
0c3ec466
AM
72 * This does the actual work of updating an inodes time or version. Must have
73 * had called mnt_want_write() before calling this.
74 */
75-static int update_time(struct inode *inode, struct timespec *time, int flags)
76+int update_time(struct inode *inode, struct timespec *time, int flags)
77 {
78 if (inode->i_op->update_time)
79 return inode->i_op->update_time(inode, time, flags);
7f207e10 80diff --git a/fs/splice.c b/fs/splice.c
523b37e3 81index 46a08f7..719ca3e 100644
7f207e10
AM
82--- a/fs/splice.c
83+++ b/fs/splice.c
c06a8ce3 84@@ -1093,8 +1093,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
7f207e10
AM
85 /*
86 * Attempt to initiate a splice from pipe to file.
87 */
88-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
89- loff_t *ppos, size_t len, unsigned int flags)
90+long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
91+ loff_t *ppos, size_t len, unsigned int flags)
92 {
93 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
94 loff_t *, size_t, unsigned int);
392086de 95@@ -1110,9 +1110,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
7f207e10
AM
96 /*
97 * Attempt to initiate a splice from a file to a pipe.
98 */
99-static long do_splice_to(struct file *in, loff_t *ppos,
100- struct pipe_inode_info *pipe, size_t len,
101- unsigned int flags)
102+long do_splice_to(struct file *in, loff_t *ppos,
103+ struct pipe_inode_info *pipe, size_t len,
104+ unsigned int flags)
105 {
106 ssize_t (*splice_read)(struct file *, loff_t *,
107 struct pipe_inode_info *, size_t, unsigned int);
0c3ec466 108diff --git a/include/linux/fs.h b/include/linux/fs.h
523b37e3 109index 121f11f..39bf86d 100644
0c3ec466
AM
110--- a/include/linux/fs.h
111+++ b/include/linux/fs.h
523b37e3 112@@ -2657,6 +2657,7 @@ extern int inode_change_ok(const struct inode *, struct iattr *);
0c3ec466
AM
113 extern int inode_newsize_ok(const struct inode *, loff_t offset);
114 extern void setattr_copy(struct inode *inode, const struct iattr *attr);
115
116+extern int update_time(struct inode *, struct timespec *, int);
117 extern int file_update_time(struct file *file);
118
119 extern int generic_show_options(struct seq_file *m, struct dentry *root);
1e00d052 120diff --git a/include/linux/splice.h b/include/linux/splice.h
86dc4139 121index 74575cb..bfc6fb6 100644
1e00d052
AM
122--- a/include/linux/splice.h
123+++ b/include/linux/splice.h
86dc4139 124@@ -92,4 +92,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *);
4b3da204
AM
125 extern void spd_release_page(struct splice_pipe_desc *, unsigned int);
126
127 extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
1e00d052
AM
128+
129+extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
130+ loff_t *ppos, size_t len, unsigned int flags);
131+extern long do_splice_to(struct file *in, loff_t *ppos,
132+ struct pipe_inode_info *pipe, size_t len,
133+ unsigned int flags);
134 #endif
f6b6e03d 135aufs3.13 standalone patch
7f207e10 136
1e00d052 137diff --git a/fs/inode.c b/fs/inode.c
523b37e3 138index bc83168..6dd1207 100644
1e00d052
AM
139--- a/fs/inode.c
140+++ b/fs/inode.c
392086de 141@@ -57,6 +57,7 @@ static struct hlist_head *inode_hashtable __read_mostly;
4b3da204 142 static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock);
2cbb1c4b
JR
143
144 __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock);
2cbb1c4b 145+EXPORT_SYMBOL(inode_sb_list_lock);
7f207e10
AM
146
147 /*
4b3da204 148 * Empty aops. Can be used for the cases where the user does not
523b37e3 149@@ -1513,6 +1514,7 @@ int update_time(struct inode *inode, struct timespec *time, int flags)
0c3ec466
AM
150 mark_inode_dirty_sync(inode);
151 return 0;
152 }
153+EXPORT_SYMBOL(update_time);
154
155 /**
156 * touch_atime - update the access time
7f207e10 157diff --git a/fs/namespace.c b/fs/namespace.c
f6b6e03d 158index be32ebc..d3f6f59 100644
7f207e10
AM
159--- a/fs/namespace.c
160+++ b/fs/namespace.c
523b37e3 161@@ -425,6 +425,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
c06a8ce3
AM
162 mnt_dec_writers(real_mount(mnt));
163 preempt_enable();
164 }
165+EXPORT_SYMBOL_GPL(__mnt_drop_write);
166
167 /**
168 * mnt_drop_write - give up write access to a mount
523b37e3 169@@ -1509,6 +1510,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
7f207e10
AM
170 }
171 return 0;
172 }
173+EXPORT_SYMBOL(iterate_mounts);
174
7eafdf33 175 static void cleanup_group_ids(struct mount *mnt, struct mount *end)
7f207e10
AM
176 {
177diff --git a/fs/notify/group.c b/fs/notify/group.c
1716fcea 178index bd2625b..2ff2a0f 100644
7f207e10
AM
179--- a/fs/notify/group.c
180+++ b/fs/notify/group.c
181@@ -22,6 +22,7 @@
182 #include <linux/srcu.h>
183 #include <linux/rculist.h>
184 #include <linux/wait.h>
185+#include <linux/module.h>
186
187 #include <linux/fsnotify_backend.h>
188 #include "fsnotify.h"
1716fcea
AM
189@@ -65,6 +66,7 @@ void fsnotify_get_group(struct fsnotify_group *group)
190 {
191 atomic_inc(&group->refcnt);
192 }
193+EXPORT_SYMBOL(fsnotify_get_group);
194
195 /*
196 * Drop a reference to a group. Free it if it's through.
197@@ -74,6 +76,7 @@ void fsnotify_put_group(struct fsnotify_group *group)
7f207e10 198 if (atomic_dec_and_test(&group->refcnt))
1716fcea 199 fsnotify_final_destroy_group(group);
7f207e10
AM
200 }
201+EXPORT_SYMBOL(fsnotify_put_group);
202
203 /*
204 * Create a new fsnotify_group and hold a reference for the group returned.
1716fcea 205@@ -102,6 +105,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
7f207e10
AM
206
207 return group;
208 }
209+EXPORT_SYMBOL(fsnotify_alloc_group);
1716fcea
AM
210
211 int fsnotify_fasync(int fd, struct file *file, int on)
212 {
7f207e10 213diff --git a/fs/notify/mark.c b/fs/notify/mark.c
392086de 214index 923fe4a..176b435 100644
7f207e10
AM
215--- a/fs/notify/mark.c
216+++ b/fs/notify/mark.c
392086de 217@@ -109,6 +109,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
7f207e10 218 mark->free_mark(mark);
1716fcea 219 }
7f207e10
AM
220 }
221+EXPORT_SYMBOL(fsnotify_put_mark);
222
223 /*
224 * Any time a mark is getting freed we end up here.
392086de 225@@ -191,6 +192,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark,
1716fcea
AM
226 fsnotify_destroy_mark_locked(mark, group);
227 mutex_unlock(&group->mark_mutex);
7f207e10
AM
228 }
229+EXPORT_SYMBOL(fsnotify_destroy_mark);
230
231 void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask)
232 {
392086de 233@@ -275,6 +277,7 @@ err:
7f207e10
AM
234
235 return ret;
236 }
237+EXPORT_SYMBOL(fsnotify_add_mark);
238
1716fcea
AM
239 int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
240 struct inode *inode, struct vfsmount *mnt, int allow_dups)
392086de 241@@ -336,6 +339,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
7f207e10
AM
242 atomic_set(&mark->refcnt, 1);
243 mark->free_mark = free_mark;
244 }
245+EXPORT_SYMBOL(fsnotify_init_mark);
246
247 static int fsnotify_mark_destroy(void *ignored)
248 {
249diff --git a/fs/open.c b/fs/open.c
523b37e3 250index 4b3e1ed..ce49f2b 100644
7f207e10
AM
251--- a/fs/open.c
252+++ b/fs/open.c
523b37e3 253@@ -62,6 +62,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
7f207e10
AM
254 mutex_unlock(&dentry->d_inode->i_mutex);
255 return ret;
256 }
257+EXPORT_SYMBOL(do_truncate);
258
1716fcea 259 long vfs_truncate(struct path *path, loff_t length)
7f207e10
AM
260 {
261diff --git a/fs/splice.c b/fs/splice.c
523b37e3 262index 719ca3e..6300dc8 100644
7f207e10
AM
263--- a/fs/splice.c
264+++ b/fs/splice.c
392086de
AM
265@@ -1106,6 +1106,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
266
267 return splice_write(pipe, out, ppos, len, flags);
7f207e10
AM
268 }
269+EXPORT_SYMBOL(do_splice_from);
270
271 /*
272 * Attempt to initiate a splice from a file to a pipe.
392086de 273@@ -1132,6 +1133,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
7f207e10
AM
274
275 return splice_read(in, ppos, pipe, len, flags);
276 }
277+EXPORT_SYMBOL(do_splice_to);
278
279 /**
280 * splice_direct_to_actor - splices data directly between two non-pipes
281diff --git a/security/commoncap.c b/security/commoncap.c
392086de 282index b9d613e..ba3b618 100644
7f207e10
AM
283--- a/security/commoncap.c
284+++ b/security/commoncap.c
1716fcea 285@@ -988,9 +988,11 @@ int cap_mmap_addr(unsigned long addr)
94337f0d 286 }
7f207e10
AM
287 return ret;
288 }
0c3ec466
AM
289+EXPORT_SYMBOL(cap_mmap_addr);
290
291 int cap_mmap_file(struct file *file, unsigned long reqprot,
292 unsigned long prot, unsigned long flags)
293 {
294 return 0;
295 }
296+EXPORT_SYMBOL(cap_mmap_file);
7f207e10 297diff --git a/security/device_cgroup.c b/security/device_cgroup.c
523b37e3 298index 7c2a0a7..a37c054 100644
7f207e10
AM
299--- a/security/device_cgroup.c
300+++ b/security/device_cgroup.c
f6c5ef8b
AM
301@@ -7,6 +7,7 @@
302 #include <linux/device_cgroup.h>
303 #include <linux/cgroup.h>
304 #include <linux/ctype.h>
305+#include <linux/export.h>
306 #include <linux/list.h>
307 #include <linux/uaccess.h>
308 #include <linux/seq_file.h>
523b37e3 309@@ -745,6 +746,7 @@ int __devcgroup_inode_permission(struct inode *inode, int mask)
537831f9
AM
310 return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
311 access);
7f207e10 312 }
2cbb1c4b 313+EXPORT_SYMBOL(__devcgroup_inode_permission);
7f207e10
AM
314
315 int devcgroup_inode_mknod(int mode, dev_t dev)
316 {
317diff --git a/security/security.c b/security/security.c
523b37e3 318index 15b6928..ae6eba6 100644
7f207e10
AM
319--- a/security/security.c
320+++ b/security/security.c
392086de 321@@ -407,6 +407,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry)
7f207e10
AM
322 return 0;
323 return security_ops->path_rmdir(dir, dentry);
324 }
325+EXPORT_SYMBOL(security_path_rmdir);
326
327 int security_path_unlink(struct path *dir, struct dentry *dentry)
328 {
392086de 329@@ -423,6 +424,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry,
7f207e10
AM
330 return 0;
331 return security_ops->path_symlink(dir, dentry, old_name);
332 }
333+EXPORT_SYMBOL(security_path_symlink);
334
335 int security_path_link(struct dentry *old_dentry, struct path *new_dir,
336 struct dentry *new_dentry)
392086de 337@@ -431,6 +433,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
7f207e10
AM
338 return 0;
339 return security_ops->path_link(old_dentry, new_dir, new_dentry);
340 }
341+EXPORT_SYMBOL(security_path_link);
342
343 int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
344 struct path *new_dir, struct dentry *new_dentry)
392086de 345@@ -449,6 +452,7 @@ int security_path_truncate(struct path *path)
7f207e10
AM
346 return 0;
347 return security_ops->path_truncate(path);
348 }
349+EXPORT_SYMBOL(security_path_truncate);
350
7eafdf33
AM
351 int security_path_chmod(struct path *path, umode_t mode)
352 {
392086de 353@@ -456,6 +460,7 @@ int security_path_chmod(struct path *path, umode_t mode)
7f207e10 354 return 0;
7eafdf33 355 return security_ops->path_chmod(path, mode);
7f207e10
AM
356 }
357+EXPORT_SYMBOL(security_path_chmod);
358
537831f9 359 int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
7f207e10 360 {
392086de 361@@ -463,6 +468,7 @@ int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
7f207e10
AM
362 return 0;
363 return security_ops->path_chown(path, uid, gid);
364 }
365+EXPORT_SYMBOL(security_path_chown);
366
367 int security_path_chroot(struct path *path)
368 {
392086de 369@@ -539,6 +545,7 @@ int security_inode_readlink(struct dentry *dentry)
7f207e10
AM
370 return 0;
371 return security_ops->inode_readlink(dentry);
372 }
373+EXPORT_SYMBOL(security_inode_readlink);
374
375 int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
376 {
392086de 377@@ -553,6 +560,7 @@ int security_inode_permission(struct inode *inode, int mask)
7f207e10 378 return 0;
1e00d052 379 return security_ops->inode_permission(inode, mask);
7f207e10
AM
380 }
381+EXPORT_SYMBOL(security_inode_permission);
382
1e00d052 383 int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
7f207e10 384 {
392086de 385@@ -675,6 +683,7 @@ int security_file_permission(struct file *file, int mask)
7f207e10
AM
386
387 return fsnotify_perm(file, mask);
388 }
389+EXPORT_SYMBOL(security_file_permission);
390
391 int security_file_alloc(struct file *file)
392 {
392086de 393@@ -735,6 +744,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
7f207e10
AM
394 return ret;
395 return ima_file_mmap(file, prot);
396 }
0c3ec466 397+EXPORT_SYMBOL(security_mmap_file);
7f207e10 398
0c3ec466
AM
399 int security_mmap_addr(unsigned long addr)
400 {
7f207e10
AM
401diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs
402--- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100
f6b6e03d 403+++ linux/Documentation/ABI/testing/debugfs-aufs 2014-01-27 23:16:52.651751827 +0100
86dc4139 404@@ -0,0 +1,50 @@
7f207e10
AM
405+What: /debug/aufs/si_<id>/
406+Date: March 2009
f6b6e03d 407+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
408+Description:
409+ Under /debug/aufs, a directory named si_<id> is created
410+ per aufs mount, where <id> is a unique id generated
411+ internally.
1facf9fc 412+
86dc4139
AM
413+What: /debug/aufs/si_<id>/plink
414+Date: Apr 2013
f6b6e03d 415+Contact: J. R. Okajima <hooanon05g@gmail.com>
86dc4139
AM
416+Description:
417+ It has three lines and shows the information about the
418+ pseudo-link. The first line is a single number
419+ representing a number of buckets. The second line is a
420+ number of pseudo-links per buckets (separated by a
421+ blank). The last line is a single number representing a
422+ total number of psedo-links.
423+ When the aufs mount option 'noplink' is specified, it
424+ will show "1\n0\n0\n".
425+
7f207e10
AM
426+What: /debug/aufs/si_<id>/xib
427+Date: March 2009
f6b6e03d 428+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
429+Description:
430+ It shows the consumed blocks by xib (External Inode Number
431+ Bitmap), its block size and file size.
432+ When the aufs mount option 'noxino' is specified, it
433+ will be empty. About XINO files, see the aufs manual.
434+
435+What: /debug/aufs/si_<id>/xino0, xino1 ... xinoN
436+Date: March 2009
f6b6e03d 437+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
438+Description:
439+ It shows the consumed blocks by xino (External Inode Number
440+ Translation Table), its link count, block size and file
441+ size.
442+ When the aufs mount option 'noxino' is specified, it
443+ will be empty. About XINO files, see the aufs manual.
444+
445+What: /debug/aufs/si_<id>/xigen
446+Date: March 2009
f6b6e03d 447+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
448+Description:
449+ It shows the consumed blocks by xigen (External Inode
450+ Generation Table), its block size and file size.
451+ If CONFIG_AUFS_EXPORT is disabled, this entry will not
452+ be created.
453+ When the aufs mount option 'noxino' is specified, it
454+ will be empty. About XINO files, see the aufs manual.
455diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs
456--- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100
f6b6e03d 457+++ linux/Documentation/ABI/testing/sysfs-aufs 2014-01-27 23:16:52.651751827 +0100
392086de 458@@ -0,0 +1,31 @@
7f207e10
AM
459+What: /sys/fs/aufs/si_<id>/
460+Date: March 2009
f6b6e03d 461+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
462+Description:
463+ Under /sys/fs/aufs, a directory named si_<id> is created
464+ per aufs mount, where <id> is a unique id generated
465+ internally.
466+
467+What: /sys/fs/aufs/si_<id>/br0, br1 ... brN
468+Date: March 2009
f6b6e03d 469+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
470+Description:
471+ It shows the abolute path of a member directory (which
472+ is called branch) in aufs, and its permission.
473+
392086de
AM
474+What: /sys/fs/aufs/si_<id>/brid0, brid1 ... bridN
475+Date: July 2013
f6b6e03d 476+Contact: J. R. Okajima <hooanon05g@gmail.com>
392086de
AM
477+Description:
478+ It shows the id of a member directory (which is called
479+ branch) in aufs.
480+
7f207e10
AM
481+What: /sys/fs/aufs/si_<id>/xi_path
482+Date: March 2009
f6b6e03d 483+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
484+Description:
485+ It shows the abolute path of XINO (External Inode Number
486+ Bitmap, Translation Table and Generation Table) file
487+ even if it is the default path.
488+ When the aufs mount option 'noxino' is specified, it
489+ will be empty. About XINO files, see the aufs manual.
53392da6
AM
490diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt
491--- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
492+++ linux/Documentation/filesystems/aufs/design/01intro.txt 2014-01-20 20:16:14.729463171 +0100
493@@ -0,0 +1,161 @@
53392da6 494+
523b37e3 495+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
496+#
497+# This program is free software; you can redistribute it and/or modify
498+# it under the terms of the GNU General Public License as published by
499+# the Free Software Foundation; either version 2 of the License, or
500+# (at your option) any later version.
501+#
502+# This program is distributed in the hope that it will be useful,
503+# but WITHOUT ANY WARRANTY; without even the implied warranty of
504+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
505+# GNU General Public License for more details.
506+#
507+# You should have received a copy of the GNU General Public License
523b37e3 508+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
509+
510+Introduction
511+----------------------------------------
512+
513+aufs [ei ju: ef es] | [a u f s]
514+1. abbrev. for "advanced multi-layered unification filesystem".
515+2. abbrev. for "another unionfs".
516+3. abbrev. for "auf das" in German which means "on the" in English.
517+ Ex. "Butter aufs Brot"(G) means "butter onto bread"(E).
518+ But "Filesystem aufs Filesystem" is hard to understand.
519+
520+AUFS is a filesystem with features:
521+- multi layered stackable unification filesystem, the member directory
522+ is called as a branch.
523+- branch permission and attribute, 'readonly', 'real-readonly',
524+ 'readwrite', 'whiteout-able', 'link-able whiteout' and their
525+ combination.
526+- internal "file copy-on-write".
527+- logical deletion, whiteout.
528+- dynamic branch manipulation, adding, deleting and changing permission.
529+- allow bypassing aufs, user's direct branch access.
530+- external inode number translation table and bitmap which maintains the
531+ persistent aufs inode number.
532+- seekable directory, including NFS readdir.
533+- file mapping, mmap and sharing pages.
534+- pseudo-link, hardlink over branches.
535+- loopback mounted filesystem as a branch.
536+- several policies to select one among multiple writable branches.
537+- revert a single systemcall when an error occurs in aufs.
538+- and more...
539+
540+
541+Multi Layered Stackable Unification Filesystem
542+----------------------------------------------------------------------
543+Most people already knows what it is.
544+It is a filesystem which unifies several directories and provides a
545+merged single directory. When users access a file, the access will be
546+passed/re-directed/converted (sorry, I am not sure which English word is
547+correct) to the real file on the member filesystem. The member
548+filesystem is called 'lower filesystem' or 'branch' and has a mode
549+'readonly' and 'readwrite.' And the deletion for a file on the lower
550+readonly branch is handled by creating 'whiteout' on the upper writable
551+branch.
552+
553+On LKML, there have been discussions about UnionMount (Jan Blunck,
554+Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took
555+different approaches to implement the merged-view.
556+The former tries putting it into VFS, and the latter implements as a
557+separate filesystem.
558+(If I misunderstand about these implementations, please let me know and
559+I shall correct it. Because it is a long time ago when I read their
560+source files last time).
561+
562+UnionMount's approach will be able to small, but may be hard to share
563+branches between several UnionMount since the whiteout in it is
564+implemented in the inode on branch filesystem and always
565+shared. According to Bharata's post, readdir does not seems to be
566+finished yet.
567+There are several missing features known in this implementations such as
568+- for users, the inode number may change silently. eg. copy-up.
569+- link(2) may break by copy-up.
570+- read(2) may get an obsoleted filedata (fstat(2) too).
571+- fcntl(F_SETLK) may be broken by copy-up.
572+- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
573+ open(O_RDWR).
574+
575+Unionfs has a longer history. When I started implementing a stacking filesystem
576+(Aug 2005), it already existed. It has virtual super_block, inode,
577+dentry and file objects and they have an array pointing lower same kind
578+objects. After contributing many patches for Unionfs, I re-started my
579+project AUFS (Jun 2006).
580+
581+In AUFS, the structure of filesystem resembles to Unionfs, but I
582+implemented my own ideas, approaches and enhancements and it became
583+totally different one.
584+
585+Comparing DM snapshot and fs based implementation
586+- the number of bytes to be copied between devices is much smaller.
587+- the type of filesystem must be one and only.
588+- the fs must be writable, no readonly fs, even for the lower original
589+ device. so the compression fs will not be usable. but if we use
590+ loopback mount, we may address this issue.
591+ for instance,
592+ mount /cdrom/squashfs.img /sq
593+ losetup /sq/ext2.img
594+ losetup /somewhere/cow
595+ dmsetup "snapshot /dev/loop0 /dev/loop1 ..."
596+- it will be difficult (or needs more operations) to extract the
597+ difference between the original device and COW.
598+- DM snapshot-merge may help a lot when users try merging. in the
599+ fs-layer union, users will use rsync(1).
600+
601+
602+Several characters/aspects of aufs
603+----------------------------------------------------------------------
604+
605+Aufs has several characters or aspects.
606+1. a filesystem, callee of VFS helper
607+2. sub-VFS, caller of VFS helper for branches
608+3. a virtual filesystem which maintains persistent inode number
609+4. reader/writer of files on branches such like an application
610+
611+1. Callee of VFS Helper
612+As an ordinary linux filesystem, aufs is a callee of VFS. For instance,
613+unlink(2) from an application reaches sys_unlink() kernel function and
614+then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it
615+calls filesystem specific unlink operation. Actually aufs implements the
616+unlink operation but it behaves like a redirector.
617+
618+2. Caller of VFS Helper for Branches
619+aufs_unlink() passes the unlink request to the branch filesystem as if
620+it were called from VFS. So the called unlink operation of the branch
621+filesystem acts as usual. As a caller of VFS helper, aufs should handle
622+every necessary pre/post operation for the branch filesystem.
623+- acquire the lock for the parent dir on a branch
624+- lookup in a branch
625+- revalidate dentry on a branch
626+- mnt_want_write() for a branch
627+- vfs_unlink() for a branch
628+- mnt_drop_write() for a branch
629+- release the lock on a branch
630+
631+3. Persistent Inode Number
632+One of the most important issue for a filesystem is to maintain inode
633+numbers. This is particularly important to support exporting a
634+filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
635+backend block device for its own. But some storage is necessary to
636+maintain inode number. It may be a large space and may not suit to keep
637+in memory. Aufs rents some space from its first writable branch
638+filesystem (by default) and creates file(s) on it. These files are
639+created by aufs internally and removed soon (currently) keeping opened.
640+Note: Because these files are removed, they are totally gone after
641+ unmounting aufs. It means the inode numbers are not persistent
642+ across unmount or reboot. I have a plan to make them really
643+ persistent which will be important for aufs on NFS server.
644+
645+4. Read/Write Files Internally (copy-on-write)
646+Because a branch can be readonly, when you write a file on it, aufs will
647+"copy-up" it to the upper writable branch internally. And then write the
648+originally requested thing to the file. Generally kernel doesn't
649+open/read/write file actively. In aufs, even a single write may cause a
650+internal "file copy". This behaviour is very similar to cp(1) command.
651+
652+Some people may think it is better to pass such work to user space
653+helper, instead of doing in kernel space. Actually I am still thinking
654+about it. But currently I have implemented it in kernel space.
655diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt linux/Documentation/filesystems/aufs/design/02struct.txt
656--- /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
657+++ linux/Documentation/filesystems/aufs/design/02struct.txt 2014-01-20 20:16:14.729463171 +0100
658@@ -0,0 +1,242 @@
53392da6 659+
523b37e3 660+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
661+#
662+# This program is free software; you can redistribute it and/or modify
663+# it under the terms of the GNU General Public License as published by
664+# the Free Software Foundation; either version 2 of the License, or
665+# (at your option) any later version.
666+#
667+# This program is distributed in the hope that it will be useful,
668+# but WITHOUT ANY WARRANTY; without even the implied warranty of
669+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
670+# GNU General Public License for more details.
671+#
672+# You should have received a copy of the GNU General Public License
523b37e3 673+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
674+
675+Basic Aufs Internal Structure
676+
677+Superblock/Inode/Dentry/File Objects
678+----------------------------------------------------------------------
679+As like an ordinary filesystem, aufs has its own
680+superblock/inode/dentry/file objects. All these objects have a
681+dynamically allocated array and store the same kind of pointers to the
682+lower filesystem, branch.
683+For example, when you build a union with one readwrite branch and one
684+readonly, mounted /au, /rw and /ro respectively.
685+- /au = /rw + /ro
686+- /ro/fileA exists but /rw/fileA
687+
688+Aufs lookup operation finds /ro/fileA and gets dentry for that. These
689+pointers are stored in a aufs dentry. The array in aufs dentry will be,
690+- [0] = NULL
691+- [1] = /ro/fileA
692+
693+This style of an array is essentially same to the aufs
694+superblock/inode/dentry/file objects.
695+
696+Because aufs supports manipulating branches, ie. add/delete/change
697+dynamically, these objects has its own generation. When branches are
698+changed, the generation in aufs superblock is incremented. And a
699+generation in other object are compared when it is accessed.
700+When a generation in other objects are obsoleted, aufs refreshes the
701+internal array.
702+
703+
704+Superblock
705+----------------------------------------------------------------------
706+Additionally aufs superblock has some data for policies to select one
707+among multiple writable branches, XIB files, pseudo-links and kobject.
708+See below in detail.
709+About the policies which supports copy-down a directory, see policy.txt
710+too.
711+
712+
713+Branch and XINO(External Inode Number Translation Table)
714+----------------------------------------------------------------------
715+Every branch has its own xino (external inode number translation table)
716+file. The xino file is created and unlinked by aufs internally. When two
717+members of a union exist on the same filesystem, they share the single
718+xino file.
719+The struct of a xino file is simple, just a sequence of aufs inode
720+numbers which is indexed by the lower inode number.
721+In the above sample, assume the inode number of /ro/fileA is i111 and
722+aufs assigns the inode number i999 for fileA. Then aufs writes 999 as
723+4(8) bytes at 111 * 4(8) bytes offset in the xino file.
724+
725+When the inode numbers are not contiguous, the xino file will be sparse
726+which has a hole in it and doesn't consume as much disk space as it
727+might appear. If your branch filesystem consumes disk space for such
728+holes, then you should specify 'xino=' option at mounting aufs.
729+
730+Also a writable branch has three kinds of "whiteout bases". All these
731+are existed when the branch is joined to aufs and the names are
732+whiteout-ed doubly, so that users will never see their names in aufs
733+hierarchy.
734+1. a regular file which will be linked to all whiteouts.
735+2. a directory to store a pseudo-link.
736+3. a directory to store an "orphan-ed" file temporary.
737+
738+1. Whiteout Base
739+ When you remove a file on a readonly branch, aufs handles it as a
740+ logical deletion and creates a whiteout on the upper writable branch
741+ as a hardlink of this file in order not to consume inode on the
742+ writable branch.
743+2. Pseudo-link Dir
744+ See below, Pseudo-link.
745+3. Step-Parent Dir
746+ When "fileC" exists on the lower readonly branch only and it is
747+ opened and removed with its parent dir, and then user writes
748+ something into it, then aufs copies-up fileC to this
749+ directory. Because there is no other dir to store fileC. After
750+ creating a file under this dir, the file is unlinked.
751+
752+Because aufs supports manipulating branches, ie. add/delete/change
753+dynamically, a branch has its own id. When the branch order changes, aufs
754+finds the new index by searching the branch id.
755+
756+
757+Pseudo-link
758+----------------------------------------------------------------------
759+Assume "fileA" exists on the lower readonly branch only and it is
760+hardlinked to "fileB" on the branch. When you write something to fileA,
761+aufs copies-up it to the upper writable branch. Additionally aufs
762+creates a hardlink under the Pseudo-link Directory of the writable
763+branch. The inode of a pseudo-link is kept in aufs super_block as a
764+simple list. If fileB is read after unlinking fileA, aufs returns
765+filedata from the pseudo-link instead of the lower readonly
766+branch. Because the pseudo-link is based upon the inode, to keep the
767+inode number by xino (see above) is important.
768+
769+All the hardlinks under the Pseudo-link Directory of the writable branch
770+should be restored in a proper location later. Aufs provides a utility
771+to do this. The userspace helpers executed at remounting and unmounting
772+aufs by default.
773+During this utility is running, it puts aufs into the pseudo-link
774+maintenance mode. In this mode, only the process which began the
775+maintenance mode (and its child processes) is allowed to operate in
776+aufs. Some other processes which are not related to the pseudo-link will
777+be allowed to run too, but the rest have to return an error or wait
778+until the maintenance mode ends. If a process already acquires an inode
779+mutex (in VFS), it has to return an error.
780+
781+
782+XIB(external inode number bitmap)
783+----------------------------------------------------------------------
784+Addition to the xino file per a branch, aufs has an external inode number
785+bitmap in a superblock object. It is also a file such like a xino file.
786+It is a simple bitmap to mark whether the aufs inode number is in-use or
787+not.
788+To reduce the file I/O, aufs prepares a single memory page to cache xib.
789+
790+Aufs implements a feature to truncate/refresh both of xino and xib to
791+reduce the number of consumed disk blocks for these files.
792+
793+
794+Virtual or Vertical Dir, and Readdir in Userspace
795+----------------------------------------------------------------------
796+In order to support multiple layers (branches), aufs readdir operation
797+constructs a virtual dir block on memory. For readdir, aufs calls
798+vfs_readdir() internally for each dir on branches, merges their entries
799+with eliminating the whiteout-ed ones, and sets it to file (dir)
800+object. So the file object has its entry list until it is closed. The
801+entry list will be updated when the file position is zero and becomes
802+old. This decision is made in aufs automatically.
803+
804+The dynamically allocated memory block for the name of entries has a
805+unit of 512 bytes (by default) and stores the names contiguously (no
806+padding). Another block for each entry is handled by kmem_cache too.
807+During building dir blocks, aufs creates hash list and judging whether
808+the entry is whiteouted by its upper branch or already listed.
809+The merged result is cached in the corresponding inode object and
810+maintained by a customizable life-time option.
811+
812+Some people may call it can be a security hole or invite DoS attack
813+since the opened and once readdir-ed dir (file object) holds its entry
814+list and becomes a pressure for system memory. But I'd say it is similar
815+to files under /proc or /sys. The virtual files in them also holds a
816+memory page (generally) while they are opened. When an idea to reduce
817+memory for them is introduced, it will be applied to aufs too.
818+For those who really hate this situation, I've developed readdir(3)
819+library which operates this merging in userspace. You just need to set
820+LD_PRELOAD environment variable, and aufs will not consume no memory in
821+kernel space for readdir(3).
822+
823+
824+Workqueue
825+----------------------------------------------------------------------
826+Aufs sometimes requires privilege access to a branch. For instance,
827+in copy-up/down operation. When a user process is going to make changes
828+to a file which exists in the lower readonly branch only, and the mode
829+of one of ancestor directories may not be writable by a user
830+process. Here aufs copy-up the file with its ancestors and they may
831+require privilege to set its owner/group/mode/etc.
832+This is a typical case of a application character of aufs (see
833+Introduction).
834+
835+Aufs uses workqueue synchronously for this case. It creates its own
836+workqueue. The workqueue is a kernel thread and has privilege. Aufs
837+passes the request to call mkdir or write (for example), and wait for
838+its completion. This approach solves a problem of a signal handler
839+simply.
840+If aufs didn't adopt the workqueue and changed the privilege of the
841+process, and if the mkdir/write call arises SIGXFSZ or other signal,
842+then the user process might gain a privilege or the generated core file
843+was owned by a superuser.
844+
845+Also aufs uses the system global workqueue ("events" kernel thread) too
846+for asynchronous tasks, such like handling inotify/fsnotify, re-creating a
847+whiteout base and etc. This is unrelated to a privilege.
848+Most of aufs operation tries acquiring a rw_semaphore for aufs
849+superblock at the beginning, at the same time waits for the completion
850+of all queued asynchronous tasks.
851+
852+
853+Whiteout
854+----------------------------------------------------------------------
855+The whiteout in aufs is very similar to Unionfs's. That is represented
856+by its filename. UnionMount takes an approach of a file mode, but I am
857+afraid several utilities (find(1) or something) will have to support it.
858+
859+Basically the whiteout represents "logical deletion" which stops aufs to
860+lookup further, but also it represents "dir is opaque" which also stop
861+lookup.
862+
863+In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively.
864+In order to make several functions in a single systemcall to be
865+revertible, aufs adopts an approach to rename a directory to a temporary
866+unique whiteouted name.
867+For example, in rename(2) dir where the target dir already existed, aufs
868+renames the target dir to a temporary unique whiteouted name before the
869+actual rename on a branch and then handles other actions (make it opaque,
870+update the attributes, etc). If an error happens in these actions, aufs
871+simply renames the whiteouted name back and returns an error. If all are
872+succeeded, aufs registers a function to remove the whiteouted unique
873+temporary name completely and asynchronously to the system global
874+workqueue.
875+
876+
877+Copy-up
878+----------------------------------------------------------------------
879+It is a well-known feature or concept.
880+When user modifies a file on a readonly branch, aufs operate "copy-up"
881+internally and makes change to the new file on the upper writable branch.
882+When the trigger systemcall does not update the timestamps of the parent
883+dir, aufs reverts it after copy-up.
c2b27bf2
AM
884+
885+
886+Move-down (aufs3.9 and later)
887+----------------------------------------------------------------------
888+"Copy-up" is one of the essential feature in aufs. It copies a file from
889+the lower readonly branch to the upper writable branch when a user
890+changes something about the file.
891+"Move-down" is an opposite action of copy-up. Basically this action is
892+ran manually instead of automatically and internally.
893+
894+Sometimes users want to move-down a file from the upper writable branch
895+to the lower readonly or writable branch. For instance,
896+- the free space of the upper writable branch is going to run out.
897+- create a new intermediate branch between the upper and lower branch.
898+- etc.
899+
900+For this purpose, use "aumvdown" command in aufs-util.git.
53392da6
AM
901diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt
902--- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
903+++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2014-01-20 20:16:14.729463171 +0100
904@@ -0,0 +1,105 @@
53392da6 905+
523b37e3 906+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
907+#
908+# This program is free software; you can redistribute it and/or modify
909+# it under the terms of the GNU General Public License as published by
910+# the Free Software Foundation; either version 2 of the License, or
911+# (at your option) any later version.
912+#
913+# This program is distributed in the hope that it will be useful,
914+# but WITHOUT ANY WARRANTY; without even the implied warranty of
915+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
916+# GNU General Public License for more details.
917+#
918+# You should have received a copy of the GNU General Public License
523b37e3 919+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
920+
921+Lookup in a Branch
922+----------------------------------------------------------------------
923+Since aufs has a character of sub-VFS (see Introduction), it operates
924+lookup for branches as VFS does. It may be a heavy work. Generally
925+speaking struct nameidata is a bigger structure and includes many
926+information. But almost all lookup operation in aufs is the simplest
927+case, ie. lookup only an entry directly connected to its parent. Digging
928+down the directory hierarchy is unnecessary.
929+
930+VFS has a function lookup_one_len() for that use, but it is not usable
931+for a branch filesystem which requires struct nameidata. So aufs
932+implements a simple lookup wrapper function. When a branch filesystem
933+allows NULL as nameidata, it calls lookup_one_len(). Otherwise it builds
934+a simplest nameidata and calls lookup_hash().
935+Here aufs applies "a principle in NFSD", ie. if the filesystem supports
936+NFS-export, then it has to support NULL as a nameidata parameter for
937+->create(), ->lookup() and ->d_revalidate(). So the lookup wrapper in
938+aufs tests if ->s_export_op in the branch is NULL or not.
939+
940+When a branch is a remote filesystem, aufs basically trusts its
941+->d_revalidate(), also aufs forces the hardest revalidate tests for
942+them.
943+For d_revalidate, aufs implements three levels of revalidate tests. See
944+"Revalidate Dentry and UDBA" in detail.
945+
946+
947+Loopback Mount
948+----------------------------------------------------------------------
949+Basically aufs supports any type of filesystem and block device for a
950+branch (actually there are some exceptions). But it is prohibited to add
951+a loopback mounted one whose backend file exists in a filesystem which is
952+already added to aufs. The reason is to protect aufs from a recursive
953+lookup. If it was allowed, the aufs lookup operation might re-enter a
954+lookup for the loopback mounted branch in the same context, and will
955+cause a deadlock.
956+
957+
958+Revalidate Dentry and UDBA (User's Direct Branch Access)
959+----------------------------------------------------------------------
960+Generally VFS helpers re-validate a dentry as a part of lookup.
961+0. digging down the directory hierarchy.
962+1. lock the parent dir by its i_mutex.
963+2. lookup the final (child) entry.
964+3. revalidate it.
965+4. call the actual operation (create, unlink, etc.)
966+5. unlock the parent dir
967+
968+If the filesystem implements its ->d_revalidate() (step 3), then it is
969+called. Actually aufs implements it and checks the dentry on a branch is
970+still valid.
971+But it is not enough. Because aufs has to release the lock for the
972+parent dir on a branch at the end of ->lookup() (step 2) and
973+->d_revalidate() (step 3) while the i_mutex of the aufs dir is still
974+held by VFS.
975+If the file on a branch is changed directly, eg. bypassing aufs, after
976+aufs released the lock, then the subsequent operation may cause
977+something unpleasant result.
978+
979+This situation is a result of VFS architecture, ->lookup() and
980+->d_revalidate() is separated. But I never say it is wrong. It is a good
981+design from VFS's point of view. It is just not suitable for sub-VFS
982+character in aufs.
983+
984+Aufs supports such case by three level of revalidation which is
985+selectable by user.
986+1. Simple Revalidate
987+ Addition to the native flow in VFS's, confirm the child-parent
988+ relationship on the branch just after locking the parent dir on the
989+ branch in the "actual operation" (step 4). When this validation
990+ fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still
991+ checks the validation of the dentry on branches.
992+2. Monitor Changes Internally by Inotify/Fsnotify
993+ Addition to above, in the "actual operation" (step 4) aufs re-lookup
994+ the dentry on the branch, and returns EBUSY if it finds different
995+ dentry.
996+ Additionally, aufs sets the inotify/fsnotify watch for every dir on branches
997+ during it is in cache. When the event is notified, aufs registers a
998+ function to kernel 'events' thread by schedule_work(). And the
999+ function sets some special status to the cached aufs dentry and inode
1000+ private data. If they are not cached, then aufs has nothing to
1001+ do. When the same file is accessed through aufs (step 0-3) later,
1002+ aufs will detect the status and refresh all necessary data.
1003+ In this mode, aufs has to ignore the event which is fired by aufs
1004+ itself.
1005+3. No Extra Validation
1006+ This is the simplest test and doesn't add any additional revalidation
1007+ test, and skip therevalidatin in step 4. It is useful and improves
1008+ aufs performance when system surely hide the aufs branches from user,
1009+ by over-mounting something (or another method).
1010diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt linux/Documentation/filesystems/aufs/design/04branch.txt
1011--- /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
1012+++ linux/Documentation/filesystems/aufs/design/04branch.txt 2014-01-20 20:16:14.729463171 +0100
1013@@ -0,0 +1,75 @@
53392da6 1014+
523b37e3 1015+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1016+#
1017+# This program is free software; you can redistribute it and/or modify
1018+# it under the terms of the GNU General Public License as published by
1019+# the Free Software Foundation; either version 2 of the License, or
1020+# (at your option) any later version.
1021+#
1022+# This program is distributed in the hope that it will be useful,
1023+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1024+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1025+# GNU General Public License for more details.
1026+#
1027+# You should have received a copy of the GNU General Public License
523b37e3 1028+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1029+
1030+Branch Manipulation
1031+
1032+Since aufs supports dynamic branch manipulation, ie. add/remove a branch
1033+and changing its permission/attribute, there are a lot of works to do.
1034+
1035+
1036+Add a Branch
1037+----------------------------------------------------------------------
1038+o Confirm the adding dir exists outside of aufs, including loopback
1039+ mount.
1040+- and other various attributes...
1041+o Initialize the xino file and whiteout bases if necessary.
1042+ See struct.txt.
1043+
1044+o Check the owner/group/mode of the directory
1045+ When the owner/group/mode of the adding directory differs from the
1046+ existing branch, aufs issues a warning because it may impose a
1047+ security risk.
1048+ For example, when a upper writable branch has a world writable empty
1049+ top directory, a malicious user can create any files on the writable
1050+ branch directly, like copy-up and modify manually. If something like
1051+ /etc/{passwd,shadow} exists on the lower readonly branch but the upper
1052+ writable branch, and the writable branch is world-writable, then a
1053+ malicious guy may create /etc/passwd on the writable branch directly
1054+ and the infected file will be valid in aufs.
1055+ I am afraid it can be a security issue, but nothing to do except
1056+ producing a warning.
1057+
1058+
1059+Delete a Branch
1060+----------------------------------------------------------------------
1061+o Confirm the deleting branch is not busy
1062+ To be general, there is one merit to adopt "remount" interface to
1063+ manipulate branches. It is to discard caches. At deleting a branch,
1064+ aufs checks the still cached (and connected) dentries and inodes. If
1065+ there are any, then they are all in-use. An inode without its
1066+ corresponding dentry can be alive alone (for example, inotify/fsnotify case).
1067+
1068+ For the cached one, aufs checks whether the same named entry exists on
1069+ other branches.
1070+ If the cached one is a directory, because aufs provides a merged view
1071+ to users, as long as one dir is left on any branch aufs can show the
1072+ dir to users. In this case, the branch can be removed from aufs.
1073+ Otherwise aufs rejects deleting the branch.
1074+
1075+ If any file on the deleting branch is opened by aufs, then aufs
1076+ rejects deleting.
1077+
1078+
1079+Modify the Permission of a Branch
1080+----------------------------------------------------------------------
1081+o Re-initialize or remove the xino file and whiteout bases if necessary.
1082+ See struct.txt.
1083+
1084+o rw --> ro: Confirm the modifying branch is not busy
1085+ Aufs rejects the request if any of these conditions are true.
1086+ - a file on the branch is mmap-ed.
1087+ - a regular file on the branch is opened for write and there is no
1088+ same named entry on the upper branch.
1089diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt linux/Documentation/filesystems/aufs/design/05wbr_policy.txt
1090--- /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
1091+++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2014-01-20 20:16:14.729463171 +0100
1092@@ -0,0 +1,64 @@
53392da6 1093+
523b37e3 1094+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1095+#
1096+# This program is free software; you can redistribute it and/or modify
1097+# it under the terms of the GNU General Public License as published by
1098+# the Free Software Foundation; either version 2 of the License, or
1099+# (at your option) any later version.
1100+#
1101+# This program is distributed in the hope that it will be useful,
1102+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1103+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1104+# GNU General Public License for more details.
1105+#
1106+# You should have received a copy of the GNU General Public License
523b37e3 1107+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1108+
1109+Policies to Select One among Multiple Writable Branches
1110+----------------------------------------------------------------------
1111+When the number of writable branch is more than one, aufs has to decide
1112+the target branch for file creation or copy-up. By default, the highest
1113+writable branch which has the parent (or ancestor) dir of the target
1114+file is chosen (top-down-parent policy).
1115+By user's request, aufs implements some other policies to select the
1116+writable branch, for file creation two policies, round-robin and
1117+most-free-space policies. For copy-up three policies, top-down-parent,
1118+bottom-up-parent and bottom-up policies.
1119+
1120+As expected, the round-robin policy selects the branch in circular. When
1121+you have two writable branches and creates 10 new files, 5 files will be
1122+created for each branch. mkdir(2) systemcall is an exception. When you
1123+create 10 new directories, all will be created on the same branch.
1124+And the most-free-space policy selects the one which has most free
1125+space among the writable branches. The amount of free space will be
1126+checked by aufs internally, and users can specify its time interval.
1127+
1128+The policies for copy-up is more simple,
1129+top-down-parent is equivalent to the same named on in create policy,
1130+bottom-up-parent selects the writable branch where the parent dir
1131+exists and the nearest upper one from the copyup-source,
1132+bottom-up selects the nearest upper writable branch from the
1133+copyup-source, regardless the existence of the parent dir.
1134+
1135+There are some rules or exceptions to apply these policies.
1136+- If there is a readonly branch above the policy-selected branch and
1137+ the parent dir is marked as opaque (a variation of whiteout), or the
1138+ target (creating) file is whiteout-ed on the upper readonly branch,
1139+ then the result of the policy is ignored and the target file will be
1140+ created on the nearest upper writable branch than the readonly branch.
1141+- If there is a writable branch above the policy-selected branch and
1142+ the parent dir is marked as opaque or the target file is whiteouted
1143+ on the branch, then the result of the policy is ignored and the target
1144+ file will be created on the highest one among the upper writable
1145+ branches who has diropq or whiteout. In case of whiteout, aufs removes
1146+ it as usual.
1147+- link(2) and rename(2) systemcalls are exceptions in every policy.
1148+ They try selecting the branch where the source exists as possible
1149+ since copyup a large file will take long time. If it can't be,
1150+ ie. the branch where the source exists is readonly, then they will
1151+ follow the copyup policy.
1152+- There is an exception for rename(2) when the target exists.
1153+ If the rename target exists, aufs compares the index of the branches
1154+ where the source and the target exists and selects the higher
1155+ one. If the selected branch is readonly, then aufs follows the
1156+ copyup policy.
1157diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt
1158--- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
1159+++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2014-01-20 20:16:14.729463171 +0100
1160@@ -0,0 +1,46 @@
53392da6 1161+
523b37e3 1162+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1163+#
1164+# This program is free software; you can redistribute it and/or modify
1165+# it under the terms of the GNU General Public License as published by
1166+# the Free Software Foundation; either version 2 of the License, or
1167+# (at your option) any later version.
1168+#
1169+# This program is distributed in the hope that it will be useful,
1170+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1171+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1172+# GNU General Public License for more details.
1173+#
1174+# You should have received a copy of the GNU General Public License
523b37e3 1175+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1176+
1177+mmap(2) -- File Memory Mapping
1178+----------------------------------------------------------------------
1179+In aufs, the file-mapped pages are handled by a branch fs directly, no
1180+interaction with aufs. It means aufs_mmap() calls the branch fs's
1181+->mmap().
1182+This approach is simple and good, but there is one problem.
1183+Under /proc, several entries show the mmap-ped files by its path (with
1184+device and inode number), and the printed path will be the path on the
1185+branch fs's instead of virtual aufs's.
1186+This is not a problem in most cases, but some utilities lsof(1) (and its
1187+user) may expect the path on aufs.
1188+
1189+To address this issue, aufs adds a new member called vm_prfile in struct
1190+vm_area_struct (and struct vm_region). The original vm_file points to
1191+the file on the branch fs in order to handle everything correctly as
1192+usual. The new vm_prfile points to a virtual file in aufs, and the
1193+show-functions in procfs refers to vm_prfile if it is set.
1194+Also we need to maintain several other places where touching vm_file
1195+such like
1196+- fork()/clone() copies vma and the reference count of vm_file is
1197+ incremented.
1198+- merging vma maintains the ref count too.
1199+
1200+This is not a good approach. It just faking the printed path. But it
1201+leaves all behaviour around f_mapping unchanged. This is surely an
1202+advantage.
1203+Actually aufs had adopted another complicated approach which calls
1204+generic_file_mmap() and handles struct vm_operations_struct. In this
1205+approach, aufs met a hard problem and I could not solve it without
1206+switching the approach.
1207diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt
1208--- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
1209+++ linux/Documentation/filesystems/aufs/design/07export.txt 2014-01-20 20:16:14.729463171 +0100
1210@@ -0,0 +1,58 @@
53392da6 1211+
523b37e3 1212+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1213+#
1214+# This program is free software; you can redistribute it and/or modify
1215+# it under the terms of the GNU General Public License as published by
1216+# the Free Software Foundation; either version 2 of the License, or
1217+# (at your option) any later version.
1218+#
1219+# This program is distributed in the hope that it will be useful,
1220+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1221+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1222+# GNU General Public License for more details.
1223+#
1224+# You should have received a copy of the GNU General Public License
523b37e3 1225+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1226+
1227+Export Aufs via NFS
1228+----------------------------------------------------------------------
1229+Here is an approach.
1230+- like xino/xib, add a new file 'xigen' which stores aufs inode
1231+ generation.
1232+- iget_locked(): initialize aufs inode generation for a new inode, and
1233+ store it in xigen file.
1234+- destroy_inode(): increment aufs inode generation and store it in xigen
1235+ file. it is necessary even if it is not unlinked, because any data of
1236+ inode may be changed by UDBA.
1237+- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise
1238+ build file handle by
1239+ + branch id (4 bytes)
1240+ + superblock generation (4 bytes)
1241+ + inode number (4 or 8 bytes)
1242+ + parent dir inode number (4 or 8 bytes)
1243+ + inode generation (4 bytes))
1244+ + return value of exportfs_encode_fh() for the parent on a branch (4
1245+ bytes)
1246+ + file handle for a branch (by exportfs_encode_fh())
1247+- fh_to_dentry():
1248+ + find the index of a branch from its id in handle, and check it is
1249+ still exist in aufs.
1250+ + 1st level: get the inode number from handle and search it in cache.
1251+ + 2nd level: if not found, get the parent inode number from handle and
1252+ search it in cache. and then open the parent dir, find the matching
1253+ inode number by vfs_readdir() and get its name, and call
1254+ lookup_one_len() for the target dentry.
1255+ + 3rd level: if the parent dir is not cached, call
1256+ exportfs_decode_fh() for a branch and get the parent on a branch,
1257+ build a pathname of it, convert it a pathname in aufs, call
1258+ path_lookup(). now aufs gets a parent dir dentry, then handle it as
1259+ the 2nd level.
1260+ + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount
1261+ for every branch, but not itself. to get this, (currently) aufs
1262+ searches in current->nsproxy->mnt_ns list. it may not be a good
1263+ idea, but I didn't get other approach.
1264+ + test the generation of the gotten inode.
1265+- every inode operation: they may get EBUSY due to UDBA. in this case,
1266+ convert it into ESTALE for NFSD.
1267+- readdir(): call lockdep_on/off() because filldir in NFSD calls
1268+ lookup_one_len(), vfs_getattr(), encode_fh() and others.
1269diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linux/Documentation/filesystems/aufs/design/08shwh.txt
1270--- /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
1271+++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2014-01-20 20:16:14.729463171 +0100
1272@@ -0,0 +1,52 @@
53392da6 1273+
523b37e3 1274+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1275+#
1276+# This program is free software; you can redistribute it and/or modify
1277+# it under the terms of the GNU General Public License as published by
1278+# the Free Software Foundation; either version 2 of the License, or
1279+# (at your option) any later version.
1280+#
1281+# This program is distributed in the hope that it will be useful,
1282+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1283+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1284+# GNU General Public License for more details.
1285+#
1286+# You should have received a copy of the GNU General Public License
523b37e3 1287+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1288+
1289+Show Whiteout Mode (shwh)
1290+----------------------------------------------------------------------
1291+Generally aufs hides the name of whiteouts. But in some cases, to show
1292+them is very useful for users. For instance, creating a new middle layer
1293+(branch) by merging existing layers.
1294+
1295+(borrowing aufs1 HOW-TO from a user, Michael Towers)
1296+When you have three branches,
1297+- Bottom: 'system', squashfs (underlying base system), read-only
1298+- Middle: 'mods', squashfs, read-only
1299+- Top: 'overlay', ram (tmpfs), read-write
1300+
1301+The top layer is loaded at boot time and saved at shutdown, to preserve
1302+the changes made to the system during the session.
1303+When larger changes have been made, or smaller changes have accumulated,
1304+the size of the saved top layer data grows. At this point, it would be
1305+nice to be able to merge the two overlay branches ('mods' and 'overlay')
1306+and rewrite the 'mods' squashfs, clearing the top layer and thus
1307+restoring save and load speed.
1308+
1309+This merging is simplified by the use of another aufs mount, of just the
1310+two overlay branches using the 'shwh' option.
1311+# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \
1312+ aufs /livesys/merge_union
1313+
1314+A merged view of these two branches is then available at
1315+/livesys/merge_union, and the new feature is that the whiteouts are
1316+visible!
1317+Note that in 'shwh' mode the aufs mount must be 'ro', which will disable
1318+writing to all branches. Also the default mode for all branches is 'ro'.
1319+It is now possible to save the combined contents of the two overlay
1320+branches to a new squashfs, e.g.:
1321+# mksquashfs /livesys/merge_union /path/to/newmods.squash
1322+
1323+This new squashfs archive can be stored on the boot device and the
1324+initramfs will use it to replace the old one at the next boot.
1325diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt linux/Documentation/filesystems/aufs/design/10dynop.txt
1326--- /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
1327+++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2014-01-20 20:16:14.729463171 +0100
1328@@ -0,0 +1,46 @@
53392da6 1329+
523b37e3 1330+# Copyright (C) 2010-2014 Junjiro R. Okajima
53392da6
AM
1331+#
1332+# This program is free software; you can redistribute it and/or modify
1333+# it under the terms of the GNU General Public License as published by
1334+# the Free Software Foundation; either version 2 of the License, or
1335+# (at your option) any later version.
1336+#
1337+# This program is distributed in the hope that it will be useful,
1338+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1339+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1340+# GNU General Public License for more details.
1341+#
1342+# You should have received a copy of the GNU General Public License
523b37e3 1343+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1344+
1345+Dynamically customizable FS operations
1346+----------------------------------------------------------------------
1347+Generally FS operations (struct inode_operations, struct
1348+address_space_operations, struct file_operations, etc.) are defined as
1349+"static const", but it never means that FS have only one set of
1350+operation. Some FS have multiple sets of them. For instance, ext2 has
1351+three sets, one for XIP, for NOBH, and for normal.
1352+Since aufs overrides and redirects these operations, sometimes aufs has
1353+to change its behaviour according to the branch FS type. More imporantly
1354+VFS acts differently if a function (member in the struct) is set or
1355+not. It means aufs should have several sets of operations and select one
1356+among them according to the branch FS definition.
1357+
1358+In order to solve this problem and not to affect the behavour of VFS,
1359+aufs defines these operations dynamically. For instance, aufs defines
1360+aio_read function for struct file_operations, but it may not be set to
1361+the file_operations. When the branch FS doesn't have it, aufs doesn't
1362+set it to its file_operations while the function definition itself is
1363+still alive. So the behaviour of io_submit(2) will not change, and it
1364+will return an error when aio_read is not defined.
1365+
1366+The lifetime of these dynamically generated operation object is
1367+maintained by aufs branch object. When the branch is removed from aufs,
1368+the reference counter of the object is decremented. When it reaches
1369+zero, the dynamically generated operation object will be freed.
1370+
1371+This approach is designed to support AIO (io_submit), Direcit I/O and
1372+XIP mainly.
1373+Currently this approach is applied to file_operations and
1374+vm_operations_struct for regular files only.
1375diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt linux/Documentation/filesystems/aufs/design/99plan.txt
1376--- /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
1377+++ linux/Documentation/filesystems/aufs/design/99plan.txt 2014-01-20 20:16:14.732796615 +0100
1378@@ -0,0 +1,95 @@
53392da6 1379+
523b37e3 1380+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1381+#
1382+# This program is free software; you can redistribute it and/or modify
1383+# it under the terms of the GNU General Public License as published by
1384+# the Free Software Foundation; either version 2 of the License, or
1385+# (at your option) any later version.
1386+#
1387+# This program is distributed in the hope that it will be useful,
1388+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1389+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1390+# GNU General Public License for more details.
1391+#
1392+# You should have received a copy of the GNU General Public License
523b37e3 1393+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1394+
1395+Plan
1396+
1397+Restoring some features which was implemented in aufs1.
1398+They were dropped in aufs2 in order to make source files simpler and
1399+easier to be reviewed.
1400+
1401+
1402+Test Only the Highest One for the Directory Permission (dirperm1 option)
1403+----------------------------------------------------------------------
1404+Let's try case study.
1405+- aufs has two branches, upper readwrite and lower readonly.
1406+ /au = /rw + /ro
1407+- "dirA" exists under /ro, but /rw. and its mode is 0700.
1408+- user invoked "chmod a+rx /au/dirA"
1409+- then "dirA" becomes world readable?
1410+
1411+In this case, /ro/dirA is still 0700 since it exists in readonly branch,
1412+or it may be a natively readonly filesystem. If aufs respects the lower
1413+branch, it should not respond readdir request from other users. But user
1414+allowed it by chmod. Should really aufs rejects showing the entries
1415+under /ro/dirA?
1416+
1417+To be honest, I don't have a best solution for this case. So I
1418+implemented 'dirperm1' and 'nodirperm1' option in aufs1, and leave it to
1419+users.
1420+When dirperm1 is specified, aufs checks only the highest one for the
1421+directory permission, and shows the entries. Otherwise, as usual, checks
1422+every dir existing on all branches and rejects the request.
1423+
1424+As a side effect, dirperm1 option improves the performance of aufs
1425+because the number of permission check is reduced.
1426+
1427+
1428+Being Another Aufs's Readonly Branch (robr)
1429+----------------------------------------------------------------------
1430+Aufs1 allows aufs to be another aufs's readonly branch.
1431+This feature was developed by a user's request. But it may not be used
1432+currecnly.
1433+
1434+
1435+Copy-up on Open (coo=)
1436+----------------------------------------------------------------------
1437+By default the internal copy-up is executed when it is really necessary.
1438+It is not done when a file is opened for writing, but when write(2) is
1439+done. Users who have many (over 100) branches want to know and analyse
1440+when and what file is copied-up. To insert a new upper branch which
1441+contains such files only may improve the performance of aufs.
1442+
1443+Aufs1 implemented "coo=none | leaf | all" option.
1444+
1445+
1446+Refresh the Opened File (refrof)
1447+----------------------------------------------------------------------
1448+This option is implemented in aufs1 but incomplete.
1449+
1450+When user reads from a file, he expects to get its latest filedata
1451+generally. If the file is removed and a new same named file is created,
1452+the content he gets is unchanged, ie. the unlinked filedata.
1453+
1454+Let's try case study again.
1455+- aufs has two branches.
1456+ /au = /rw + /ro
1457+- "fileA" exists under /ro, but /rw.
1458+- user opened "/au/fileA".
1459+- he or someone else inserts a branch (/new) between /rw and /ro.
1460+ /au = /rw + /new + /ro
1461+- the new branch has "fileA".
1462+- user reads from the opened "fileA"
1463+- which filedata should aufs return, from /ro or /new?
1464+
1465+Some people says it has to be "from /ro" and it is a semantics of Unix.
1466+The others say it should be "from /new" because the file is not removed
1467+and it is equivalent to the case of someone else modifies the file.
1468+
1469+Here again I don't have a best and final answer. I got an idea to
1470+implement 'refrof' and 'norefrof' option. When 'refrof' (REFResh the
1471+Opened File) is specified (by default), aufs returns the filedata from
1472+/new.
1473+Otherwise from /new.
1474diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README
1475--- /usr/share/empty/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
1476+++ linux/Documentation/filesystems/aufs/README 2014-01-20 20:16:14.729463171 +0100
1477@@ -0,0 +1,344 @@
53392da6
AM
1478+
1479+Aufs3 -- advanced multi layered unification filesystem version 3.x
1480+http://aufs.sf.net
1481+Junjiro R. Okajima
1482+
1483+
1484+0. Introduction
1485+----------------------------------------
1486+In the early days, aufs was entirely re-designed and re-implemented
1487+Unionfs Version 1.x series. After many original ideas, approaches,
1488+improvements and implementations, it becomes totally different from
1489+Unionfs while keeping the basic features.
1490+Recently, Unionfs Version 2.x series begin taking some of the same
1491+approaches to aufs1's.
1492+Unionfs is being developed by Professor Erez Zadok at Stony Brook
1493+University and his team.
1494+
1495+Aufs3 supports linux-3.0 and later.
1496+If you want older kernel version support, try aufs2-2.6.git or
1497+aufs2-standalone.git repository, aufs1 from CVS on SourceForge.
1498+
1499+Note: it becomes clear that "Aufs was rejected. Let's give it up."
1500+According to Christoph Hellwig, linux rejects all union-type filesystems
1501+but UnionMount.
1502+<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
1503+
1504+
1505+1. Features
1506+----------------------------------------
1507+- unite several directories into a single virtual filesystem. The member
1508+ directory is called as a branch.
1509+- you can specify the permission flags to the branch, which are 'readonly',
1510+ 'readwrite' and 'whiteout-able.'
1511+- by upper writable branch, internal copyup and whiteout, files/dirs on
1512+ readonly branch are modifiable logically.
1513+- dynamic branch manipulation, add, del.
1514+- etc...
1515+
1516+Also there are many enhancements in aufs1, such as:
1517+- readdir(3) in userspace.
1518+- keep inode number by external inode number table
1519+- keep the timestamps of file/dir in internal copyup operation
1520+- seekable directory, supporting NFS readdir.
1521+- whiteout is hardlinked in order to reduce the consumption of inodes
1522+ on branch
1523+- do not copyup, nor create a whiteout when it is unnecessary
1524+- revert a single systemcall when an error occurs in aufs
1525+- remount interface instead of ioctl
1526+- maintain /etc/mtab by an external command, /sbin/mount.aufs.
1527+- loopback mounted filesystem as a branch
1528+- kernel thread for removing the dir who has a plenty of whiteouts
1529+- support copyup sparse file (a file which has a 'hole' in it)
1530+- default permission flags for branches
1531+- selectable permission flags for ro branch, whether whiteout can
1532+ exist or not
1533+- export via NFS.
1534+- support <sysfs>/fs/aufs and <debugfs>/aufs.
1535+- support multiple writable branches, some policies to select one
1536+ among multiple writable branches.
1537+- a new semantics for link(2) and rename(2) to support multiple
1538+ writable branches.
1539+- no glibc changes are required.
1540+- pseudo hardlink (hardlink over branches)
1541+- allow a direct access manually to a file on branch, e.g. bypassing aufs.
1542+ including NFS or remote filesystem branch.
1543+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
1544+- and more...
1545+
1546+Currently these features are dropped temporary from aufs3.
1547+See design/08plan.txt in detail.
1548+- test only the highest one for the directory permission (dirperm1)
1549+- copyup on open (coo=)
1550+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
1551+ (robr)
1552+- statistics of aufs thread (/sys/fs/aufs/stat)
1553+- delegation mode (dlgt)
1554+ a delegation of the internal branch access to support task I/O
1555+ accounting, which also supports Linux Security Modules (LSM) mainly
1556+ for Suse AppArmor.
1557+- intent.open/create (file open in a single lookup)
1558+
1559+Features or just an idea in the future (see also design/*.txt),
1560+- reorder the branch index without del/re-add.
1561+- permanent xino files for NFSD
1562+- an option for refreshing the opened files after add/del branches
1563+- 'move' policy for copy-up between two writable branches, after
1564+ checking free space.
1565+- light version, without branch manipulation. (unnecessary?)
1566+- copyup in userspace
1567+- inotify in userspace
1568+- readv/writev
1569+- xattr, acl
1570+
1571+
1572+2. Download
1573+----------------------------------------
1e00d052
AM
1574+There were three GIT trees for aufs3, aufs3-linux.git,
1575+aufs3-standalone.git, and aufs-util.git. Note that there is no "3" in
1576+"aufs-util.git."
1577+While the aufs-util is always necessary, you need either of aufs3-linux
1578+or aufs3-standalone.
1579+
1580+The aufs3-linux tree includes the whole linux mainline GIT tree,
1581+git://git.kernel.org/.../torvalds/linux.git.
1582+And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
b4510431 1583+build aufs3 as an external kernel module.
1e00d052
AM
1584+
1585+On the other hand, the aufs3-standalone tree has only aufs source files
53392da6
AM
1586+and necessary patches, and you can select CONFIG_AUFS_FS=m.
1587+
1588+You will find GIT branches whose name is in form of "aufs3.x" where "x"
1589+represents the linux kernel version, "linux-3.x". For instance,
1e00d052
AM
1590+"aufs3.0" is for linux-3.0. For latest "linux-3.x-rcN", use
1591+"aufs3.x-rcN" branch.
1592+
1593+o aufs3-linux tree
1594+$ git clone --reference /your/linux/git/tree \
86dc4139 1595+ git://git.code.sf.net/p/aufs/aufs3-linux aufs-aufs3-linux \
1e00d052
AM
1596+ aufs3-linux.git
1597+- if you don't have linux GIT tree, then remove "--reference ..."
1598+$ cd aufs3-linux.git
1599+$ git checkout origin/aufs3.0
53392da6
AM
1600+
1601+o aufs3-standalone tree
86dc4139 1602+$ git clone git://git.code.sf.net/p/aufs/aufs3-standalone \
53392da6
AM
1603+ aufs3-standalone.git
1604+$ cd aufs3-standalone.git
1605+$ git checkout origin/aufs3.0
1606+
1607+o aufs-util tree
86dc4139 1608+$ git clone git://git.code.sf.net/p/aufs/aufs-util \
53392da6
AM
1609+ aufs-util.git
1610+$ cd aufs-util.git
1611+$ git checkout origin/aufs3.0
1612+
9dbd164d
AM
1613+Note: The 3.x-rcN branch is to be used with `rc' kernel versions ONLY.
1614+The minor version number, 'x' in '3.x', of aufs may not always
1615+follow the minor version number of the kernel.
1616+Because changes in the kernel that cause the use of a new
1617+minor version number do not always require changes to aufs-util.
1618+
1619+Since aufs-util has its own minor version number, you may not be
1620+able to find a GIT branch in aufs-util for your kernel's
1621+exact minor version number.
1622+In this case, you should git-checkout the branch for the
53392da6 1623+nearest lower number.
9dbd164d
AM
1624+
1625+For (an unreleased) example:
1626+If you are using "linux-3.10" and the "aufs3.10" branch
7eafdf33 1627+does not exist in aufs-util repository, then "aufs3.9", "aufs3.8"
9dbd164d
AM
1628+or something numerically smaller is the branch for your kernel.
1629+
53392da6
AM
1630+Also you can view all branches by
1631+ $ git branch -a
1632+
1633+
1634+3. Configuration and Compilation
1635+----------------------------------------
1636+Make sure you have git-checkout'ed the correct branch.
1637+
1e00d052 1638+For aufs3-linux tree,
c06a8ce3 1639+- enable CONFIG_AUFS_FS.
1e00d052
AM
1640+- set other aufs configurations if necessary.
1641+
53392da6
AM
1642+For aufs3-standalone tree,
1643+There are several ways to build.
1644+
1645+1.
1646+- apply ./aufs3-kbuild.patch to your kernel source files.
1647+- apply ./aufs3-base.patch too.
523b37e3 1648+- apply ./aufs3-mmap.patch too.
53392da6
AM
1649+- apply ./aufs3-standalone.patch too, if you have a plan to set
1650+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs3-standalone.patch.
537831f9
AM
1651+- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
1652+ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
c06a8ce3 1653+- enable CONFIG_AUFS_FS, you can select either
53392da6
AM
1654+ =m or =y.
1655+- and build your kernel as usual.
1656+- install the built kernel.
c06a8ce3
AM
1657+ Note: Since linux-3.9, every filesystem module requires an alias
1658+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
1659+ modules.aliases file if you set CONFIG_AUFS_FS=m.
7eafdf33
AM
1660+- install the header files too by "make headers_install" to the
1661+ directory where you specify. By default, it is $PWD/usr.
b4510431 1662+ "make help" shows a brief note for headers_install.
53392da6
AM
1663+- and reboot your system.
1664+
1665+2.
1666+- module only (CONFIG_AUFS_FS=m).
1667+- apply ./aufs3-base.patch to your kernel source files.
523b37e3 1668+- apply ./aufs3-mmap.patch too.
53392da6
AM
1669+- apply ./aufs3-standalone.patch too.
1670+- build your kernel, don't forget "make headers_install", and reboot.
1671+- edit ./config.mk and set other aufs configurations if necessary.
b4510431 1672+ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
53392da6
AM
1673+ every aufs configurations.
1674+- build the module by simple "make".
c06a8ce3
AM
1675+ Note: Since linux-3.9, every filesystem module requires an alias
1676+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
1677+ modules.aliases file.
53392da6
AM
1678+- you can specify ${KDIR} make variable which points to your kernel
1679+ source tree.
1680+- install the files
1681+ + run "make install" to install the aufs module, or copy the built
b4510431
AM
1682+ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply).
1683+ + run "make install_headers" (instead of headers_install) to install
1684+ the modified aufs header file (you can specify DESTDIR which is
1685+ available in aufs standalone version's Makefile only), or copy
1686+ $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever
1687+ you like manually. By default, the target directory is $PWD/usr.
53392da6
AM
1688+- no need to apply aufs3-kbuild.patch, nor copying source files to your
1689+ kernel source tree.
1690+
b4510431 1691+Note: The header file aufs_type.h is necessary to build aufs-util
53392da6
AM
1692+ as well as "make headers_install" in the kernel source tree.
1693+ headers_install is subject to be forgotten, but it is essentially
1694+ necessary, not only for building aufs-util.
1695+ You may not meet problems without headers_install in some older
1696+ version though.
1697+
1698+And then,
1699+- read README in aufs-util, build and install it
9dbd164d
AM
1700+- note that your distribution may contain an obsoleted version of
1701+ aufs_type.h in /usr/include/linux or something. When you build aufs
1702+ utilities, make sure that your compiler refers the correct aufs header
1703+ file which is built by "make headers_install."
53392da6
AM
1704+- if you want to use readdir(3) in userspace or pathconf(3) wrapper,
1705+ then run "make install_ulib" too. And refer to the aufs manual in
1706+ detail.
1707+
1708+
1709+4. Usage
1710+----------------------------------------
1711+At first, make sure aufs-util are installed, and please read the aufs
1712+manual, aufs.5 in aufs-util.git tree.
1713+$ man -l aufs.5
1714+
1715+And then,
1716+$ mkdir /tmp/rw /tmp/aufs
1717+# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs
1718+
1719+Here is another example. The result is equivalent.
1720+# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
1721+ Or
1722+# mount -t aufs -o br:/tmp/rw none /tmp/aufs
1723+# mount -o remount,append:${HOME} /tmp/aufs
1724+
1725+Then, you can see whole tree of your home dir through /tmp/aufs. If
1726+you modify a file under /tmp/aufs, the one on your home directory is
1727+not affected, instead the same named file will be newly created under
1728+/tmp/rw. And all of your modification to a file will be applied to
1729+the one under /tmp/rw. This is called the file based Copy on Write
1730+(COW) method.
1731+Aufs mount options are described in aufs.5.
1732+If you run chroot or something and make your aufs as a root directory,
1733+then you need to customize the shutdown script. See the aufs manual in
1734+detail.
1735+
1736+Additionally, there are some sample usages of aufs which are a
1737+diskless system with network booting, and LiveCD over NFS.
1738+See sample dir in CVS tree on SourceForge.
1739+
1740+
1741+5. Contact
1742+----------------------------------------
1743+When you have any problems or strange behaviour in aufs, please let me
1744+know with:
1745+- /proc/mounts (instead of the output of mount(8))
1746+- /sys/module/aufs/*
1747+- /sys/fs/aufs/* (if you have them)
1748+- /debug/aufs/* (if you have them)
1749+- linux kernel version
1750+ if your kernel is not plain, for example modified by distributor,
1751+ the url where i can download its source is necessary too.
1752+- aufs version which was printed at loading the module or booting the
1753+ system, instead of the date you downloaded.
1754+- configuration (define/undefine CONFIG_AUFS_xxx)
1755+- kernel configuration or /proc/config.gz (if you have it)
1756+- behaviour which you think to be incorrect
1757+- actual operation, reproducible one is better
1758+- mailto: aufs-users at lists.sourceforge.net
1759+
1760+Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches,
1761+and Feature Requests) on SourceForge. Please join and write to
1762+aufs-users ML.
1763+
1764+
1765+6. Acknowledgements
1766+----------------------------------------
1767+Thanks to everyone who have tried and are using aufs, whoever
1768+have reported a bug or any feedback.
1769+
1770+Especially donators:
1771+Tomas Matejicek(slax.org) made a donation (much more than once).
1772+ Since Apr 2010, Tomas M (the author of Slax and Linux Live
1773+ scripts) is making "doubling" donations.
1774+ Unfortunately I cannot list all of the donators, but I really
b4510431 1775+ appreciate.
53392da6
AM
1776+ It ends Aug 2010, but the ordinary donation URL is still available.
1777+ <http://sourceforge.net/donate/index.php?group_id=167503>
1778+Dai Itasaka made a donation (2007/8).
1779+Chuck Smith made a donation (2008/4, 10 and 12).
1780+Henk Schoneveld made a donation (2008/9).
1781+Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10).
1782+Francois Dupoux made a donation (2008/11).
1783+Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public
1784+ aufs2 GIT tree (2009/2).
1785+William Grant made a donation (2009/3).
1786+Patrick Lane made a donation (2009/4).
1787+The Mail Archive (mail-archive.com) made donations (2009/5).
1788+Nippy Networks (Ed Wildgoose) made a donation (2009/7).
1789+New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11).
1790+Pavel Pronskiy made a donation (2011/2).
1791+Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy
1792+ Networks (Ed Wildgoose) made a donation for hardware (2011/3).
537831f9
AM
1793+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
1794+11).
1e00d052 1795+Sam Liddicott made a donation (2011/9).
86dc4139
AM
1796+Era Scarecrow made a donation (2013/4).
1797+Bor Ratajc made a donation (2013/4).
1798+Alessandro Gorreta made a donation (2013/4).
1799+POIRETTE Marc made a donation (2013/4).
1800+Alessandro Gorreta made a donation (2013/4).
1801+lauri kasvandik made a donation (2013/5).
392086de 1802+"pemasu from Finland" made a donation (2013/7).
523b37e3
AM
1803+The Parted Magic Project made a donation (2013/9 and 11).
1804+Pavel Barta made a donation (2013/10).
53392da6
AM
1805+
1806+Thank you very much.
1807+Donations are always, including future donations, very important and
1808+helpful for me to keep on developing aufs.
1809+
1810+
1811+7.
1812+----------------------------------------
1813+If you are an experienced user, no explanation is needed. Aufs is
1814+just a linux filesystem.
1815+
1816+
1817+Enjoy!
1818+
1819+# Local variables: ;
1820+# mode: text;
1821+# End: ;
7f207e10
AM
1822diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
1823--- /usr/share/empty/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
1824+++ linux/fs/aufs/aufs.h 2014-01-20 20:16:14.732796615 +0100
1825@@ -0,0 +1,59 @@
7f207e10 1826+/*
523b37e3 1827+ * Copyright (C) 2005-2014 Junjiro R. Okajima
7f207e10
AM
1828+ *
1829+ * This program, aufs is free software; you can redistribute it and/or modify
1830+ * it under the terms of the GNU General Public License as published by
1831+ * the Free Software Foundation; either version 2 of the License, or
1832+ * (at your option) any later version.
1833+ *
1834+ * This program is distributed in the hope that it will be useful,
1835+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1836+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1837+ * GNU General Public License for more details.
1838+ *
1839+ * You should have received a copy of the GNU General Public License
523b37e3 1840+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
1841+ */
1842+
1843+/*
1844+ * all header files
1845+ */
1846+
1847+#ifndef __AUFS_H__
1848+#define __AUFS_H__
1849+
1850+#ifdef __KERNEL__
1851+
1852+#define AuStub(type, name, body, ...) \
1853+ static inline type name(__VA_ARGS__) { body; }
1854+
1855+#define AuStubVoid(name, ...) \
1856+ AuStub(void, name, , __VA_ARGS__)
1857+#define AuStubInt0(name, ...) \
1858+ AuStub(int, name, return 0, __VA_ARGS__)
1859+
1860+#include "debug.h"
1861+
1862+#include "branch.h"
1863+#include "cpup.h"
1864+#include "dcsub.h"
1865+#include "dbgaufs.h"
1866+#include "dentry.h"
1867+#include "dir.h"
1868+#include "dynop.h"
1869+#include "file.h"
1870+#include "fstype.h"
1871+#include "inode.h"
1872+#include "loop.h"
1873+#include "module.h"
7f207e10
AM
1874+#include "opts.h"
1875+#include "rwsem.h"
1876+#include "spl.h"
1877+#include "super.h"
1878+#include "sysaufs.h"
1879+#include "vfsub.h"
1880+#include "whout.h"
1881+#include "wkq.h"
1882+
1883+#endif /* __KERNEL__ */
1884+#endif /* __AUFS_H__ */
1885diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
1886--- /usr/share/empty/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
1887+++ linux/fs/aufs/branch.c 2014-01-20 20:16:14.732796615 +0100
1888@@ -0,0 +1,1219 @@
7f207e10 1889+/*
523b37e3 1890+ * Copyright (C) 2005-2014 Junjiro R. Okajima
7f207e10
AM
1891+ *
1892+ * This program, aufs is free software; you can redistribute it and/or modify
1893+ * it under the terms of the GNU General Public License as published by
1894+ * the Free Software Foundation; either version 2 of the License, or
1895+ * (at your option) any later version.
1896+ *
1897+ * This program is distributed in the hope that it will be useful,
1898+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1899+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1900+ * GNU General Public License for more details.
1901+ *
1902+ * You should have received a copy of the GNU General Public License
523b37e3 1903+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
1904+ */
1905+
1906+/*
1907+ * branch management
1908+ */
1909+
027c5e7a 1910+#include <linux/compat.h>
7f207e10
AM
1911+#include <linux/statfs.h>
1912+#include "aufs.h"
1913+
1914+/*
1915+ * free a single branch
1facf9fc 1916+ */
86dc4139
AM
1917+
1918+/* prohibit rmdir to the root of the branch */
1919+/* todo: another new flag? */
1920+static void au_br_dflags_force(struct au_branch *br)
1921+{
1922+ struct dentry *h_dentry;
1923+
1924+ h_dentry = au_br_dentry(br);
1925+ spin_lock(&h_dentry->d_lock);
1926+ br->br_dflags = h_dentry->d_flags & DCACHE_MOUNTED;
1927+ h_dentry->d_flags |= DCACHE_MOUNTED;
1928+ spin_unlock(&h_dentry->d_lock);
1929+}
1930+
1931+/* restore its d_flags */
1932+static void au_br_dflags_restore(struct au_branch *br)
1933+{
1934+ struct dentry *h_dentry;
1935+
1936+ if (br->br_dflags)
1937+ return;
1938+
1939+ h_dentry = au_br_dentry(br);
1940+ spin_lock(&h_dentry->d_lock);
1941+ h_dentry->d_flags &= ~DCACHE_MOUNTED;
1942+ spin_unlock(&h_dentry->d_lock);
1943+}
1944+
1facf9fc 1945+static void au_br_do_free(struct au_branch *br)
1946+{
1947+ int i;
1948+ struct au_wbr *wbr;
4a4d8108 1949+ struct au_dykey **key;
1facf9fc 1950+
027c5e7a
AM
1951+ au_hnotify_fin_br(br);
1952+
1facf9fc 1953+ if (br->br_xino.xi_file)
1954+ fput(br->br_xino.xi_file);
1955+ mutex_destroy(&br->br_xino.xi_nondir_mtx);
1956+
1957+ AuDebugOn(atomic_read(&br->br_count));
1958+
1959+ wbr = br->br_wbr;
1960+ if (wbr) {
1961+ for (i = 0; i < AuBrWh_Last; i++)
1962+ dput(wbr->wbr_wh[i]);
1963+ AuDebugOn(atomic_read(&wbr->wbr_wh_running));
dece6358 1964+ AuRwDestroy(&wbr->wbr_wh_rwsem);
1facf9fc 1965+ }
1966+
4a4d8108
AM
1967+ key = br->br_dykey;
1968+ for (i = 0; i < AuBrDynOp; i++, key++)
1969+ if (*key)
1970+ au_dy_put(*key);
1971+ else
1972+ break;
1973+
86dc4139
AM
1974+ au_br_dflags_restore(br);
1975+
537831f9
AM
1976+ /* recursive lock, s_umount of branch's */
1977+ lockdep_off();
86dc4139 1978+ path_put(&br->br_path);
537831f9 1979+ lockdep_on();
1facf9fc 1980+ kfree(wbr);
1981+ kfree(br);
1982+}
1983+
1984+/*
1985+ * frees all branches
1986+ */
1987+void au_br_free(struct au_sbinfo *sbinfo)
1988+{
1989+ aufs_bindex_t bmax;
1990+ struct au_branch **br;
1991+
dece6358
AM
1992+ AuRwMustWriteLock(&sbinfo->si_rwsem);
1993+
1facf9fc 1994+ bmax = sbinfo->si_bend + 1;
1995+ br = sbinfo->si_branch;
1996+ while (bmax--)
1997+ au_br_do_free(*br++);
1998+}
1999+
2000+/*
2001+ * find the index of a branch which is specified by @br_id.
2002+ */
2003+int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
2004+{
2005+ aufs_bindex_t bindex, bend;
2006+
2007+ bend = au_sbend(sb);
2008+ for (bindex = 0; bindex <= bend; bindex++)
2009+ if (au_sbr_id(sb, bindex) == br_id)
2010+ return bindex;
2011+ return -1;
2012+}
2013+
2014+/* ---------------------------------------------------------------------- */
2015+
2016+/*
2017+ * add a branch
2018+ */
2019+
b752ccd1
AM
2020+static int test_overlap(struct super_block *sb, struct dentry *h_adding,
2021+ struct dentry *h_root)
1facf9fc 2022+{
b752ccd1
AM
2023+ if (unlikely(h_adding == h_root
2024+ || au_test_loopback_overlap(sb, h_adding)))
1facf9fc 2025+ return 1;
b752ccd1
AM
2026+ if (h_adding->d_sb != h_root->d_sb)
2027+ return 0;
2028+ return au_test_subdir(h_adding, h_root)
2029+ || au_test_subdir(h_root, h_adding);
1facf9fc 2030+}
2031+
2032+/*
2033+ * returns a newly allocated branch. @new_nbranch is a number of branches
2034+ * after adding a branch.
2035+ */
2036+static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
2037+ int perm)
2038+{
2039+ struct au_branch *add_branch;
2040+ struct dentry *root;
4a4d8108 2041+ int err;
1facf9fc 2042+
4a4d8108 2043+ err = -ENOMEM;
1facf9fc 2044+ root = sb->s_root;
2045+ add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS);
2046+ if (unlikely(!add_branch))
2047+ goto out;
2048+
027c5e7a
AM
2049+ err = au_hnotify_init_br(add_branch, perm);
2050+ if (unlikely(err))
2051+ goto out_br;
2052+
1facf9fc 2053+ add_branch->br_wbr = NULL;
2054+ if (au_br_writable(perm)) {
2055+ /* may be freed separately at changing the branch permission */
2056+ add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr),
2057+ GFP_NOFS);
2058+ if (unlikely(!add_branch->br_wbr))
027c5e7a 2059+ goto out_hnotify;
1facf9fc 2060+ }
2061+
4a4d8108
AM
2062+ err = au_sbr_realloc(au_sbi(sb), new_nbranch);
2063+ if (!err)
2064+ err = au_di_realloc(au_di(root), new_nbranch);
2065+ if (!err)
2066+ err = au_ii_realloc(au_ii(root->d_inode), new_nbranch);
2067+ if (!err)
2068+ return add_branch; /* success */
1facf9fc 2069+
1facf9fc 2070+ kfree(add_branch->br_wbr);
4a4d8108 2071+
027c5e7a
AM
2072+out_hnotify:
2073+ au_hnotify_fin_br(add_branch);
4f0767ce 2074+out_br:
1facf9fc 2075+ kfree(add_branch);
4f0767ce 2076+out:
4a4d8108 2077+ return ERR_PTR(err);
1facf9fc 2078+}
2079+
2080+/*
2081+ * test if the branch permission is legal or not.
2082+ */
2083+static int test_br(struct inode *inode, int brperm, char *path)
2084+{
2085+ int err;
2086+
4a4d8108
AM
2087+ err = (au_br_writable(brperm) && IS_RDONLY(inode));
2088+ if (!err)
2089+ goto out;
1facf9fc 2090+
4a4d8108
AM
2091+ err = -EINVAL;
2092+ pr_err("write permission for readonly mount or inode, %s\n", path);
2093+
4f0767ce 2094+out:
1facf9fc 2095+ return err;
2096+}
2097+
2098+/*
2099+ * returns:
2100+ * 0: success, the caller will add it
2101+ * plus: success, it is already unified, the caller should ignore it
2102+ * minus: error
2103+ */
2104+static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
2105+{
2106+ int err;
2107+ aufs_bindex_t bend, bindex;
2108+ struct dentry *root;
2109+ struct inode *inode, *h_inode;
2110+
2111+ root = sb->s_root;
2112+ bend = au_sbend(sb);
2113+ if (unlikely(bend >= 0
2114+ && au_find_dbindex(root, add->path.dentry) >= 0)) {
2115+ err = 1;
2116+ if (!remount) {
2117+ err = -EINVAL;
4a4d8108 2118+ pr_err("%s duplicated\n", add->pathname);
1facf9fc 2119+ }
2120+ goto out;
2121+ }
2122+
2123+ err = -ENOSPC; /* -E2BIG; */
2124+ if (unlikely(AUFS_BRANCH_MAX <= add->bindex
2125+ || AUFS_BRANCH_MAX - 1 <= bend)) {
4a4d8108 2126+ pr_err("number of branches exceeded %s\n", add->pathname);
1facf9fc 2127+ goto out;
2128+ }
2129+
2130+ err = -EDOM;
2131+ if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) {
4a4d8108 2132+ pr_err("bad index %d\n", add->bindex);
1facf9fc 2133+ goto out;
2134+ }
2135+
2136+ inode = add->path.dentry->d_inode;
2137+ err = -ENOENT;
2138+ if (unlikely(!inode->i_nlink)) {
4a4d8108 2139+ pr_err("no existence %s\n", add->pathname);
1facf9fc 2140+ goto out;
2141+ }
2142+
2143+ err = -EINVAL;
2144+ if (unlikely(inode->i_sb == sb)) {
4a4d8108 2145+ pr_err("%s must be outside\n", add->pathname);
1facf9fc 2146+ goto out;
2147+ }
2148+
2149+ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
4a4d8108
AM
2150+ pr_err("unsupported filesystem, %s (%s)\n",
2151+ add->pathname, au_sbtype(inode->i_sb));
1facf9fc 2152+ goto out;
2153+ }
2154+
2155+ err = test_br(add->path.dentry->d_inode, add->perm, add->pathname);
2156+ if (unlikely(err))
2157+ goto out;
2158+
2159+ if (bend < 0)
2160+ return 0; /* success */
2161+
2162+ err = -EINVAL;
2163+ for (bindex = 0; bindex <= bend; bindex++)
2164+ if (unlikely(test_overlap(sb, add->path.dentry,
2165+ au_h_dptr(root, bindex)))) {
4a4d8108 2166+ pr_err("%s is overlapped\n", add->pathname);
1facf9fc 2167+ goto out;
2168+ }
2169+
2170+ err = 0;
2171+ if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
2172+ h_inode = au_h_dptr(root, 0)->d_inode;
2173+ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
0c3ec466
AM
2174+ || !uid_eq(h_inode->i_uid, inode->i_uid)
2175+ || !gid_eq(h_inode->i_gid, inode->i_gid))
2176+ pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
2177+ add->pathname,
2178+ i_uid_read(inode), i_gid_read(inode),
2179+ (inode->i_mode & S_IALLUGO),
2180+ i_uid_read(h_inode), i_gid_read(h_inode),
2181+ (h_inode->i_mode & S_IALLUGO));
1facf9fc 2182+ }
2183+
4f0767ce 2184+out:
1facf9fc 2185+ return err;
2186+}
2187+
2188+/*
2189+ * initialize or clean the whiteouts for an adding branch
2190+ */
2191+static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
86dc4139 2192+ int new_perm)
1facf9fc 2193+{
2194+ int err, old_perm;
2195+ aufs_bindex_t bindex;
2196+ struct mutex *h_mtx;
2197+ struct au_wbr *wbr;
2198+ struct au_hinode *hdir;
2199+
86dc4139
AM
2200+ err = vfsub_mnt_want_write(au_br_mnt(br));
2201+ if (unlikely(err))
2202+ goto out;
2203+
1facf9fc 2204+ wbr = br->br_wbr;
2205+ old_perm = br->br_perm;
2206+ br->br_perm = new_perm;
2207+ hdir = NULL;
2208+ h_mtx = NULL;
2209+ bindex = au_br_index(sb, br->br_id);
2210+ if (0 <= bindex) {
2211+ hdir = au_hi(sb->s_root->d_inode, bindex);
4a4d8108 2212+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 2213+ } else {
86dc4139 2214+ h_mtx = &au_br_dentry(br)->d_inode->i_mutex;
1facf9fc 2215+ mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
2216+ }
2217+ if (!wbr)
86dc4139 2218+ err = au_wh_init(br, sb);
1facf9fc 2219+ else {
2220+ wbr_wh_write_lock(wbr);
86dc4139 2221+ err = au_wh_init(br, sb);
1facf9fc 2222+ wbr_wh_write_unlock(wbr);
2223+ }
2224+ if (hdir)
4a4d8108 2225+ au_hn_imtx_unlock(hdir);
1facf9fc 2226+ else
2227+ mutex_unlock(h_mtx);
86dc4139 2228+ vfsub_mnt_drop_write(au_br_mnt(br));
1facf9fc 2229+ br->br_perm = old_perm;
2230+
2231+ if (!err && wbr && !au_br_writable(new_perm)) {
2232+ kfree(wbr);
2233+ br->br_wbr = NULL;
2234+ }
2235+
86dc4139 2236+out:
1facf9fc 2237+ return err;
2238+}
2239+
2240+static int au_wbr_init(struct au_branch *br, struct super_block *sb,
86dc4139 2241+ int perm)
1facf9fc 2242+{
2243+ int err;
4a4d8108 2244+ struct kstatfs kst;
1facf9fc 2245+ struct au_wbr *wbr;
2246+
2247+ wbr = br->br_wbr;
dece6358 2248+ au_rw_init(&wbr->wbr_wh_rwsem);
1facf9fc 2249+ memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh));
2250+ atomic_set(&wbr->wbr_wh_running, 0);
2251+ wbr->wbr_bytes = 0;
2252+
4a4d8108
AM
2253+ /*
2254+ * a limit for rmdir/rename a dir
523b37e3 2255+ * cf. AUFS_MAX_NAMELEN in include/uapi/linux/aufs_type.h
4a4d8108 2256+ */
86dc4139 2257+ err = vfs_statfs(&br->br_path, &kst);
4a4d8108
AM
2258+ if (unlikely(err))
2259+ goto out;
2260+ err = -EINVAL;
2261+ if (kst.f_namelen >= NAME_MAX)
86dc4139 2262+ err = au_br_init_wh(sb, br, perm);
4a4d8108 2263+ else
523b37e3
AM
2264+ pr_err("%pd(%s), unsupported namelen %ld\n",
2265+ au_br_dentry(br),
86dc4139 2266+ au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen);
1facf9fc 2267+
4f0767ce 2268+out:
1facf9fc 2269+ return err;
2270+}
2271+
2272+/* intialize a new branch */
2273+static int au_br_init(struct au_branch *br, struct super_block *sb,
2274+ struct au_opt_add *add)
2275+{
2276+ int err;
2277+
2278+ err = 0;
2279+ memset(&br->br_xino, 0, sizeof(br->br_xino));
2280+ mutex_init(&br->br_xino.xi_nondir_mtx);
2281+ br->br_perm = add->perm;
86dc4139
AM
2282+ BUILD_BUG_ON(sizeof(br->br_dflags)
2283+ != sizeof(br->br_path.dentry->d_flags));
2284+ br->br_dflags = DCACHE_MOUNTED;
2285+ br->br_path = add->path; /* set first, path_get() later */
4a4d8108
AM
2286+ spin_lock_init(&br->br_dykey_lock);
2287+ memset(br->br_dykey, 0, sizeof(br->br_dykey));
1facf9fc 2288+ atomic_set(&br->br_count, 0);
1facf9fc 2289+ atomic_set(&br->br_xino_running, 0);
2290+ br->br_id = au_new_br_id(sb);
7f207e10 2291+ AuDebugOn(br->br_id < 0);
1facf9fc 2292+
2293+ if (au_br_writable(add->perm)) {
86dc4139 2294+ err = au_wbr_init(br, sb, add->perm);
1facf9fc 2295+ if (unlikely(err))
b752ccd1 2296+ goto out_err;
1facf9fc 2297+ }
2298+
2299+ if (au_opt_test(au_mntflags(sb), XINO)) {
2300+ err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino,
2301+ au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
2302+ if (unlikely(err)) {
2303+ AuDebugOn(br->br_xino.xi_file);
b752ccd1 2304+ goto out_err;
1facf9fc 2305+ }
2306+ }
2307+
2308+ sysaufs_br_init(br);
86dc4139 2309+ path_get(&br->br_path);
b752ccd1 2310+ goto out; /* success */
1facf9fc 2311+
4f0767ce 2312+out_err:
86dc4139 2313+ memset(&br->br_path, 0, sizeof(br->br_path));
4f0767ce 2314+out:
1facf9fc 2315+ return err;
2316+}
2317+
2318+static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
2319+ struct au_branch *br, aufs_bindex_t bend,
2320+ aufs_bindex_t amount)
2321+{
2322+ struct au_branch **brp;
2323+
dece6358
AM
2324+ AuRwMustWriteLock(&sbinfo->si_rwsem);
2325+
1facf9fc 2326+ brp = sbinfo->si_branch + bindex;
2327+ memmove(brp + 1, brp, sizeof(*brp) * amount);
2328+ *brp = br;
2329+ sbinfo->si_bend++;
2330+ if (unlikely(bend < 0))
2331+ sbinfo->si_bend = 0;
2332+}
2333+
2334+static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
2335+ aufs_bindex_t bend, aufs_bindex_t amount)
2336+{
2337+ struct au_hdentry *hdp;
2338+
1308ab2a 2339+ AuRwMustWriteLock(&dinfo->di_rwsem);
2340+
1facf9fc 2341+ hdp = dinfo->di_hdentry + bindex;
2342+ memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
2343+ au_h_dentry_init(hdp);
2344+ dinfo->di_bend++;
2345+ if (unlikely(bend < 0))
2346+ dinfo->di_bstart = 0;
2347+}
2348+
2349+static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
2350+ aufs_bindex_t bend, aufs_bindex_t amount)
2351+{
2352+ struct au_hinode *hip;
2353+
1308ab2a 2354+ AuRwMustWriteLock(&iinfo->ii_rwsem);
2355+
1facf9fc 2356+ hip = iinfo->ii_hinode + bindex;
2357+ memmove(hip + 1, hip, sizeof(*hip) * amount);
2358+ hip->hi_inode = NULL;
4a4d8108 2359+ au_hn_init(hip);
1facf9fc 2360+ iinfo->ii_bend++;
2361+ if (unlikely(bend < 0))
2362+ iinfo->ii_bstart = 0;
2363+}
2364+
86dc4139
AM
2365+static void au_br_do_add(struct super_block *sb, struct au_branch *br,
2366+ aufs_bindex_t bindex)
1facf9fc 2367+{
86dc4139 2368+ struct dentry *root, *h_dentry;
1facf9fc 2369+ struct inode *root_inode;
2370+ aufs_bindex_t bend, amount;
2371+
86dc4139
AM
2372+ au_br_dflags_force(br);
2373+
1facf9fc 2374+ root = sb->s_root;
2375+ root_inode = root->d_inode;
1facf9fc 2376+ bend = au_sbend(sb);
2377+ amount = bend + 1 - bindex;
86dc4139 2378+ h_dentry = au_br_dentry(br);
53392da6 2379+ au_sbilist_lock();
1facf9fc 2380+ au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount);
2381+ au_br_do_add_hdp(au_di(root), bindex, bend, amount);
2382+ au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount);
2383+ au_set_h_dptr(root, bindex, dget(h_dentry));
2384+ au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode),
2385+ /*flags*/0);
53392da6 2386+ au_sbilist_unlock();
1facf9fc 2387+}
2388+
2389+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
2390+{
2391+ int err;
1facf9fc 2392+ aufs_bindex_t bend, add_bindex;
2393+ struct dentry *root, *h_dentry;
2394+ struct inode *root_inode;
2395+ struct au_branch *add_branch;
2396+
2397+ root = sb->s_root;
2398+ root_inode = root->d_inode;
2399+ IMustLock(root_inode);
2400+ err = test_add(sb, add, remount);
2401+ if (unlikely(err < 0))
2402+ goto out;
2403+ if (err) {
2404+ err = 0;
2405+ goto out; /* success */
2406+ }
2407+
2408+ bend = au_sbend(sb);
2409+ add_branch = au_br_alloc(sb, bend + 2, add->perm);
2410+ err = PTR_ERR(add_branch);
2411+ if (IS_ERR(add_branch))
2412+ goto out;
2413+
2414+ err = au_br_init(add_branch, sb, add);
2415+ if (unlikely(err)) {
2416+ au_br_do_free(add_branch);
2417+ goto out;
2418+ }
2419+
2420+ add_bindex = add->bindex;
1facf9fc 2421+ if (!remount)
86dc4139 2422+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 2423+ else {
2424+ sysaufs_brs_del(sb, add_bindex);
86dc4139 2425+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 2426+ sysaufs_brs_add(sb, add_bindex);
2427+ }
2428+
86dc4139 2429+ h_dentry = add->path.dentry;
1308ab2a 2430+ if (!add_bindex) {
1facf9fc 2431+ au_cpup_attr_all(root_inode, /*force*/1);
1308ab2a 2432+ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
2433+ } else
1facf9fc 2434+ au_add_nlink(root_inode, h_dentry->d_inode);
1facf9fc 2435+
2436+ /*
4a4d8108 2437+ * this test/set prevents aufs from handling unnecesary notify events
027c5e7a 2438+ * of xino files, in case of re-adding a writable branch which was
1facf9fc 2439+ * once detached from aufs.
2440+ */
2441+ if (au_xino_brid(sb) < 0
2442+ && au_br_writable(add_branch->br_perm)
2443+ && !au_test_fs_bad_xino(h_dentry->d_sb)
2444+ && add_branch->br_xino.xi_file
2445+ && add_branch->br_xino.xi_file->f_dentry->d_parent == h_dentry)
2446+ au_xino_brid_set(sb, add_branch->br_id);
2447+
4f0767ce 2448+out:
1facf9fc 2449+ return err;
2450+}
2451+
2452+/* ---------------------------------------------------------------------- */
2453+
2454+/*
2455+ * delete a branch
2456+ */
2457+
2458+/* to show the line number, do not make it inlined function */
4a4d8108 2459+#define AuVerbose(do_info, fmt, ...) do { \
1facf9fc 2460+ if (do_info) \
4a4d8108 2461+ pr_info(fmt, ##__VA_ARGS__); \
1facf9fc 2462+} while (0)
2463+
027c5e7a
AM
2464+static int au_test_ibusy(struct inode *inode, aufs_bindex_t bstart,
2465+ aufs_bindex_t bend)
2466+{
2467+ return (inode && !S_ISDIR(inode->i_mode)) || bstart == bend;
2468+}
2469+
2470+static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t bstart,
2471+ aufs_bindex_t bend)
2472+{
2473+ return au_test_ibusy(dentry->d_inode, bstart, bend);
2474+}
2475+
1facf9fc 2476+/*
2477+ * test if the branch is deletable or not.
2478+ */
2479+static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
b752ccd1 2480+ unsigned int sigen, const unsigned int verbose)
1facf9fc 2481+{
2482+ int err, i, j, ndentry;
2483+ aufs_bindex_t bstart, bend;
1facf9fc 2484+ struct au_dcsub_pages dpages;
2485+ struct au_dpage *dpage;
2486+ struct dentry *d;
1facf9fc 2487+
2488+ err = au_dpages_init(&dpages, GFP_NOFS);
2489+ if (unlikely(err))
2490+ goto out;
2491+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
2492+ if (unlikely(err))
2493+ goto out_dpages;
2494+
1facf9fc 2495+ for (i = 0; !err && i < dpages.ndpage; i++) {
2496+ dpage = dpages.dpages + i;
2497+ ndentry = dpage->ndentry;
2498+ for (j = 0; !err && j < ndentry; j++) {
2499+ d = dpage->dentries[j];
392086de 2500+ AuDebugOn(!d_count(d));
027c5e7a 2501+ if (!au_digen_test(d, sigen)) {
1facf9fc 2502+ di_read_lock_child(d, AuLock_IR);
027c5e7a
AM
2503+ if (unlikely(au_dbrange_test(d))) {
2504+ di_read_unlock(d, AuLock_IR);
2505+ continue;
2506+ }
2507+ } else {
1facf9fc 2508+ di_write_lock_child(d);
027c5e7a
AM
2509+ if (unlikely(au_dbrange_test(d))) {
2510+ di_write_unlock(d);
2511+ continue;
2512+ }
1facf9fc 2513+ err = au_reval_dpath(d, sigen);
2514+ if (!err)
2515+ di_downgrade_lock(d, AuLock_IR);
2516+ else {
2517+ di_write_unlock(d);
2518+ break;
2519+ }
2520+ }
2521+
027c5e7a 2522+ /* AuDbgDentry(d); */
1facf9fc 2523+ bstart = au_dbstart(d);
2524+ bend = au_dbend(d);
2525+ if (bstart <= bindex
2526+ && bindex <= bend
2527+ && au_h_dptr(d, bindex)
027c5e7a 2528+ && au_test_dbusy(d, bstart, bend)) {
1facf9fc 2529+ err = -EBUSY;
523b37e3 2530+ AuVerbose(verbose, "busy %pd\n", d);
027c5e7a 2531+ AuDbgDentry(d);
1facf9fc 2532+ }
2533+ di_read_unlock(d, AuLock_IR);
2534+ }
2535+ }
2536+
4f0767ce 2537+out_dpages:
1facf9fc 2538+ au_dpages_free(&dpages);
4f0767ce 2539+out:
1facf9fc 2540+ return err;
2541+}
2542+
2543+static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
b752ccd1 2544+ unsigned int sigen, const unsigned int verbose)
1facf9fc 2545+{
2546+ int err;
7f207e10
AM
2547+ unsigned long long max, ull;
2548+ struct inode *i, **array;
1facf9fc 2549+ aufs_bindex_t bstart, bend;
1facf9fc 2550+
7f207e10
AM
2551+ array = au_iarray_alloc(sb, &max);
2552+ err = PTR_ERR(array);
2553+ if (IS_ERR(array))
2554+ goto out;
2555+
1facf9fc 2556+ err = 0;
7f207e10
AM
2557+ AuDbg("b%d\n", bindex);
2558+ for (ull = 0; !err && ull < max; ull++) {
2559+ i = array[ull];
2560+ if (i->i_ino == AUFS_ROOT_INO)
1facf9fc 2561+ continue;
2562+
7f207e10 2563+ /* AuDbgInode(i); */
537831f9 2564+ if (au_iigen(i, NULL) == sigen)
1facf9fc 2565+ ii_read_lock_child(i);
2566+ else {
2567+ ii_write_lock_child(i);
027c5e7a
AM
2568+ err = au_refresh_hinode_self(i);
2569+ au_iigen_dec(i);
1facf9fc 2570+ if (!err)
2571+ ii_downgrade_lock(i);
2572+ else {
2573+ ii_write_unlock(i);
2574+ break;
2575+ }
2576+ }
2577+
2578+ bstart = au_ibstart(i);
2579+ bend = au_ibend(i);
2580+ if (bstart <= bindex
2581+ && bindex <= bend
2582+ && au_h_iptr(i, bindex)
027c5e7a 2583+ && au_test_ibusy(i, bstart, bend)) {
1facf9fc 2584+ err = -EBUSY;
2585+ AuVerbose(verbose, "busy i%lu\n", i->i_ino);
7f207e10 2586+ AuDbgInode(i);
1facf9fc 2587+ }
2588+ ii_read_unlock(i);
2589+ }
7f207e10 2590+ au_iarray_free(array, max);
1facf9fc 2591+
7f207e10 2592+out:
1facf9fc 2593+ return err;
2594+}
2595+
b752ccd1
AM
2596+static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
2597+ const unsigned int verbose)
1facf9fc 2598+{
2599+ int err;
2600+ unsigned int sigen;
2601+
2602+ sigen = au_sigen(root->d_sb);
2603+ DiMustNoWaiters(root);
2604+ IiMustNoWaiters(root->d_inode);
2605+ di_write_unlock(root);
b752ccd1 2606+ err = test_dentry_busy(root, bindex, sigen, verbose);
1facf9fc 2607+ if (!err)
b752ccd1 2608+ err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
1facf9fc 2609+ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
2610+
2611+ return err;
2612+}
2613+
2614+static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
2615+ const aufs_bindex_t bindex,
2616+ const aufs_bindex_t bend)
2617+{
2618+ struct au_branch **brp, **p;
2619+
dece6358
AM
2620+ AuRwMustWriteLock(&sbinfo->si_rwsem);
2621+
1facf9fc 2622+ brp = sbinfo->si_branch + bindex;
2623+ if (bindex < bend)
2624+ memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex));
2625+ sbinfo->si_branch[0 + bend] = NULL;
2626+ sbinfo->si_bend--;
2627+
53392da6 2628+ p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 2629+ if (p)
2630+ sbinfo->si_branch = p;
4a4d8108 2631+ /* harmless error */
1facf9fc 2632+}
2633+
2634+static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
2635+ const aufs_bindex_t bend)
2636+{
2637+ struct au_hdentry *hdp, *p;
2638+
1308ab2a 2639+ AuRwMustWriteLock(&dinfo->di_rwsem);
2640+
4a4d8108 2641+ hdp = dinfo->di_hdentry;
1facf9fc 2642+ if (bindex < bend)
4a4d8108
AM
2643+ memmove(hdp + bindex, hdp + bindex + 1,
2644+ sizeof(*hdp) * (bend - bindex));
2645+ hdp[0 + bend].hd_dentry = NULL;
1facf9fc 2646+ dinfo->di_bend--;
2647+
53392da6 2648+ p = krealloc(hdp, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 2649+ if (p)
2650+ dinfo->di_hdentry = p;
4a4d8108 2651+ /* harmless error */
1facf9fc 2652+}
2653+
2654+static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
2655+ const aufs_bindex_t bend)
2656+{
2657+ struct au_hinode *hip, *p;
2658+
1308ab2a 2659+ AuRwMustWriteLock(&iinfo->ii_rwsem);
2660+
1facf9fc 2661+ hip = iinfo->ii_hinode + bindex;
2662+ if (bindex < bend)
2663+ memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex));
2664+ iinfo->ii_hinode[0 + bend].hi_inode = NULL;
4a4d8108 2665+ au_hn_init(iinfo->ii_hinode + bend);
1facf9fc 2666+ iinfo->ii_bend--;
2667+
53392da6 2668+ p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 2669+ if (p)
2670+ iinfo->ii_hinode = p;
4a4d8108 2671+ /* harmless error */
1facf9fc 2672+}
2673+
2674+static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
2675+ struct au_branch *br)
2676+{
2677+ aufs_bindex_t bend;
2678+ struct au_sbinfo *sbinfo;
53392da6
AM
2679+ struct dentry *root, *h_root;
2680+ struct inode *inode, *h_inode;
2681+ struct au_hinode *hinode;
1facf9fc 2682+
dece6358
AM
2683+ SiMustWriteLock(sb);
2684+
1facf9fc 2685+ root = sb->s_root;
2686+ inode = root->d_inode;
1facf9fc 2687+ sbinfo = au_sbi(sb);
2688+ bend = sbinfo->si_bend;
2689+
53392da6
AM
2690+ h_root = au_h_dptr(root, bindex);
2691+ hinode = au_hi(inode, bindex);
2692+ h_inode = au_igrab(hinode->hi_inode);
2693+ au_hiput(hinode);
1facf9fc 2694+
53392da6 2695+ au_sbilist_lock();
1facf9fc 2696+ au_br_do_del_brp(sbinfo, bindex, bend);
2697+ au_br_do_del_hdp(au_di(root), bindex, bend);
2698+ au_br_do_del_hip(au_ii(inode), bindex, bend);
53392da6
AM
2699+ au_sbilist_unlock();
2700+
2701+ dput(h_root);
2702+ iput(h_inode);
2703+ au_br_do_free(br);
1facf9fc 2704+}
2705+
2706+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
2707+{
2708+ int err, rerr, i;
2709+ unsigned int mnt_flags;
2710+ aufs_bindex_t bindex, bend, br_id;
2711+ unsigned char do_wh, verbose;
2712+ struct au_branch *br;
2713+ struct au_wbr *wbr;
2714+
2715+ err = 0;
2716+ bindex = au_find_dbindex(sb->s_root, del->h_path.dentry);
2717+ if (bindex < 0) {
2718+ if (remount)
2719+ goto out; /* success */
2720+ err = -ENOENT;
4a4d8108 2721+ pr_err("%s no such branch\n", del->pathname);
1facf9fc 2722+ goto out;
2723+ }
2724+ AuDbg("bindex b%d\n", bindex);
2725+
2726+ err = -EBUSY;
2727+ mnt_flags = au_mntflags(sb);
2728+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
2729+ bend = au_sbend(sb);
2730+ if (unlikely(!bend)) {
2731+ AuVerbose(verbose, "no more branches left\n");
2732+ goto out;
2733+ }
2734+ br = au_sbr(sb, bindex);
86dc4139 2735+ AuDebugOn(!path_equal(&br->br_path, &del->h_path));
1facf9fc 2736+ i = atomic_read(&br->br_count);
2737+ if (unlikely(i)) {
2738+ AuVerbose(verbose, "%d file(s) opened\n", i);
e49829fe 2739+ goto out;
1facf9fc 2740+ }
2741+
2742+ wbr = br->br_wbr;
2743+ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
2744+ if (do_wh) {
1308ab2a 2745+ /* instead of WbrWhMustWriteLock(wbr) */
2746+ SiMustWriteLock(sb);
1facf9fc 2747+ for (i = 0; i < AuBrWh_Last; i++) {
2748+ dput(wbr->wbr_wh[i]);
2749+ wbr->wbr_wh[i] = NULL;
2750+ }
2751+ }
2752+
b752ccd1 2753+ err = test_children_busy(sb->s_root, bindex, verbose);
1facf9fc 2754+ if (unlikely(err)) {
2755+ if (do_wh)
2756+ goto out_wh;
2757+ goto out;
2758+ }
2759+
2760+ err = 0;
2761+ br_id = br->br_id;
2762+ if (!remount)
2763+ au_br_do_del(sb, bindex, br);
2764+ else {
2765+ sysaufs_brs_del(sb, bindex);
2766+ au_br_do_del(sb, bindex, br);
2767+ sysaufs_brs_add(sb, bindex);
2768+ }
2769+
1308ab2a 2770+ if (!bindex) {
1facf9fc 2771+ au_cpup_attr_all(sb->s_root->d_inode, /*force*/1);
1308ab2a 2772+ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
2773+ } else
1facf9fc 2774+ au_sub_nlink(sb->s_root->d_inode, del->h_path.dentry->d_inode);
2775+ if (au_opt_test(mnt_flags, PLINK))
2776+ au_plink_half_refresh(sb, br_id);
2777+
b752ccd1 2778+ if (au_xino_brid(sb) == br_id)
1facf9fc 2779+ au_xino_brid_set(sb, -1);
2780+ goto out; /* success */
2781+
4f0767ce 2782+out_wh:
1facf9fc 2783+ /* revert */
86dc4139 2784+ rerr = au_br_init_wh(sb, br, br->br_perm);
1facf9fc 2785+ if (rerr)
0c3ec466
AM
2786+ pr_warn("failed re-creating base whiteout, %s. (%d)\n",
2787+ del->pathname, rerr);
4f0767ce 2788+out:
1facf9fc 2789+ return err;
2790+}
2791+
2792+/* ---------------------------------------------------------------------- */
2793+
027c5e7a
AM
2794+static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg)
2795+{
2796+ int err;
2797+ aufs_bindex_t bstart, bend;
2798+ struct aufs_ibusy ibusy;
2799+ struct inode *inode, *h_inode;
2800+
2801+ err = -EPERM;
2802+ if (unlikely(!capable(CAP_SYS_ADMIN)))
2803+ goto out;
2804+
2805+ err = copy_from_user(&ibusy, arg, sizeof(ibusy));
2806+ if (!err)
2807+ err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino));
2808+ if (unlikely(err)) {
2809+ err = -EFAULT;
2810+ AuTraceErr(err);
2811+ goto out;
2812+ }
2813+
2814+ err = -EINVAL;
2815+ si_read_lock(sb, AuLock_FLUSH);
2816+ if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbend(sb)))
2817+ goto out_unlock;
2818+
2819+ err = 0;
2820+ ibusy.h_ino = 0; /* invalid */
2821+ inode = ilookup(sb, ibusy.ino);
2822+ if (!inode
2823+ || inode->i_ino == AUFS_ROOT_INO
2824+ || is_bad_inode(inode))
2825+ goto out_unlock;
2826+
2827+ ii_read_lock_child(inode);
2828+ bstart = au_ibstart(inode);
2829+ bend = au_ibend(inode);
2830+ if (bstart <= ibusy.bindex && ibusy.bindex <= bend) {
2831+ h_inode = au_h_iptr(inode, ibusy.bindex);
2832+ if (h_inode && au_test_ibusy(inode, bstart, bend))
2833+ ibusy.h_ino = h_inode->i_ino;
2834+ }
2835+ ii_read_unlock(inode);
2836+ iput(inode);
2837+
2838+out_unlock:
2839+ si_read_unlock(sb);
2840+ if (!err) {
2841+ err = __put_user(ibusy.h_ino, &arg->h_ino);
2842+ if (unlikely(err)) {
2843+ err = -EFAULT;
2844+ AuTraceErr(err);
2845+ }
2846+ }
2847+out:
2848+ return err;
2849+}
2850+
2851+long au_ibusy_ioctl(struct file *file, unsigned long arg)
2852+{
2853+ return au_ibusy(file->f_dentry->d_sb, (void __user *)arg);
2854+}
2855+
2856+#ifdef CONFIG_COMPAT
2857+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg)
2858+{
2859+ return au_ibusy(file->f_dentry->d_sb, compat_ptr(arg));
2860+}
2861+#endif
2862+
2863+/* ---------------------------------------------------------------------- */
2864+
1facf9fc 2865+/*
2866+ * change a branch permission
2867+ */
2868+
dece6358
AM
2869+static void au_warn_ima(void)
2870+{
2871+#ifdef CONFIG_IMA
1308ab2a 2872+ /* since it doesn't support mark_files_ro() */
027c5e7a 2873+ AuWarn1("RW -> RO makes IMA to produce wrong message\n");
dece6358
AM
2874+#endif
2875+}
2876+
1facf9fc 2877+static int do_need_sigen_inc(int a, int b)
2878+{
2879+ return au_br_whable(a) && !au_br_whable(b);
2880+}
2881+
2882+static int need_sigen_inc(int old, int new)
2883+{
2884+ return do_need_sigen_inc(old, new)
2885+ || do_need_sigen_inc(new, old);
2886+}
2887+
7f207e10
AM
2888+static unsigned long long au_farray_cb(void *a,
2889+ unsigned long long max __maybe_unused,
2890+ void *arg)
2891+{
2892+ unsigned long long n;
2893+ struct file **p, *f;
523b37e3
AM
2894+ struct au_sphlhead *files;
2895+ struct au_finfo *finfo;
7f207e10
AM
2896+ struct super_block *sb = arg;
2897+
2898+ n = 0;
2899+ p = a;
523b37e3
AM
2900+ files = &au_sbi(sb)->si_files;
2901+ spin_lock(&files->spin);
2902+ hlist_for_each_entry(finfo, &files->head, fi_hlist) {
2903+ f = finfo->fi_file;
2904+ if (file_count(f)
c06a8ce3 2905+ && !special_file(file_inode(f)->i_mode)) {
7f207e10
AM
2906+ get_file(f);
2907+ *p++ = f;
2908+ n++;
2909+ AuDebugOn(n > max);
2910+ }
523b37e3
AM
2911+ }
2912+ spin_unlock(&files->spin);
7f207e10
AM
2913+
2914+ return n;
2915+}
2916+
2917+static struct file **au_farray_alloc(struct super_block *sb,
2918+ unsigned long long *max)
2919+{
2920+ *max = atomic_long_read(&au_sbi(sb)->si_nfiles);
2921+ return au_array_alloc(max, au_farray_cb, sb);
2922+}
2923+
2924+static void au_farray_free(struct file **a, unsigned long long max)
2925+{
2926+ unsigned long long ull;
2927+
2928+ for (ull = 0; ull < max; ull++)
2929+ if (a[ull])
2930+ fput(a[ull]);
2931+ au_array_free(a);
2932+}
2933+
1facf9fc 2934+static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
2935+{
7f207e10 2936+ int err, do_warn;
027c5e7a 2937+ unsigned int mnt_flags;
7f207e10 2938+ unsigned long long ull, max;
e49829fe 2939+ aufs_bindex_t br_id;
027c5e7a 2940+ unsigned char verbose;
7f207e10 2941+ struct file *file, *hf, **array;
e49829fe
JR
2942+ struct inode *inode;
2943+ struct au_hfile *hfile;
1facf9fc 2944+
027c5e7a
AM
2945+ mnt_flags = au_mntflags(sb);
2946+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
2947+
7f207e10
AM
2948+ array = au_farray_alloc(sb, &max);
2949+ err = PTR_ERR(array);
2950+ if (IS_ERR(array))
1facf9fc 2951+ goto out;
2952+
7f207e10 2953+ do_warn = 0;
e49829fe 2954+ br_id = au_sbr_id(sb, bindex);
7f207e10
AM
2955+ for (ull = 0; ull < max; ull++) {
2956+ file = array[ull];
1facf9fc 2957+
523b37e3 2958+ /* AuDbg("%pD\n", file); */
1facf9fc 2959+ fi_read_lock(file);
2960+ if (unlikely(au_test_mmapped(file))) {
2961+ err = -EBUSY;
523b37e3 2962+ AuVerbose(verbose, "mmapped %pD\n", file);
7f207e10 2963+ AuDbgFile(file);
1facf9fc 2964+ FiMustNoWaiters(file);
2965+ fi_read_unlock(file);
7f207e10 2966+ goto out_array;
1facf9fc 2967+ }
2968+
c06a8ce3 2969+ inode = file_inode(file);
e49829fe
JR
2970+ hfile = &au_fi(file)->fi_htop;
2971+ hf = hfile->hf_file;
2972+ if (!S_ISREG(inode->i_mode)
1facf9fc 2973+ || !(file->f_mode & FMODE_WRITE)
e49829fe 2974+ || hfile->hf_br->br_id != br_id
7f207e10
AM
2975+ || !(hf->f_mode & FMODE_WRITE))
2976+ array[ull] = NULL;
2977+ else {
2978+ do_warn = 1;
2979+ get_file(file);
1facf9fc 2980+ }
2981+
1facf9fc 2982+ FiMustNoWaiters(file);
2983+ fi_read_unlock(file);
7f207e10
AM
2984+ fput(file);
2985+ }
1facf9fc 2986+
2987+ err = 0;
7f207e10 2988+ if (do_warn)
dece6358 2989+ au_warn_ima();
7f207e10
AM
2990+
2991+ for (ull = 0; ull < max; ull++) {
2992+ file = array[ull];
2993+ if (!file)
2994+ continue;
2995+
1facf9fc 2996+ /* todo: already flushed? */
523b37e3
AM
2997+ /*
2998+ * fs/super.c:mark_files_ro() is gone, but aufs keeps its
2999+ * approach which resets f_mode and calls mnt_drop_write() and
3000+ * file_release_write() for each file, because the branch
3001+ * attribute in aufs world is totally different from the native
3002+ * fs rw/ro mode.
3003+ */
7f207e10
AM
3004+ /* fi_read_lock(file); */
3005+ hfile = &au_fi(file)->fi_htop;
3006+ hf = hfile->hf_file;
3007+ /* fi_read_unlock(file); */
027c5e7a 3008+ spin_lock(&hf->f_lock);
1facf9fc 3009+ hf->f_mode &= ~FMODE_WRITE;
027c5e7a 3010+ spin_unlock(&hf->f_lock);
1facf9fc 3011+ if (!file_check_writeable(hf)) {
c06a8ce3 3012+ __mnt_drop_write(hf->f_path.mnt);
1facf9fc 3013+ file_release_write(hf);
1facf9fc 3014+ }
3015+ }
3016+
7f207e10
AM
3017+out_array:
3018+ au_farray_free(array, max);
4f0767ce 3019+out:
7f207e10 3020+ AuTraceErr(err);
1facf9fc 3021+ return err;
3022+}
3023+
3024+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 3025+ int *do_refresh)
1facf9fc 3026+{
3027+ int err, rerr;
3028+ aufs_bindex_t bindex;
3029+ struct dentry *root;
3030+ struct au_branch *br;
3031+
3032+ root = sb->s_root;
1facf9fc 3033+ bindex = au_find_dbindex(root, mod->h_root);
3034+ if (bindex < 0) {
3035+ if (remount)
3036+ return 0; /* success */
3037+ err = -ENOENT;
4a4d8108 3038+ pr_err("%s no such branch\n", mod->path);
1facf9fc 3039+ goto out;
3040+ }
3041+ AuDbg("bindex b%d\n", bindex);
3042+
3043+ err = test_br(mod->h_root->d_inode, mod->perm, mod->path);
3044+ if (unlikely(err))
3045+ goto out;
3046+
3047+ br = au_sbr(sb, bindex);
86dc4139 3048+ AuDebugOn(mod->h_root != au_br_dentry(br));
1facf9fc 3049+ if (br->br_perm == mod->perm)
3050+ return 0; /* success */
3051+
3052+ if (au_br_writable(br->br_perm)) {
3053+ /* remove whiteout base */
86dc4139 3054+ err = au_br_init_wh(sb, br, mod->perm);
1facf9fc 3055+ if (unlikely(err))
3056+ goto out;
3057+
3058+ if (!au_br_writable(mod->perm)) {
3059+ /* rw --> ro, file might be mmapped */
3060+ DiMustNoWaiters(root);
3061+ IiMustNoWaiters(root->d_inode);
3062+ di_write_unlock(root);
3063+ err = au_br_mod_files_ro(sb, bindex);
3064+ /* aufs_write_lock() calls ..._child() */
3065+ di_write_lock_child(root);
3066+
3067+ if (unlikely(err)) {
3068+ rerr = -ENOMEM;
3069+ br->br_wbr = kmalloc(sizeof(*br->br_wbr),
3070+ GFP_NOFS);
86dc4139
AM
3071+ if (br->br_wbr)
3072+ rerr = au_wbr_init(br, sb, br->br_perm);
1facf9fc 3073+ if (unlikely(rerr)) {
3074+ AuIOErr("nested error %d (%d)\n",
3075+ rerr, err);
3076+ br->br_perm = mod->perm;
3077+ }
3078+ }
3079+ }
3080+ } else if (au_br_writable(mod->perm)) {
3081+ /* ro --> rw */
3082+ err = -ENOMEM;
3083+ br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS);
3084+ if (br->br_wbr) {
86dc4139 3085+ err = au_wbr_init(br, sb, mod->perm);
1facf9fc 3086+ if (unlikely(err)) {
3087+ kfree(br->br_wbr);
3088+ br->br_wbr = NULL;
3089+ }
3090+ }
3091+ }
3092+
3093+ if (!err) {
86dc4139
AM
3094+ if ((br->br_perm & AuBrAttr_UNPIN)
3095+ && !(mod->perm & AuBrAttr_UNPIN))
3096+ au_br_dflags_force(br);
3097+ else if (!(br->br_perm & AuBrAttr_UNPIN)
3098+ && (mod->perm & AuBrAttr_UNPIN))
3099+ au_br_dflags_restore(br);
7f207e10 3100+ *do_refresh |= need_sigen_inc(br->br_perm, mod->perm);
1facf9fc 3101+ br->br_perm = mod->perm;
3102+ }
3103+
4f0767ce 3104+out:
7f207e10 3105+ AuTraceErr(err);
1facf9fc 3106+ return err;
3107+}
7f207e10
AM
3108diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
3109--- /usr/share/empty/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
3110+++ linux/fs/aufs/branch.h 2014-01-20 20:16:14.732796615 +0100
3111@@ -0,0 +1,264 @@
1facf9fc 3112+/*
523b37e3 3113+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 3114+ *
3115+ * This program, aufs is free software; you can redistribute it and/or modify
3116+ * it under the terms of the GNU General Public License as published by
3117+ * the Free Software Foundation; either version 2 of the License, or
3118+ * (at your option) any later version.
dece6358
AM
3119+ *
3120+ * This program is distributed in the hope that it will be useful,
3121+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3122+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3123+ * GNU General Public License for more details.
3124+ *
3125+ * You should have received a copy of the GNU General Public License
523b37e3 3126+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 3127+ */
3128+
3129+/*
3130+ * branch filesystems and xino for them
3131+ */
3132+
3133+#ifndef __AUFS_BRANCH_H__
3134+#define __AUFS_BRANCH_H__
3135+
3136+#ifdef __KERNEL__
3137+
1facf9fc 3138+#include <linux/mount.h>
4a4d8108 3139+#include "dynop.h"
1facf9fc 3140+#include "rwsem.h"
3141+#include "super.h"
3142+
3143+/* ---------------------------------------------------------------------- */
3144+
3145+/* a xino file */
3146+struct au_xino_file {
3147+ struct file *xi_file;
3148+ struct mutex xi_nondir_mtx;
3149+
3150+ /* todo: make xino files an array to support huge inode number */
3151+
3152+#ifdef CONFIG_DEBUG_FS
3153+ struct dentry *xi_dbgaufs;
3154+#endif
3155+};
3156+
3157+/* members for writable branch only */
3158+enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
3159+struct au_wbr {
dece6358 3160+ struct au_rwsem wbr_wh_rwsem;
1facf9fc 3161+ struct dentry *wbr_wh[AuBrWh_Last];
4a4d8108 3162+ atomic_t wbr_wh_running;
1facf9fc 3163+#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
3164+#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
3165+#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
3166+
3167+ /* mfs mode */
3168+ unsigned long long wbr_bytes;
3169+};
3170+
4a4d8108
AM
3171+/* ext2 has 3 types of operations at least, ext3 has 4 */
3172+#define AuBrDynOp (AuDyLast * 4)
3173+
1716fcea
AM
3174+#ifdef CONFIG_AUFS_HFSNOTIFY
3175+/* support for asynchronous destruction */
3176+struct au_br_hfsnotify {
3177+ struct fsnotify_group *hfsn_group;
3178+};
3179+#endif
3180+
392086de
AM
3181+/* sysfs entries */
3182+struct au_brsysfs {
3183+ char name[16];
3184+ struct attribute attr;
3185+};
3186+
3187+enum {
3188+ AuBrSysfs_BR,
3189+ AuBrSysfs_BRID,
3190+ AuBrSysfs_Last
3191+};
3192+
1facf9fc 3193+/* protected by superblock rwsem */
3194+struct au_branch {
3195+ struct au_xino_file br_xino;
3196+
3197+ aufs_bindex_t br_id;
3198+
3199+ int br_perm;
86dc4139
AM
3200+ unsigned int br_dflags;
3201+ struct path br_path;
4a4d8108
AM
3202+ spinlock_t br_dykey_lock;
3203+ struct au_dykey *br_dykey[AuBrDynOp];
1facf9fc 3204+ atomic_t br_count;
3205+
3206+ struct au_wbr *br_wbr;
3207+
3208+ /* xino truncation */
1facf9fc 3209+ atomic_t br_xino_running;
3210+
027c5e7a 3211+#ifdef CONFIG_AUFS_HFSNOTIFY
1716fcea 3212+ struct au_br_hfsnotify *br_hfsn;
027c5e7a
AM
3213+#endif
3214+
1facf9fc 3215+#ifdef CONFIG_SYSFS
392086de
AM
3216+ /* entries under sysfs per mount-point */
3217+ struct au_brsysfs br_sysfs[AuBrSysfs_Last];
1facf9fc 3218+#endif
3219+};
3220+
3221+/* ---------------------------------------------------------------------- */
3222+
86dc4139
AM
3223+static inline struct vfsmount *au_br_mnt(struct au_branch *br)
3224+{
3225+ return br->br_path.mnt;
3226+}
3227+
3228+static inline struct dentry *au_br_dentry(struct au_branch *br)
3229+{
3230+ return br->br_path.dentry;
3231+}
3232+
3233+static inline struct super_block *au_br_sb(struct au_branch *br)
3234+{
3235+ return au_br_mnt(br)->mnt_sb;
3236+}
3237+
1e00d052
AM
3238+/* branch permissions and attributes */
3239+#define AuBrPerm_RW 1 /* writable, hardlinkable wh */
3240+#define AuBrPerm_RO (1 << 1) /* readonly */
3241+#define AuBrPerm_RR (1 << 2) /* natively readonly */
3242+#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
1facf9fc 3243+
1e00d052 3244+#define AuBrRAttr_WH (1 << 3) /* whiteout-able */
1facf9fc 3245+
1e00d052 3246+#define AuBrWAttr_NoLinkWH (1 << 4) /* un-hardlinkable whiteouts */
1facf9fc 3247+
86dc4139
AM
3248+#define AuBrAttr_UNPIN (1 << 5) /* rename-able top dir of
3249+ branch */
3250+
1facf9fc 3251+static inline int au_br_writable(int brperm)
3252+{
1e00d052 3253+ return brperm & AuBrPerm_RW;
1facf9fc 3254+}
3255+
3256+static inline int au_br_whable(int brperm)
3257+{
1e00d052
AM
3258+ return brperm & (AuBrPerm_RW | AuBrRAttr_WH);
3259+}
3260+
3261+static inline int au_br_wh_linkable(int brperm)
3262+{
3263+ return !(brperm & AuBrWAttr_NoLinkWH);
1facf9fc 3264+}
3265+
3266+static inline int au_br_rdonly(struct au_branch *br)
3267+{
86dc4139 3268+ return ((au_br_sb(br)->s_flags & MS_RDONLY)
1facf9fc 3269+ || !au_br_writable(br->br_perm))
3270+ ? -EROFS : 0;
3271+}
3272+
4a4d8108 3273+static inline int au_br_hnotifyable(int brperm __maybe_unused)
1facf9fc 3274+{
4a4d8108 3275+#ifdef CONFIG_AUFS_HNOTIFY
1e00d052 3276+ return !(brperm & AuBrPerm_RR);
1facf9fc 3277+#else
3278+ return 0;
3279+#endif
3280+}
3281+
3282+/* ---------------------------------------------------------------------- */
3283+
3284+/* branch.c */
3285+struct au_sbinfo;
3286+void au_br_free(struct au_sbinfo *sinfo);
3287+int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
3288+struct au_opt_add;
3289+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
3290+struct au_opt_del;
3291+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
027c5e7a
AM
3292+long au_ibusy_ioctl(struct file *file, unsigned long arg);
3293+#ifdef CONFIG_COMPAT
3294+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
3295+#endif
1facf9fc 3296+struct au_opt_mod;
3297+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 3298+ int *do_refresh);
1facf9fc 3299+
3300+/* xino.c */
3301+static const loff_t au_loff_max = LLONG_MAX;
3302+
3303+int au_xib_trunc(struct super_block *sb);
3304+ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size,
3305+ loff_t *pos);
3306+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
3307+ loff_t *pos);
3308+struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
3309+struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
3310+ino_t au_xino_new_ino(struct super_block *sb);
b752ccd1 3311+void au_xino_delete_inode(struct inode *inode, const int unlinked);
1facf9fc 3312+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
3313+ ino_t ino);
3314+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
3315+ ino_t *ino);
3316+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
3317+ struct file *base_file, int do_test);
3318+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
3319+
3320+struct au_opt_xino;
3321+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
3322+void au_xino_clr(struct super_block *sb);
3323+struct file *au_xino_def(struct super_block *sb);
3324+int au_xino_path(struct seq_file *seq, struct file *file);
3325+
3326+/* ---------------------------------------------------------------------- */
3327+
3328+/* Superblock to branch */
3329+static inline
3330+aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
3331+{
3332+ return au_sbr(sb, bindex)->br_id;
3333+}
3334+
3335+static inline
3336+struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
3337+{
86dc4139 3338+ return au_br_mnt(au_sbr(sb, bindex));
1facf9fc 3339+}
3340+
3341+static inline
3342+struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
3343+{
86dc4139 3344+ return au_br_sb(au_sbr(sb, bindex));
1facf9fc 3345+}
3346+
3347+static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
3348+{
e49829fe 3349+ atomic_dec(&au_sbr(sb, bindex)->br_count);
1facf9fc 3350+}
3351+
3352+static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
3353+{
3354+ return au_sbr(sb, bindex)->br_perm;
3355+}
3356+
3357+static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
3358+{
3359+ return au_br_whable(au_sbr_perm(sb, bindex));
3360+}
3361+
3362+/* ---------------------------------------------------------------------- */
3363+
3364+/*
3365+ * wbr_wh_read_lock, wbr_wh_write_lock
3366+ * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
3367+ */
3368+AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
3369+
dece6358
AM
3370+#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
3371+#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
3372+#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
3373+
1facf9fc 3374+#endif /* __KERNEL__ */
3375+#endif /* __AUFS_BRANCH_H__ */
7f207e10
AM
3376diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
3377--- /usr/share/empty/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
3378+++ linux/fs/aufs/conf.mk 2014-01-20 20:16:14.732796615 +0100
3379@@ -0,0 +1,37 @@
4a4d8108
AM
3380+
3381+AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
3382+
3383+define AuConf
3384+ifdef ${1}
3385+AuConfStr += ${1}=${${1}}
3386+endif
3387+endef
3388+
b752ccd1 3389+AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
e49829fe 3390+ SBILIST \
7f207e10 3391+ HNOTIFY HFSNOTIFY \
4a4d8108
AM
3392+ EXPORT INO_T_64 \
3393+ RDU \
3394+ SP_IATTR \
3395+ SHWH \
3396+ BR_RAMFS \
3397+ BR_FUSE POLL \
3398+ BR_HFSPLUS \
3399+ BDEV_LOOP \
b752ccd1
AM
3400+ DEBUG MAGIC_SYSRQ
3401+$(foreach i, ${AuConfAll}, \
4a4d8108
AM
3402+ $(eval $(call AuConf,CONFIG_AUFS_${i})))
3403+
3404+AuConfName = ${obj}/conf.str
3405+${AuConfName}.tmp: FORCE
3406+ @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
3407+${AuConfName}: ${AuConfName}.tmp
3408+ @diff -q $< $@ > /dev/null 2>&1 || { \
3409+ echo ' GEN ' $@; \
3410+ cp -p $< $@; \
3411+ }
3412+FORCE:
3413+clean-files += ${AuConfName} ${AuConfName}.tmp
3414+${obj}/sysfs.o: ${AuConfName}
b752ccd1
AM
3415+
3416+-include ${srctree}/${src}/conf_priv.mk
7f207e10
AM
3417diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
3418--- /usr/share/empty/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
3419+++ linux/fs/aufs/cpup.c 2014-01-20 20:16:14.732796615 +0100
3420@@ -0,0 +1,1277 @@
1facf9fc 3421+/*
523b37e3 3422+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 3423+ *
3424+ * This program, aufs is free software; you can redistribute it and/or modify
3425+ * it under the terms of the GNU General Public License as published by
3426+ * the Free Software Foundation; either version 2 of the License, or
3427+ * (at your option) any later version.
dece6358
AM
3428+ *
3429+ * This program is distributed in the hope that it will be useful,
3430+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3431+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3432+ * GNU General Public License for more details.
3433+ *
3434+ * You should have received a copy of the GNU General Public License
523b37e3 3435+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 3436+ */
3437+
3438+/*
3439+ * copy-up functions, see wbr_policy.c for copy-down
3440+ */
3441+
3442+#include <linux/fs_stack.h>
dece6358 3443+#include <linux/mm.h>
1facf9fc 3444+#include "aufs.h"
3445+
86dc4139 3446+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags)
1facf9fc 3447+{
3448+ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
367653fa 3449+ | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT;
1facf9fc 3450+
86dc4139
AM
3451+ BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags));
3452+
3453+ dst->i_flags |= iflags & ~mask;
1facf9fc 3454+ if (au_test_fs_notime(dst->i_sb))
3455+ dst->i_flags |= S_NOATIME | S_NOCMTIME;
3456+}
3457+
3458+void au_cpup_attr_timesizes(struct inode *inode)
3459+{
3460+ struct inode *h_inode;
3461+
3462+ h_inode = au_h_iptr(inode, au_ibstart(inode));
3463+ fsstack_copy_attr_times(inode, h_inode);
4a4d8108 3464+ fsstack_copy_inode_size(inode, h_inode);
1facf9fc 3465+}
3466+
3467+void au_cpup_attr_nlink(struct inode *inode, int force)
3468+{
3469+ struct inode *h_inode;
3470+ struct super_block *sb;
3471+ aufs_bindex_t bindex, bend;
3472+
3473+ sb = inode->i_sb;
3474+ bindex = au_ibstart(inode);
3475+ h_inode = au_h_iptr(inode, bindex);
3476+ if (!force
3477+ && !S_ISDIR(h_inode->i_mode)
3478+ && au_opt_test(au_mntflags(sb), PLINK)
3479+ && au_plink_test(inode))
3480+ return;
3481+
7eafdf33
AM
3482+ /*
3483+ * 0 can happen in revalidating.
3484+ * h_inode->i_mutex is not held, but it is harmless since once i_nlink
3485+ * reaches 0, it will never become positive.
3486+ */
92d182d2 3487+ set_nlink(inode, h_inode->i_nlink);
1facf9fc 3488+
3489+ /*
3490+ * fewer nlink makes find(1) noisy, but larger nlink doesn't.
3491+ * it may includes whplink directory.
3492+ */
3493+ if (S_ISDIR(h_inode->i_mode)) {
3494+ bend = au_ibend(inode);
3495+ for (bindex++; bindex <= bend; bindex++) {
3496+ h_inode = au_h_iptr(inode, bindex);
3497+ if (h_inode)
3498+ au_add_nlink(inode, h_inode);
3499+ }
3500+ }
3501+}
3502+
3503+void au_cpup_attr_changeable(struct inode *inode)
3504+{
3505+ struct inode *h_inode;
3506+
3507+ h_inode = au_h_iptr(inode, au_ibstart(inode));
3508+ inode->i_mode = h_inode->i_mode;
3509+ inode->i_uid = h_inode->i_uid;
3510+ inode->i_gid = h_inode->i_gid;
3511+ au_cpup_attr_timesizes(inode);
86dc4139 3512+ au_cpup_attr_flags(inode, h_inode->i_flags);
1facf9fc 3513+}
3514+
3515+void au_cpup_igen(struct inode *inode, struct inode *h_inode)
3516+{
3517+ struct au_iinfo *iinfo = au_ii(inode);
3518+
1308ab2a 3519+ IiMustWriteLock(inode);
3520+
1facf9fc 3521+ iinfo->ii_higen = h_inode->i_generation;
3522+ iinfo->ii_hsb1 = h_inode->i_sb;
3523+}
3524+
3525+void au_cpup_attr_all(struct inode *inode, int force)
3526+{
3527+ struct inode *h_inode;
3528+
3529+ h_inode = au_h_iptr(inode, au_ibstart(inode));
3530+ au_cpup_attr_changeable(inode);
3531+ if (inode->i_nlink > 0)
3532+ au_cpup_attr_nlink(inode, force);
3533+ inode->i_rdev = h_inode->i_rdev;
3534+ inode->i_blkbits = h_inode->i_blkbits;
3535+ au_cpup_igen(inode, h_inode);
3536+}
3537+
3538+/* ---------------------------------------------------------------------- */
3539+
3540+/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
3541+
3542+/* keep the timestamps of the parent dir when cpup */
3543+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
3544+ struct path *h_path)
3545+{
3546+ struct inode *h_inode;
3547+
3548+ dt->dt_dentry = dentry;
3549+ dt->dt_h_path = *h_path;
3550+ h_inode = h_path->dentry->d_inode;
3551+ dt->dt_atime = h_inode->i_atime;
3552+ dt->dt_mtime = h_inode->i_mtime;
3553+ /* smp_mb(); */
3554+}
3555+
3556+void au_dtime_revert(struct au_dtime *dt)
3557+{
3558+ struct iattr attr;
3559+ int err;
3560+
3561+ attr.ia_atime = dt->dt_atime;
3562+ attr.ia_mtime = dt->dt_mtime;
3563+ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
3564+ | ATTR_ATIME | ATTR_ATIME_SET;
3565+
523b37e3
AM
3566+ /* no delegation since this is a directory */
3567+ err = vfsub_notify_change(&dt->dt_h_path, &attr, /*delegated*/NULL);
1facf9fc 3568+ if (unlikely(err))
0c3ec466 3569+ pr_warn("restoring timestamps failed(%d). ignored\n", err);
1facf9fc 3570+}
3571+
3572+/* ---------------------------------------------------------------------- */
3573+
86dc4139
AM
3574+/* internal use only */
3575+struct au_cpup_reg_attr {
3576+ int valid;
3577+ struct kstat st;
3578+ unsigned int iflags; /* inode->i_flags */
3579+};
3580+
1facf9fc 3581+static noinline_for_stack
86dc4139
AM
3582+int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src,
3583+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 3584+{
3585+ int err, sbits;
3586+ struct iattr ia;
3587+ struct path h_path;
1308ab2a 3588+ struct inode *h_isrc, *h_idst;
86dc4139 3589+ struct kstat *h_st;
1facf9fc 3590+
3591+ h_path.dentry = au_h_dptr(dst, bindex);
1308ab2a 3592+ h_idst = h_path.dentry->d_inode;
1facf9fc 3593+ h_path.mnt = au_sbr_mnt(dst->d_sb, bindex);
3594+ h_isrc = h_src->d_inode;
1308ab2a 3595+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
1facf9fc 3596+ | ATTR_ATIME | ATTR_MTIME
3597+ | ATTR_ATIME_SET | ATTR_MTIME_SET;
86dc4139
AM
3598+ if (h_src_attr && h_src_attr->valid) {
3599+ h_st = &h_src_attr->st;
3600+ ia.ia_uid = h_st->uid;
3601+ ia.ia_gid = h_st->gid;
3602+ ia.ia_atime = h_st->atime;
3603+ ia.ia_mtime = h_st->mtime;
3604+ if (h_idst->i_mode != h_st->mode
3605+ && !S_ISLNK(h_idst->i_mode)) {
3606+ ia.ia_valid |= ATTR_MODE;
3607+ ia.ia_mode = h_st->mode;
3608+ }
3609+ sbits = !!(h_st->mode & (S_ISUID | S_ISGID));
3610+ au_cpup_attr_flags(h_idst, h_src_attr->iflags);
3611+ } else {
3612+ ia.ia_uid = h_isrc->i_uid;
3613+ ia.ia_gid = h_isrc->i_gid;
3614+ ia.ia_atime = h_isrc->i_atime;
3615+ ia.ia_mtime = h_isrc->i_mtime;
3616+ if (h_idst->i_mode != h_isrc->i_mode
3617+ && !S_ISLNK(h_idst->i_mode)) {
3618+ ia.ia_valid |= ATTR_MODE;
3619+ ia.ia_mode = h_isrc->i_mode;
3620+ }
3621+ sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
3622+ au_cpup_attr_flags(h_idst, h_isrc->i_flags);
1308ab2a 3623+ }
523b37e3
AM
3624+ /* no delegation since it is just created */
3625+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 3626+
3627+ /* is this nfs only? */
3628+ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
3629+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
3630+ ia.ia_mode = h_isrc->i_mode;
523b37e3 3631+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 3632+ }
3633+
3634+ return err;
3635+}
3636+
3637+/* ---------------------------------------------------------------------- */
3638+
3639+static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
3640+ char *buf, unsigned long blksize)
3641+{
3642+ int err;
3643+ size_t sz, rbytes, wbytes;
3644+ unsigned char all_zero;
3645+ char *p, *zp;
3646+ struct mutex *h_mtx;
3647+ /* reduce stack usage */
3648+ struct iattr *ia;
3649+
3650+ zp = page_address(ZERO_PAGE(0));
3651+ if (unlikely(!zp))
3652+ return -ENOMEM; /* possible? */
3653+
3654+ err = 0;
3655+ all_zero = 0;
3656+ while (len) {
3657+ AuDbg("len %lld\n", len);
3658+ sz = blksize;
3659+ if (len < blksize)
3660+ sz = len;
3661+
3662+ rbytes = 0;
3663+ /* todo: signal_pending? */
3664+ while (!rbytes || err == -EAGAIN || err == -EINTR) {
3665+ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
3666+ err = rbytes;
3667+ }
3668+ if (unlikely(err < 0))
3669+ break;
3670+
3671+ all_zero = 0;
3672+ if (len >= rbytes && rbytes == blksize)
3673+ all_zero = !memcmp(buf, zp, rbytes);
3674+ if (!all_zero) {
3675+ wbytes = rbytes;
3676+ p = buf;
3677+ while (wbytes) {
3678+ size_t b;
3679+
3680+ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
3681+ err = b;
3682+ /* todo: signal_pending? */
3683+ if (unlikely(err == -EAGAIN || err == -EINTR))
3684+ continue;
3685+ if (unlikely(err < 0))
3686+ break;
3687+ wbytes -= b;
3688+ p += b;
3689+ }
392086de
AM
3690+ if (unlikely(err < 0))
3691+ break;
1facf9fc 3692+ } else {
3693+ loff_t res;
3694+
3695+ AuLabel(hole);
3696+ res = vfsub_llseek(dst, rbytes, SEEK_CUR);
3697+ err = res;
3698+ if (unlikely(res < 0))
3699+ break;
3700+ }
3701+ len -= rbytes;
3702+ err = 0;
3703+ }
3704+
3705+ /* the last block may be a hole */
3706+ if (!err && all_zero) {
3707+ AuLabel(last hole);
3708+
3709+ err = 1;
3710+ if (au_test_nfs(dst->f_dentry->d_sb)) {
3711+ /* nfs requires this step to make last hole */
3712+ /* is this only nfs? */
3713+ do {
3714+ /* todo: signal_pending? */
3715+ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
3716+ } while (err == -EAGAIN || err == -EINTR);
3717+ if (err == 1)
3718+ dst->f_pos--;
3719+ }
3720+
3721+ if (err == 1) {
3722+ ia = (void *)buf;
3723+ ia->ia_size = dst->f_pos;
3724+ ia->ia_valid = ATTR_SIZE | ATTR_FILE;
3725+ ia->ia_file = dst;
c06a8ce3 3726+ h_mtx = &file_inode(dst)->i_mutex;
1facf9fc 3727+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
523b37e3
AM
3728+ /* no delegation since it is just created */
3729+ err = vfsub_notify_change(&dst->f_path, ia,
3730+ /*delegated*/NULL);
1facf9fc 3731+ mutex_unlock(h_mtx);
3732+ }
3733+ }
3734+
3735+ return err;
3736+}
3737+
3738+int au_copy_file(struct file *dst, struct file *src, loff_t len)
3739+{
3740+ int err;
3741+ unsigned long blksize;
3742+ unsigned char do_kfree;
3743+ char *buf;
3744+
3745+ err = -ENOMEM;
3746+ blksize = dst->f_dentry->d_sb->s_blocksize;
3747+ if (!blksize || PAGE_SIZE < blksize)
3748+ blksize = PAGE_SIZE;
3749+ AuDbg("blksize %lu\n", blksize);
3750+ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
3751+ if (do_kfree)
3752+ buf = kmalloc(blksize, GFP_NOFS);
3753+ else
3754+ buf = (void *)__get_free_page(GFP_NOFS);
3755+ if (unlikely(!buf))
3756+ goto out;
3757+
3758+ if (len > (1 << 22))
3759+ AuDbg("copying a large file %lld\n", (long long)len);
3760+
3761+ src->f_pos = 0;
3762+ dst->f_pos = 0;
3763+ err = au_do_copy_file(dst, src, len, buf, blksize);
3764+ if (do_kfree)
3765+ kfree(buf);
3766+ else
3767+ free_page((unsigned long)buf);
3768+
4f0767ce 3769+out:
1facf9fc 3770+ return err;
3771+}
3772+
3773+/*
3774+ * to support a sparse file which is opened with O_APPEND,
3775+ * we need to close the file.
3776+ */
c2b27bf2 3777+static int au_cp_regular(struct au_cp_generic *cpg)
1facf9fc 3778+{
3779+ int err, i;
3780+ enum { SRC, DST };
3781+ struct {
3782+ aufs_bindex_t bindex;
3783+ unsigned int flags;
3784+ struct dentry *dentry;
392086de 3785+ int force_wr;
1facf9fc 3786+ struct file *file;
523b37e3 3787+ void *label;
1facf9fc 3788+ } *f, file[] = {
3789+ {
c2b27bf2 3790+ .bindex = cpg->bsrc,
1facf9fc 3791+ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
523b37e3 3792+ .label = &&out
1facf9fc 3793+ },
3794+ {
c2b27bf2 3795+ .bindex = cpg->bdst,
1facf9fc 3796+ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
392086de 3797+ .force_wr = !!au_ftest_cpup(cpg->flags, RWDST),
523b37e3 3798+ .label = &&out_src
1facf9fc 3799+ }
3800+ };
3801+ struct super_block *sb;
3802+
3803+ /* bsrc branch can be ro/rw. */
c2b27bf2 3804+ sb = cpg->dentry->d_sb;
1facf9fc 3805+ f = file;
3806+ for (i = 0; i < 2; i++, f++) {
c2b27bf2
AM
3807+ f->dentry = au_h_dptr(cpg->dentry, f->bindex);
3808+ f->file = au_h_open(cpg->dentry, f->bindex, f->flags,
392086de 3809+ /*file*/NULL, f->force_wr);
1facf9fc 3810+ err = PTR_ERR(f->file);
3811+ if (IS_ERR(f->file))
3812+ goto *f->label;
1facf9fc 3813+ }
3814+
3815+ /* try stopping to update while we copyup */
3816+ IMustLock(file[SRC].dentry->d_inode);
c2b27bf2 3817+ err = au_copy_file(file[DST].file, file[SRC].file, cpg->len);
1facf9fc 3818+
1facf9fc 3819+ fput(file[DST].file);
3820+ au_sbr_put(sb, file[DST].bindex);
523b37e3 3821+
4f0767ce 3822+out_src:
1facf9fc 3823+ fput(file[SRC].file);
3824+ au_sbr_put(sb, file[SRC].bindex);
4f0767ce 3825+out:
1facf9fc 3826+ return err;
3827+}
3828+
c2b27bf2 3829+static int au_do_cpup_regular(struct au_cp_generic *cpg,
86dc4139 3830+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 3831+{
3832+ int err, rerr;
3833+ loff_t l;
86dc4139
AM
3834+ struct path h_path;
3835+ struct inode *h_src_inode;
1facf9fc 3836+
3837+ err = 0;
c2b27bf2 3838+ h_src_inode = au_h_iptr(cpg->dentry->d_inode, cpg->bsrc);
86dc4139 3839+ l = i_size_read(h_src_inode);
c2b27bf2
AM
3840+ if (cpg->len == -1 || l < cpg->len)
3841+ cpg->len = l;
3842+ if (cpg->len) {
86dc4139
AM
3843+ /* try stopping to update while we are referencing */
3844+ mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD);
c2b27bf2 3845+ au_pin_hdir_unlock(cpg->pin);
1facf9fc 3846+
c2b27bf2
AM
3847+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
3848+ h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc);
86dc4139
AM
3849+ h_src_attr->iflags = h_src_inode->i_flags;
3850+ err = vfs_getattr(&h_path, &h_src_attr->st);
3851+ if (unlikely(err)) {
3852+ mutex_unlock(&h_src_inode->i_mutex);
3853+ goto out;
3854+ }
3855+ h_src_attr->valid = 1;
c2b27bf2 3856+ err = au_cp_regular(cpg);
86dc4139 3857+ mutex_unlock(&h_src_inode->i_mutex);
c2b27bf2 3858+ rerr = au_pin_hdir_relock(cpg->pin);
86dc4139
AM
3859+ if (!err && rerr)
3860+ err = rerr;
1facf9fc 3861+ }
3862+
4f0767ce 3863+out:
1facf9fc 3864+ return err;
3865+}
3866+
3867+static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
3868+ struct inode *h_dir)
3869+{
3870+ int err, symlen;
3871+ mm_segment_t old_fs;
b752ccd1
AM
3872+ union {
3873+ char *k;
3874+ char __user *u;
3875+ } sym;
1facf9fc 3876+
3877+ err = -ENOSYS;
3878+ if (unlikely(!h_src->d_inode->i_op->readlink))
3879+ goto out;
3880+
3881+ err = -ENOMEM;
537831f9 3882+ sym.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 3883+ if (unlikely(!sym.k))
1facf9fc 3884+ goto out;
3885+
9dbd164d 3886+ /* unnecessary to support mmap_sem since symlink is not mmap-able */
1facf9fc 3887+ old_fs = get_fs();
3888+ set_fs(KERNEL_DS);
b752ccd1 3889+ symlen = h_src->d_inode->i_op->readlink(h_src, sym.u, PATH_MAX);
1facf9fc 3890+ err = symlen;
3891+ set_fs(old_fs);
3892+
3893+ if (symlen > 0) {
b752ccd1
AM
3894+ sym.k[symlen] = 0;
3895+ err = vfsub_symlink(h_dir, h_path, sym.k);
1facf9fc 3896+ }
537831f9 3897+ free_page((unsigned long)sym.k);
1facf9fc 3898+
4f0767ce 3899+out:
1facf9fc 3900+ return err;
3901+}
3902+
1facf9fc 3903+static noinline_for_stack
c2b27bf2 3904+int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent,
86dc4139 3905+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 3906+{
3907+ int err;
3908+ umode_t mode;
3909+ unsigned int mnt_flags;
3910+ unsigned char isdir;
c2b27bf2 3911+ const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 3912+ struct au_dtime dt;
3913+ struct path h_path;
3914+ struct dentry *h_src, *h_dst, *h_parent;
3915+ struct inode *h_inode, *h_dir;
3916+ struct super_block *sb;
3917+
3918+ /* bsrc branch can be ro/rw. */
c2b27bf2 3919+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
1facf9fc 3920+ h_inode = h_src->d_inode;
c2b27bf2 3921+ AuDebugOn(h_inode != au_h_iptr(cpg->dentry->d_inode, cpg->bsrc));
1facf9fc 3922+
3923+ /* try stopping to be referenced while we are creating */
c2b27bf2
AM
3924+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
3925+ if (au_ftest_cpup(cpg->flags, RENAME))
86dc4139
AM
3926+ AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX,
3927+ AUFS_WH_PFX_LEN));
1facf9fc 3928+ h_parent = h_dst->d_parent; /* dir inode is locked */
3929+ h_dir = h_parent->d_inode;
3930+ IMustLock(h_dir);
3931+ AuDebugOn(h_parent != h_dst->d_parent);
3932+
c2b27bf2
AM
3933+ sb = cpg->dentry->d_sb;
3934+ h_path.mnt = au_sbr_mnt(sb, cpg->bdst);
1facf9fc 3935+ if (do_dt) {
3936+ h_path.dentry = h_parent;
3937+ au_dtime_store(&dt, dst_parent, &h_path);
3938+ }
3939+ h_path.dentry = h_dst;
3940+
3941+ isdir = 0;
3942+ mode = h_inode->i_mode;
3943+ switch (mode & S_IFMT) {
3944+ case S_IFREG:
b4510431
AM
3945+ err = vfsub_create(h_dir, &h_path, mode | S_IWUSR,
3946+ /*want_excl*/true);
1facf9fc 3947+ if (!err)
c2b27bf2 3948+ err = au_do_cpup_regular(cpg, h_src_attr);
1facf9fc 3949+ break;
3950+ case S_IFDIR:
3951+ isdir = 1;
3952+ err = vfsub_mkdir(h_dir, &h_path, mode);
3953+ if (!err) {
3954+ /*
3955+ * strange behaviour from the users view,
3956+ * particularry setattr case
3957+ */
c2b27bf2 3958+ if (au_ibstart(dst_parent->d_inode) == cpg->bdst)
1facf9fc 3959+ au_cpup_attr_nlink(dst_parent->d_inode,
3960+ /*force*/1);
c2b27bf2 3961+ au_cpup_attr_nlink(cpg->dentry->d_inode, /*force*/1);
1facf9fc 3962+ }
3963+ break;
3964+ case S_IFLNK:
3965+ err = au_do_cpup_symlink(&h_path, h_src, h_dir);
3966+ break;
3967+ case S_IFCHR:
3968+ case S_IFBLK:
3969+ AuDebugOn(!capable(CAP_MKNOD));
3970+ /*FALLTHROUGH*/
3971+ case S_IFIFO:
3972+ case S_IFSOCK:
3973+ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
3974+ break;
3975+ default:
3976+ AuIOErr("Unknown inode type 0%o\n", mode);
3977+ err = -EIO;
3978+ }
3979+
3980+ mnt_flags = au_mntflags(sb);
3981+ if (!au_opt_test(mnt_flags, UDBA_NONE)
3982+ && !isdir
3983+ && au_opt_test(mnt_flags, XINO)
3984+ && h_inode->i_nlink == 1
3985+ /* todo: unnecessary? */
c2b27bf2
AM
3986+ /* && cpg->dentry->d_inode->i_nlink == 1 */
3987+ && cpg->bdst < cpg->bsrc
3988+ && !au_ftest_cpup(cpg->flags, KEEPLINO))
3989+ au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0);
1facf9fc 3990+ /* ignore this error */
3991+
3992+ if (do_dt)
3993+ au_dtime_revert(&dt);
3994+ return err;
3995+}
3996+
392086de 3997+static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path)
86dc4139
AM
3998+{
3999+ int err;
392086de 4000+ struct dentry *dentry, *h_dentry, *h_parent, *parent;
86dc4139 4001+ struct inode *h_dir;
392086de 4002+ aufs_bindex_t bdst;
86dc4139 4003+
392086de
AM
4004+ dentry = cpg->dentry;
4005+ bdst = cpg->bdst;
4006+ h_dentry = au_h_dptr(dentry, bdst);
4007+ if (!au_ftest_cpup(cpg->flags, OVERWRITE)) {
4008+ dget(h_dentry);
4009+ au_set_h_dptr(dentry, bdst, NULL);
4010+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
4011+ if (!err)
4012+ h_path->dentry = dget(au_h_dptr(dentry, bdst));
86dc4139 4013+ au_set_h_dptr(dentry, bdst, h_dentry);
392086de
AM
4014+ } else {
4015+ err = 0;
4016+ parent = dget_parent(dentry);
4017+ h_parent = au_h_dptr(parent, bdst);
4018+ dput(parent);
4019+ h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
4020+ if (IS_ERR(h_path->dentry))
4021+ err = PTR_ERR(h_path->dentry);
86dc4139 4022+ }
392086de
AM
4023+ if (unlikely(err))
4024+ goto out;
86dc4139 4025+
86dc4139
AM
4026+ h_parent = h_dentry->d_parent; /* dir inode is locked */
4027+ h_dir = h_parent->d_inode;
4028+ IMustLock(h_dir);
523b37e3
AM
4029+ AuDbg("%pd %pd\n", h_dentry, h_path->dentry);
4030+ /* no delegation since it is just created */
4031+ err = vfsub_rename(h_dir, h_dentry, h_dir, h_path, /*delegated*/NULL);
86dc4139
AM
4032+ dput(h_path->dentry);
4033+
4034+out:
4035+ return err;
4036+}
4037+
1facf9fc 4038+/*
4039+ * copyup the @dentry from @bsrc to @bdst.
4040+ * the caller must set the both of lower dentries.
4041+ * @len is for truncating when it is -1 copyup the entire file.
4042+ * in link/rename cases, @dst_parent may be different from the real one.
c2b27bf2 4043+ * basic->bsrc can be larger than basic->bdst.
1facf9fc 4044+ */
c2b27bf2 4045+static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 4046+{
4047+ int err, rerr;
4048+ aufs_bindex_t old_ibstart;
4049+ unsigned char isdir, plink;
1facf9fc 4050+ struct dentry *h_src, *h_dst, *h_parent;
523b37e3 4051+ struct inode *dst_inode, *h_dir, *inode, *delegated;
1facf9fc 4052+ struct super_block *sb;
86dc4139 4053+ struct au_branch *br;
c2b27bf2
AM
4054+ /* to reuduce stack size */
4055+ struct {
4056+ struct au_dtime dt;
4057+ struct path h_path;
4058+ struct au_cpup_reg_attr h_src_attr;
4059+ } *a;
1facf9fc 4060+
c2b27bf2
AM
4061+ err = -ENOMEM;
4062+ a = kmalloc(sizeof(*a), GFP_NOFS);
4063+ if (unlikely(!a))
4064+ goto out;
4065+ a->h_src_attr.valid = 0;
1facf9fc 4066+
c2b27bf2
AM
4067+ sb = cpg->dentry->d_sb;
4068+ br = au_sbr(sb, cpg->bdst);
4069+ a->h_path.mnt = au_br_mnt(br);
4070+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
1facf9fc 4071+ h_parent = h_dst->d_parent; /* dir inode is locked */
4072+ h_dir = h_parent->d_inode;
4073+ IMustLock(h_dir);
4074+
c2b27bf2
AM
4075+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
4076+ inode = cpg->dentry->d_inode;
1facf9fc 4077+
4078+ if (!dst_parent)
c2b27bf2 4079+ dst_parent = dget_parent(cpg->dentry);
1facf9fc 4080+ else
4081+ dget(dst_parent);
4082+
4083+ plink = !!au_opt_test(au_mntflags(sb), PLINK);
c2b27bf2 4084+ dst_inode = au_h_iptr(inode, cpg->bdst);
1facf9fc 4085+ if (dst_inode) {
4086+ if (unlikely(!plink)) {
4087+ err = -EIO;
027c5e7a
AM
4088+ AuIOErr("hi%lu(i%lu) exists on b%d "
4089+ "but plink is disabled\n",
c2b27bf2
AM
4090+ dst_inode->i_ino, inode->i_ino, cpg->bdst);
4091+ goto out_parent;
1facf9fc 4092+ }
4093+
4094+ if (dst_inode->i_nlink) {
c2b27bf2 4095+ const int do_dt = au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 4096+
c2b27bf2 4097+ h_src = au_plink_lkup(inode, cpg->bdst);
1facf9fc 4098+ err = PTR_ERR(h_src);
4099+ if (IS_ERR(h_src))
c2b27bf2 4100+ goto out_parent;
1facf9fc 4101+ if (unlikely(!h_src->d_inode)) {
4102+ err = -EIO;
4103+ AuIOErr("i%lu exists on a upper branch "
027c5e7a
AM
4104+ "but not pseudo-linked\n",
4105+ inode->i_ino);
1facf9fc 4106+ dput(h_src);
c2b27bf2 4107+ goto out_parent;
1facf9fc 4108+ }
4109+
4110+ if (do_dt) {
c2b27bf2
AM
4111+ a->h_path.dentry = h_parent;
4112+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
1facf9fc 4113+ }
86dc4139 4114+
c2b27bf2 4115+ a->h_path.dentry = h_dst;
523b37e3
AM
4116+ delegated = NULL;
4117+ err = vfsub_link(h_src, h_dir, &a->h_path, &delegated);
c2b27bf2 4118+ if (!err && au_ftest_cpup(cpg->flags, RENAME))
392086de 4119+ err = au_do_ren_after_cpup(cpg, &a->h_path);
1facf9fc 4120+ if (do_dt)
c2b27bf2 4121+ au_dtime_revert(&a->dt);
523b37e3
AM
4122+ if (unlikely(err == -EWOULDBLOCK)) {
4123+ pr_warn("cannot retry for NFSv4 delegation"
4124+ " for an internal link\n");
4125+ iput(delegated);
4126+ }
1facf9fc 4127+ dput(h_src);
c2b27bf2 4128+ goto out_parent;
1facf9fc 4129+ } else
4130+ /* todo: cpup_wh_file? */
4131+ /* udba work */
4a4d8108 4132+ au_update_ibrange(inode, /*do_put_zero*/1);
1facf9fc 4133+ }
4134+
86dc4139 4135+ isdir = S_ISDIR(inode->i_mode);
1facf9fc 4136+ old_ibstart = au_ibstart(inode);
c2b27bf2 4137+ err = cpup_entry(cpg, dst_parent, &a->h_src_attr);
1facf9fc 4138+ if (unlikely(err))
86dc4139 4139+ goto out_rev;
1facf9fc 4140+ dst_inode = h_dst->d_inode;
4141+ mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
86dc4139 4142+ /* todo: necessary? */
c2b27bf2 4143+ /* au_pin_hdir_unlock(cpg->pin); */
1facf9fc 4144+
c2b27bf2 4145+ err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &a->h_src_attr);
86dc4139
AM
4146+ if (unlikely(err)) {
4147+ /* todo: necessary? */
c2b27bf2 4148+ /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */
86dc4139
AM
4149+ mutex_unlock(&dst_inode->i_mutex);
4150+ goto out_rev;
4151+ }
4152+
c2b27bf2 4153+ if (cpg->bdst < old_ibstart) {
86dc4139 4154+ if (S_ISREG(inode->i_mode)) {
c2b27bf2 4155+ err = au_dy_iaop(inode, cpg->bdst, dst_inode);
86dc4139 4156+ if (unlikely(err)) {
c2b27bf2
AM
4157+ /* ignore an error */
4158+ /* au_pin_hdir_relock(cpg->pin); */
86dc4139
AM
4159+ mutex_unlock(&dst_inode->i_mutex);
4160+ goto out_rev;
4a4d8108 4161+ }
4a4d8108 4162+ }
c2b27bf2
AM
4163+ au_set_ibstart(inode, cpg->bdst);
4164+ } else
4165+ au_set_ibend(inode, cpg->bdst);
4166+ au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode),
86dc4139
AM
4167+ au_hi_flags(inode, isdir));
4168+
4169+ /* todo: necessary? */
c2b27bf2 4170+ /* err = au_pin_hdir_relock(cpg->pin); */
86dc4139
AM
4171+ mutex_unlock(&dst_inode->i_mutex);
4172+ if (unlikely(err))
4173+ goto out_rev;
4174+
4175+ if (!isdir
4176+ && h_src->d_inode->i_nlink > 1
4177+ && plink)
c2b27bf2 4178+ au_plink_append(inode, cpg->bdst, h_dst);
86dc4139 4179+
c2b27bf2
AM
4180+ if (au_ftest_cpup(cpg->flags, RENAME)) {
4181+ a->h_path.dentry = h_dst;
392086de 4182+ err = au_do_ren_after_cpup(cpg, &a->h_path);
86dc4139
AM
4183+ }
4184+ if (!err)
c2b27bf2 4185+ goto out_parent; /* success */
1facf9fc 4186+
4187+ /* revert */
4a4d8108 4188+out_rev:
c2b27bf2
AM
4189+ a->h_path.dentry = h_parent;
4190+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
4191+ a->h_path.dentry = h_dst;
86dc4139
AM
4192+ rerr = 0;
4193+ if (h_dst->d_inode) {
523b37e3
AM
4194+ if (!isdir) {
4195+ /* no delegation since it is just created */
4196+ rerr = vfsub_unlink(h_dir, &a->h_path,
4197+ /*delegated*/NULL, /*force*/0);
4198+ } else
c2b27bf2 4199+ rerr = vfsub_rmdir(h_dir, &a->h_path);
86dc4139 4200+ }
c2b27bf2 4201+ au_dtime_revert(&a->dt);
1facf9fc 4202+ if (rerr) {
4203+ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
4204+ err = -EIO;
4205+ }
c2b27bf2 4206+out_parent:
1facf9fc 4207+ dput(dst_parent);
c2b27bf2
AM
4208+ kfree(a);
4209+out:
1facf9fc 4210+ return err;
4211+}
4212+
c2b27bf2 4213+#if 0 /* unused */
1facf9fc 4214+struct au_cpup_single_args {
4215+ int *errp;
c2b27bf2 4216+ struct au_cp_generic *cpg;
1facf9fc 4217+ struct dentry *dst_parent;
4218+};
4219+
4220+static void au_call_cpup_single(void *args)
4221+{
4222+ struct au_cpup_single_args *a = args;
86dc4139 4223+
c2b27bf2
AM
4224+ au_pin_hdir_acquire_nest(a->cpg->pin);
4225+ *a->errp = au_cpup_single(a->cpg, a->dst_parent);
4226+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 4227+}
c2b27bf2 4228+#endif
1facf9fc 4229+
53392da6
AM
4230+/*
4231+ * prevent SIGXFSZ in copy-up.
4232+ * testing CAP_MKNOD is for generic fs,
4233+ * but CAP_FSETID is for xfs only, currently.
4234+ */
86dc4139 4235+static int au_cpup_sio_test(struct au_pin *pin, umode_t mode)
53392da6
AM
4236+{
4237+ int do_sio;
86dc4139
AM
4238+ struct super_block *sb;
4239+ struct inode *h_dir;
53392da6
AM
4240+
4241+ do_sio = 0;
86dc4139 4242+ sb = au_pinned_parent(pin)->d_sb;
53392da6
AM
4243+ if (!au_wkq_test()
4244+ && (!au_sbi(sb)->si_plink_maint_pid
4245+ || au_plink_maint(sb, AuLock_NOPLM))) {
4246+ switch (mode & S_IFMT) {
4247+ case S_IFREG:
4248+ /* no condition about RLIMIT_FSIZE and the file size */
4249+ do_sio = 1;
4250+ break;
4251+ case S_IFCHR:
4252+ case S_IFBLK:
4253+ do_sio = !capable(CAP_MKNOD);
4254+ break;
4255+ }
4256+ if (!do_sio)
4257+ do_sio = ((mode & (S_ISUID | S_ISGID))
4258+ && !capable(CAP_FSETID));
86dc4139
AM
4259+ /* this workaround may be removed in the future */
4260+ if (!do_sio) {
4261+ h_dir = au_pinned_h_dir(pin);
4262+ do_sio = h_dir->i_mode & S_ISVTX;
4263+ }
53392da6
AM
4264+ }
4265+
4266+ return do_sio;
4267+}
4268+
c2b27bf2
AM
4269+#if 0 /* unused */
4270+int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 4271+{
4272+ int err, wkq_err;
1facf9fc 4273+ struct dentry *h_dentry;
4274+
c2b27bf2 4275+ h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
86dc4139 4276+ if (!au_cpup_sio_test(pin, h_dentry->d_inode->i_mode))
c2b27bf2 4277+ err = au_cpup_single(cpg, dst_parent);
1facf9fc 4278+ else {
4279+ struct au_cpup_single_args args = {
4280+ .errp = &err,
c2b27bf2
AM
4281+ .cpg = cpg,
4282+ .dst_parent = dst_parent
1facf9fc 4283+ };
4284+ wkq_err = au_wkq_wait(au_call_cpup_single, &args);
4285+ if (unlikely(wkq_err))
4286+ err = wkq_err;
4287+ }
4288+
4289+ return err;
4290+}
c2b27bf2 4291+#endif
1facf9fc 4292+
4293+/*
4294+ * copyup the @dentry from the first active lower branch to @bdst,
4295+ * using au_cpup_single().
4296+ */
c2b27bf2 4297+static int au_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 4298+{
4299+ int err;
c2b27bf2
AM
4300+ unsigned int flags_orig;
4301+ struct dentry *dentry;
4302+
4303+ AuDebugOn(cpg->bsrc < 0);
1facf9fc 4304+
c2b27bf2 4305+ dentry = cpg->dentry;
86dc4139 4306+ DiMustWriteLock(dentry);
1facf9fc 4307+
c2b27bf2 4308+ err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1);
1facf9fc 4309+ if (!err) {
c2b27bf2
AM
4310+ flags_orig = cpg->flags;
4311+ au_fset_cpup(cpg->flags, RENAME);
4312+ err = au_cpup_single(cpg, NULL);
4313+ cpg->flags = flags_orig;
1facf9fc 4314+ if (!err)
4315+ return 0; /* success */
4316+
4317+ /* revert */
c2b27bf2
AM
4318+ au_set_h_dptr(dentry, cpg->bdst, NULL);
4319+ au_set_dbstart(dentry, cpg->bsrc);
1facf9fc 4320+ }
4321+
4322+ return err;
4323+}
4324+
4325+struct au_cpup_simple_args {
4326+ int *errp;
c2b27bf2 4327+ struct au_cp_generic *cpg;
1facf9fc 4328+};
4329+
4330+static void au_call_cpup_simple(void *args)
4331+{
4332+ struct au_cpup_simple_args *a = args;
86dc4139 4333+
c2b27bf2
AM
4334+ au_pin_hdir_acquire_nest(a->cpg->pin);
4335+ *a->errp = au_cpup_simple(a->cpg);
4336+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 4337+}
4338+
c2b27bf2 4339+static int au_do_sio_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 4340+{
4341+ int err, wkq_err;
c2b27bf2
AM
4342+ struct dentry *dentry, *parent;
4343+ struct file *h_file;
1facf9fc 4344+ struct inode *h_dir;
4345+
c2b27bf2
AM
4346+ dentry = cpg->dentry;
4347+ h_file = NULL;
4348+ if (au_ftest_cpup(cpg->flags, HOPEN)) {
4349+ AuDebugOn(cpg->bsrc < 0);
392086de 4350+ h_file = au_h_open_pre(dentry, cpg->bsrc, /*force_wr*/0);
c2b27bf2
AM
4351+ err = PTR_ERR(h_file);
4352+ if (IS_ERR(h_file))
4353+ goto out;
4354+ }
4355+
1facf9fc 4356+ parent = dget_parent(dentry);
c2b27bf2 4357+ h_dir = au_h_iptr(parent->d_inode, cpg->bdst);
53392da6 4358+ if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
c2b27bf2
AM
4359+ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode))
4360+ err = au_cpup_simple(cpg);
1facf9fc 4361+ else {
4362+ struct au_cpup_simple_args args = {
4363+ .errp = &err,
c2b27bf2 4364+ .cpg = cpg
1facf9fc 4365+ };
4366+ wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
4367+ if (unlikely(wkq_err))
4368+ err = wkq_err;
4369+ }
4370+
4371+ dput(parent);
c2b27bf2
AM
4372+ if (h_file)
4373+ au_h_open_post(dentry, cpg->bsrc, h_file);
4374+
4375+out:
1facf9fc 4376+ return err;
4377+}
4378+
c2b27bf2 4379+int au_sio_cpup_simple(struct au_cp_generic *cpg)
367653fa 4380+{
c2b27bf2
AM
4381+ aufs_bindex_t bsrc, bend;
4382+ struct dentry *dentry, *h_dentry;
367653fa 4383+
c2b27bf2
AM
4384+ if (cpg->bsrc < 0) {
4385+ dentry = cpg->dentry;
4386+ bend = au_dbend(dentry);
4387+ for (bsrc = cpg->bdst + 1; bsrc <= bend; bsrc++) {
4388+ h_dentry = au_h_dptr(dentry, bsrc);
4389+ if (h_dentry) {
4390+ AuDebugOn(!h_dentry->d_inode);
4391+ break;
4392+ }
4393+ }
4394+ AuDebugOn(bsrc > bend);
4395+ cpg->bsrc = bsrc;
367653fa 4396+ }
c2b27bf2
AM
4397+ AuDebugOn(cpg->bsrc <= cpg->bdst);
4398+ return au_do_sio_cpup_simple(cpg);
4399+}
367653fa 4400+
c2b27bf2
AM
4401+int au_sio_cpdown_simple(struct au_cp_generic *cpg)
4402+{
4403+ AuDebugOn(cpg->bdst <= cpg->bsrc);
4404+ return au_do_sio_cpup_simple(cpg);
367653fa
AM
4405+}
4406+
1facf9fc 4407+/* ---------------------------------------------------------------------- */
4408+
4409+/*
4410+ * copyup the deleted file for writing.
4411+ */
c2b27bf2
AM
4412+static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry,
4413+ struct file *file)
1facf9fc 4414+{
4415+ int err;
c2b27bf2
AM
4416+ unsigned int flags_orig;
4417+ aufs_bindex_t bsrc_orig;
1facf9fc 4418+ struct dentry *h_d_dst, *h_d_start;
c2b27bf2 4419+ struct au_dinfo *dinfo;
4a4d8108 4420+ struct au_hdentry *hdp;
1facf9fc 4421+
c2b27bf2 4422+ dinfo = au_di(cpg->dentry);
1308ab2a 4423+ AuRwMustWriteLock(&dinfo->di_rwsem);
4424+
c2b27bf2
AM
4425+ bsrc_orig = cpg->bsrc;
4426+ cpg->bsrc = dinfo->di_bstart;
4a4d8108 4427+ hdp = dinfo->di_hdentry;
c2b27bf2
AM
4428+ h_d_dst = hdp[0 + cpg->bdst].hd_dentry;
4429+ dinfo->di_bstart = cpg->bdst;
4430+ hdp[0 + cpg->bdst].hd_dentry = wh_dentry;
86dc4139 4431+ h_d_start = NULL;
027c5e7a 4432+ if (file) {
c2b27bf2
AM
4433+ h_d_start = hdp[0 + cpg->bsrc].hd_dentry;
4434+ hdp[0 + cpg->bsrc].hd_dentry = au_hf_top(file)->f_dentry;
027c5e7a 4435+ }
c2b27bf2
AM
4436+ flags_orig = cpg->flags;
4437+ cpg->flags = !AuCpup_DTIME;
4438+ err = au_cpup_single(cpg, /*h_parent*/NULL);
4439+ cpg->flags = flags_orig;
027c5e7a
AM
4440+ if (file) {
4441+ if (!err)
4442+ err = au_reopen_nondir(file);
c2b27bf2 4443+ hdp[0 + cpg->bsrc].hd_dentry = h_d_start;
1facf9fc 4444+ }
c2b27bf2
AM
4445+ hdp[0 + cpg->bdst].hd_dentry = h_d_dst;
4446+ dinfo->di_bstart = cpg->bsrc;
4447+ cpg->bsrc = bsrc_orig;
1facf9fc 4448+
4449+ return err;
4450+}
4451+
c2b27bf2 4452+static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 4453+{
4454+ int err;
c2b27bf2 4455+ aufs_bindex_t bdst;
1facf9fc 4456+ struct au_dtime dt;
c2b27bf2 4457+ struct dentry *dentry, *parent, *h_parent, *wh_dentry;
1facf9fc 4458+ struct au_branch *br;
4459+ struct path h_path;
4460+
c2b27bf2
AM
4461+ dentry = cpg->dentry;
4462+ bdst = cpg->bdst;
1facf9fc 4463+ br = au_sbr(dentry->d_sb, bdst);
4464+ parent = dget_parent(dentry);
4465+ h_parent = au_h_dptr(parent, bdst);
4466+ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
4467+ err = PTR_ERR(wh_dentry);
4468+ if (IS_ERR(wh_dentry))
4469+ goto out;
4470+
4471+ h_path.dentry = h_parent;
86dc4139 4472+ h_path.mnt = au_br_mnt(br);
1facf9fc 4473+ au_dtime_store(&dt, parent, &h_path);
c2b27bf2 4474+ err = au_do_cpup_wh(cpg, wh_dentry, file);
1facf9fc 4475+ if (unlikely(err))
4476+ goto out_wh;
4477+
4478+ dget(wh_dentry);
4479+ h_path.dentry = wh_dentry;
523b37e3
AM
4480+ if (!S_ISDIR(wh_dentry->d_inode->i_mode)) {
4481+ /* no delegation since it is just created */
4482+ err = vfsub_unlink(h_parent->d_inode, &h_path,
4483+ /*delegated*/NULL, /*force*/0);
4484+ } else
4a4d8108 4485+ err = vfsub_rmdir(h_parent->d_inode, &h_path);
1facf9fc 4486+ if (unlikely(err)) {
523b37e3
AM
4487+ AuIOErr("failed remove copied-up tmp file %pd(%d)\n",
4488+ wh_dentry, err);
1facf9fc 4489+ err = -EIO;
4490+ }
4491+ au_dtime_revert(&dt);
4492+ au_set_hi_wh(dentry->d_inode, bdst, wh_dentry);
4493+
4f0767ce 4494+out_wh:
1facf9fc 4495+ dput(wh_dentry);
4f0767ce 4496+out:
1facf9fc 4497+ dput(parent);
4498+ return err;
4499+}
4500+
4501+struct au_cpup_wh_args {
4502+ int *errp;
c2b27bf2 4503+ struct au_cp_generic *cpg;
1facf9fc 4504+ struct file *file;
4505+};
4506+
4507+static void au_call_cpup_wh(void *args)
4508+{
4509+ struct au_cpup_wh_args *a = args;
86dc4139 4510+
c2b27bf2
AM
4511+ au_pin_hdir_acquire_nest(a->cpg->pin);
4512+ *a->errp = au_cpup_wh(a->cpg, a->file);
4513+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 4514+}
4515+
c2b27bf2 4516+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 4517+{
4518+ int err, wkq_err;
c2b27bf2
AM
4519+ aufs_bindex_t bdst;
4520+ struct dentry *dentry, *parent, *h_orph, *h_parent, *h_dentry;
86dc4139 4521+ struct inode *dir, *h_dir, *h_tmpdir;
1facf9fc 4522+ struct au_wbr *wbr;
c2b27bf2 4523+ struct au_pin wh_pin, *pin_orig;
1facf9fc 4524+
c2b27bf2
AM
4525+ dentry = cpg->dentry;
4526+ bdst = cpg->bdst;
1facf9fc 4527+ parent = dget_parent(dentry);
4528+ dir = parent->d_inode;
4529+ h_orph = NULL;
4530+ h_parent = NULL;
4531+ h_dir = au_igrab(au_h_iptr(dir, bdst));
4532+ h_tmpdir = h_dir;
c2b27bf2 4533+ pin_orig = NULL;
1facf9fc 4534+ if (!h_dir->i_nlink) {
4535+ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
4536+ h_orph = wbr->wbr_orph;
4537+
4538+ h_parent = dget(au_h_dptr(parent, bdst));
1facf9fc 4539+ au_set_h_dptr(parent, bdst, dget(h_orph));
4540+ h_tmpdir = h_orph->d_inode;
1facf9fc 4541+ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
4542+
1facf9fc 4543+ if (file)
4a4d8108 4544+ h_dentry = au_hf_top(file)->f_dentry;
1facf9fc 4545+ else
4546+ h_dentry = au_h_dptr(dentry, au_dbstart(dentry));
dece6358 4547+ mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
4a4d8108 4548+ /* todo: au_h_open_pre()? */
86dc4139 4549+
c2b27bf2 4550+ pin_orig = cpg->pin;
86dc4139 4551+ au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT,
c2b27bf2
AM
4552+ AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED);
4553+ cpg->pin = &wh_pin;
1facf9fc 4554+ }
4555+
53392da6 4556+ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
c2b27bf2
AM
4557+ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode))
4558+ err = au_cpup_wh(cpg, file);
1facf9fc 4559+ else {
4560+ struct au_cpup_wh_args args = {
4561+ .errp = &err,
c2b27bf2
AM
4562+ .cpg = cpg,
4563+ .file = file
1facf9fc 4564+ };
4565+ wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
4566+ if (unlikely(wkq_err))
4567+ err = wkq_err;
4568+ }
4569+
4570+ if (h_orph) {
4571+ mutex_unlock(&h_tmpdir->i_mutex);
4a4d8108 4572+ /* todo: au_h_open_post()? */
1facf9fc 4573+ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
1facf9fc 4574+ au_set_h_dptr(parent, bdst, h_parent);
c2b27bf2
AM
4575+ AuDebugOn(!pin_orig);
4576+ cpg->pin = pin_orig;
1facf9fc 4577+ }
4578+ iput(h_dir);
4579+ dput(parent);
4580+
4581+ return err;
4582+}
4583+
4584+/* ---------------------------------------------------------------------- */
4585+
4586+/*
4587+ * generic routine for both of copy-up and copy-down.
4588+ */
4589+/* cf. revalidate function in file.c */
4590+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
4591+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 4592+ struct au_pin *pin,
1facf9fc 4593+ struct dentry *h_parent, void *arg),
4594+ void *arg)
4595+{
4596+ int err;
4597+ struct au_pin pin;
4598+ struct dentry *d, *parent, *h_parent, *real_parent;
4599+
4600+ err = 0;
4601+ parent = dget_parent(dentry);
4602+ if (IS_ROOT(parent))
4603+ goto out;
4604+
4605+ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
4606+ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
4607+
4608+ /* do not use au_dpage */
4609+ real_parent = parent;
4610+ while (1) {
4611+ dput(parent);
4612+ parent = dget_parent(dentry);
4613+ h_parent = au_h_dptr(parent, bdst);
4614+ if (h_parent)
4615+ goto out; /* success */
4616+
4617+ /* find top dir which is necessary to cpup */
4618+ do {
4619+ d = parent;
4620+ dput(parent);
4621+ parent = dget_parent(d);
4622+ di_read_lock_parent3(parent, !AuLock_IR);
4623+ h_parent = au_h_dptr(parent, bdst);
4624+ di_read_unlock(parent, !AuLock_IR);
4625+ } while (!h_parent);
4626+
4627+ if (d != real_parent)
4628+ di_write_lock_child3(d);
4629+
4630+ /* somebody else might create while we were sleeping */
4631+ if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) {
4632+ if (au_h_dptr(d, bdst))
4633+ au_update_dbstart(d);
4634+
4635+ au_pin_set_dentry(&pin, d);
4636+ err = au_do_pin(&pin);
4637+ if (!err) {
86dc4139 4638+ err = cp(d, bdst, &pin, h_parent, arg);
1facf9fc 4639+ au_unpin(&pin);
4640+ }
4641+ }
4642+
4643+ if (d != real_parent)
4644+ di_write_unlock(d);
4645+ if (unlikely(err))
4646+ break;
4647+ }
4648+
4f0767ce 4649+out:
1facf9fc 4650+ dput(parent);
4651+ return err;
4652+}
4653+
4654+static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 4655+ struct au_pin *pin,
1facf9fc 4656+ struct dentry *h_parent __maybe_unused ,
4657+ void *arg __maybe_unused)
4658+{
c2b27bf2
AM
4659+ struct au_cp_generic cpg = {
4660+ .dentry = dentry,
4661+ .bdst = bdst,
4662+ .bsrc = -1,
4663+ .len = 0,
4664+ .pin = pin,
4665+ .flags = AuCpup_DTIME
4666+ };
4667+ return au_sio_cpup_simple(&cpg);
1facf9fc 4668+}
4669+
4670+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
4671+{
4672+ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
4673+}
4674+
4675+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
4676+{
4677+ int err;
4678+ struct dentry *parent;
4679+ struct inode *dir;
4680+
4681+ parent = dget_parent(dentry);
4682+ dir = parent->d_inode;
4683+ err = 0;
4684+ if (au_h_iptr(dir, bdst))
4685+ goto out;
4686+
4687+ di_read_unlock(parent, AuLock_IR);
4688+ di_write_lock_parent(parent);
4689+ /* someone else might change our inode while we were sleeping */
4690+ if (!au_h_iptr(dir, bdst))
4691+ err = au_cpup_dirs(dentry, bdst);
4692+ di_downgrade_lock(parent, AuLock_IR);
4693+
4f0767ce 4694+out:
1facf9fc 4695+ dput(parent);
4696+ return err;
4697+}
7f207e10
AM
4698diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
4699--- /usr/share/empty/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
4700+++ linux/fs/aufs/cpup.h 2014-01-20 20:16:14.732796615 +0100
4701@@ -0,0 +1,94 @@
1facf9fc 4702+/*
523b37e3 4703+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 4704+ *
4705+ * This program, aufs is free software; you can redistribute it and/or modify
4706+ * it under the terms of the GNU General Public License as published by
4707+ * the Free Software Foundation; either version 2 of the License, or
4708+ * (at your option) any later version.
dece6358
AM
4709+ *
4710+ * This program is distributed in the hope that it will be useful,
4711+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4712+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4713+ * GNU General Public License for more details.
4714+ *
4715+ * You should have received a copy of the GNU General Public License
523b37e3 4716+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 4717+ */
4718+
4719+/*
4720+ * copy-up/down functions
4721+ */
4722+
4723+#ifndef __AUFS_CPUP_H__
4724+#define __AUFS_CPUP_H__
4725+
4726+#ifdef __KERNEL__
4727+
dece6358 4728+#include <linux/path.h>
1facf9fc 4729+
dece6358
AM
4730+struct inode;
4731+struct file;
86dc4139 4732+struct au_pin;
dece6358 4733+
86dc4139 4734+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags);
1facf9fc 4735+void au_cpup_attr_timesizes(struct inode *inode);
4736+void au_cpup_attr_nlink(struct inode *inode, int force);
4737+void au_cpup_attr_changeable(struct inode *inode);
4738+void au_cpup_igen(struct inode *inode, struct inode *h_inode);
4739+void au_cpup_attr_all(struct inode *inode, int force);
4740+
4741+/* ---------------------------------------------------------------------- */
4742+
c2b27bf2
AM
4743+struct au_cp_generic {
4744+ struct dentry *dentry;
4745+ aufs_bindex_t bdst, bsrc;
4746+ loff_t len;
4747+ struct au_pin *pin;
4748+ unsigned int flags;
4749+};
4750+
1facf9fc 4751+/* cpup flags */
392086de
AM
4752+#define AuCpup_DTIME 1 /* do dtime_store/revert */
4753+#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino,
4754+ for link(2) */
4755+#define AuCpup_RENAME (1 << 2) /* rename after cpup */
4756+#define AuCpup_HOPEN (1 << 3) /* call h_open_pre/post() in
4757+ cpup */
4758+#define AuCpup_OVERWRITE (1 << 4) /* allow overwriting the
4759+ existing entry */
4760+#define AuCpup_RWDST (1 << 5) /* force write target even if
4761+ the branch is marked as RO */
c2b27bf2 4762+
1facf9fc 4763+#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name)
7f207e10
AM
4764+#define au_fset_cpup(flags, name) \
4765+ do { (flags) |= AuCpup_##name; } while (0)
4766+#define au_fclr_cpup(flags, name) \
4767+ do { (flags) &= ~AuCpup_##name; } while (0)
1facf9fc 4768+
4769+int au_copy_file(struct file *dst, struct file *src, loff_t len);
c2b27bf2
AM
4770+int au_sio_cpup_simple(struct au_cp_generic *cpg);
4771+int au_sio_cpdown_simple(struct au_cp_generic *cpg);
4772+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file);
1facf9fc 4773+
4774+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
4775+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 4776+ struct au_pin *pin,
1facf9fc 4777+ struct dentry *h_parent, void *arg),
4778+ void *arg);
4779+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
4780+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
4781+
4782+/* ---------------------------------------------------------------------- */
4783+
4784+/* keep timestamps when copyup */
4785+struct au_dtime {
4786+ struct dentry *dt_dentry;
4787+ struct path dt_h_path;
4788+ struct timespec dt_atime, dt_mtime;
4789+};
4790+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
4791+ struct path *h_path);
4792+void au_dtime_revert(struct au_dtime *dt);
4793+
4794+#endif /* __KERNEL__ */
4795+#endif /* __AUFS_CPUP_H__ */
7f207e10
AM
4796diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
4797--- /usr/share/empty/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
4798+++ linux/fs/aufs/dbgaufs.c 2014-01-20 20:16:14.732796615 +0100
4799@@ -0,0 +1,432 @@
1facf9fc 4800+/*
523b37e3 4801+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 4802+ *
4803+ * This program, aufs is free software; you can redistribute it and/or modify
4804+ * it under the terms of the GNU General Public License as published by
4805+ * the Free Software Foundation; either version 2 of the License, or
4806+ * (at your option) any later version.
dece6358
AM
4807+ *
4808+ * This program is distributed in the hope that it will be useful,
4809+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4810+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4811+ * GNU General Public License for more details.
4812+ *
4813+ * You should have received a copy of the GNU General Public License
523b37e3 4814+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 4815+ */
4816+
4817+/*
4818+ * debugfs interface
4819+ */
4820+
4821+#include <linux/debugfs.h>
4822+#include "aufs.h"
4823+
4824+#ifndef CONFIG_SYSFS
4825+#error DEBUG_FS depends upon SYSFS
4826+#endif
4827+
4828+static struct dentry *dbgaufs;
4829+static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
4830+
4831+/* 20 is max digits length of ulong 64 */
4832+struct dbgaufs_arg {
4833+ int n;
4834+ char a[20 * 4];
4835+};
4836+
4837+/*
4838+ * common function for all XINO files
4839+ */
4840+static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
4841+ struct file *file)
4842+{
4843+ kfree(file->private_data);
4844+ return 0;
4845+}
4846+
4847+static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
4848+{
4849+ int err;
4850+ struct kstat st;
4851+ struct dbgaufs_arg *p;
4852+
4853+ err = -ENOMEM;
4854+ p = kmalloc(sizeof(*p), GFP_NOFS);
4855+ if (unlikely(!p))
4856+ goto out;
4857+
4858+ err = 0;
4859+ p->n = 0;
4860+ file->private_data = p;
4861+ if (!xf)
4862+ goto out;
4863+
c06a8ce3 4864+ err = vfs_getattr(&xf->f_path, &st);
1facf9fc 4865+ if (!err) {
4866+ if (do_fcnt)
4867+ p->n = snprintf
4868+ (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n",
4869+ (long)file_count(xf), st.blocks, st.blksize,
4870+ (long long)st.size);
4871+ else
4872+ p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n",
4873+ st.blocks, st.blksize,
4874+ (long long)st.size);
4875+ AuDebugOn(p->n >= sizeof(p->a));
4876+ } else {
4877+ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
4878+ err = 0;
4879+ }
4880+
4f0767ce 4881+out:
1facf9fc 4882+ return err;
4883+
4884+}
4885+
4886+static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
4887+ size_t count, loff_t *ppos)
4888+{
4889+ struct dbgaufs_arg *p;
4890+
4891+ p = file->private_data;
4892+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
4893+}
4894+
4895+/* ---------------------------------------------------------------------- */
4896+
86dc4139
AM
4897+struct dbgaufs_plink_arg {
4898+ int n;
4899+ char a[];
4900+};
4901+
4902+static int dbgaufs_plink_release(struct inode *inode __maybe_unused,
4903+ struct file *file)
4904+{
4905+ free_page((unsigned long)file->private_data);
4906+ return 0;
4907+}
4908+
4909+static int dbgaufs_plink_open(struct inode *inode, struct file *file)
4910+{
4911+ int err, i, limit;
4912+ unsigned long n, sum;
4913+ struct dbgaufs_plink_arg *p;
4914+ struct au_sbinfo *sbinfo;
4915+ struct super_block *sb;
4916+ struct au_sphlhead *sphl;
4917+
4918+ err = -ENOMEM;
4919+ p = (void *)get_zeroed_page(GFP_NOFS);
4920+ if (unlikely(!p))
4921+ goto out;
4922+
4923+ err = -EFBIG;
4924+ sbinfo = inode->i_private;
4925+ sb = sbinfo->si_sb;
4926+ si_noflush_read_lock(sb);
4927+ if (au_opt_test(au_mntflags(sb), PLINK)) {
4928+ limit = PAGE_SIZE - sizeof(p->n);
4929+
4930+ /* the number of buckets */
4931+ n = snprintf(p->a + p->n, limit, "%d\n", AuPlink_NHASH);
4932+ p->n += n;
4933+ limit -= n;
4934+
4935+ sum = 0;
4936+ for (i = 0, sphl = sbinfo->si_plink;
4937+ i < AuPlink_NHASH;
4938+ i++, sphl++) {
4939+ n = au_sphl_count(sphl);
4940+ sum += n;
4941+
4942+ n = snprintf(p->a + p->n, limit, "%lu ", n);
4943+ p->n += n;
4944+ limit -= n;
4945+ if (unlikely(limit <= 0))
4946+ goto out_free;
4947+ }
4948+ p->a[p->n - 1] = '\n';
4949+
4950+ /* the sum of plinks */
4951+ n = snprintf(p->a + p->n, limit, "%lu\n", sum);
4952+ p->n += n;
4953+ limit -= n;
4954+ if (unlikely(limit <= 0))
4955+ goto out_free;
4956+ } else {
4957+#define str "1\n0\n0\n"
4958+ p->n = sizeof(str) - 1;
4959+ strcpy(p->a, str);
4960+#undef str
4961+ }
4962+ si_read_unlock(sb);
4963+
4964+ err = 0;
4965+ file->private_data = p;
4966+ goto out; /* success */
4967+
4968+out_free:
4969+ free_page((unsigned long)p);
4970+out:
4971+ return err;
4972+}
4973+
4974+static ssize_t dbgaufs_plink_read(struct file *file, char __user *buf,
4975+ size_t count, loff_t *ppos)
4976+{
4977+ struct dbgaufs_plink_arg *p;
4978+
4979+ p = file->private_data;
4980+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
4981+}
4982+
4983+static const struct file_operations dbgaufs_plink_fop = {
4984+ .owner = THIS_MODULE,
4985+ .open = dbgaufs_plink_open,
4986+ .release = dbgaufs_plink_release,
4987+ .read = dbgaufs_plink_read
4988+};
4989+
4990+/* ---------------------------------------------------------------------- */
4991+
1facf9fc 4992+static int dbgaufs_xib_open(struct inode *inode, struct file *file)
4993+{
4994+ int err;
4995+ struct au_sbinfo *sbinfo;
4996+ struct super_block *sb;
4997+
4998+ sbinfo = inode->i_private;
4999+ sb = sbinfo->si_sb;
5000+ si_noflush_read_lock(sb);
5001+ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0);
5002+ si_read_unlock(sb);
5003+ return err;
5004+}
5005+
5006+static const struct file_operations dbgaufs_xib_fop = {
4a4d8108 5007+ .owner = THIS_MODULE,
1facf9fc 5008+ .open = dbgaufs_xib_open,
5009+ .release = dbgaufs_xi_release,
5010+ .read = dbgaufs_xi_read
5011+};
5012+
5013+/* ---------------------------------------------------------------------- */
5014+
5015+#define DbgaufsXi_PREFIX "xi"
5016+
5017+static int dbgaufs_xino_open(struct inode *inode, struct file *file)
5018+{
5019+ int err;
5020+ long l;
5021+ struct au_sbinfo *sbinfo;
5022+ struct super_block *sb;
5023+ struct file *xf;
5024+ struct qstr *name;
5025+
5026+ err = -ENOENT;
5027+ xf = NULL;
5028+ name = &file->f_dentry->d_name;
5029+ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
5030+ || memcmp(name->name, DbgaufsXi_PREFIX,
5031+ sizeof(DbgaufsXi_PREFIX) - 1)))
5032+ goto out;
9dbd164d 5033+ err = kstrtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
1facf9fc 5034+ if (unlikely(err))
5035+ goto out;
5036+
5037+ sbinfo = inode->i_private;
5038+ sb = sbinfo->si_sb;
5039+ si_noflush_read_lock(sb);
5040+ if (l <= au_sbend(sb)) {
5041+ xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file;
5042+ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1);
5043+ } else
5044+ err = -ENOENT;
5045+ si_read_unlock(sb);
5046+
4f0767ce 5047+out:
1facf9fc 5048+ return err;
5049+}
5050+
5051+static const struct file_operations dbgaufs_xino_fop = {
4a4d8108 5052+ .owner = THIS_MODULE,
1facf9fc 5053+ .open = dbgaufs_xino_open,
5054+ .release = dbgaufs_xi_release,
5055+ .read = dbgaufs_xi_read
5056+};
5057+
5058+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
5059+{
5060+ aufs_bindex_t bend;
5061+ struct au_branch *br;
5062+ struct au_xino_file *xi;
5063+
5064+ if (!au_sbi(sb)->si_dbgaufs)
5065+ return;
5066+
5067+ bend = au_sbend(sb);
5068+ for (; bindex <= bend; bindex++) {
5069+ br = au_sbr(sb, bindex);
5070+ xi = &br->br_xino;
c06a8ce3
AM
5071+ debugfs_remove(xi->xi_dbgaufs);
5072+ xi->xi_dbgaufs = NULL;
1facf9fc 5073+ }
5074+}
5075+
5076+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
5077+{
5078+ struct au_sbinfo *sbinfo;
5079+ struct dentry *parent;
5080+ struct au_branch *br;
5081+ struct au_xino_file *xi;
5082+ aufs_bindex_t bend;
5083+ char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */
5084+
5085+ sbinfo = au_sbi(sb);
5086+ parent = sbinfo->si_dbgaufs;
5087+ if (!parent)
5088+ return;
5089+
5090+ bend = au_sbend(sb);
5091+ for (; bindex <= bend; bindex++) {
5092+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
5093+ br = au_sbr(sb, bindex);
5094+ xi = &br->br_xino;
5095+ AuDebugOn(xi->xi_dbgaufs);
5096+ xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
5097+ sbinfo, &dbgaufs_xino_fop);
5098+ /* ignore an error */
5099+ if (unlikely(!xi->xi_dbgaufs))
5100+ AuWarn1("failed %s under debugfs\n", name);
5101+ }
5102+}
5103+
5104+/* ---------------------------------------------------------------------- */
5105+
5106+#ifdef CONFIG_AUFS_EXPORT
5107+static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
5108+{
5109+ int err;
5110+ struct au_sbinfo *sbinfo;
5111+ struct super_block *sb;
5112+
5113+ sbinfo = inode->i_private;
5114+ sb = sbinfo->si_sb;
5115+ si_noflush_read_lock(sb);
5116+ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0);
5117+ si_read_unlock(sb);
5118+ return err;
5119+}
5120+
5121+static const struct file_operations dbgaufs_xigen_fop = {
4a4d8108 5122+ .owner = THIS_MODULE,
1facf9fc 5123+ .open = dbgaufs_xigen_open,
5124+ .release = dbgaufs_xi_release,
5125+ .read = dbgaufs_xi_read
5126+};
5127+
5128+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
5129+{
5130+ int err;
5131+
dece6358
AM
5132+ /*
5133+ * This function is a dynamic '__init' fucntion actually,
5134+ * so the tiny check for si_rwsem is unnecessary.
5135+ */
5136+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
5137+
1facf9fc 5138+ err = -EIO;
5139+ sbinfo->si_dbgaufs_xigen = debugfs_create_file
5140+ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
5141+ &dbgaufs_xigen_fop);
5142+ if (sbinfo->si_dbgaufs_xigen)
5143+ err = 0;
5144+
5145+ return err;
5146+}
5147+#else
5148+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
5149+{
5150+ return 0;
5151+}
5152+#endif /* CONFIG_AUFS_EXPORT */
5153+
5154+/* ---------------------------------------------------------------------- */
5155+
5156+void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
5157+{
dece6358
AM
5158+ /*
5159+ * This function is a dynamic '__init' fucntion actually,
5160+ * so the tiny check for si_rwsem is unnecessary.
5161+ */
5162+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
5163+
1facf9fc 5164+ debugfs_remove_recursive(sbinfo->si_dbgaufs);
5165+ sbinfo->si_dbgaufs = NULL;
5166+ kobject_put(&sbinfo->si_kobj);
5167+}
5168+
5169+int dbgaufs_si_init(struct au_sbinfo *sbinfo)
5170+{
5171+ int err;
5172+ char name[SysaufsSiNameLen];
5173+
dece6358
AM
5174+ /*
5175+ * This function is a dynamic '__init' fucntion actually,
5176+ * so the tiny check for si_rwsem is unnecessary.
5177+ */
5178+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
5179+
1facf9fc 5180+ err = -ENOENT;
5181+ if (!dbgaufs) {
5182+ AuErr1("/debug/aufs is uninitialized\n");
5183+ goto out;
5184+ }
5185+
5186+ err = -EIO;
5187+ sysaufs_name(sbinfo, name);
5188+ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
5189+ if (unlikely(!sbinfo->si_dbgaufs))
5190+ goto out;
5191+ kobject_get(&sbinfo->si_kobj);
5192+
5193+ sbinfo->si_dbgaufs_xib = debugfs_create_file
5194+ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
5195+ &dbgaufs_xib_fop);
5196+ if (unlikely(!sbinfo->si_dbgaufs_xib))
5197+ goto out_dir;
5198+
86dc4139
AM
5199+ sbinfo->si_dbgaufs_plink = debugfs_create_file
5200+ ("plink", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
5201+ &dbgaufs_plink_fop);
5202+ if (unlikely(!sbinfo->si_dbgaufs_plink))
5203+ goto out_dir;
5204+
1facf9fc 5205+ err = dbgaufs_xigen_init(sbinfo);
5206+ if (!err)
5207+ goto out; /* success */
5208+
4f0767ce 5209+out_dir:
1facf9fc 5210+ dbgaufs_si_fin(sbinfo);
4f0767ce 5211+out:
1facf9fc 5212+ return err;
5213+}
5214+
5215+/* ---------------------------------------------------------------------- */
5216+
5217+void dbgaufs_fin(void)
5218+{
5219+ debugfs_remove(dbgaufs);
5220+}
5221+
5222+int __init dbgaufs_init(void)
5223+{
5224+ int err;
5225+
5226+ err = -EIO;
5227+ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
5228+ if (dbgaufs)
5229+ err = 0;
5230+ return err;
5231+}
7f207e10
AM
5232diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
5233--- /usr/share/empty/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
5234+++ linux/fs/aufs/dbgaufs.h 2014-01-20 20:16:14.732796615 +0100
5235@@ -0,0 +1,48 @@
1facf9fc 5236+/*
523b37e3 5237+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 5238+ *
5239+ * This program, aufs is free software; you can redistribute it and/or modify
5240+ * it under the terms of the GNU General Public License as published by
5241+ * the Free Software Foundation; either version 2 of the License, or
5242+ * (at your option) any later version.
dece6358
AM
5243+ *
5244+ * This program is distributed in the hope that it will be useful,
5245+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5246+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5247+ * GNU General Public License for more details.
5248+ *
5249+ * You should have received a copy of the GNU General Public License
523b37e3 5250+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 5251+ */
5252+
5253+/*
5254+ * debugfs interface
5255+ */
5256+
5257+#ifndef __DBGAUFS_H__
5258+#define __DBGAUFS_H__
5259+
5260+#ifdef __KERNEL__
5261+
dece6358 5262+struct super_block;
1facf9fc 5263+struct au_sbinfo;
dece6358 5264+
1facf9fc 5265+#ifdef CONFIG_DEBUG_FS
5266+/* dbgaufs.c */
5267+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
5268+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
5269+void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
5270+int dbgaufs_si_init(struct au_sbinfo *sbinfo);
5271+void dbgaufs_fin(void);
5272+int __init dbgaufs_init(void);
1facf9fc 5273+#else
4a4d8108
AM
5274+AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
5275+AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
5276+AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
5277+AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
5278+AuStubVoid(dbgaufs_fin, void)
5279+AuStubInt0(__init dbgaufs_init, void)
1facf9fc 5280+#endif /* CONFIG_DEBUG_FS */
5281+
5282+#endif /* __KERNEL__ */
5283+#endif /* __DBGAUFS_H__ */
7f207e10
AM
5284diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
5285--- /usr/share/empty/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100
523b37e3 5286+++ linux/fs/aufs/dcsub.c 2014-01-20 20:16:14.732796615 +0100
027c5e7a 5287@@ -0,0 +1,243 @@
1facf9fc 5288+/*
523b37e3 5289+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 5290+ *
5291+ * This program, aufs is free software; you can redistribute it and/or modify
5292+ * it under the terms of the GNU General Public License as published by
5293+ * the Free Software Foundation; either version 2 of the License, or
5294+ * (at your option) any later version.
dece6358
AM
5295+ *
5296+ * This program is distributed in the hope that it will be useful,
5297+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5298+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5299+ * GNU General Public License for more details.
5300+ *
5301+ * You should have received a copy of the GNU General Public License
523b37e3 5302+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 5303+ */
5304+
5305+/*
5306+ * sub-routines for dentry cache
5307+ */
5308+
5309+#include "aufs.h"
5310+
5311+static void au_dpage_free(struct au_dpage *dpage)
5312+{
5313+ int i;
5314+ struct dentry **p;
5315+
5316+ p = dpage->dentries;
5317+ for (i = 0; i < dpage->ndentry; i++)
5318+ dput(*p++);
5319+ free_page((unsigned long)dpage->dentries);
5320+}
5321+
5322+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
5323+{
5324+ int err;
5325+ void *p;
5326+
5327+ err = -ENOMEM;
5328+ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
5329+ if (unlikely(!dpages->dpages))
5330+ goto out;
5331+
5332+ p = (void *)__get_free_page(gfp);
5333+ if (unlikely(!p))
5334+ goto out_dpages;
5335+
5336+ dpages->dpages[0].ndentry = 0;
5337+ dpages->dpages[0].dentries = p;
5338+ dpages->ndpage = 1;
5339+ return 0; /* success */
5340+
4f0767ce 5341+out_dpages:
1facf9fc 5342+ kfree(dpages->dpages);
4f0767ce 5343+out:
1facf9fc 5344+ return err;
5345+}
5346+
5347+void au_dpages_free(struct au_dcsub_pages *dpages)
5348+{
5349+ int i;
5350+ struct au_dpage *p;
5351+
5352+ p = dpages->dpages;
5353+ for (i = 0; i < dpages->ndpage; i++)
5354+ au_dpage_free(p++);
5355+ kfree(dpages->dpages);
5356+}
5357+
5358+static int au_dpages_append(struct au_dcsub_pages *dpages,
5359+ struct dentry *dentry, gfp_t gfp)
5360+{
5361+ int err, sz;
5362+ struct au_dpage *dpage;
5363+ void *p;
5364+
5365+ dpage = dpages->dpages + dpages->ndpage - 1;
5366+ sz = PAGE_SIZE / sizeof(dentry);
5367+ if (unlikely(dpage->ndentry >= sz)) {
5368+ AuLabel(new dpage);
5369+ err = -ENOMEM;
5370+ sz = dpages->ndpage * sizeof(*dpages->dpages);
5371+ p = au_kzrealloc(dpages->dpages, sz,
5372+ sz + sizeof(*dpages->dpages), gfp);
5373+ if (unlikely(!p))
5374+ goto out;
5375+
5376+ dpages->dpages = p;
5377+ dpage = dpages->dpages + dpages->ndpage;
5378+ p = (void *)__get_free_page(gfp);
5379+ if (unlikely(!p))
5380+ goto out;
5381+
5382+ dpage->ndentry = 0;
5383+ dpage->dentries = p;
5384+ dpages->ndpage++;
5385+ }
5386+
392086de 5387+ AuDebugOn(!d_count(dentry));
027c5e7a 5388+ dpage->dentries[dpage->ndentry++] = dget_dlock(dentry);
1facf9fc 5389+ return 0; /* success */
5390+
4f0767ce 5391+out:
1facf9fc 5392+ return err;
5393+}
5394+
523b37e3 5395+/* try d_walk() in linux/fs/dcache.c */
1facf9fc 5396+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
5397+ au_dpages_test test, void *arg)
5398+{
5399+ int err;
027c5e7a 5400+ struct dentry *this_parent;
1facf9fc 5401+ struct list_head *next;
5402+ struct super_block *sb = root->d_sb;
5403+
5404+ err = 0;
027c5e7a
AM
5405+ write_seqlock(&rename_lock);
5406+ this_parent = root;
5407+ spin_lock(&this_parent->d_lock);
4f0767ce 5408+repeat:
1facf9fc 5409+ next = this_parent->d_subdirs.next;
4f0767ce 5410+resume:
1facf9fc 5411+ if (this_parent->d_sb == sb
5412+ && !IS_ROOT(this_parent)
027c5e7a 5413+ && au_di(this_parent)
392086de 5414+ && d_count(this_parent)
1facf9fc 5415+ && (!test || test(this_parent, arg))) {
5416+ err = au_dpages_append(dpages, this_parent, GFP_ATOMIC);
5417+ if (unlikely(err))
5418+ goto out;
5419+ }
5420+
5421+ while (next != &this_parent->d_subdirs) {
5422+ struct list_head *tmp = next;
5423+ struct dentry *dentry = list_entry(tmp, struct dentry,
5424+ d_u.d_child);
027c5e7a 5425+
1facf9fc 5426+ next = tmp->next;
027c5e7a 5427+ spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
392086de 5428+ if (d_count(dentry)) {
027c5e7a
AM
5429+ if (!list_empty(&dentry->d_subdirs)) {
5430+ spin_unlock(&this_parent->d_lock);
5431+ spin_release(&dentry->d_lock.dep_map, 1,
5432+ _RET_IP_);
5433+ this_parent = dentry;
5434+ spin_acquire(&this_parent->d_lock.dep_map, 0, 1,
5435+ _RET_IP_);
5436+ goto repeat;
5437+ }
5438+ if (dentry->d_sb == sb
5439+ && au_di(dentry)
5440+ && (!test || test(dentry, arg)))
5441+ err = au_dpages_append(dpages, dentry,
5442+ GFP_ATOMIC);
1facf9fc 5443+ }
027c5e7a
AM
5444+ spin_unlock(&dentry->d_lock);
5445+ if (unlikely(err))
5446+ goto out;
1facf9fc 5447+ }
5448+
5449+ if (this_parent != root) {
027c5e7a
AM
5450+ struct dentry *tmp;
5451+ struct dentry *child;
5452+
5453+ tmp = this_parent->d_parent;
5454+ rcu_read_lock();
5455+ spin_unlock(&this_parent->d_lock);
5456+ child = this_parent;
5457+ this_parent = tmp;
5458+ spin_lock(&this_parent->d_lock);
5459+ rcu_read_unlock();
5460+ next = child->d_u.d_child.next;
1facf9fc 5461+ goto resume;
5462+ }
027c5e7a 5463+
4f0767ce 5464+out:
027c5e7a
AM
5465+ spin_unlock(&this_parent->d_lock);
5466+ write_sequnlock(&rename_lock);
1facf9fc 5467+ return err;
5468+}
5469+
5470+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
5471+ int do_include, au_dpages_test test, void *arg)
5472+{
5473+ int err;
5474+
5475+ err = 0;
027c5e7a
AM
5476+ write_seqlock(&rename_lock);
5477+ spin_lock(&dentry->d_lock);
5478+ if (do_include
392086de 5479+ && d_count(dentry)
027c5e7a 5480+ && (!test || test(dentry, arg)))
1facf9fc 5481+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
5482+ spin_unlock(&dentry->d_lock);
5483+ if (unlikely(err))
5484+ goto out;
5485+
5486+ /*
523b37e3 5487+ * RCU for vfsmount is unnecessary since this is a traverse in a single
027c5e7a
AM
5488+ * mount
5489+ */
1facf9fc 5490+ while (!IS_ROOT(dentry)) {
027c5e7a
AM
5491+ dentry = dentry->d_parent; /* rename_lock is locked */
5492+ spin_lock(&dentry->d_lock);
392086de 5493+ if (d_count(dentry)
027c5e7a 5494+ && (!test || test(dentry, arg)))
1facf9fc 5495+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
5496+ spin_unlock(&dentry->d_lock);
5497+ if (unlikely(err))
5498+ break;
1facf9fc 5499+ }
5500+
4f0767ce 5501+out:
027c5e7a 5502+ write_sequnlock(&rename_lock);
1facf9fc 5503+ return err;
5504+}
5505+
027c5e7a
AM
5506+static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg)
5507+{
5508+ return au_di(dentry) && dentry->d_sb == arg;
5509+}
5510+
5511+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
5512+ struct dentry *dentry, int do_include)
5513+{
5514+ return au_dcsub_pages_rev(dpages, dentry, do_include,
5515+ au_dcsub_dpages_aufs, dentry->d_sb);
5516+}
5517+
4a4d8108 5518+int au_test_subdir(struct dentry *d1, struct dentry *d2)
1facf9fc 5519+{
4a4d8108
AM
5520+ struct path path[2] = {
5521+ {
5522+ .dentry = d1
5523+ },
5524+ {
5525+ .dentry = d2
5526+ }
5527+ };
1facf9fc 5528+
4a4d8108 5529+ return path_is_under(path + 0, path + 1);
1facf9fc 5530+}
7f207e10
AM
5531diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
5532--- /usr/share/empty/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
5533+++ linux/fs/aufs/dcsub.h 2014-01-20 20:16:14.736130059 +0100
5534@@ -0,0 +1,98 @@
1facf9fc 5535+/*
523b37e3 5536+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 5537+ *
5538+ * This program, aufs is free software; you can redistribute it and/or modify
5539+ * it under the terms of the GNU General Public License as published by
5540+ * the Free Software Foundation; either version 2 of the License, or
5541+ * (at your option) any later version.
dece6358
AM
5542+ *
5543+ * This program is distributed in the hope that it will be useful,
5544+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5545+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5546+ * GNU General Public License for more details.
5547+ *
5548+ * You should have received a copy of the GNU General Public License
523b37e3 5549+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 5550+ */
5551+
5552+/*
5553+ * sub-routines for dentry cache
5554+ */
5555+
5556+#ifndef __AUFS_DCSUB_H__
5557+#define __AUFS_DCSUB_H__
5558+
5559+#ifdef __KERNEL__
5560+
7f207e10 5561+#include <linux/dcache.h>
027c5e7a 5562+#include <linux/fs.h>
dece6358
AM
5563+
5564+struct dentry;
1facf9fc 5565+
5566+struct au_dpage {
5567+ int ndentry;
5568+ struct dentry **dentries;
5569+};
5570+
5571+struct au_dcsub_pages {
5572+ int ndpage;
5573+ struct au_dpage *dpages;
5574+};
5575+
5576+/* ---------------------------------------------------------------------- */
5577+
7f207e10 5578+/* dcsub.c */
1facf9fc 5579+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
5580+void au_dpages_free(struct au_dcsub_pages *dpages);
5581+typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
5582+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
5583+ au_dpages_test test, void *arg);
5584+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
5585+ int do_include, au_dpages_test test, void *arg);
027c5e7a
AM
5586+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
5587+ struct dentry *dentry, int do_include);
4a4d8108 5588+int au_test_subdir(struct dentry *d1, struct dentry *d2);
1facf9fc 5589+
7f207e10
AM
5590+/* ---------------------------------------------------------------------- */
5591+
523b37e3
AM
5592+/*
5593+ * todo: in linux-3.13, several similar (but faster) helpers are added to
5594+ * include/linux/dcache.h. Try them (in the future).
5595+ */
5596+
027c5e7a
AM
5597+static inline int au_d_hashed_positive(struct dentry *d)
5598+{
5599+ int err;
5600+ struct inode *inode = d->d_inode;
5601+ err = 0;
5602+ if (unlikely(d_unhashed(d) || !inode || !inode->i_nlink))
5603+ err = -ENOENT;
5604+ return err;
5605+}
5606+
5607+static inline int au_d_alive(struct dentry *d)
5608+{
5609+ int err;
5610+ struct inode *inode;
5611+ err = 0;
5612+ if (!IS_ROOT(d))
5613+ err = au_d_hashed_positive(d);
5614+ else {
5615+ inode = d->d_inode;
5616+ if (unlikely(d_unlinked(d) || !inode || !inode->i_nlink))
5617+ err = -ENOENT;
5618+ }
5619+ return err;
5620+}
5621+
5622+static inline int au_alive_dir(struct dentry *d)
7f207e10 5623+{
027c5e7a
AM
5624+ int err;
5625+ err = au_d_alive(d);
5626+ if (unlikely(err || IS_DEADDIR(d->d_inode)))
5627+ err = -ENOENT;
5628+ return err;
7f207e10
AM
5629+}
5630+
1facf9fc 5631+#endif /* __KERNEL__ */
5632+#endif /* __AUFS_DCSUB_H__ */
7f207e10
AM
5633diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
5634--- /usr/share/empty/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
5635+++ linux/fs/aufs/debug.c 2014-01-20 20:16:14.736130059 +0100
5636@@ -0,0 +1,517 @@
1facf9fc 5637+/*
523b37e3 5638+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 5639+ *
5640+ * This program, aufs is free software; you can redistribute it and/or modify
5641+ * it under the terms of the GNU General Public License as published by
5642+ * the Free Software Foundation; either version 2 of the License, or
5643+ * (at your option) any later version.
dece6358
AM
5644+ *
5645+ * This program is distributed in the hope that it will be useful,
5646+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5647+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5648+ * GNU General Public License for more details.
5649+ *
5650+ * You should have received a copy of the GNU General Public License
523b37e3 5651+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 5652+ */
5653+
5654+/*
5655+ * debug print functions
5656+ */
5657+
7f207e10 5658+#include <linux/vt_kern.h>
1facf9fc 5659+#include "aufs.h"
5660+
392086de
AM
5661+/* Returns 0, or -errno. arg is in kp->arg. */
5662+static int param_atomic_t_set(const char *val, const struct kernel_param *kp)
5663+{
5664+ int err, n;
5665+
5666+ err = kstrtoint(val, 0, &n);
5667+ if (!err) {
5668+ if (n > 0)
5669+ au_debug_on();
5670+ else
5671+ au_debug_off();
5672+ }
5673+ return err;
5674+}
5675+
5676+/* Returns length written or -errno. Buffer is 4k (ie. be short!) */
5677+static int param_atomic_t_get(char *buffer, const struct kernel_param *kp)
5678+{
5679+ atomic_t *a;
5680+
5681+ a = kp->arg;
5682+ return sprintf(buffer, "%d", atomic_read(a));
5683+}
5684+
5685+static struct kernel_param_ops param_ops_atomic_t = {
5686+ .set = param_atomic_t_set,
5687+ .get = param_atomic_t_get
5688+ /* void (*free)(void *arg) */
5689+};
5690+
5691+atomic_t aufs_debug = ATOMIC_INIT(0);
1facf9fc 5692+MODULE_PARM_DESC(debug, "debug print");
392086de 5693+module_param_named(debug, aufs_debug, atomic_t, S_IRUGO | S_IWUSR | S_IWGRP);
1facf9fc 5694+
5695+char *au_plevel = KERN_DEBUG;
e49829fe
JR
5696+#define dpri(fmt, ...) do { \
5697+ if ((au_plevel \
5698+ && strcmp(au_plevel, KERN_DEBUG)) \
5699+ || au_debug_test()) \
5700+ printk("%s" fmt, au_plevel, ##__VA_ARGS__); \
1facf9fc 5701+} while (0)
5702+
5703+/* ---------------------------------------------------------------------- */
5704+
5705+void au_dpri_whlist(struct au_nhash *whlist)
5706+{
5707+ unsigned long ul, n;
5708+ struct hlist_head *head;
c06a8ce3 5709+ struct au_vdir_wh *pos;
1facf9fc 5710+
5711+ n = whlist->nh_num;
5712+ head = whlist->nh_head;
5713+ for (ul = 0; ul < n; ul++) {
c06a8ce3 5714+ hlist_for_each_entry(pos, head, wh_hash)
1facf9fc 5715+ dpri("b%d, %.*s, %d\n",
c06a8ce3
AM
5716+ pos->wh_bindex,
5717+ pos->wh_str.len, pos->wh_str.name,
5718+ pos->wh_str.len);
1facf9fc 5719+ head++;
5720+ }
5721+}
5722+
5723+void au_dpri_vdir(struct au_vdir *vdir)
5724+{
5725+ unsigned long ul;
5726+ union au_vdir_deblk_p p;
5727+ unsigned char *o;
5728+
5729+ if (!vdir || IS_ERR(vdir)) {
5730+ dpri("err %ld\n", PTR_ERR(vdir));
5731+ return;
5732+ }
5733+
5734+ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n",
5735+ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
5736+ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
5737+ for (ul = 0; ul < vdir->vd_nblk; ul++) {
5738+ p.deblk = vdir->vd_deblk[ul];
5739+ o = p.deblk;
5740+ dpri("[%lu]: %p\n", ul, o);
5741+ }
5742+}
5743+
53392da6 5744+static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn,
1facf9fc 5745+ struct dentry *wh)
5746+{
5747+ char *n = NULL;
5748+ int l = 0;
5749+
5750+ if (!inode || IS_ERR(inode)) {
5751+ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
5752+ return -1;
5753+ }
5754+
c2b27bf2 5755+ /* the type of i_blocks depends upon CONFIG_LBDAF */
1facf9fc 5756+ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
5757+ && sizeof(inode->i_blocks) != sizeof(u64));
5758+ if (wh) {
5759+ n = (void *)wh->d_name.name;
5760+ l = wh->d_name.len;
5761+ }
5762+
53392da6
AM
5763+ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
5764+ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
5765+ bindex, inode,
1facf9fc 5766+ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
5767+ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
5768+ i_size_read(inode), (unsigned long long)inode->i_blocks,
53392da6 5769+ hn, (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
1facf9fc 5770+ inode->i_mapping ? inode->i_mapping->nrpages : 0,
b752ccd1
AM
5771+ inode->i_state, inode->i_flags, inode->i_version,
5772+ inode->i_generation,
1facf9fc 5773+ l ? ", wh " : "", l, n);
5774+ return 0;
5775+}
5776+
5777+void au_dpri_inode(struct inode *inode)
5778+{
5779+ struct au_iinfo *iinfo;
5780+ aufs_bindex_t bindex;
53392da6 5781+ int err, hn;
1facf9fc 5782+
53392da6 5783+ err = do_pri_inode(-1, inode, -1, NULL);
1facf9fc 5784+ if (err || !au_test_aufs(inode->i_sb))
5785+ return;
5786+
5787+ iinfo = au_ii(inode);
5788+ if (!iinfo)
5789+ return;
5790+ dpri("i-1: bstart %d, bend %d, gen %d\n",
537831f9 5791+ iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode, NULL));
1facf9fc 5792+ if (iinfo->ii_bstart < 0)
5793+ return;
53392da6
AM
5794+ hn = 0;
5795+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++) {
5796+ hn = !!au_hn(iinfo->ii_hinode + bindex);
5797+ do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode, hn,
1facf9fc 5798+ iinfo->ii_hinode[0 + bindex].hi_whdentry);
53392da6 5799+ }
1facf9fc 5800+}
5801+
2cbb1c4b
JR
5802+void au_dpri_dalias(struct inode *inode)
5803+{
5804+ struct dentry *d;
5805+
5806+ spin_lock(&inode->i_lock);
c06a8ce3 5807+ hlist_for_each_entry(d, &inode->i_dentry, d_alias)
2cbb1c4b
JR
5808+ au_dpri_dentry(d);
5809+ spin_unlock(&inode->i_lock);
5810+}
5811+
1facf9fc 5812+static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
5813+{
5814+ struct dentry *wh = NULL;
53392da6 5815+ int hn;
1facf9fc 5816+
5817+ if (!dentry || IS_ERR(dentry)) {
5818+ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
5819+ return -1;
5820+ }
5821+ /* do not call dget_parent() here */
027c5e7a 5822+ /* note: access d_xxx without d_lock */
523b37e3
AM
5823+ dpri("d%d: %p, %pd2?, %s, cnt %d, flags 0x%x, %shashed\n",
5824+ bindex, dentry, dentry,
1facf9fc 5825+ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
523b37e3
AM
5826+ d_count(dentry), dentry->d_flags,
5827+ d_unhashed(dentry) ? "un" : "");
53392da6 5828+ hn = -1;
1facf9fc 5829+ if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) {
5830+ struct au_iinfo *iinfo = au_ii(dentry->d_inode);
53392da6
AM
5831+ if (iinfo) {
5832+ hn = !!au_hn(iinfo->ii_hinode + bindex);
1facf9fc 5833+ wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
53392da6 5834+ }
1facf9fc 5835+ }
53392da6 5836+ do_pri_inode(bindex, dentry->d_inode, hn, wh);
1facf9fc 5837+ return 0;
5838+}
5839+
5840+void au_dpri_dentry(struct dentry *dentry)
5841+{
5842+ struct au_dinfo *dinfo;
5843+ aufs_bindex_t bindex;
5844+ int err;
4a4d8108 5845+ struct au_hdentry *hdp;
1facf9fc 5846+
5847+ err = do_pri_dentry(-1, dentry);
5848+ if (err || !au_test_aufs(dentry->d_sb))
5849+ return;
5850+
5851+ dinfo = au_di(dentry);
5852+ if (!dinfo)
5853+ return;
5854+ dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d\n",
5855+ dinfo->di_bstart, dinfo->di_bend,
5856+ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry));
5857+ if (dinfo->di_bstart < 0)
5858+ return;
4a4d8108 5859+ hdp = dinfo->di_hdentry;
1facf9fc 5860+ for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++)
4a4d8108 5861+ do_pri_dentry(bindex, hdp[0 + bindex].hd_dentry);
1facf9fc 5862+}
5863+
5864+static int do_pri_file(aufs_bindex_t bindex, struct file *file)
5865+{
5866+ char a[32];
5867+
5868+ if (!file || IS_ERR(file)) {
5869+ dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
5870+ return -1;
5871+ }
5872+ a[0] = 0;
5873+ if (bindex < 0
5874+ && file->f_dentry
5875+ && au_test_aufs(file->f_dentry->d_sb)
5876+ && au_fi(file))
e49829fe 5877+ snprintf(a, sizeof(a), ", gen %d, mmapped %d",
2cbb1c4b 5878+ au_figen(file), atomic_read(&au_fi(file)->fi_mmapped));
b752ccd1 5879+ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
1facf9fc 5880+ bindex, file->f_mode, file->f_flags, (long)file_count(file),
b752ccd1 5881+ file->f_version, file->f_pos, a);
1facf9fc 5882+ if (file->f_dentry)
5883+ do_pri_dentry(bindex, file->f_dentry);
5884+ return 0;
5885+}
5886+
5887+void au_dpri_file(struct file *file)
5888+{
5889+ struct au_finfo *finfo;
4a4d8108
AM
5890+ struct au_fidir *fidir;
5891+ struct au_hfile *hfile;
1facf9fc 5892+ aufs_bindex_t bindex;
5893+ int err;
5894+
5895+ err = do_pri_file(-1, file);
5896+ if (err || !file->f_dentry || !au_test_aufs(file->f_dentry->d_sb))
5897+ return;
5898+
5899+ finfo = au_fi(file);
5900+ if (!finfo)
5901+ return;
4a4d8108 5902+ if (finfo->fi_btop < 0)
1facf9fc 5903+ return;
4a4d8108
AM
5904+ fidir = finfo->fi_hdir;
5905+ if (!fidir)
5906+ do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
5907+ else
e49829fe
JR
5908+ for (bindex = finfo->fi_btop;
5909+ bindex >= 0 && bindex <= fidir->fd_bbot;
4a4d8108
AM
5910+ bindex++) {
5911+ hfile = fidir->fd_hfile + bindex;
5912+ do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
5913+ }
1facf9fc 5914+}
5915+
5916+static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
5917+{
5918+ struct vfsmount *mnt;
5919+ struct super_block *sb;
5920+
5921+ if (!br || IS_ERR(br))
5922+ goto out;
86dc4139 5923+ mnt = au_br_mnt(br);
1facf9fc 5924+ if (!mnt || IS_ERR(mnt))
5925+ goto out;
5926+ sb = mnt->mnt_sb;
5927+ if (!sb || IS_ERR(sb))
5928+ goto out;
5929+
1e00d052 5930+ dpri("s%d: {perm 0x%x, id %d, cnt %d, wbr %p}, "
b752ccd1 5931+ "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
1facf9fc 5932+ "xino %d\n",
1e00d052
AM
5933+ bindex, br->br_perm, br->br_id, atomic_read(&br->br_count),
5934+ br->br_wbr, au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
b752ccd1 5935+ sb->s_flags, sb->s_count,
1facf9fc 5936+ atomic_read(&sb->s_active), !!br->br_xino.xi_file);
5937+ return 0;
5938+
4f0767ce 5939+out:
1facf9fc 5940+ dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
5941+ return -1;
5942+}
5943+
5944+void au_dpri_sb(struct super_block *sb)
5945+{
5946+ struct au_sbinfo *sbinfo;
5947+ aufs_bindex_t bindex;
5948+ int err;
5949+ /* to reuduce stack size */
5950+ struct {
5951+ struct vfsmount mnt;
5952+ struct au_branch fake;
5953+ } *a;
5954+
5955+ /* this function can be called from magic sysrq */
5956+ a = kzalloc(sizeof(*a), GFP_ATOMIC);
5957+ if (unlikely(!a)) {
5958+ dpri("no memory\n");
5959+ return;
5960+ }
5961+
5962+ a->mnt.mnt_sb = sb;
5963+ a->fake.br_perm = 0;
86dc4139 5964+ a->fake.br_path.mnt = &a->mnt;
1facf9fc 5965+ a->fake.br_xino.xi_file = NULL;
5966+ atomic_set(&a->fake.br_count, 0);
5967+ smp_mb(); /* atomic_set */
5968+ err = do_pri_br(-1, &a->fake);
5969+ kfree(a);
5970+ dpri("dev 0x%x\n", sb->s_dev);
5971+ if (err || !au_test_aufs(sb))
5972+ return;
5973+
5974+ sbinfo = au_sbi(sb);
5975+ if (!sbinfo)
5976+ return;
5977+ dpri("nw %d, gen %u, kobj %d\n",
5978+ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
5979+ atomic_read(&sbinfo->si_kobj.kref.refcount));
5980+ for (bindex = 0; bindex <= sbinfo->si_bend; bindex++)
5981+ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
5982+}
5983+
5984+/* ---------------------------------------------------------------------- */
5985+
5986+void au_dbg_sleep_jiffy(int jiffy)
5987+{
5988+ while (jiffy)
5989+ jiffy = schedule_timeout_uninterruptible(jiffy);
5990+}
5991+
5992+void au_dbg_iattr(struct iattr *ia)
5993+{
c06a8ce3
AM
5994+#define AuBit(name) \
5995+ do { \
5996+ if (ia->ia_valid & ATTR_ ## name) \
5997+ dpri(#name "\n"); \
5998+ } while (0)
1facf9fc 5999+ AuBit(MODE);
6000+ AuBit(UID);
6001+ AuBit(GID);
6002+ AuBit(SIZE);
6003+ AuBit(ATIME);
6004+ AuBit(MTIME);
6005+ AuBit(CTIME);
6006+ AuBit(ATIME_SET);
6007+ AuBit(MTIME_SET);
6008+ AuBit(FORCE);
6009+ AuBit(ATTR_FLAG);
6010+ AuBit(KILL_SUID);
6011+ AuBit(KILL_SGID);
6012+ AuBit(FILE);
6013+ AuBit(KILL_PRIV);
6014+ AuBit(OPEN);
6015+ AuBit(TIMES_SET);
6016+#undef AuBit
6017+ dpri("ia_file %p\n", ia->ia_file);
6018+}
6019+
6020+/* ---------------------------------------------------------------------- */
6021+
027c5e7a
AM
6022+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
6023+{
6024+ struct inode *h_inode, *inode = dentry->d_inode;
6025+ struct dentry *h_dentry;
6026+ aufs_bindex_t bindex, bend, bi;
6027+
6028+ if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */)
6029+ return;
6030+
6031+ bend = au_dbend(dentry);
6032+ bi = au_ibend(inode);
6033+ if (bi < bend)
6034+ bend = bi;
6035+ bindex = au_dbstart(dentry);
6036+ bi = au_ibstart(inode);
6037+ if (bi > bindex)
6038+ bindex = bi;
6039+
6040+ for (; bindex <= bend; bindex++) {
6041+ h_dentry = au_h_dptr(dentry, bindex);
6042+ if (!h_dentry)
6043+ continue;
6044+ h_inode = au_h_iptr(inode, bindex);
6045+ if (unlikely(h_inode != h_dentry->d_inode)) {
392086de 6046+ au_debug_on();
027c5e7a
AM
6047+ AuDbg("b%d, %s:%d\n", bindex, func, line);
6048+ AuDbgDentry(dentry);
6049+ AuDbgInode(inode);
392086de 6050+ au_debug_off();
027c5e7a
AM
6051+ BUG();
6052+ }
6053+ }
6054+}
6055+
1facf9fc 6056+void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen)
6057+{
6058+ struct dentry *parent;
6059+
6060+ parent = dget_parent(dentry);
027c5e7a
AM
6061+ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
6062+ AuDebugOn(IS_ROOT(dentry));
6063+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 6064+ dput(parent);
6065+}
6066+
6067+void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen)
6068+{
6069+ struct dentry *parent;
027c5e7a 6070+ struct inode *inode;
1facf9fc 6071+
6072+ parent = dget_parent(dentry);
027c5e7a
AM
6073+ inode = dentry->d_inode;
6074+ AuDebugOn(inode && S_ISDIR(dentry->d_inode->i_mode));
6075+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 6076+ dput(parent);
6077+}
6078+
6079+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
6080+{
6081+ int err, i, j;
6082+ struct au_dcsub_pages dpages;
6083+ struct au_dpage *dpage;
6084+ struct dentry **dentries;
6085+
6086+ err = au_dpages_init(&dpages, GFP_NOFS);
6087+ AuDebugOn(err);
027c5e7a 6088+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
1facf9fc 6089+ AuDebugOn(err);
6090+ for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
6091+ dpage = dpages.dpages + i;
6092+ dentries = dpage->dentries;
6093+ for (j = dpage->ndentry - 1; !err && j >= 0; j--)
027c5e7a 6094+ AuDebugOn(au_digen_test(dentries[j], sigen));
1facf9fc 6095+ }
6096+ au_dpages_free(&dpages);
6097+}
6098+
1facf9fc 6099+void au_dbg_verify_kthread(void)
6100+{
53392da6 6101+ if (au_wkq_test()) {
1facf9fc 6102+ au_dbg_blocked();
1e00d052
AM
6103+ /*
6104+ * It may be recursive, but udba=notify between two aufs mounts,
6105+ * where a single ro branch is shared, is not a problem.
6106+ */
6107+ /* WARN_ON(1); */
1facf9fc 6108+ }
6109+}
6110+
6111+/* ---------------------------------------------------------------------- */
6112+
6113+void au_debug_sbinfo_init(struct au_sbinfo *sbinfo __maybe_unused)
6114+{
6115+#ifdef AuForceNoPlink
6116+ au_opt_clr(sbinfo->si_mntflags, PLINK);
6117+#endif
6118+#ifdef AuForceNoXino
6119+ au_opt_clr(sbinfo->si_mntflags, XINO);
6120+#endif
6121+#ifdef AuForceNoRefrof
6122+ au_opt_clr(sbinfo->si_mntflags, REFROF);
6123+#endif
4a4d8108
AM
6124+#ifdef AuForceHnotify
6125+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_HNOTIFY);
1facf9fc 6126+#endif
1308ab2a 6127+#ifdef AuForceRd0
6128+ sbinfo->si_rdblk = 0;
6129+ sbinfo->si_rdhash = 0;
6130+#endif
1facf9fc 6131+}
6132+
6133+int __init au_debug_init(void)
6134+{
6135+ aufs_bindex_t bindex;
6136+ struct au_vdir_destr destr;
6137+
6138+ bindex = -1;
6139+ AuDebugOn(bindex >= 0);
6140+
6141+ destr.len = -1;
6142+ AuDebugOn(destr.len < NAME_MAX);
6143+
6144+#ifdef CONFIG_4KSTACKS
0c3ec466 6145+ pr_warn("CONFIG_4KSTACKS is defined.\n");
1facf9fc 6146+#endif
6147+
6148+#ifdef AuForceNoBrs
6149+ sysaufs_brs = 0;
6150+#endif
6151+
6152+ return 0;
6153+}
7f207e10
AM
6154diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
6155--- /usr/share/empty/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
6156+++ linux/fs/aufs/debug.h 2014-01-20 20:16:14.736130059 +0100
6157@@ -0,0 +1,247 @@
1facf9fc 6158+/*
523b37e3 6159+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 6160+ *
6161+ * This program, aufs is free software; you can redistribute it and/or modify
6162+ * it under the terms of the GNU General Public License as published by
6163+ * the Free Software Foundation; either version 2 of the License, or
6164+ * (at your option) any later version.
dece6358
AM
6165+ *
6166+ * This program is distributed in the hope that it will be useful,
6167+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6168+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6169+ * GNU General Public License for more details.
6170+ *
6171+ * You should have received a copy of the GNU General Public License
523b37e3 6172+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6173+ */
6174+
6175+/*
6176+ * debug print functions
6177+ */
6178+
6179+#ifndef __AUFS_DEBUG_H__
6180+#define __AUFS_DEBUG_H__
6181+
6182+#ifdef __KERNEL__
6183+
392086de 6184+#include <linux/atomic.h>
4a4d8108
AM
6185+#include <linux/module.h>
6186+#include <linux/kallsyms.h>
1facf9fc 6187+#include <linux/sysrq.h>
4a4d8108 6188+
1facf9fc 6189+#ifdef CONFIG_AUFS_DEBUG
6190+#define AuDebugOn(a) BUG_ON(a)
6191+
6192+/* module parameter */
392086de
AM
6193+extern atomic_t aufs_debug;
6194+static inline void au_debug_on(void)
1facf9fc 6195+{
392086de
AM
6196+ atomic_inc(&aufs_debug);
6197+}
6198+static inline void au_debug_off(void)
6199+{
6200+ atomic_dec_if_positive(&aufs_debug);
1facf9fc 6201+}
6202+
6203+static inline int au_debug_test(void)
6204+{
392086de 6205+ return atomic_read(&aufs_debug) > 0;
1facf9fc 6206+}
6207+#else
6208+#define AuDebugOn(a) do {} while (0)
392086de
AM
6209+AuStubVoid(au_debug_on, void)
6210+AuStubVoid(au_debug_off, void)
4a4d8108 6211+AuStubInt0(au_debug_test, void)
1facf9fc 6212+#endif /* CONFIG_AUFS_DEBUG */
6213+
392086de
AM
6214+#define param_check_atomic_t(name, p) __param_check(name, p, atomic_t)
6215+
1facf9fc 6216+/* ---------------------------------------------------------------------- */
6217+
6218+/* debug print */
6219+
4a4d8108 6220+#define AuDbg(fmt, ...) do { \
1facf9fc 6221+ if (au_debug_test()) \
4a4d8108 6222+ pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
1facf9fc 6223+} while (0)
4a4d8108
AM
6224+#define AuLabel(l) AuDbg(#l "\n")
6225+#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__)
6226+#define AuWarn1(fmt, ...) do { \
1facf9fc 6227+ static unsigned char _c; \
6228+ if (!_c++) \
0c3ec466 6229+ pr_warn(fmt, ##__VA_ARGS__); \
1facf9fc 6230+} while (0)
6231+
4a4d8108 6232+#define AuErr1(fmt, ...) do { \
1facf9fc 6233+ static unsigned char _c; \
6234+ if (!_c++) \
4a4d8108 6235+ pr_err(fmt, ##__VA_ARGS__); \
1facf9fc 6236+} while (0)
6237+
4a4d8108 6238+#define AuIOErr1(fmt, ...) do { \
1facf9fc 6239+ static unsigned char _c; \
6240+ if (!_c++) \
4a4d8108 6241+ AuIOErr(fmt, ##__VA_ARGS__); \
1facf9fc 6242+} while (0)
6243+
6244+#define AuUnsupportMsg "This operation is not supported." \
6245+ " Please report this application to aufs-users ML."
4a4d8108
AM
6246+#define AuUnsupport(fmt, ...) do { \
6247+ pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
1facf9fc 6248+ dump_stack(); \
6249+} while (0)
6250+
6251+#define AuTraceErr(e) do { \
6252+ if (unlikely((e) < 0)) \
6253+ AuDbg("err %d\n", (int)(e)); \
6254+} while (0)
6255+
6256+#define AuTraceErrPtr(p) do { \
6257+ if (IS_ERR(p)) \
6258+ AuDbg("err %ld\n", PTR_ERR(p)); \
6259+} while (0)
6260+
6261+/* dirty macros for debug print, use with "%.*s" and caution */
6262+#define AuLNPair(qstr) (qstr)->len, (qstr)->name
1facf9fc 6263+
6264+/* ---------------------------------------------------------------------- */
6265+
6266+struct au_sbinfo;
6267+struct au_finfo;
dece6358 6268+struct dentry;
1facf9fc 6269+#ifdef CONFIG_AUFS_DEBUG
6270+extern char *au_plevel;
6271+struct au_nhash;
6272+void au_dpri_whlist(struct au_nhash *whlist);
6273+struct au_vdir;
6274+void au_dpri_vdir(struct au_vdir *vdir);
dece6358 6275+struct inode;
1facf9fc 6276+void au_dpri_inode(struct inode *inode);
2cbb1c4b 6277+void au_dpri_dalias(struct inode *inode);
1facf9fc 6278+void au_dpri_dentry(struct dentry *dentry);
dece6358 6279+struct file;
1facf9fc 6280+void au_dpri_file(struct file *filp);
dece6358 6281+struct super_block;
1facf9fc 6282+void au_dpri_sb(struct super_block *sb);
6283+
6284+void au_dbg_sleep_jiffy(int jiffy);
dece6358 6285+struct iattr;
1facf9fc 6286+void au_dbg_iattr(struct iattr *ia);
6287+
027c5e7a
AM
6288+#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__)
6289+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line);
1facf9fc 6290+void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen);
6291+void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen);
6292+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
1facf9fc 6293+void au_dbg_verify_kthread(void);
6294+
6295+int __init au_debug_init(void);
6296+void au_debug_sbinfo_init(struct au_sbinfo *sbinfo);
6297+#define AuDbgWhlist(w) do { \
6298+ AuDbg(#w "\n"); \
6299+ au_dpri_whlist(w); \
6300+} while (0)
6301+
6302+#define AuDbgVdir(v) do { \
6303+ AuDbg(#v "\n"); \
6304+ au_dpri_vdir(v); \
6305+} while (0)
6306+
6307+#define AuDbgInode(i) do { \
6308+ AuDbg(#i "\n"); \
6309+ au_dpri_inode(i); \
6310+} while (0)
6311+
2cbb1c4b
JR
6312+#define AuDbgDAlias(i) do { \
6313+ AuDbg(#i "\n"); \
6314+ au_dpri_dalias(i); \
6315+} while (0)
6316+
1facf9fc 6317+#define AuDbgDentry(d) do { \
6318+ AuDbg(#d "\n"); \
6319+ au_dpri_dentry(d); \
6320+} while (0)
6321+
6322+#define AuDbgFile(f) do { \
6323+ AuDbg(#f "\n"); \
6324+ au_dpri_file(f); \
6325+} while (0)
6326+
6327+#define AuDbgSb(sb) do { \
6328+ AuDbg(#sb "\n"); \
6329+ au_dpri_sb(sb); \
6330+} while (0)
6331+
6332+#define AuDbgSleep(sec) do { \
6333+ AuDbg("sleep %d sec\n", sec); \
6334+ ssleep(sec); \
6335+} while (0)
6336+
6337+#define AuDbgSleepJiffy(jiffy) do { \
6338+ AuDbg("sleep %d jiffies\n", jiffy); \
6339+ au_dbg_sleep_jiffy(jiffy); \
6340+} while (0)
6341+
6342+#define AuDbgIAttr(ia) do { \
6343+ AuDbg("ia_valid 0x%x\n", (ia)->ia_valid); \
6344+ au_dbg_iattr(ia); \
6345+} while (0)
4a4d8108
AM
6346+
6347+#define AuDbgSym(addr) do { \
6348+ char sym[KSYM_SYMBOL_LEN]; \
6349+ sprint_symbol(sym, (unsigned long)addr); \
6350+ AuDbg("%s\n", sym); \
6351+} while (0)
6352+
6353+#define AuInfoSym(addr) do { \
6354+ char sym[KSYM_SYMBOL_LEN]; \
6355+ sprint_symbol(sym, (unsigned long)addr); \
6356+ AuInfo("%s\n", sym); \
6357+} while (0)
1facf9fc 6358+#else
027c5e7a 6359+AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
4a4d8108
AM
6360+AuStubVoid(au_dbg_verify_dir_parent, struct dentry *dentry, unsigned int sigen)
6361+AuStubVoid(au_dbg_verify_nondir_parent, struct dentry *dentry,
6362+ unsigned int sigen)
6363+AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
6364+AuStubVoid(au_dbg_verify_kthread, void)
6365+AuStubInt0(__init au_debug_init, void)
6366+AuStubVoid(au_debug_sbinfo_init, struct au_sbinfo *sbinfo)
1facf9fc 6367+
1facf9fc 6368+#define AuDbgWhlist(w) do {} while (0)
6369+#define AuDbgVdir(v) do {} while (0)
6370+#define AuDbgInode(i) do {} while (0)
2cbb1c4b 6371+#define AuDbgDAlias(i) do {} while (0)
1facf9fc 6372+#define AuDbgDentry(d) do {} while (0)
6373+#define AuDbgFile(f) do {} while (0)
6374+#define AuDbgSb(sb) do {} while (0)
6375+#define AuDbgSleep(sec) do {} while (0)
6376+#define AuDbgSleepJiffy(jiffy) do {} while (0)
6377+#define AuDbgIAttr(ia) do {} while (0)
4a4d8108
AM
6378+#define AuDbgSym(addr) do {} while (0)
6379+#define AuInfoSym(addr) do {} while (0)
1facf9fc 6380+#endif /* CONFIG_AUFS_DEBUG */
6381+
6382+/* ---------------------------------------------------------------------- */
6383+
6384+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
6385+int __init au_sysrq_init(void);
6386+void au_sysrq_fin(void);
6387+
6388+#ifdef CONFIG_HW_CONSOLE
6389+#define au_dbg_blocked() do { \
6390+ WARN_ON(1); \
0c5527e5 6391+ handle_sysrq('w'); \
1facf9fc 6392+} while (0)
6393+#else
4a4d8108 6394+AuStubVoid(au_dbg_blocked, void)
1facf9fc 6395+#endif
6396+
6397+#else
4a4d8108
AM
6398+AuStubInt0(__init au_sysrq_init, void)
6399+AuStubVoid(au_sysrq_fin, void)
6400+AuStubVoid(au_dbg_blocked, void)
1facf9fc 6401+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
6402+
6403+#endif /* __KERNEL__ */
6404+#endif /* __AUFS_DEBUG_H__ */
7f207e10
AM
6405diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
6406--- /usr/share/empty/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100
f6b6e03d 6407+++ linux/fs/aufs/dentry.c 2014-01-27 23:16:52.701753487 +0100
523b37e3 6408@@ -0,0 +1,1081 @@
1facf9fc 6409+/*
523b37e3 6410+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 6411+ *
6412+ * This program, aufs is free software; you can redistribute it and/or modify
6413+ * it under the terms of the GNU General Public License as published by
6414+ * the Free Software Foundation; either version 2 of the License, or
6415+ * (at your option) any later version.
dece6358
AM
6416+ *
6417+ * This program is distributed in the hope that it will be useful,
6418+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6419+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6420+ * GNU General Public License for more details.
6421+ *
6422+ * You should have received a copy of the GNU General Public License
523b37e3 6423+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6424+ */
6425+
6426+/*
6427+ * lookup and dentry operations
6428+ */
6429+
dece6358 6430+#include <linux/namei.h>
1facf9fc 6431+#include "aufs.h"
6432+
1facf9fc 6433+#define AuLkup_ALLOW_NEG 1
6434+#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name)
7f207e10
AM
6435+#define au_fset_lkup(flags, name) \
6436+ do { (flags) |= AuLkup_##name; } while (0)
6437+#define au_fclr_lkup(flags, name) \
6438+ do { (flags) &= ~AuLkup_##name; } while (0)
1facf9fc 6439+
6440+struct au_do_lookup_args {
6441+ unsigned int flags;
6442+ mode_t type;
1facf9fc 6443+};
6444+
6445+/*
6446+ * returns positive/negative dentry, NULL or an error.
6447+ * NULL means whiteout-ed or not-found.
6448+ */
6449+static struct dentry*
6450+au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
6451+ aufs_bindex_t bindex, struct qstr *wh_name,
6452+ struct au_do_lookup_args *args)
6453+{
6454+ struct dentry *h_dentry;
6455+ struct inode *h_inode, *inode;
1facf9fc 6456+ struct au_branch *br;
6457+ int wh_found, opq;
6458+ unsigned char wh_able;
6459+ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
6460+
1facf9fc 6461+ wh_found = 0;
6462+ br = au_sbr(dentry->d_sb, bindex);
6463+ wh_able = !!au_br_whable(br->br_perm);
6464+ if (wh_able)
6465+ wh_found = au_wh_test(h_parent, wh_name, br, /*try_sio*/0);
6466+ h_dentry = ERR_PTR(wh_found);
6467+ if (!wh_found)
6468+ goto real_lookup;
6469+ if (unlikely(wh_found < 0))
6470+ goto out;
6471+
6472+ /* We found a whiteout */
6473+ /* au_set_dbend(dentry, bindex); */
6474+ au_set_dbwh(dentry, bindex);
6475+ if (!allow_neg)
6476+ return NULL; /* success */
6477+
4f0767ce 6478+real_lookup:
b4510431 6479+ h_dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
1facf9fc 6480+ if (IS_ERR(h_dentry))
6481+ goto out;
6482+
6483+ h_inode = h_dentry->d_inode;
6484+ if (!h_inode) {
6485+ if (!allow_neg)
6486+ goto out_neg;
6487+ } else if (wh_found
6488+ || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
6489+ goto out_neg;
6490+
6491+ if (au_dbend(dentry) <= bindex)
6492+ au_set_dbend(dentry, bindex);
6493+ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
6494+ au_set_dbstart(dentry, bindex);
6495+ au_set_h_dptr(dentry, bindex, h_dentry);
6496+
6497+ inode = dentry->d_inode;
6498+ if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able
6499+ || (inode && !S_ISDIR(inode->i_mode)))
6500+ goto out; /* success */
6501+
6502+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
6503+ opq = au_diropq_test(h_dentry, br);
6504+ mutex_unlock(&h_inode->i_mutex);
6505+ if (opq > 0)
6506+ au_set_dbdiropq(dentry, bindex);
6507+ else if (unlikely(opq < 0)) {
6508+ au_set_h_dptr(dentry, bindex, NULL);
6509+ h_dentry = ERR_PTR(opq);
6510+ }
6511+ goto out;
6512+
4f0767ce 6513+out_neg:
1facf9fc 6514+ dput(h_dentry);
6515+ h_dentry = NULL;
4f0767ce 6516+out:
1facf9fc 6517+ return h_dentry;
6518+}
6519+
dece6358
AM
6520+static int au_test_shwh(struct super_block *sb, const struct qstr *name)
6521+{
6522+ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
6523+ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
6524+ return -EPERM;
6525+ return 0;
6526+}
6527+
1facf9fc 6528+/*
6529+ * returns the number of lower positive dentries,
6530+ * otherwise an error.
6531+ * can be called at unlinking with @type is zero.
6532+ */
537831f9 6533+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type)
1facf9fc 6534+{
6535+ int npositive, err;
6536+ aufs_bindex_t bindex, btail, bdiropq;
6537+ unsigned char isdir;
6538+ struct qstr whname;
6539+ struct au_do_lookup_args args = {
b4510431 6540+ .flags = 0,
537831f9 6541+ .type = type
1facf9fc 6542+ };
6543+ const struct qstr *name = &dentry->d_name;
6544+ struct dentry *parent;
6545+ struct inode *inode;
6546+
dece6358
AM
6547+ err = au_test_shwh(dentry->d_sb, name);
6548+ if (unlikely(err))
1facf9fc 6549+ goto out;
6550+
6551+ err = au_wh_name_alloc(&whname, name);
6552+ if (unlikely(err))
6553+ goto out;
6554+
6555+ inode = dentry->d_inode;
6556+ isdir = !!(inode && S_ISDIR(inode->i_mode));
6557+ if (!type)
6558+ au_fset_lkup(args.flags, ALLOW_NEG);
6559+
6560+ npositive = 0;
4a4d8108 6561+ parent = dget_parent(dentry);
1facf9fc 6562+ btail = au_dbtaildir(parent);
6563+ for (bindex = bstart; bindex <= btail; bindex++) {
6564+ struct dentry *h_parent, *h_dentry;
6565+ struct inode *h_inode, *h_dir;
6566+
6567+ h_dentry = au_h_dptr(dentry, bindex);
6568+ if (h_dentry) {
6569+ if (h_dentry->d_inode)
6570+ npositive++;
6571+ if (type != S_IFDIR)
6572+ break;
6573+ continue;
6574+ }
6575+ h_parent = au_h_dptr(parent, bindex);
6576+ if (!h_parent)
6577+ continue;
6578+ h_dir = h_parent->d_inode;
6579+ if (!h_dir || !S_ISDIR(h_dir->i_mode))
6580+ continue;
6581+
6582+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
6583+ h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
6584+ &args);
6585+ mutex_unlock(&h_dir->i_mutex);
6586+ err = PTR_ERR(h_dentry);
6587+ if (IS_ERR(h_dentry))
4a4d8108 6588+ goto out_parent;
1facf9fc 6589+ au_fclr_lkup(args.flags, ALLOW_NEG);
6590+
6591+ if (au_dbwh(dentry) >= 0)
6592+ break;
6593+ if (!h_dentry)
6594+ continue;
6595+ h_inode = h_dentry->d_inode;
6596+ if (!h_inode)
6597+ continue;
6598+ npositive++;
6599+ if (!args.type)
6600+ args.type = h_inode->i_mode & S_IFMT;
6601+ if (args.type != S_IFDIR)
6602+ break;
6603+ else if (isdir) {
6604+ /* the type of lower may be different */
6605+ bdiropq = au_dbdiropq(dentry);
6606+ if (bdiropq >= 0 && bdiropq <= bindex)
6607+ break;
6608+ }
6609+ }
6610+
6611+ if (npositive) {
6612+ AuLabel(positive);
6613+ au_update_dbstart(dentry);
6614+ }
6615+ err = npositive;
6616+ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
027c5e7a 6617+ && au_dbstart(dentry) < 0)) {
1facf9fc 6618+ err = -EIO;
523b37e3
AM
6619+ AuIOErr("both of real entry and whiteout found, %pd, err %d\n",
6620+ dentry, err);
027c5e7a 6621+ }
1facf9fc 6622+
4f0767ce 6623+out_parent:
4a4d8108 6624+ dput(parent);
1facf9fc 6625+ kfree(whname.name);
4f0767ce 6626+out:
1facf9fc 6627+ return err;
6628+}
6629+
6630+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
6631+ struct au_branch *br)
6632+{
6633+ struct dentry *dentry;
6634+ int wkq_err;
6635+
6636+ if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC))
b4510431 6637+ dentry = vfsub_lkup_one(name, parent);
1facf9fc 6638+ else {
b4510431
AM
6639+ struct vfsub_lkup_one_args args = {
6640+ .errp = &dentry,
6641+ .name = name,
6642+ .parent = parent
1facf9fc 6643+ };
6644+
b4510431 6645+ wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args);
1facf9fc 6646+ if (unlikely(wkq_err))
6647+ dentry = ERR_PTR(wkq_err);
6648+ }
6649+
6650+ return dentry;
6651+}
6652+
6653+/*
6654+ * lookup @dentry on @bindex which should be negative.
6655+ */
86dc4139 6656+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh)
1facf9fc 6657+{
6658+ int err;
6659+ struct dentry *parent, *h_parent, *h_dentry;
86dc4139 6660+ struct au_branch *br;
1facf9fc 6661+
1facf9fc 6662+ parent = dget_parent(dentry);
6663+ h_parent = au_h_dptr(parent, bindex);
86dc4139
AM
6664+ br = au_sbr(dentry->d_sb, bindex);
6665+ if (wh)
6666+ h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
6667+ else
6668+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent, br);
1facf9fc 6669+ err = PTR_ERR(h_dentry);
6670+ if (IS_ERR(h_dentry))
6671+ goto out;
6672+ if (unlikely(h_dentry->d_inode)) {
6673+ err = -EIO;
523b37e3 6674+ AuIOErr("%pd should be negative on b%d.\n", h_dentry, bindex);
1facf9fc 6675+ dput(h_dentry);
6676+ goto out;
6677+ }
6678+
4a4d8108 6679+ err = 0;
1facf9fc 6680+ if (bindex < au_dbstart(dentry))
6681+ au_set_dbstart(dentry, bindex);
6682+ if (au_dbend(dentry) < bindex)
6683+ au_set_dbend(dentry, bindex);
6684+ au_set_h_dptr(dentry, bindex, h_dentry);
1facf9fc 6685+
4f0767ce 6686+out:
1facf9fc 6687+ dput(parent);
6688+ return err;
6689+}
6690+
6691+/* ---------------------------------------------------------------------- */
6692+
6693+/* subset of struct inode */
6694+struct au_iattr {
6695+ unsigned long i_ino;
6696+ /* unsigned int i_nlink; */
0c3ec466
AM
6697+ kuid_t i_uid;
6698+ kgid_t i_gid;
1facf9fc 6699+ u64 i_version;
6700+/*
6701+ loff_t i_size;
6702+ blkcnt_t i_blocks;
6703+*/
6704+ umode_t i_mode;
6705+};
6706+
6707+static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
6708+{
6709+ ia->i_ino = h_inode->i_ino;
6710+ /* ia->i_nlink = h_inode->i_nlink; */
6711+ ia->i_uid = h_inode->i_uid;
6712+ ia->i_gid = h_inode->i_gid;
6713+ ia->i_version = h_inode->i_version;
6714+/*
6715+ ia->i_size = h_inode->i_size;
6716+ ia->i_blocks = h_inode->i_blocks;
6717+*/
6718+ ia->i_mode = (h_inode->i_mode & S_IFMT);
6719+}
6720+
6721+static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
6722+{
6723+ return ia->i_ino != h_inode->i_ino
6724+ /* || ia->i_nlink != h_inode->i_nlink */
0c3ec466 6725+ || !uid_eq(ia->i_uid, h_inode->i_uid)
2dfbb274 6726+ || !gid_eq(ia->i_gid, h_inode->i_gid)
1facf9fc 6727+ || ia->i_version != h_inode->i_version
6728+/*
6729+ || ia->i_size != h_inode->i_size
6730+ || ia->i_blocks != h_inode->i_blocks
6731+*/
6732+ || ia->i_mode != (h_inode->i_mode & S_IFMT);
6733+}
6734+
6735+static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
6736+ struct au_branch *br)
6737+{
6738+ int err;
6739+ struct au_iattr ia;
6740+ struct inode *h_inode;
6741+ struct dentry *h_d;
6742+ struct super_block *h_sb;
6743+
6744+ err = 0;
6745+ memset(&ia, -1, sizeof(ia));
6746+ h_sb = h_dentry->d_sb;
6747+ h_inode = h_dentry->d_inode;
6748+ if (h_inode)
6749+ au_iattr_save(&ia, h_inode);
6750+ else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
6751+ /* nfs d_revalidate may return 0 for negative dentry */
6752+ /* fuse d_revalidate always return 0 for negative dentry */
6753+ goto out;
6754+
6755+ /* main purpose is namei.c:cached_lookup() and d_revalidate */
b4510431 6756+ h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent);
1facf9fc 6757+ err = PTR_ERR(h_d);
6758+ if (IS_ERR(h_d))
6759+ goto out;
6760+
6761+ err = 0;
6762+ if (unlikely(h_d != h_dentry
6763+ || h_d->d_inode != h_inode
6764+ || (h_inode && au_iattr_test(&ia, h_inode))))
6765+ err = au_busy_or_stale();
6766+ dput(h_d);
6767+
4f0767ce 6768+out:
1facf9fc 6769+ AuTraceErr(err);
6770+ return err;
6771+}
6772+
6773+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
6774+ struct dentry *h_parent, struct au_branch *br)
6775+{
6776+ int err;
6777+
6778+ err = 0;
027c5e7a
AM
6779+ if (udba == AuOpt_UDBA_REVAL
6780+ && !au_test_fs_remote(h_dentry->d_sb)) {
1facf9fc 6781+ IMustLock(h_dir);
6782+ err = (h_dentry->d_parent->d_inode != h_dir);
027c5e7a 6783+ } else if (udba != AuOpt_UDBA_NONE)
1facf9fc 6784+ err = au_h_verify_dentry(h_dentry, h_parent, br);
6785+
6786+ return err;
6787+}
6788+
6789+/* ---------------------------------------------------------------------- */
6790+
027c5e7a 6791+static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
1facf9fc 6792+{
027c5e7a 6793+ int err;
1facf9fc 6794+ aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq;
027c5e7a
AM
6795+ struct au_hdentry tmp, *p, *q;
6796+ struct au_dinfo *dinfo;
6797+ struct super_block *sb;
1facf9fc 6798+
027c5e7a 6799+ DiMustWriteLock(dentry);
1308ab2a 6800+
027c5e7a
AM
6801+ sb = dentry->d_sb;
6802+ dinfo = au_di(dentry);
1facf9fc 6803+ bend = dinfo->di_bend;
6804+ bwh = dinfo->di_bwh;
6805+ bdiropq = dinfo->di_bdiropq;
027c5e7a 6806+ p = dinfo->di_hdentry + dinfo->di_bstart;
1facf9fc 6807+ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
027c5e7a 6808+ if (!p->hd_dentry)
1facf9fc 6809+ continue;
6810+
027c5e7a
AM
6811+ new_bindex = au_br_index(sb, p->hd_id);
6812+ if (new_bindex == bindex)
1facf9fc 6813+ continue;
1facf9fc 6814+
1facf9fc 6815+ if (dinfo->di_bwh == bindex)
6816+ bwh = new_bindex;
6817+ if (dinfo->di_bdiropq == bindex)
6818+ bdiropq = new_bindex;
6819+ if (new_bindex < 0) {
6820+ au_hdput(p);
6821+ p->hd_dentry = NULL;
6822+ continue;
6823+ }
6824+
6825+ /* swap two lower dentries, and loop again */
6826+ q = dinfo->di_hdentry + new_bindex;
6827+ tmp = *q;
6828+ *q = *p;
6829+ *p = tmp;
6830+ if (tmp.hd_dentry) {
6831+ bindex--;
6832+ p--;
6833+ }
6834+ }
6835+
1facf9fc 6836+ dinfo->di_bwh = -1;
6837+ if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))
6838+ dinfo->di_bwh = bwh;
6839+
6840+ dinfo->di_bdiropq = -1;
6841+ if (bdiropq >= 0
6842+ && bdiropq <= au_sbend(sb)
6843+ && au_sbr_whable(sb, bdiropq))
6844+ dinfo->di_bdiropq = bdiropq;
6845+
027c5e7a
AM
6846+ err = -EIO;
6847+ dinfo->di_bstart = -1;
6848+ dinfo->di_bend = -1;
1facf9fc 6849+ bend = au_dbend(parent);
6850+ p = dinfo->di_hdentry;
6851+ for (bindex = 0; bindex <= bend; bindex++, p++)
6852+ if (p->hd_dentry) {
6853+ dinfo->di_bstart = bindex;
6854+ break;
6855+ }
6856+
027c5e7a
AM
6857+ if (dinfo->di_bstart >= 0) {
6858+ p = dinfo->di_hdentry + bend;
6859+ for (bindex = bend; bindex >= 0; bindex--, p--)
6860+ if (p->hd_dentry) {
6861+ dinfo->di_bend = bindex;
6862+ err = 0;
6863+ break;
6864+ }
6865+ }
6866+
6867+ return err;
1facf9fc 6868+}
6869+
027c5e7a 6870+static void au_do_hide(struct dentry *dentry)
1facf9fc 6871+{
027c5e7a 6872+ struct inode *inode;
1facf9fc 6873+
027c5e7a
AM
6874+ inode = dentry->d_inode;
6875+ if (inode) {
6876+ if (!S_ISDIR(inode->i_mode)) {
6877+ if (inode->i_nlink && !d_unhashed(dentry))
6878+ drop_nlink(inode);
6879+ } else {
6880+ clear_nlink(inode);
6881+ /* stop next lookup */
6882+ inode->i_flags |= S_DEAD;
6883+ }
6884+ smp_mb(); /* necessary? */
6885+ }
6886+ d_drop(dentry);
6887+}
1308ab2a 6888+
027c5e7a
AM
6889+static int au_hide_children(struct dentry *parent)
6890+{
6891+ int err, i, j, ndentry;
6892+ struct au_dcsub_pages dpages;
6893+ struct au_dpage *dpage;
6894+ struct dentry *dentry;
1facf9fc 6895+
027c5e7a 6896+ err = au_dpages_init(&dpages, GFP_NOFS);
1facf9fc 6897+ if (unlikely(err))
6898+ goto out;
027c5e7a
AM
6899+ err = au_dcsub_pages(&dpages, parent, NULL, NULL);
6900+ if (unlikely(err))
6901+ goto out_dpages;
1facf9fc 6902+
027c5e7a
AM
6903+ /* in reverse order */
6904+ for (i = dpages.ndpage - 1; i >= 0; i--) {
6905+ dpage = dpages.dpages + i;
6906+ ndentry = dpage->ndentry;
6907+ for (j = ndentry - 1; j >= 0; j--) {
6908+ dentry = dpage->dentries[j];
6909+ if (dentry != parent)
6910+ au_do_hide(dentry);
6911+ }
6912+ }
1facf9fc 6913+
027c5e7a
AM
6914+out_dpages:
6915+ au_dpages_free(&dpages);
4f0767ce 6916+out:
027c5e7a 6917+ return err;
1facf9fc 6918+}
6919+
027c5e7a 6920+static void au_hide(struct dentry *dentry)
1facf9fc 6921+{
027c5e7a
AM
6922+ int err;
6923+ struct inode *inode;
1facf9fc 6924+
027c5e7a
AM
6925+ AuDbgDentry(dentry);
6926+ inode = dentry->d_inode;
6927+ if (inode && S_ISDIR(inode->i_mode)) {
6928+ /* shrink_dcache_parent(dentry); */
6929+ err = au_hide_children(dentry);
6930+ if (unlikely(err))
523b37e3
AM
6931+ AuIOErr("%pd, failed hiding children, ignored %d\n",
6932+ dentry, err);
027c5e7a
AM
6933+ }
6934+ au_do_hide(dentry);
6935+}
1facf9fc 6936+
027c5e7a
AM
6937+/*
6938+ * By adding a dirty branch, a cached dentry may be affected in various ways.
6939+ *
6940+ * a dirty branch is added
6941+ * - on the top of layers
6942+ * - in the middle of layers
6943+ * - to the bottom of layers
6944+ *
6945+ * on the added branch there exists
6946+ * - a whiteout
6947+ * - a diropq
6948+ * - a same named entry
6949+ * + exist
6950+ * * negative --> positive
6951+ * * positive --> positive
6952+ * - type is unchanged
6953+ * - type is changed
6954+ * + doesn't exist
6955+ * * negative --> negative
6956+ * * positive --> negative (rejected by au_br_del() for non-dir case)
6957+ * - none
6958+ */
6959+static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
6960+ struct au_dinfo *tmp)
6961+{
6962+ int err;
6963+ aufs_bindex_t bindex, bend;
6964+ struct {
6965+ struct dentry *dentry;
6966+ struct inode *inode;
6967+ mode_t mode;
6968+ } orig_h, tmp_h;
6969+ struct au_hdentry *hd;
6970+ struct inode *inode, *h_inode;
6971+ struct dentry *h_dentry;
6972+
6973+ err = 0;
6974+ AuDebugOn(dinfo->di_bstart < 0);
6975+ orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry;
6976+ orig_h.inode = orig_h.dentry->d_inode;
6977+ orig_h.mode = 0;
6978+ if (orig_h.inode)
6979+ orig_h.mode = orig_h.inode->i_mode & S_IFMT;
6980+ memset(&tmp_h, 0, sizeof(tmp_h));
6981+ if (tmp->di_bstart >= 0) {
6982+ tmp_h.dentry = tmp->di_hdentry[tmp->di_bstart].hd_dentry;
6983+ tmp_h.inode = tmp_h.dentry->d_inode;
6984+ if (tmp_h.inode)
6985+ tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
6986+ }
6987+
6988+ inode = dentry->d_inode;
6989+ if (!orig_h.inode) {
6990+ AuDbg("nagative originally\n");
6991+ if (inode) {
6992+ au_hide(dentry);
6993+ goto out;
6994+ }
6995+ AuDebugOn(inode);
6996+ AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
6997+ AuDebugOn(dinfo->di_bdiropq != -1);
6998+
6999+ if (!tmp_h.inode) {
7000+ AuDbg("negative --> negative\n");
7001+ /* should have only one negative lower */
7002+ if (tmp->di_bstart >= 0
7003+ && tmp->di_bstart < dinfo->di_bstart) {
7004+ AuDebugOn(tmp->di_bstart != tmp->di_bend);
7005+ AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
7006+ au_set_h_dptr(dentry, dinfo->di_bstart, NULL);
7007+ au_di_cp(dinfo, tmp);
7008+ hd = tmp->di_hdentry + tmp->di_bstart;
7009+ au_set_h_dptr(dentry, tmp->di_bstart,
7010+ dget(hd->hd_dentry));
7011+ }
7012+ au_dbg_verify_dinode(dentry);
7013+ } else {
7014+ AuDbg("negative --> positive\n");
7015+ /*
7016+ * similar to the behaviour of creating with bypassing
7017+ * aufs.
7018+ * unhash it in order to force an error in the
7019+ * succeeding create operation.
7020+ * we should not set S_DEAD here.
7021+ */
7022+ d_drop(dentry);
7023+ /* au_di_swap(tmp, dinfo); */
7024+ au_dbg_verify_dinode(dentry);
7025+ }
7026+ } else {
7027+ AuDbg("positive originally\n");
7028+ /* inode may be NULL */
7029+ AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode);
7030+ if (!tmp_h.inode) {
7031+ AuDbg("positive --> negative\n");
7032+ /* or bypassing aufs */
7033+ au_hide(dentry);
7034+ if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_bstart)
7035+ dinfo->di_bwh = tmp->di_bwh;
7036+ if (inode)
7037+ err = au_refresh_hinode_self(inode);
7038+ au_dbg_verify_dinode(dentry);
7039+ } else if (orig_h.mode == tmp_h.mode) {
7040+ AuDbg("positive --> positive, same type\n");
7041+ if (!S_ISDIR(orig_h.mode)
7042+ && dinfo->di_bstart > tmp->di_bstart) {
7043+ /*
7044+ * similar to the behaviour of removing and
7045+ * creating.
7046+ */
7047+ au_hide(dentry);
7048+ if (inode)
7049+ err = au_refresh_hinode_self(inode);
7050+ au_dbg_verify_dinode(dentry);
7051+ } else {
7052+ /* fill empty slots */
7053+ if (dinfo->di_bstart > tmp->di_bstart)
7054+ dinfo->di_bstart = tmp->di_bstart;
7055+ if (dinfo->di_bend < tmp->di_bend)
7056+ dinfo->di_bend = tmp->di_bend;
7057+ dinfo->di_bwh = tmp->di_bwh;
7058+ dinfo->di_bdiropq = tmp->di_bdiropq;
7059+ hd = tmp->di_hdentry;
7060+ bend = dinfo->di_bend;
7061+ for (bindex = tmp->di_bstart; bindex <= bend;
7062+ bindex++) {
7063+ if (au_h_dptr(dentry, bindex))
7064+ continue;
7065+ h_dentry = hd[bindex].hd_dentry;
7066+ if (!h_dentry)
7067+ continue;
7068+ h_inode = h_dentry->d_inode;
7069+ AuDebugOn(!h_inode);
7070+ AuDebugOn(orig_h.mode
7071+ != (h_inode->i_mode
7072+ & S_IFMT));
7073+ au_set_h_dptr(dentry, bindex,
7074+ dget(h_dentry));
7075+ }
7076+ err = au_refresh_hinode(inode, dentry);
7077+ au_dbg_verify_dinode(dentry);
7078+ }
7079+ } else {
7080+ AuDbg("positive --> positive, different type\n");
7081+ /* similar to the behaviour of removing and creating */
7082+ au_hide(dentry);
7083+ if (inode)
7084+ err = au_refresh_hinode_self(inode);
7085+ au_dbg_verify_dinode(dentry);
7086+ }
7087+ }
7088+
7089+out:
7090+ return err;
7091+}
7092+
7093+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
7094+{
7095+ int err, ebrange;
7096+ unsigned int sigen;
7097+ struct au_dinfo *dinfo, *tmp;
7098+ struct super_block *sb;
7099+ struct inode *inode;
7100+
7101+ DiMustWriteLock(dentry);
7102+ AuDebugOn(IS_ROOT(dentry));
7103+ AuDebugOn(!parent->d_inode);
7104+
7105+ sb = dentry->d_sb;
7106+ inode = dentry->d_inode;
7107+ sigen = au_sigen(sb);
7108+ err = au_digen_test(parent, sigen);
7109+ if (unlikely(err))
7110+ goto out;
7111+
7112+ dinfo = au_di(dentry);
7113+ err = au_di_realloc(dinfo, au_sbend(sb) + 1);
7114+ if (unlikely(err))
7115+ goto out;
7116+ ebrange = au_dbrange_test(dentry);
7117+ if (!ebrange)
7118+ ebrange = au_do_refresh_hdentry(dentry, parent);
7119+
7120+ if (d_unhashed(dentry) || ebrange) {
7121+ AuDebugOn(au_dbstart(dentry) < 0 && au_dbend(dentry) >= 0);
7122+ if (inode)
7123+ err = au_refresh_hinode_self(inode);
7124+ au_dbg_verify_dinode(dentry);
7125+ if (!err)
7126+ goto out_dgen; /* success */
7127+ goto out;
7128+ }
7129+
7130+ /* temporary dinfo */
7131+ AuDbgDentry(dentry);
7132+ err = -ENOMEM;
7133+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
7134+ if (unlikely(!tmp))
7135+ goto out;
7136+ au_di_swap(tmp, dinfo);
7137+ /* returns the number of positive dentries */
7138+ /*
7139+ * if current working dir is removed, it returns an error.
7140+ * but the dentry is legal.
7141+ */
537831f9 7142+ err = au_lkup_dentry(dentry, /*bstart*/0, /*type*/0);
027c5e7a
AM
7143+ AuDbgDentry(dentry);
7144+ au_di_swap(tmp, dinfo);
7145+ if (err == -ENOENT)
7146+ err = 0;
7147+ if (err >= 0) {
7148+ /* compare/refresh by dinfo */
7149+ AuDbgDentry(dentry);
7150+ err = au_refresh_by_dinfo(dentry, dinfo, tmp);
7151+ au_dbg_verify_dinode(dentry);
7152+ AuTraceErr(err);
7153+ }
7154+ au_rw_write_unlock(&tmp->di_rwsem);
7155+ au_di_free(tmp);
7156+ if (unlikely(err))
7157+ goto out;
7158+
7159+out_dgen:
7160+ au_update_digen(dentry);
7161+out:
7162+ if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) {
523b37e3 7163+ AuIOErr("failed refreshing %pd, %d\n", dentry, err);
027c5e7a
AM
7164+ AuDbgDentry(dentry);
7165+ }
7166+ AuTraceErr(err);
7167+ return err;
7168+}
7169+
b4510431
AM
7170+static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags,
7171+ struct dentry *dentry, aufs_bindex_t bindex)
027c5e7a
AM
7172+{
7173+ int err, valid;
027c5e7a
AM
7174+
7175+ err = 0;
7176+ if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE))
7177+ goto out;
027c5e7a
AM
7178+
7179+ AuDbg("b%d\n", bindex);
b4510431
AM
7180+ /*
7181+ * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
7182+ * due to whiteout and branch permission.
7183+ */
7184+ flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
7185+ | LOOKUP_FOLLOW | LOOKUP_EXCL);
7186+ /* it may return tri-state */
7187+ valid = h_dentry->d_op->d_revalidate(h_dentry, flags);
1facf9fc 7188+
7189+ if (unlikely(valid < 0))
7190+ err = valid;
7191+ else if (!valid)
7192+ err = -EINVAL;
7193+
4f0767ce 7194+out:
1facf9fc 7195+ AuTraceErr(err);
7196+ return err;
7197+}
7198+
7199+/* todo: remove this */
7200+static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
b4510431 7201+ unsigned int flags, int do_udba)
1facf9fc 7202+{
7203+ int err;
7204+ umode_t mode, h_mode;
7205+ aufs_bindex_t bindex, btail, bstart, ibs, ibe;
523b37e3 7206+ unsigned char plus, unhashed, is_root, h_plus, h_nfs;
4a4d8108 7207+ struct inode *h_inode, *h_cached_inode;
1facf9fc 7208+ struct dentry *h_dentry;
7209+ struct qstr *name, *h_name;
7210+
7211+ err = 0;
7212+ plus = 0;
7213+ mode = 0;
1facf9fc 7214+ ibs = -1;
7215+ ibe = -1;
7216+ unhashed = !!d_unhashed(dentry);
7217+ is_root = !!IS_ROOT(dentry);
7218+ name = &dentry->d_name;
7219+
7220+ /*
7f207e10
AM
7221+ * Theoretically, REVAL test should be unnecessary in case of
7222+ * {FS,I}NOTIFY.
7223+ * But {fs,i}notify doesn't fire some necessary events,
1facf9fc 7224+ * IN_ATTRIB for atime/nlink/pageio
7225+ * IN_DELETE for NFS dentry
7226+ * Let's do REVAL test too.
7227+ */
7228+ if (do_udba && inode) {
7229+ mode = (inode->i_mode & S_IFMT);
7230+ plus = (inode->i_nlink > 0);
1facf9fc 7231+ ibs = au_ibstart(inode);
7232+ ibe = au_ibend(inode);
7233+ }
7234+
7235+ bstart = au_dbstart(dentry);
7236+ btail = bstart;
7237+ if (inode && S_ISDIR(inode->i_mode))
7238+ btail = au_dbtaildir(dentry);
7239+ for (bindex = bstart; bindex <= btail; bindex++) {
7240+ h_dentry = au_h_dptr(dentry, bindex);
7241+ if (!h_dentry)
7242+ continue;
7243+
523b37e3
AM
7244+ AuDbg("b%d, %pd\n", bindex, h_dentry);
7245+ h_nfs = !!au_test_nfs(h_dentry->d_sb);
027c5e7a 7246+ spin_lock(&h_dentry->d_lock);
1facf9fc 7247+ h_name = &h_dentry->d_name;
7248+ if (unlikely(do_udba
7249+ && !is_root
523b37e3
AM
7250+ && ((!h_nfs
7251+ && (unhashed != !!d_unhashed(h_dentry)
7252+ || name->len != h_name->len
7253+ || memcmp(name->name, h_name->name,
7254+ name->len)))
7255+ || (h_nfs
7256+ && !(flags & LOOKUP_OPEN)
7257+ && (h_dentry->d_flags
7258+ & DCACHE_NFSFS_RENAMED)))
1facf9fc 7259+ )) {
523b37e3
AM
7260+ AuDbg("unhash 0x%x 0x%x, %pd %pd\n",
7261+ unhashed, d_unhashed(h_dentry),
7262+ dentry, h_dentry);
027c5e7a 7263+ spin_unlock(&h_dentry->d_lock);
1facf9fc 7264+ goto err;
7265+ }
027c5e7a 7266+ spin_unlock(&h_dentry->d_lock);
1facf9fc 7267+
b4510431 7268+ err = au_do_h_d_reval(h_dentry, flags, dentry, bindex);
1facf9fc 7269+ if (unlikely(err))
7270+ /* do not goto err, to keep the errno */
7271+ break;
7272+
7273+ /* todo: plink too? */
7274+ if (!do_udba)
7275+ continue;
7276+
7277+ /* UDBA tests */
7278+ h_inode = h_dentry->d_inode;
7279+ if (unlikely(!!inode != !!h_inode))
7280+ goto err;
7281+
7282+ h_plus = plus;
7283+ h_mode = mode;
7284+ h_cached_inode = h_inode;
7285+ if (h_inode) {
7286+ h_mode = (h_inode->i_mode & S_IFMT);
7287+ h_plus = (h_inode->i_nlink > 0);
7288+ }
7289+ if (inode && ibs <= bindex && bindex <= ibe)
7290+ h_cached_inode = au_h_iptr(inode, bindex);
7291+
523b37e3
AM
7292+ if (!h_nfs) {
7293+ if (unlikely(plus != h_plus))
7294+ goto err;
7295+ } else {
7296+ if (unlikely(!(h_dentry->d_flags & DCACHE_NFSFS_RENAMED)
7297+ && !is_root
7298+ && !IS_ROOT(h_dentry)
7299+ && unhashed != d_unhashed(h_dentry)))
7300+ goto err;
7301+ }
7302+ if (unlikely(mode != h_mode
1facf9fc 7303+ || h_cached_inode != h_inode))
7304+ goto err;
7305+ continue;
7306+
f6b6e03d 7307+err:
1facf9fc 7308+ err = -EINVAL;
7309+ break;
7310+ }
7311+
523b37e3 7312+ AuTraceErr(err);
1facf9fc 7313+ return err;
7314+}
7315+
027c5e7a 7316+/* todo: consolidate with do_refresh() and au_reval_for_attr() */
1facf9fc 7317+static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
7318+{
7319+ int err;
7320+ struct dentry *parent;
1facf9fc 7321+
027c5e7a 7322+ if (!au_digen_test(dentry, sigen))
1facf9fc 7323+ return 0;
7324+
7325+ parent = dget_parent(dentry);
7326+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 7327+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 7328+ au_dbg_verify_gen(parent, sigen);
027c5e7a 7329+ err = au_refresh_dentry(dentry, parent);
1facf9fc 7330+ di_read_unlock(parent, AuLock_IR);
7331+ dput(parent);
027c5e7a 7332+ AuTraceErr(err);
1facf9fc 7333+ return err;
7334+}
7335+
7336+int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
7337+{
7338+ int err;
7339+ struct dentry *d, *parent;
7340+ struct inode *inode;
7341+
027c5e7a 7342+ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
1facf9fc 7343+ return simple_reval_dpath(dentry, sigen);
7344+
7345+ /* slow loop, keep it simple and stupid */
7346+ /* cf: au_cpup_dirs() */
7347+ err = 0;
7348+ parent = NULL;
027c5e7a 7349+ while (au_digen_test(dentry, sigen)) {
1facf9fc 7350+ d = dentry;
7351+ while (1) {
7352+ dput(parent);
7353+ parent = dget_parent(d);
027c5e7a 7354+ if (!au_digen_test(parent, sigen))
1facf9fc 7355+ break;
7356+ d = parent;
7357+ }
7358+
7359+ inode = d->d_inode;
7360+ if (d != dentry)
027c5e7a 7361+ di_write_lock_child2(d);
1facf9fc 7362+
7363+ /* someone might update our dentry while we were sleeping */
027c5e7a
AM
7364+ if (au_digen_test(d, sigen)) {
7365+ /*
7366+ * todo: consolidate with simple_reval_dpath(),
7367+ * do_refresh() and au_reval_for_attr().
7368+ */
1facf9fc 7369+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 7370+ err = au_refresh_dentry(d, parent);
1facf9fc 7371+ di_read_unlock(parent, AuLock_IR);
7372+ }
7373+
7374+ if (d != dentry)
7375+ di_write_unlock(d);
7376+ dput(parent);
7377+ if (unlikely(err))
7378+ break;
7379+ }
7380+
7381+ return err;
7382+}
7383+
7384+/*
7385+ * if valid returns 1, otherwise 0.
7386+ */
b4510431 7387+static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags)
1facf9fc 7388+{
7389+ int valid, err;
7390+ unsigned int sigen;
7391+ unsigned char do_udba;
7392+ struct super_block *sb;
7393+ struct inode *inode;
7394+
027c5e7a 7395+ /* todo: support rcu-walk? */
b4510431 7396+ if (flags & LOOKUP_RCU)
027c5e7a
AM
7397+ return -ECHILD;
7398+
7399+ valid = 0;
7400+ if (unlikely(!au_di(dentry)))
7401+ goto out;
7402+
7403+ inode = dentry->d_inode;
7404+ if (inode && is_bad_inode(inode))
7405+ goto out;
7406+
e49829fe 7407+ valid = 1;
1facf9fc 7408+ sb = dentry->d_sb;
e49829fe
JR
7409+ /*
7410+ * todo: very ugly
7411+ * i_mutex of parent dir may be held,
7412+ * but we should not return 'invalid' due to busy.
7413+ */
7414+ err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM);
7415+ if (unlikely(err)) {
7416+ valid = err;
027c5e7a 7417+ AuTraceErr(err);
e49829fe
JR
7418+ goto out;
7419+ }
027c5e7a
AM
7420+ if (unlikely(au_dbrange_test(dentry))) {
7421+ err = -EINVAL;
7422+ AuTraceErr(err);
7423+ goto out_dgrade;
1facf9fc 7424+ }
027c5e7a
AM
7425+
7426+ sigen = au_sigen(sb);
7427+ if (au_digen_test(dentry, sigen)) {
1facf9fc 7428+ AuDebugOn(IS_ROOT(dentry));
027c5e7a
AM
7429+ err = au_reval_dpath(dentry, sigen);
7430+ if (unlikely(err)) {
7431+ AuTraceErr(err);
1facf9fc 7432+ goto out_dgrade;
027c5e7a 7433+ }
1facf9fc 7434+ }
7435+ di_downgrade_lock(dentry, AuLock_IR);
7436+
1facf9fc 7437+ err = -EINVAL;
523b37e3
AM
7438+ if (!(flags & LOOKUP_OPEN)
7439+ && inode
7440+ && (IS_DEADDIR(inode) || !inode->i_nlink))
027c5e7a
AM
7441+ goto out_inval;
7442+
1facf9fc 7443+ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
7444+ if (do_udba && inode) {
7445+ aufs_bindex_t bstart = au_ibstart(inode);
027c5e7a 7446+ struct inode *h_inode;
1facf9fc 7447+
027c5e7a
AM
7448+ if (bstart >= 0) {
7449+ h_inode = au_h_iptr(inode, bstart);
7450+ if (h_inode && au_test_higen(inode, h_inode))
7451+ goto out_inval;
7452+ }
1facf9fc 7453+ }
7454+
b4510431 7455+ err = h_d_revalidate(dentry, inode, flags, do_udba);
027c5e7a 7456+ if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) {
1facf9fc 7457+ err = -EIO;
523b37e3
AM
7458+ AuDbg("both of real entry and whiteout found, %p, err %d\n",
7459+ dentry, err);
027c5e7a 7460+ }
e49829fe 7461+ goto out_inval;
1facf9fc 7462+
4f0767ce 7463+out_dgrade:
1facf9fc 7464+ di_downgrade_lock(dentry, AuLock_IR);
e49829fe 7465+out_inval:
1facf9fc 7466+ aufs_read_unlock(dentry, AuLock_IR);
7467+ AuTraceErr(err);
7468+ valid = !err;
e49829fe 7469+out:
027c5e7a 7470+ if (!valid) {
523b37e3 7471+ AuDbg("%pd invalid, %d\n", dentry, valid);
027c5e7a
AM
7472+ d_drop(dentry);
7473+ }
1facf9fc 7474+ return valid;
7475+}
7476+
7477+static void aufs_d_release(struct dentry *dentry)
7478+{
027c5e7a 7479+ if (au_di(dentry)) {
4a4d8108
AM
7480+ au_di_fin(dentry);
7481+ au_hn_di_reinit(dentry);
1facf9fc 7482+ }
1facf9fc 7483+}
7484+
4a4d8108 7485+const struct dentry_operations aufs_dop = {
c06a8ce3
AM
7486+ .d_revalidate = aufs_d_revalidate,
7487+ .d_weak_revalidate = aufs_d_revalidate,
7488+ .d_release = aufs_d_release
1facf9fc 7489+};
7f207e10
AM
7490diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
7491--- /usr/share/empty/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
7492+++ linux/fs/aufs/dentry.h 2014-01-20 20:16:14.736130059 +0100
7493@@ -0,0 +1,233 @@
1facf9fc 7494+/*
523b37e3 7495+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 7496+ *
7497+ * This program, aufs is free software; you can redistribute it and/or modify
7498+ * it under the terms of the GNU General Public License as published by
7499+ * the Free Software Foundation; either version 2 of the License, or
7500+ * (at your option) any later version.
dece6358
AM
7501+ *
7502+ * This program is distributed in the hope that it will be useful,
7503+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7504+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7505+ * GNU General Public License for more details.
7506+ *
7507+ * You should have received a copy of the GNU General Public License
523b37e3 7508+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7509+ */
7510+
7511+/*
7512+ * lookup and dentry operations
7513+ */
7514+
7515+#ifndef __AUFS_DENTRY_H__
7516+#define __AUFS_DENTRY_H__
7517+
7518+#ifdef __KERNEL__
7519+
dece6358 7520+#include <linux/dcache.h>
1facf9fc 7521+#include "rwsem.h"
7522+
1facf9fc 7523+struct au_hdentry {
7524+ struct dentry *hd_dentry;
027c5e7a 7525+ aufs_bindex_t hd_id;
1facf9fc 7526+};
7527+
7528+struct au_dinfo {
7529+ atomic_t di_generation;
7530+
dece6358 7531+ struct au_rwsem di_rwsem;
1facf9fc 7532+ aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq;
7533+ struct au_hdentry *di_hdentry;
4a4d8108 7534+} ____cacheline_aligned_in_smp;
1facf9fc 7535+
7536+/* ---------------------------------------------------------------------- */
7537+
7538+/* dentry.c */
4a4d8108 7539+extern const struct dentry_operations aufs_dop;
1facf9fc 7540+struct au_branch;
1facf9fc 7541+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
7542+ struct au_branch *br);
7543+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
7544+ struct dentry *h_parent, struct au_branch *br);
7545+
537831f9 7546+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type);
86dc4139 7547+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh);
027c5e7a 7548+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
1facf9fc 7549+int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
7550+
7551+/* dinfo.c */
4a4d8108 7552+void au_di_init_once(void *_di);
027c5e7a
AM
7553+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
7554+void au_di_free(struct au_dinfo *dinfo);
7555+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
7556+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
4a4d8108
AM
7557+int au_di_init(struct dentry *dentry);
7558+void au_di_fin(struct dentry *dentry);
1facf9fc 7559+int au_di_realloc(struct au_dinfo *dinfo, int nbr);
7560+
7561+void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
7562+void di_read_unlock(struct dentry *d, int flags);
7563+void di_downgrade_lock(struct dentry *d, int flags);
7564+void di_write_lock(struct dentry *d, unsigned int lsc);
7565+void di_write_unlock(struct dentry *d);
7566+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
7567+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
7568+void di_write_unlock2(struct dentry *d1, struct dentry *d2);
7569+
7570+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
2cbb1c4b 7571+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
1facf9fc 7572+aufs_bindex_t au_dbtail(struct dentry *dentry);
7573+aufs_bindex_t au_dbtaildir(struct dentry *dentry);
7574+
7575+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
7576+ struct dentry *h_dentry);
027c5e7a
AM
7577+int au_digen_test(struct dentry *dentry, unsigned int sigen);
7578+int au_dbrange_test(struct dentry *dentry);
1facf9fc 7579+void au_update_digen(struct dentry *dentry);
7580+void au_update_dbrange(struct dentry *dentry, int do_put_zero);
7581+void au_update_dbstart(struct dentry *dentry);
7582+void au_update_dbend(struct dentry *dentry);
7583+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
7584+
7585+/* ---------------------------------------------------------------------- */
7586+
7587+static inline struct au_dinfo *au_di(struct dentry *dentry)
7588+{
7589+ return dentry->d_fsdata;
7590+}
7591+
7592+/* ---------------------------------------------------------------------- */
7593+
7594+/* lock subclass for dinfo */
7595+enum {
7596+ AuLsc_DI_CHILD, /* child first */
4a4d8108 7597+ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */
1facf9fc 7598+ AuLsc_DI_CHILD3, /* copyup dirs */
7599+ AuLsc_DI_PARENT,
7600+ AuLsc_DI_PARENT2,
027c5e7a
AM
7601+ AuLsc_DI_PARENT3,
7602+ AuLsc_DI_TMP /* temp for replacing dinfo */
1facf9fc 7603+};
7604+
7605+/*
7606+ * di_read_lock_child, di_write_lock_child,
7607+ * di_read_lock_child2, di_write_lock_child2,
7608+ * di_read_lock_child3, di_write_lock_child3,
7609+ * di_read_lock_parent, di_write_lock_parent,
7610+ * di_read_lock_parent2, di_write_lock_parent2,
7611+ * di_read_lock_parent3, di_write_lock_parent3,
7612+ */
7613+#define AuReadLockFunc(name, lsc) \
7614+static inline void di_read_lock_##name(struct dentry *d, int flags) \
7615+{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
7616+
7617+#define AuWriteLockFunc(name, lsc) \
7618+static inline void di_write_lock_##name(struct dentry *d) \
7619+{ di_write_lock(d, AuLsc_DI_##lsc); }
7620+
7621+#define AuRWLockFuncs(name, lsc) \
7622+ AuReadLockFunc(name, lsc) \
7623+ AuWriteLockFunc(name, lsc)
7624+
7625+AuRWLockFuncs(child, CHILD);
7626+AuRWLockFuncs(child2, CHILD2);
7627+AuRWLockFuncs(child3, CHILD3);
7628+AuRWLockFuncs(parent, PARENT);
7629+AuRWLockFuncs(parent2, PARENT2);
7630+AuRWLockFuncs(parent3, PARENT3);
7631+
7632+#undef AuReadLockFunc
7633+#undef AuWriteLockFunc
7634+#undef AuRWLockFuncs
7635+
7636+#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
dece6358
AM
7637+#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
7638+#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
1facf9fc 7639+
7640+/* ---------------------------------------------------------------------- */
7641+
7642+/* todo: memory barrier? */
7643+static inline unsigned int au_digen(struct dentry *d)
7644+{
7645+ return atomic_read(&au_di(d)->di_generation);
7646+}
7647+
7648+static inline void au_h_dentry_init(struct au_hdentry *hdentry)
7649+{
7650+ hdentry->hd_dentry = NULL;
7651+}
7652+
7653+static inline void au_hdput(struct au_hdentry *hd)
7654+{
4a4d8108
AM
7655+ if (hd)
7656+ dput(hd->hd_dentry);
1facf9fc 7657+}
7658+
7659+static inline aufs_bindex_t au_dbstart(struct dentry *dentry)
7660+{
1308ab2a 7661+ DiMustAnyLock(dentry);
1facf9fc 7662+ return au_di(dentry)->di_bstart;
7663+}
7664+
7665+static inline aufs_bindex_t au_dbend(struct dentry *dentry)
7666+{
1308ab2a 7667+ DiMustAnyLock(dentry);
1facf9fc 7668+ return au_di(dentry)->di_bend;
7669+}
7670+
7671+static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
7672+{
1308ab2a 7673+ DiMustAnyLock(dentry);
1facf9fc 7674+ return au_di(dentry)->di_bwh;
7675+}
7676+
7677+static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
7678+{
1308ab2a 7679+ DiMustAnyLock(dentry);
1facf9fc 7680+ return au_di(dentry)->di_bdiropq;
7681+}
7682+
7683+/* todo: hard/soft set? */
7684+static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex)
7685+{
1308ab2a 7686+ DiMustWriteLock(dentry);
1facf9fc 7687+ au_di(dentry)->di_bstart = bindex;
7688+}
7689+
7690+static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex)
7691+{
1308ab2a 7692+ DiMustWriteLock(dentry);
1facf9fc 7693+ au_di(dentry)->di_bend = bindex;
7694+}
7695+
7696+static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
7697+{
1308ab2a 7698+ DiMustWriteLock(dentry);
1facf9fc 7699+ /* dbwh can be outside of bstart - bend range */
7700+ au_di(dentry)->di_bwh = bindex;
7701+}
7702+
7703+static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
7704+{
1308ab2a 7705+ DiMustWriteLock(dentry);
1facf9fc 7706+ au_di(dentry)->di_bdiropq = bindex;
7707+}
7708+
7709+/* ---------------------------------------------------------------------- */
7710+
4a4d8108 7711+#ifdef CONFIG_AUFS_HNOTIFY
1facf9fc 7712+static inline void au_digen_dec(struct dentry *d)
7713+{
e49829fe 7714+ atomic_dec(&au_di(d)->di_generation);
1facf9fc 7715+}
7716+
4a4d8108 7717+static inline void au_hn_di_reinit(struct dentry *dentry)
1facf9fc 7718+{
7719+ dentry->d_fsdata = NULL;
7720+}
7721+#else
4a4d8108
AM
7722+AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
7723+#endif /* CONFIG_AUFS_HNOTIFY */
1facf9fc 7724+
7725+#endif /* __KERNEL__ */
7726+#endif /* __AUFS_DENTRY_H__ */
7f207e10
AM
7727diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
7728--- /usr/share/empty/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
7729+++ linux/fs/aufs/dinfo.c 2014-01-20 20:16:14.736130059 +0100
7730@@ -0,0 +1,542 @@
1facf9fc 7731+/*
523b37e3 7732+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 7733+ *
7734+ * This program, aufs is free software; you can redistribute it and/or modify
7735+ * it under the terms of the GNU General Public License as published by
7736+ * the Free Software Foundation; either version 2 of the License, or
7737+ * (at your option) any later version.
dece6358
AM
7738+ *
7739+ * This program is distributed in the hope that it will be useful,
7740+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7741+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7742+ * GNU General Public License for more details.
7743+ *
7744+ * You should have received a copy of the GNU General Public License
523b37e3 7745+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7746+ */
7747+
7748+/*
7749+ * dentry private data
7750+ */
7751+
7752+#include "aufs.h"
7753+
e49829fe 7754+void au_di_init_once(void *_dinfo)
4a4d8108 7755+{
e49829fe
JR
7756+ struct au_dinfo *dinfo = _dinfo;
7757+ static struct lock_class_key aufs_di;
4a4d8108 7758+
e49829fe
JR
7759+ au_rw_init(&dinfo->di_rwsem);
7760+ au_rw_class(&dinfo->di_rwsem, &aufs_di);
4a4d8108
AM
7761+}
7762+
027c5e7a 7763+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
1facf9fc 7764+{
7765+ struct au_dinfo *dinfo;
027c5e7a 7766+ int nbr, i;
1facf9fc 7767+
7768+ dinfo = au_cache_alloc_dinfo();
7769+ if (unlikely(!dinfo))
7770+ goto out;
7771+
1facf9fc 7772+ nbr = au_sbend(sb) + 1;
7773+ if (nbr <= 0)
7774+ nbr = 1;
7775+ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
027c5e7a
AM
7776+ if (dinfo->di_hdentry) {
7777+ au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
7778+ dinfo->di_bstart = -1;
7779+ dinfo->di_bend = -1;
7780+ dinfo->di_bwh = -1;
7781+ dinfo->di_bdiropq = -1;
7782+ for (i = 0; i < nbr; i++)
7783+ dinfo->di_hdentry[i].hd_id = -1;
7784+ goto out;
7785+ }
1facf9fc 7786+
1facf9fc 7787+ au_cache_free_dinfo(dinfo);
027c5e7a
AM
7788+ dinfo = NULL;
7789+
4f0767ce 7790+out:
027c5e7a 7791+ return dinfo;
1facf9fc 7792+}
7793+
027c5e7a 7794+void au_di_free(struct au_dinfo *dinfo)
4a4d8108 7795+{
4a4d8108
AM
7796+ struct au_hdentry *p;
7797+ aufs_bindex_t bend, bindex;
7798+
7799+ /* dentry may not be revalidated */
027c5e7a 7800+ bindex = dinfo->di_bstart;
4a4d8108 7801+ if (bindex >= 0) {
027c5e7a
AM
7802+ bend = dinfo->di_bend;
7803+ p = dinfo->di_hdentry + bindex;
4a4d8108
AM
7804+ while (bindex++ <= bend)
7805+ au_hdput(p++);
7806+ }
027c5e7a
AM
7807+ kfree(dinfo->di_hdentry);
7808+ au_cache_free_dinfo(dinfo);
7809+}
7810+
7811+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
7812+{
7813+ struct au_hdentry *p;
7814+ aufs_bindex_t bi;
7815+
7816+ AuRwMustWriteLock(&a->di_rwsem);
7817+ AuRwMustWriteLock(&b->di_rwsem);
7818+
7819+#define DiSwap(v, name) \
7820+ do { \
7821+ v = a->di_##name; \
7822+ a->di_##name = b->di_##name; \
7823+ b->di_##name = v; \
7824+ } while (0)
7825+
7826+ DiSwap(p, hdentry);
7827+ DiSwap(bi, bstart);
7828+ DiSwap(bi, bend);
7829+ DiSwap(bi, bwh);
7830+ DiSwap(bi, bdiropq);
7831+ /* smp_mb(); */
7832+
7833+#undef DiSwap
7834+}
7835+
7836+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
7837+{
7838+ AuRwMustWriteLock(&dst->di_rwsem);
7839+ AuRwMustWriteLock(&src->di_rwsem);
7840+
7841+ dst->di_bstart = src->di_bstart;
7842+ dst->di_bend = src->di_bend;
7843+ dst->di_bwh = src->di_bwh;
7844+ dst->di_bdiropq = src->di_bdiropq;
7845+ /* smp_mb(); */
7846+}
7847+
7848+int au_di_init(struct dentry *dentry)
7849+{
7850+ int err;
7851+ struct super_block *sb;
7852+ struct au_dinfo *dinfo;
7853+
7854+ err = 0;
7855+ sb = dentry->d_sb;
7856+ dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
7857+ if (dinfo) {
7858+ atomic_set(&dinfo->di_generation, au_sigen(sb));
7859+ /* smp_mb(); */ /* atomic_set */
7860+ dentry->d_fsdata = dinfo;
7861+ } else
7862+ err = -ENOMEM;
7863+
7864+ return err;
7865+}
7866+
7867+void au_di_fin(struct dentry *dentry)
7868+{
7869+ struct au_dinfo *dinfo;
7870+
7871+ dinfo = au_di(dentry);
7872+ AuRwDestroy(&dinfo->di_rwsem);
7873+ au_di_free(dinfo);
4a4d8108
AM
7874+}
7875+
1facf9fc 7876+int au_di_realloc(struct au_dinfo *dinfo, int nbr)
7877+{
7878+ int err, sz;
7879+ struct au_hdentry *hdp;
7880+
1308ab2a 7881+ AuRwMustWriteLock(&dinfo->di_rwsem);
7882+
1facf9fc 7883+ err = -ENOMEM;
7884+ sz = sizeof(*hdp) * (dinfo->di_bend + 1);
7885+ if (!sz)
7886+ sz = sizeof(*hdp);
7887+ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS);
7888+ if (hdp) {
7889+ dinfo->di_hdentry = hdp;
7890+ err = 0;
7891+ }
7892+
7893+ return err;
7894+}
7895+
7896+/* ---------------------------------------------------------------------- */
7897+
7898+static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
7899+{
7900+ switch (lsc) {
7901+ case AuLsc_DI_CHILD:
7902+ ii_write_lock_child(inode);
7903+ break;
7904+ case AuLsc_DI_CHILD2:
7905+ ii_write_lock_child2(inode);
7906+ break;
7907+ case AuLsc_DI_CHILD3:
7908+ ii_write_lock_child3(inode);
7909+ break;
7910+ case AuLsc_DI_PARENT:
7911+ ii_write_lock_parent(inode);
7912+ break;
7913+ case AuLsc_DI_PARENT2:
7914+ ii_write_lock_parent2(inode);
7915+ break;
7916+ case AuLsc_DI_PARENT3:
7917+ ii_write_lock_parent3(inode);
7918+ break;
7919+ default:
7920+ BUG();
7921+ }
7922+}
7923+
7924+static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
7925+{
7926+ switch (lsc) {
7927+ case AuLsc_DI_CHILD:
7928+ ii_read_lock_child(inode);
7929+ break;
7930+ case AuLsc_DI_CHILD2:
7931+ ii_read_lock_child2(inode);
7932+ break;
7933+ case AuLsc_DI_CHILD3:
7934+ ii_read_lock_child3(inode);
7935+ break;
7936+ case AuLsc_DI_PARENT:
7937+ ii_read_lock_parent(inode);
7938+ break;
7939+ case AuLsc_DI_PARENT2:
7940+ ii_read_lock_parent2(inode);
7941+ break;
7942+ case AuLsc_DI_PARENT3:
7943+ ii_read_lock_parent3(inode);
7944+ break;
7945+ default:
7946+ BUG();
7947+ }
7948+}
7949+
7950+void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
7951+{
dece6358 7952+ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
1facf9fc 7953+ if (d->d_inode) {
7954+ if (au_ftest_lock(flags, IW))
7955+ do_ii_write_lock(d->d_inode, lsc);
7956+ else if (au_ftest_lock(flags, IR))
7957+ do_ii_read_lock(d->d_inode, lsc);
7958+ }
7959+}
7960+
7961+void di_read_unlock(struct dentry *d, int flags)
7962+{
7963+ if (d->d_inode) {
027c5e7a
AM
7964+ if (au_ftest_lock(flags, IW)) {
7965+ au_dbg_verify_dinode(d);
1facf9fc 7966+ ii_write_unlock(d->d_inode);
027c5e7a
AM
7967+ } else if (au_ftest_lock(flags, IR)) {
7968+ au_dbg_verify_dinode(d);
1facf9fc 7969+ ii_read_unlock(d->d_inode);
027c5e7a 7970+ }
1facf9fc 7971+ }
dece6358 7972+ au_rw_read_unlock(&au_di(d)->di_rwsem);
1facf9fc 7973+}
7974+
7975+void di_downgrade_lock(struct dentry *d, int flags)
7976+{
1facf9fc 7977+ if (d->d_inode && au_ftest_lock(flags, IR))
7978+ ii_downgrade_lock(d->d_inode);
dece6358 7979+ au_rw_dgrade_lock(&au_di(d)->di_rwsem);
1facf9fc 7980+}
7981+
7982+void di_write_lock(struct dentry *d, unsigned int lsc)
7983+{
dece6358 7984+ au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
1facf9fc 7985+ if (d->d_inode)
7986+ do_ii_write_lock(d->d_inode, lsc);
7987+}
7988+
7989+void di_write_unlock(struct dentry *d)
7990+{
027c5e7a 7991+ au_dbg_verify_dinode(d);
1facf9fc 7992+ if (d->d_inode)
7993+ ii_write_unlock(d->d_inode);
dece6358 7994+ au_rw_write_unlock(&au_di(d)->di_rwsem);
1facf9fc 7995+}
7996+
7997+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
7998+{
7999+ AuDebugOn(d1 == d2
8000+ || d1->d_inode == d2->d_inode
8001+ || d1->d_sb != d2->d_sb);
8002+
8003+ if (isdir && au_test_subdir(d1, d2)) {
8004+ di_write_lock_child(d1);
8005+ di_write_lock_child2(d2);
8006+ } else {
8007+ /* there should be no races */
8008+ di_write_lock_child(d2);
8009+ di_write_lock_child2(d1);
8010+ }
8011+}
8012+
8013+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
8014+{
8015+ AuDebugOn(d1 == d2
8016+ || d1->d_inode == d2->d_inode
8017+ || d1->d_sb != d2->d_sb);
8018+
8019+ if (isdir && au_test_subdir(d1, d2)) {
8020+ di_write_lock_parent(d1);
8021+ di_write_lock_parent2(d2);
8022+ } else {
8023+ /* there should be no races */
8024+ di_write_lock_parent(d2);
8025+ di_write_lock_parent2(d1);
8026+ }
8027+}
8028+
8029+void di_write_unlock2(struct dentry *d1, struct dentry *d2)
8030+{
8031+ di_write_unlock(d1);
8032+ if (d1->d_inode == d2->d_inode)
dece6358 8033+ au_rw_write_unlock(&au_di(d2)->di_rwsem);
1facf9fc 8034+ else
8035+ di_write_unlock(d2);
8036+}
8037+
8038+/* ---------------------------------------------------------------------- */
8039+
8040+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
8041+{
8042+ struct dentry *d;
8043+
1308ab2a 8044+ DiMustAnyLock(dentry);
8045+
1facf9fc 8046+ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
8047+ return NULL;
8048+ AuDebugOn(bindex < 0);
8049+ d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry;
392086de 8050+ AuDebugOn(d && d_count(d) <= 0);
1facf9fc 8051+ return d;
8052+}
8053+
2cbb1c4b
JR
8054+/*
8055+ * extended version of au_h_dptr().
8056+ * returns a hashed and positive h_dentry in bindex, NULL, or error.
8057+ */
8058+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
8059+{
8060+ struct dentry *h_dentry;
8061+ struct inode *inode, *h_inode;
8062+
8063+ inode = dentry->d_inode;
8064+ AuDebugOn(!inode);
8065+
8066+ h_dentry = NULL;
8067+ if (au_dbstart(dentry) <= bindex
8068+ && bindex <= au_dbend(dentry))
8069+ h_dentry = au_h_dptr(dentry, bindex);
8070+ if (h_dentry && !au_d_hashed_positive(h_dentry)) {
8071+ dget(h_dentry);
8072+ goto out; /* success */
8073+ }
8074+
8075+ AuDebugOn(bindex < au_ibstart(inode));
8076+ AuDebugOn(au_ibend(inode) < bindex);
8077+ h_inode = au_h_iptr(inode, bindex);
8078+ h_dentry = d_find_alias(h_inode);
8079+ if (h_dentry) {
8080+ if (!IS_ERR(h_dentry)) {
8081+ if (!au_d_hashed_positive(h_dentry))
8082+ goto out; /* success */
8083+ dput(h_dentry);
8084+ } else
8085+ goto out;
8086+ }
8087+
8088+ if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
8089+ h_dentry = au_plink_lkup(inode, bindex);
8090+ AuDebugOn(!h_dentry);
8091+ if (!IS_ERR(h_dentry)) {
8092+ if (!au_d_hashed_positive(h_dentry))
8093+ goto out; /* success */
8094+ dput(h_dentry);
8095+ h_dentry = NULL;
8096+ }
8097+ }
8098+
8099+out:
8100+ AuDbgDentry(h_dentry);
8101+ return h_dentry;
8102+}
8103+
1facf9fc 8104+aufs_bindex_t au_dbtail(struct dentry *dentry)
8105+{
8106+ aufs_bindex_t bend, bwh;
8107+
8108+ bend = au_dbend(dentry);
8109+ if (0 <= bend) {
8110+ bwh = au_dbwh(dentry);
8111+ if (!bwh)
8112+ return bwh;
8113+ if (0 < bwh && bwh < bend)
8114+ return bwh - 1;
8115+ }
8116+ return bend;
8117+}
8118+
8119+aufs_bindex_t au_dbtaildir(struct dentry *dentry)
8120+{
8121+ aufs_bindex_t bend, bopq;
8122+
8123+ bend = au_dbtail(dentry);
8124+ if (0 <= bend) {
8125+ bopq = au_dbdiropq(dentry);
8126+ if (0 <= bopq && bopq < bend)
8127+ bend = bopq;
8128+ }
8129+ return bend;
8130+}
8131+
8132+/* ---------------------------------------------------------------------- */
8133+
8134+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
8135+ struct dentry *h_dentry)
8136+{
8137+ struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
027c5e7a 8138+ struct au_branch *br;
1facf9fc 8139+
1308ab2a 8140+ DiMustWriteLock(dentry);
8141+
4a4d8108 8142+ au_hdput(hd);
1facf9fc 8143+ hd->hd_dentry = h_dentry;
027c5e7a
AM
8144+ if (h_dentry) {
8145+ br = au_sbr(dentry->d_sb, bindex);
8146+ hd->hd_id = br->br_id;
8147+ }
8148+}
8149+
8150+int au_dbrange_test(struct dentry *dentry)
8151+{
8152+ int err;
8153+ aufs_bindex_t bstart, bend;
8154+
8155+ err = 0;
8156+ bstart = au_dbstart(dentry);
8157+ bend = au_dbend(dentry);
8158+ if (bstart >= 0)
8159+ AuDebugOn(bend < 0 && bstart > bend);
8160+ else {
8161+ err = -EIO;
8162+ AuDebugOn(bend >= 0);
8163+ }
8164+
8165+ return err;
8166+}
8167+
8168+int au_digen_test(struct dentry *dentry, unsigned int sigen)
8169+{
8170+ int err;
8171+
8172+ err = 0;
8173+ if (unlikely(au_digen(dentry) != sigen
8174+ || au_iigen_test(dentry->d_inode, sigen)))
8175+ err = -EIO;
8176+
8177+ return err;
1facf9fc 8178+}
8179+
8180+void au_update_digen(struct dentry *dentry)
8181+{
8182+ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
8183+ /* smp_mb(); */ /* atomic_set */
8184+}
8185+
8186+void au_update_dbrange(struct dentry *dentry, int do_put_zero)
8187+{
8188+ struct au_dinfo *dinfo;
8189+ struct dentry *h_d;
4a4d8108 8190+ struct au_hdentry *hdp;
1facf9fc 8191+
1308ab2a 8192+ DiMustWriteLock(dentry);
8193+
1facf9fc 8194+ dinfo = au_di(dentry);
8195+ if (!dinfo || dinfo->di_bstart < 0)
8196+ return;
8197+
4a4d8108 8198+ hdp = dinfo->di_hdentry;
1facf9fc 8199+ if (do_put_zero) {
8200+ aufs_bindex_t bindex, bend;
8201+
8202+ bend = dinfo->di_bend;
8203+ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) {
4a4d8108 8204+ h_d = hdp[0 + bindex].hd_dentry;
1facf9fc 8205+ if (h_d && !h_d->d_inode)
8206+ au_set_h_dptr(dentry, bindex, NULL);
8207+ }
8208+ }
8209+
8210+ dinfo->di_bstart = -1;
8211+ while (++dinfo->di_bstart <= dinfo->di_bend)
4a4d8108 8212+ if (hdp[0 + dinfo->di_bstart].hd_dentry)
1facf9fc 8213+ break;
8214+ if (dinfo->di_bstart > dinfo->di_bend) {
8215+ dinfo->di_bstart = -1;
8216+ dinfo->di_bend = -1;
8217+ return;
8218+ }
8219+
8220+ dinfo->di_bend++;
8221+ while (0 <= --dinfo->di_bend)
4a4d8108 8222+ if (hdp[0 + dinfo->di_bend].hd_dentry)
1facf9fc 8223+ break;
8224+ AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0);
8225+}
8226+
8227+void au_update_dbstart(struct dentry *dentry)
8228+{
8229+ aufs_bindex_t bindex, bend;
8230+ struct dentry *h_dentry;
8231+
8232+ bend = au_dbend(dentry);
8233+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
8234+ h_dentry = au_h_dptr(dentry, bindex);
8235+ if (!h_dentry)
8236+ continue;
8237+ if (h_dentry->d_inode) {
8238+ au_set_dbstart(dentry, bindex);
8239+ return;
8240+ }
8241+ au_set_h_dptr(dentry, bindex, NULL);
8242+ }
8243+}
8244+
8245+void au_update_dbend(struct dentry *dentry)
8246+{
8247+ aufs_bindex_t bindex, bstart;
8248+ struct dentry *h_dentry;
8249+
8250+ bstart = au_dbstart(dentry);
7f207e10 8251+ for (bindex = au_dbend(dentry); bindex >= bstart; bindex--) {
1facf9fc 8252+ h_dentry = au_h_dptr(dentry, bindex);
8253+ if (!h_dentry)
8254+ continue;
8255+ if (h_dentry->d_inode) {
8256+ au_set_dbend(dentry, bindex);
8257+ return;
8258+ }
8259+ au_set_h_dptr(dentry, bindex, NULL);
8260+ }
8261+}
8262+
8263+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
8264+{
8265+ aufs_bindex_t bindex, bend;
8266+
8267+ bend = au_dbend(dentry);
8268+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++)
8269+ if (au_h_dptr(dentry, bindex) == h_dentry)
8270+ return bindex;
8271+ return -1;
8272+}
7f207e10
AM
8273diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
8274--- /usr/share/empty/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
f6b6e03d 8275+++ linux/fs/aufs/dir.c 2014-01-27 23:16:52.701753487 +0100
523b37e3 8276@@ -0,0 +1,639 @@
1facf9fc 8277+/*
523b37e3 8278+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 8279+ *
8280+ * This program, aufs is free software; you can redistribute it and/or modify
8281+ * it under the terms of the GNU General Public License as published by
8282+ * the Free Software Foundation; either version 2 of the License, or
8283+ * (at your option) any later version.
dece6358
AM
8284+ *
8285+ * This program is distributed in the hope that it will be useful,
8286+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8287+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8288+ * GNU General Public License for more details.
8289+ *
8290+ * You should have received a copy of the GNU General Public License
523b37e3 8291+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 8292+ */
8293+
8294+/*
8295+ * directory operations
8296+ */
8297+
8298+#include <linux/fs_stack.h>
8299+#include "aufs.h"
8300+
8301+void au_add_nlink(struct inode *dir, struct inode *h_dir)
8302+{
9dbd164d
AM
8303+ unsigned int nlink;
8304+
1facf9fc 8305+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
8306+
9dbd164d
AM
8307+ nlink = dir->i_nlink;
8308+ nlink += h_dir->i_nlink - 2;
1facf9fc 8309+ if (h_dir->i_nlink < 2)
9dbd164d 8310+ nlink += 2;
f6b6e03d 8311+ smp_mb(); /* for i_nlink */
7eafdf33 8312+ /* 0 can happen in revaliding */
92d182d2 8313+ set_nlink(dir, nlink);
1facf9fc 8314+}
8315+
8316+void au_sub_nlink(struct inode *dir, struct inode *h_dir)
8317+{
9dbd164d
AM
8318+ unsigned int nlink;
8319+
1facf9fc 8320+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
8321+
9dbd164d
AM
8322+ nlink = dir->i_nlink;
8323+ nlink -= h_dir->i_nlink - 2;
1facf9fc 8324+ if (h_dir->i_nlink < 2)
9dbd164d 8325+ nlink -= 2;
f6b6e03d 8326+ smp_mb(); /* for i_nlink */
92d182d2 8327+ /* nlink == 0 means the branch-fs is broken */
9dbd164d 8328+ set_nlink(dir, nlink);
1facf9fc 8329+}
8330+
1308ab2a 8331+loff_t au_dir_size(struct file *file, struct dentry *dentry)
8332+{
8333+ loff_t sz;
8334+ aufs_bindex_t bindex, bend;
8335+ struct file *h_file;
8336+ struct dentry *h_dentry;
8337+
8338+ sz = 0;
8339+ if (file) {
c06a8ce3
AM
8340+ AuDebugOn(!file_inode(file));
8341+ AuDebugOn(!S_ISDIR(file_inode(file)->i_mode));
1308ab2a 8342+
4a4d8108 8343+ bend = au_fbend_dir(file);
1308ab2a 8344+ for (bindex = au_fbstart(file);
8345+ bindex <= bend && sz < KMALLOC_MAX_SIZE;
8346+ bindex++) {
4a4d8108 8347+ h_file = au_hf_dir(file, bindex);
c06a8ce3
AM
8348+ if (h_file && file_inode(h_file))
8349+ sz += vfsub_f_size_read(h_file);
1308ab2a 8350+ }
8351+ } else {
8352+ AuDebugOn(!dentry);
8353+ AuDebugOn(!dentry->d_inode);
8354+ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
8355+
8356+ bend = au_dbtaildir(dentry);
8357+ for (bindex = au_dbstart(dentry);
8358+ bindex <= bend && sz < KMALLOC_MAX_SIZE;
8359+ bindex++) {
8360+ h_dentry = au_h_dptr(dentry, bindex);
8361+ if (h_dentry && h_dentry->d_inode)
8362+ sz += i_size_read(h_dentry->d_inode);
8363+ }
8364+ }
8365+ if (sz < KMALLOC_MAX_SIZE)
8366+ sz = roundup_pow_of_two(sz);
8367+ if (sz > KMALLOC_MAX_SIZE)
8368+ sz = KMALLOC_MAX_SIZE;
8369+ else if (sz < NAME_MAX) {
8370+ BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX);
8371+ sz = AUFS_RDBLK_DEF;
8372+ }
8373+ return sz;
8374+}
8375+
1facf9fc 8376+/* ---------------------------------------------------------------------- */
8377+
8378+static int reopen_dir(struct file *file)
8379+{
8380+ int err;
8381+ unsigned int flags;
8382+ aufs_bindex_t bindex, btail, bstart;
8383+ struct dentry *dentry, *h_dentry;
8384+ struct file *h_file;
8385+
8386+ /* open all lower dirs */
8387+ dentry = file->f_dentry;
8388+ bstart = au_dbstart(dentry);
8389+ for (bindex = au_fbstart(file); bindex < bstart; bindex++)
8390+ au_set_h_fptr(file, bindex, NULL);
8391+ au_set_fbstart(file, bstart);
8392+
8393+ btail = au_dbtaildir(dentry);
4a4d8108 8394+ for (bindex = au_fbend_dir(file); btail < bindex; bindex--)
1facf9fc 8395+ au_set_h_fptr(file, bindex, NULL);
4a4d8108 8396+ au_set_fbend_dir(file, btail);
1facf9fc 8397+
4a4d8108 8398+ flags = vfsub_file_flags(file);
1facf9fc 8399+ for (bindex = bstart; bindex <= btail; bindex++) {
8400+ h_dentry = au_h_dptr(dentry, bindex);
8401+ if (!h_dentry)
8402+ continue;
4a4d8108 8403+ h_file = au_hf_dir(file, bindex);
1facf9fc 8404+ if (h_file)
8405+ continue;
8406+
392086de 8407+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 8408+ err = PTR_ERR(h_file);
8409+ if (IS_ERR(h_file))
8410+ goto out; /* close all? */
8411+ au_set_h_fptr(file, bindex, h_file);
8412+ }
8413+ au_update_figen(file);
8414+ /* todo: necessary? */
8415+ /* file->f_ra = h_file->f_ra; */
8416+ err = 0;
8417+
4f0767ce 8418+out:
1facf9fc 8419+ return err;
8420+}
8421+
8422+static int do_open_dir(struct file *file, int flags)
8423+{
8424+ int err;
8425+ aufs_bindex_t bindex, btail;
8426+ struct dentry *dentry, *h_dentry;
8427+ struct file *h_file;
8428+
1308ab2a 8429+ FiMustWriteLock(file);
8430+
523b37e3 8431+ err = 0;
1facf9fc 8432+ dentry = file->f_dentry;
1facf9fc 8433+ file->f_version = dentry->d_inode->i_version;
8434+ bindex = au_dbstart(dentry);
8435+ au_set_fbstart(file, bindex);
8436+ btail = au_dbtaildir(dentry);
4a4d8108 8437+ au_set_fbend_dir(file, btail);
1facf9fc 8438+ for (; !err && bindex <= btail; bindex++) {
8439+ h_dentry = au_h_dptr(dentry, bindex);
8440+ if (!h_dentry)
8441+ continue;
8442+
392086de 8443+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 8444+ if (IS_ERR(h_file)) {
8445+ err = PTR_ERR(h_file);
8446+ break;
8447+ }
8448+ au_set_h_fptr(file, bindex, h_file);
8449+ }
8450+ au_update_figen(file);
8451+ /* todo: necessary? */
8452+ /* file->f_ra = h_file->f_ra; */
8453+ if (!err)
8454+ return 0; /* success */
8455+
8456+ /* close all */
8457+ for (bindex = au_fbstart(file); bindex <= btail; bindex++)
8458+ au_set_h_fptr(file, bindex, NULL);
8459+ au_set_fbstart(file, -1);
4a4d8108
AM
8460+ au_set_fbend_dir(file, -1);
8461+
1facf9fc 8462+ return err;
8463+}
8464+
8465+static int aufs_open_dir(struct inode *inode __maybe_unused,
8466+ struct file *file)
8467+{
4a4d8108
AM
8468+ int err;
8469+ struct super_block *sb;
8470+ struct au_fidir *fidir;
8471+
8472+ err = -ENOMEM;
8473+ sb = file->f_dentry->d_sb;
8474+ si_read_lock(sb, AuLock_FLUSH);
e49829fe 8475+ fidir = au_fidir_alloc(sb);
4a4d8108
AM
8476+ if (fidir) {
8477+ err = au_do_open(file, do_open_dir, fidir);
8478+ if (unlikely(err))
8479+ kfree(fidir);
8480+ }
8481+ si_read_unlock(sb);
8482+ return err;
1facf9fc 8483+}
8484+
8485+static int aufs_release_dir(struct inode *inode __maybe_unused,
8486+ struct file *file)
8487+{
8488+ struct au_vdir *vdir_cache;
4a4d8108
AM
8489+ struct au_finfo *finfo;
8490+ struct au_fidir *fidir;
8491+ aufs_bindex_t bindex, bend;
1facf9fc 8492+
4a4d8108
AM
8493+ finfo = au_fi(file);
8494+ fidir = finfo->fi_hdir;
8495+ if (fidir) {
8496+ vdir_cache = fidir->fd_vdir_cache; /* lock-free */
8497+ if (vdir_cache)
8498+ au_vdir_free(vdir_cache);
8499+
8500+ bindex = finfo->fi_btop;
8501+ if (bindex >= 0) {
8502+ /*
8503+ * calls fput() instead of filp_close(),
8504+ * since no dnotify or lock for the lower file.
8505+ */
8506+ bend = fidir->fd_bbot;
8507+ for (; bindex <= bend; bindex++)
8508+ au_set_h_fptr(file, bindex, NULL);
8509+ }
8510+ kfree(fidir);
8511+ finfo->fi_hdir = NULL;
1facf9fc 8512+ }
1facf9fc 8513+ au_finfo_fin(file);
1facf9fc 8514+ return 0;
8515+}
8516+
8517+/* ---------------------------------------------------------------------- */
8518+
4a4d8108
AM
8519+static int au_do_flush_dir(struct file *file, fl_owner_t id)
8520+{
8521+ int err;
8522+ aufs_bindex_t bindex, bend;
8523+ struct file *h_file;
8524+
8525+ err = 0;
8526+ bend = au_fbend_dir(file);
8527+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
8528+ h_file = au_hf_dir(file, bindex);
8529+ if (h_file)
8530+ err = vfsub_flush(h_file, id);
8531+ }
8532+ return err;
8533+}
8534+
8535+static int aufs_flush_dir(struct file *file, fl_owner_t id)
8536+{
8537+ return au_do_flush(file, id, au_do_flush_dir);
8538+}
8539+
8540+/* ---------------------------------------------------------------------- */
8541+
1facf9fc 8542+static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
8543+{
8544+ int err;
8545+ aufs_bindex_t bend, bindex;
8546+ struct inode *inode;
8547+ struct super_block *sb;
8548+
8549+ err = 0;
8550+ sb = dentry->d_sb;
8551+ inode = dentry->d_inode;
8552+ IMustLock(inode);
8553+ bend = au_dbend(dentry);
8554+ for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) {
8555+ struct path h_path;
1facf9fc 8556+
8557+ if (au_test_ro(sb, bindex, inode))
8558+ continue;
8559+ h_path.dentry = au_h_dptr(dentry, bindex);
8560+ if (!h_path.dentry)
8561+ continue;
1facf9fc 8562+
1facf9fc 8563+ h_path.mnt = au_sbr_mnt(sb, bindex);
53392da6 8564+ err = vfsub_fsync(NULL, &h_path, datasync);
1facf9fc 8565+ }
8566+
8567+ return err;
8568+}
8569+
8570+static int au_do_fsync_dir(struct file *file, int datasync)
8571+{
8572+ int err;
8573+ aufs_bindex_t bend, bindex;
8574+ struct file *h_file;
8575+ struct super_block *sb;
8576+ struct inode *inode;
1facf9fc 8577+
8578+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
8579+ if (unlikely(err))
8580+ goto out;
8581+
8582+ sb = file->f_dentry->d_sb;
c06a8ce3 8583+ inode = file_inode(file);
4a4d8108 8584+ bend = au_fbend_dir(file);
1facf9fc 8585+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
4a4d8108 8586+ h_file = au_hf_dir(file, bindex);
1facf9fc 8587+ if (!h_file || au_test_ro(sb, bindex, inode))
8588+ continue;
8589+
53392da6 8590+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
1facf9fc 8591+ }
8592+
4f0767ce 8593+out:
1facf9fc 8594+ return err;
8595+}
8596+
8597+/*
8598+ * @file may be NULL
8599+ */
1e00d052
AM
8600+static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end,
8601+ int datasync)
1facf9fc 8602+{
8603+ int err;
b752ccd1 8604+ struct dentry *dentry;
1facf9fc 8605+ struct super_block *sb;
1e00d052 8606+ struct mutex *mtx;
1facf9fc 8607+
8608+ err = 0;
1e00d052
AM
8609+ dentry = file->f_dentry;
8610+ mtx = &dentry->d_inode->i_mutex;
8611+ mutex_lock(mtx);
1facf9fc 8612+ sb = dentry->d_sb;
8613+ si_noflush_read_lock(sb);
8614+ if (file)
8615+ err = au_do_fsync_dir(file, datasync);
8616+ else {
8617+ di_write_lock_child(dentry);
8618+ err = au_do_fsync_dir_no_file(dentry, datasync);
8619+ }
8620+ au_cpup_attr_timesizes(dentry->d_inode);
8621+ di_write_unlock(dentry);
8622+ if (file)
8623+ fi_write_unlock(file);
8624+
8625+ si_read_unlock(sb);
1e00d052 8626+ mutex_unlock(mtx);
1facf9fc 8627+ return err;
8628+}
8629+
8630+/* ---------------------------------------------------------------------- */
8631+
392086de 8632+static int aufs_iterate(struct file *file, struct dir_context *ctx)
1facf9fc 8633+{
8634+ int err;
8635+ struct dentry *dentry;
9dbd164d 8636+ struct inode *inode, *h_inode;
1facf9fc 8637+ struct super_block *sb;
8638+
523b37e3 8639+ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
392086de 8640+
1facf9fc 8641+ dentry = file->f_dentry;
8642+ inode = dentry->d_inode;
8643+ IMustLock(inode);
8644+
8645+ sb = dentry->d_sb;
8646+ si_read_lock(sb, AuLock_FLUSH);
8647+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
8648+ if (unlikely(err))
8649+ goto out;
027c5e7a
AM
8650+ err = au_alive_dir(dentry);
8651+ if (!err)
8652+ err = au_vdir_init(file);
1facf9fc 8653+ di_downgrade_lock(dentry, AuLock_IR);
8654+ if (unlikely(err))
8655+ goto out_unlock;
8656+
9dbd164d 8657+ h_inode = au_h_iptr(inode, au_ibstart(inode));
b752ccd1 8658+ if (!au_test_nfsd()) {
392086de 8659+ err = au_vdir_fill_de(file, ctx);
9dbd164d 8660+ fsstack_copy_attr_atime(inode, h_inode);
1facf9fc 8661+ } else {
8662+ /*
8663+ * nfsd filldir may call lookup_one_len(), vfs_getattr(),
8664+ * encode_fh() and others.
8665+ */
9dbd164d 8666+ atomic_inc(&h_inode->i_count);
1facf9fc 8667+ di_read_unlock(dentry, AuLock_IR);
8668+ si_read_unlock(sb);
392086de 8669+ err = au_vdir_fill_de(file, ctx);
1facf9fc 8670+ fsstack_copy_attr_atime(inode, h_inode);
8671+ fi_write_unlock(file);
9dbd164d 8672+ iput(h_inode);
1facf9fc 8673+
8674+ AuTraceErr(err);
8675+ return err;
8676+ }
8677+
4f0767ce 8678+out_unlock:
1facf9fc 8679+ di_read_unlock(dentry, AuLock_IR);
8680+ fi_write_unlock(file);
4f0767ce 8681+out:
1facf9fc 8682+ si_read_unlock(sb);
8683+ return err;
8684+}
8685+
8686+/* ---------------------------------------------------------------------- */
8687+
8688+#define AuTestEmpty_WHONLY 1
dece6358
AM
8689+#define AuTestEmpty_CALLED (1 << 1)
8690+#define AuTestEmpty_SHWH (1 << 2)
1facf9fc 8691+#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
7f207e10
AM
8692+#define au_fset_testempty(flags, name) \
8693+ do { (flags) |= AuTestEmpty_##name; } while (0)
8694+#define au_fclr_testempty(flags, name) \
8695+ do { (flags) &= ~AuTestEmpty_##name; } while (0)
1facf9fc 8696+
dece6358
AM
8697+#ifndef CONFIG_AUFS_SHWH
8698+#undef AuTestEmpty_SHWH
8699+#define AuTestEmpty_SHWH 0
8700+#endif
8701+
1facf9fc 8702+struct test_empty_arg {
392086de 8703+ struct dir_context ctx;
1308ab2a 8704+ struct au_nhash *whlist;
1facf9fc 8705+ unsigned int flags;
8706+ int err;
8707+ aufs_bindex_t bindex;
8708+};
8709+
392086de
AM
8710+static int test_empty_cb(struct dir_context *ctx, const char *__name,
8711+ int namelen, loff_t offset __maybe_unused, u64 ino,
dece6358 8712+ unsigned int d_type)
1facf9fc 8713+{
392086de
AM
8714+ struct test_empty_arg *arg = container_of(ctx, struct test_empty_arg,
8715+ ctx);
1facf9fc 8716+ char *name = (void *)__name;
8717+
8718+ arg->err = 0;
8719+ au_fset_testempty(arg->flags, CALLED);
8720+ /* smp_mb(); */
8721+ if (name[0] == '.'
8722+ && (namelen == 1 || (name[1] == '.' && namelen == 2)))
8723+ goto out; /* success */
8724+
8725+ if (namelen <= AUFS_WH_PFX_LEN
8726+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
8727+ if (au_ftest_testempty(arg->flags, WHONLY)
1308ab2a 8728+ && !au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 8729+ arg->err = -ENOTEMPTY;
8730+ goto out;
8731+ }
8732+
8733+ name += AUFS_WH_PFX_LEN;
8734+ namelen -= AUFS_WH_PFX_LEN;
1308ab2a 8735+ if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 8736+ arg->err = au_nhash_append_wh
1308ab2a 8737+ (arg->whlist, name, namelen, ino, d_type, arg->bindex,
dece6358 8738+ au_ftest_testempty(arg->flags, SHWH));
1facf9fc 8739+
4f0767ce 8740+out:
1facf9fc 8741+ /* smp_mb(); */
8742+ AuTraceErr(arg->err);
8743+ return arg->err;
8744+}
8745+
8746+static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
8747+{
8748+ int err;
8749+ struct file *h_file;
8750+
8751+ h_file = au_h_open(dentry, arg->bindex,
8752+ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
392086de 8753+ /*file*/NULL, /*force_wr*/0);
1facf9fc 8754+ err = PTR_ERR(h_file);
8755+ if (IS_ERR(h_file))
8756+ goto out;
8757+
8758+ err = 0;
8759+ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
c06a8ce3 8760+ && !file_inode(h_file)->i_nlink)
1facf9fc 8761+ goto out_put;
8762+
8763+ do {
8764+ arg->err = 0;
8765+ au_fclr_testempty(arg->flags, CALLED);
8766+ /* smp_mb(); */
392086de 8767+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1facf9fc 8768+ if (err >= 0)
8769+ err = arg->err;
8770+ } while (!err && au_ftest_testempty(arg->flags, CALLED));
8771+
4f0767ce 8772+out_put:
1facf9fc 8773+ fput(h_file);
8774+ au_sbr_put(dentry->d_sb, arg->bindex);
4f0767ce 8775+out:
1facf9fc 8776+ return err;
8777+}
8778+
8779+struct do_test_empty_args {
8780+ int *errp;
8781+ struct dentry *dentry;
8782+ struct test_empty_arg *arg;
8783+};
8784+
8785+static void call_do_test_empty(void *args)
8786+{
8787+ struct do_test_empty_args *a = args;
8788+ *a->errp = do_test_empty(a->dentry, a->arg);
8789+}
8790+
8791+static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
8792+{
8793+ int err, wkq_err;
8794+ struct dentry *h_dentry;
8795+ struct inode *h_inode;
8796+
8797+ h_dentry = au_h_dptr(dentry, arg->bindex);
8798+ h_inode = h_dentry->d_inode;
53392da6 8799+ /* todo: i_mode changes anytime? */
1facf9fc 8800+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
8801+ err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
8802+ mutex_unlock(&h_inode->i_mutex);
8803+ if (!err)
8804+ err = do_test_empty(dentry, arg);
8805+ else {
8806+ struct do_test_empty_args args = {
8807+ .errp = &err,
8808+ .dentry = dentry,
8809+ .arg = arg
8810+ };
8811+ unsigned int flags = arg->flags;
8812+
8813+ wkq_err = au_wkq_wait(call_do_test_empty, &args);
8814+ if (unlikely(wkq_err))
8815+ err = wkq_err;
8816+ arg->flags = flags;
8817+ }
8818+
8819+ return err;
8820+}
8821+
8822+int au_test_empty_lower(struct dentry *dentry)
8823+{
8824+ int err;
1308ab2a 8825+ unsigned int rdhash;
1facf9fc 8826+ aufs_bindex_t bindex, bstart, btail;
1308ab2a 8827+ struct au_nhash whlist;
392086de
AM
8828+ struct test_empty_arg arg = {
8829+ .ctx = {
8830+ .actor = au_diractor(test_empty_cb)
8831+ }
8832+ };
1facf9fc 8833+
dece6358
AM
8834+ SiMustAnyLock(dentry->d_sb);
8835+
1308ab2a 8836+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
8837+ if (!rdhash)
8838+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry));
8839+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
dece6358 8840+ if (unlikely(err))
1facf9fc 8841+ goto out;
8842+
1facf9fc 8843+ arg.flags = 0;
1308ab2a 8844+ arg.whlist = &whlist;
8845+ bstart = au_dbstart(dentry);
dece6358
AM
8846+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
8847+ au_fset_testempty(arg.flags, SHWH);
1facf9fc 8848+ arg.bindex = bstart;
8849+ err = do_test_empty(dentry, &arg);
8850+ if (unlikely(err))
8851+ goto out_whlist;
8852+
8853+ au_fset_testempty(arg.flags, WHONLY);
8854+ btail = au_dbtaildir(dentry);
8855+ for (bindex = bstart + 1; !err && bindex <= btail; bindex++) {
8856+ struct dentry *h_dentry;
8857+
8858+ h_dentry = au_h_dptr(dentry, bindex);
8859+ if (h_dentry && h_dentry->d_inode) {
8860+ arg.bindex = bindex;
8861+ err = do_test_empty(dentry, &arg);
8862+ }
8863+ }
8864+
4f0767ce 8865+out_whlist:
1308ab2a 8866+ au_nhash_wh_free(&whlist);
4f0767ce 8867+out:
1facf9fc 8868+ return err;
8869+}
8870+
8871+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
8872+{
8873+ int err;
392086de
AM
8874+ struct test_empty_arg arg = {
8875+ .ctx = {
8876+ .actor = au_diractor(test_empty_cb)
8877+ }
8878+ };
1facf9fc 8879+ aufs_bindex_t bindex, btail;
8880+
8881+ err = 0;
1308ab2a 8882+ arg.whlist = whlist;
1facf9fc 8883+ arg.flags = AuTestEmpty_WHONLY;
dece6358
AM
8884+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
8885+ au_fset_testempty(arg.flags, SHWH);
1facf9fc 8886+ btail = au_dbtaildir(dentry);
8887+ for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) {
8888+ struct dentry *h_dentry;
8889+
8890+ h_dentry = au_h_dptr(dentry, bindex);
8891+ if (h_dentry && h_dentry->d_inode) {
8892+ arg.bindex = bindex;
8893+ err = sio_test_empty(dentry, &arg);
8894+ }
8895+ }
8896+
8897+ return err;
8898+}
8899+
8900+/* ---------------------------------------------------------------------- */
8901+
8902+const struct file_operations aufs_dir_fop = {
4a4d8108 8903+ .owner = THIS_MODULE,
027c5e7a 8904+ .llseek = default_llseek,
1facf9fc 8905+ .read = generic_read_dir,
392086de 8906+ .iterate = aufs_iterate,
1facf9fc 8907+ .unlocked_ioctl = aufs_ioctl_dir,
b752ccd1
AM
8908+#ifdef CONFIG_COMPAT
8909+ .compat_ioctl = aufs_compat_ioctl_dir,
8910+#endif
1facf9fc 8911+ .open = aufs_open_dir,
8912+ .release = aufs_release_dir,
4a4d8108 8913+ .flush = aufs_flush_dir,
1facf9fc 8914+ .fsync = aufs_fsync_dir
8915+};
7f207e10
AM
8916diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
8917--- /usr/share/empty/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
8918+++ linux/fs/aufs/dir.h 2014-01-20 20:16:14.736130059 +0100
8919@@ -0,0 +1,136 @@
1facf9fc 8920+/*
523b37e3 8921+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 8922+ *
8923+ * This program, aufs is free software; you can redistribute it and/or modify
8924+ * it under the terms of the GNU General Public License as published by
8925+ * the Free Software Foundation; either version 2 of the License, or
8926+ * (at your option) any later version.
dece6358
AM
8927+ *
8928+ * This program is distributed in the hope that it will be useful,
8929+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8930+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8931+ * GNU General Public License for more details.
8932+ *
8933+ * You should have received a copy of the GNU General Public License
523b37e3 8934+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 8935+ */
8936+
8937+/*
8938+ * directory operations
8939+ */
8940+
8941+#ifndef __AUFS_DIR_H__
8942+#define __AUFS_DIR_H__
8943+
8944+#ifdef __KERNEL__
8945+
8946+#include <linux/fs.h>
1facf9fc 8947+
8948+/* ---------------------------------------------------------------------- */
8949+
8950+/* need to be faster and smaller */
8951+
8952+struct au_nhash {
dece6358
AM
8953+ unsigned int nh_num;
8954+ struct hlist_head *nh_head;
1facf9fc 8955+};
8956+
8957+struct au_vdir_destr {
8958+ unsigned char len;
8959+ unsigned char name[0];
8960+} __packed;
8961+
8962+struct au_vdir_dehstr {
8963+ struct hlist_node hash;
8964+ struct au_vdir_destr *str;
4a4d8108 8965+} ____cacheline_aligned_in_smp;
1facf9fc 8966+
8967+struct au_vdir_de {
8968+ ino_t de_ino;
8969+ unsigned char de_type;
8970+ /* caution: packed */
8971+ struct au_vdir_destr de_str;
8972+} __packed;
8973+
8974+struct au_vdir_wh {
8975+ struct hlist_node wh_hash;
dece6358
AM
8976+#ifdef CONFIG_AUFS_SHWH
8977+ ino_t wh_ino;
1facf9fc 8978+ aufs_bindex_t wh_bindex;
dece6358
AM
8979+ unsigned char wh_type;
8980+#else
8981+ aufs_bindex_t wh_bindex;
8982+#endif
8983+ /* caution: packed */
1facf9fc 8984+ struct au_vdir_destr wh_str;
8985+} __packed;
8986+
8987+union au_vdir_deblk_p {
8988+ unsigned char *deblk;
8989+ struct au_vdir_de *de;
8990+};
8991+
8992+struct au_vdir {
8993+ unsigned char **vd_deblk;
8994+ unsigned long vd_nblk;
1facf9fc 8995+ struct {
8996+ unsigned long ul;
8997+ union au_vdir_deblk_p p;
8998+ } vd_last;
8999+
9000+ unsigned long vd_version;
dece6358 9001+ unsigned int vd_deblk_sz;
1facf9fc 9002+ unsigned long vd_jiffy;
4a4d8108 9003+} ____cacheline_aligned_in_smp;
1facf9fc 9004+
9005+/* ---------------------------------------------------------------------- */
9006+
9007+/* dir.c */
9008+extern const struct file_operations aufs_dir_fop;
9009+void au_add_nlink(struct inode *dir, struct inode *h_dir);
9010+void au_sub_nlink(struct inode *dir, struct inode *h_dir);
1308ab2a 9011+loff_t au_dir_size(struct file *file, struct dentry *dentry);
1facf9fc 9012+int au_test_empty_lower(struct dentry *dentry);
9013+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
9014+
9015+/* vdir.c */
1308ab2a 9016+unsigned int au_rdhash_est(loff_t sz);
dece6358
AM
9017+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
9018+void au_nhash_wh_free(struct au_nhash *whlist);
1facf9fc 9019+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
9020+ int limit);
dece6358
AM
9021+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
9022+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
9023+ unsigned int d_type, aufs_bindex_t bindex,
9024+ unsigned char shwh);
1facf9fc 9025+void au_vdir_free(struct au_vdir *vdir);
9026+int au_vdir_init(struct file *file);
392086de 9027+int au_vdir_fill_de(struct file *file, struct dir_context *ctx);
1facf9fc 9028+
9029+/* ioctl.c */
9030+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
9031+
1308ab2a 9032+#ifdef CONFIG_AUFS_RDU
9033+/* rdu.c */
9034+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
9035+#ifdef CONFIG_COMPAT
9036+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
9037+ unsigned long arg);
9038+#endif
1308ab2a 9039+#else
9040+static inline long au_rdu_ioctl(struct file *file, unsigned int cmd,
9041+ unsigned long arg)
9042+{
9043+ return -EINVAL;
9044+}
b752ccd1
AM
9045+#ifdef CONFIG_COMPAT
9046+static inline long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
9047+ unsigned long arg)
9048+{
9049+ return -EINVAL;
9050+}
9051+#endif
1308ab2a 9052+#endif
9053+
1facf9fc 9054+#endif /* __KERNEL__ */
9055+#endif /* __AUFS_DIR_H__ */
7f207e10
AM
9056diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
9057--- /usr/share/empty/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
9058+++ linux/fs/aufs/dynop.c 2014-01-20 20:16:14.736130059 +0100
9059@@ -0,0 +1,379 @@
1facf9fc 9060+/*
523b37e3 9061+ * Copyright (C) 2010-2014 Junjiro R. Okajima
1facf9fc 9062+ *
9063+ * This program, aufs is free software; you can redistribute it and/or modify
9064+ * it under the terms of the GNU General Public License as published by
9065+ * the Free Software Foundation; either version 2 of the License, or
9066+ * (at your option) any later version.
dece6358
AM
9067+ *
9068+ * This program is distributed in the hope that it will be useful,
9069+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9070+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9071+ * GNU General Public License for more details.
9072+ *
9073+ * You should have received a copy of the GNU General Public License
523b37e3 9074+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9075+ */
9076+
9077+/*
4a4d8108 9078+ * dynamically customizable operations for regular files
1facf9fc 9079+ */
9080+
1facf9fc 9081+#include "aufs.h"
9082+
4a4d8108 9083+#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop)
1facf9fc 9084+
4a4d8108
AM
9085+/*
9086+ * How large will these lists be?
9087+ * Usually just a few elements, 20-30 at most for each, I guess.
9088+ */
9089+static struct au_splhead dynop[AuDyLast];
9090+
9091+static struct au_dykey *dy_gfind_get(struct au_splhead *spl, const void *h_op)
1facf9fc 9092+{
4a4d8108
AM
9093+ struct au_dykey *key, *tmp;
9094+ struct list_head *head;
1facf9fc 9095+
4a4d8108
AM
9096+ key = NULL;
9097+ head = &spl->head;
9098+ rcu_read_lock();
9099+ list_for_each_entry_rcu(tmp, head, dk_list)
9100+ if (tmp->dk_op.dy_hop == h_op) {
9101+ key = tmp;
9102+ kref_get(&key->dk_kref);
9103+ break;
9104+ }
9105+ rcu_read_unlock();
9106+
9107+ return key;
1facf9fc 9108+}
9109+
4a4d8108 9110+static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
1facf9fc 9111+{
4a4d8108
AM
9112+ struct au_dykey **k, *found;
9113+ const void *h_op = key->dk_op.dy_hop;
9114+ int i;
1facf9fc 9115+
4a4d8108
AM
9116+ found = NULL;
9117+ k = br->br_dykey;
9118+ for (i = 0; i < AuBrDynOp; i++)
9119+ if (k[i]) {
9120+ if (k[i]->dk_op.dy_hop == h_op) {
9121+ found = k[i];
9122+ break;
9123+ }
9124+ } else
9125+ break;
9126+ if (!found) {
9127+ spin_lock(&br->br_dykey_lock);
9128+ for (; i < AuBrDynOp; i++)
9129+ if (k[i]) {
9130+ if (k[i]->dk_op.dy_hop == h_op) {
9131+ found = k[i];
9132+ break;
9133+ }
9134+ } else {
9135+ k[i] = key;
9136+ break;
9137+ }
9138+ spin_unlock(&br->br_dykey_lock);
9139+ BUG_ON(i == AuBrDynOp); /* expand the array */
9140+ }
9141+
9142+ return found;
1facf9fc 9143+}
9144+
4a4d8108
AM
9145+/* kref_get() if @key is already added */
9146+static struct au_dykey *dy_gadd(struct au_splhead *spl, struct au_dykey *key)
9147+{
9148+ struct au_dykey *tmp, *found;
9149+ struct list_head *head;
9150+ const void *h_op = key->dk_op.dy_hop;
1facf9fc 9151+
4a4d8108
AM
9152+ found = NULL;
9153+ head = &spl->head;
9154+ spin_lock(&spl->spin);
9155+ list_for_each_entry(tmp, head, dk_list)
9156+ if (tmp->dk_op.dy_hop == h_op) {
9157+ kref_get(&tmp->dk_kref);
9158+ found = tmp;
9159+ break;
9160+ }
9161+ if (!found)
9162+ list_add_rcu(&key->dk_list, head);
9163+ spin_unlock(&spl->spin);
1facf9fc 9164+
4a4d8108
AM
9165+ if (!found)
9166+ DyPrSym(key);
9167+ return found;
9168+}
9169+
9170+static void dy_free_rcu(struct rcu_head *rcu)
1facf9fc 9171+{
4a4d8108
AM
9172+ struct au_dykey *key;
9173+
9174+ key = container_of(rcu, struct au_dykey, dk_rcu);
9175+ DyPrSym(key);
9176+ kfree(key);
1facf9fc 9177+}
9178+
4a4d8108
AM
9179+static void dy_free(struct kref *kref)
9180+{
9181+ struct au_dykey *key;
9182+ struct au_splhead *spl;
1facf9fc 9183+
4a4d8108
AM
9184+ key = container_of(kref, struct au_dykey, dk_kref);
9185+ spl = dynop + key->dk_op.dy_type;
9186+ au_spl_del_rcu(&key->dk_list, spl);
9187+ call_rcu(&key->dk_rcu, dy_free_rcu);
9188+}
9189+
9190+void au_dy_put(struct au_dykey *key)
1facf9fc 9191+{
4a4d8108
AM
9192+ kref_put(&key->dk_kref, dy_free);
9193+}
1facf9fc 9194+
4a4d8108
AM
9195+/* ---------------------------------------------------------------------- */
9196+
9197+#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *))
9198+
9199+#ifdef CONFIG_AUFS_DEBUG
9200+#define DyDbgDeclare(cnt) unsigned int cnt = 0
4f0767ce 9201+#define DyDbgInc(cnt) do { cnt++; } while (0)
4a4d8108
AM
9202+#else
9203+#define DyDbgDeclare(cnt) do {} while (0)
9204+#define DyDbgInc(cnt) do {} while (0)
9205+#endif
9206+
9207+#define DySet(func, dst, src, h_op, h_sb) do { \
9208+ DyDbgInc(cnt); \
9209+ if (h_op->func) { \
9210+ if (src.func) \
9211+ dst.func = src.func; \
9212+ else \
9213+ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \
9214+ } \
9215+} while (0)
9216+
9217+#define DySetForce(func, dst, src) do { \
9218+ AuDebugOn(!src.func); \
9219+ DyDbgInc(cnt); \
9220+ dst.func = src.func; \
9221+} while (0)
9222+
9223+#define DySetAop(func) \
9224+ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
9225+#define DySetAopForce(func) \
9226+ DySetForce(func, dyaop->da_op, aufs_aop)
9227+
9228+static void dy_aop(struct au_dykey *key, const void *h_op,
9229+ struct super_block *h_sb __maybe_unused)
9230+{
9231+ struct au_dyaop *dyaop = (void *)key;
9232+ const struct address_space_operations *h_aop = h_op;
9233+ DyDbgDeclare(cnt);
9234+
9235+ AuDbg("%s\n", au_sbtype(h_sb));
9236+
9237+ DySetAop(writepage);
9238+ DySetAopForce(readpage); /* force */
4a4d8108
AM
9239+ DySetAop(writepages);
9240+ DySetAop(set_page_dirty);
9241+ DySetAop(readpages);
9242+ DySetAop(write_begin);
9243+ DySetAop(write_end);
9244+ DySetAop(bmap);
9245+ DySetAop(invalidatepage);
9246+ DySetAop(releasepage);
027c5e7a 9247+ DySetAop(freepage);
4a4d8108
AM
9248+ /* these two will be changed according to an aufs mount option */
9249+ DySetAop(direct_IO);
9250+ DySetAop(get_xip_mem);
9251+ DySetAop(migratepage);
9252+ DySetAop(launder_page);
9253+ DySetAop(is_partially_uptodate);
392086de 9254+ DySetAop(is_dirty_writeback);
4a4d8108 9255+ DySetAop(error_remove_page);
b4510431
AM
9256+ DySetAop(swap_activate);
9257+ DySetAop(swap_deactivate);
4a4d8108
AM
9258+
9259+ DyDbgSize(cnt, *h_aop);
9260+ dyaop->da_get_xip_mem = h_aop->get_xip_mem;
9261+}
9262+
4a4d8108
AM
9263+/* ---------------------------------------------------------------------- */
9264+
9265+static void dy_bug(struct kref *kref)
9266+{
9267+ BUG();
9268+}
9269+
9270+static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
9271+{
9272+ struct au_dykey *key, *old;
9273+ struct au_splhead *spl;
b752ccd1 9274+ struct op {
4a4d8108 9275+ unsigned int sz;
b752ccd1
AM
9276+ void (*set)(struct au_dykey *key, const void *h_op,
9277+ struct super_block *h_sb __maybe_unused);
9278+ };
9279+ static const struct op a[] = {
4a4d8108
AM
9280+ [AuDy_AOP] = {
9281+ .sz = sizeof(struct au_dyaop),
b752ccd1 9282+ .set = dy_aop
4a4d8108 9283+ }
b752ccd1
AM
9284+ };
9285+ const struct op *p;
4a4d8108
AM
9286+
9287+ spl = dynop + op->dy_type;
9288+ key = dy_gfind_get(spl, op->dy_hop);
9289+ if (key)
9290+ goto out_add; /* success */
9291+
9292+ p = a + op->dy_type;
9293+ key = kzalloc(p->sz, GFP_NOFS);
9294+ if (unlikely(!key)) {
9295+ key = ERR_PTR(-ENOMEM);
9296+ goto out;
9297+ }
9298+
9299+ key->dk_op.dy_hop = op->dy_hop;
9300+ kref_init(&key->dk_kref);
86dc4139 9301+ p->set(key, op->dy_hop, au_br_sb(br));
4a4d8108
AM
9302+ old = dy_gadd(spl, key);
9303+ if (old) {
9304+ kfree(key);
9305+ key = old;
9306+ }
9307+
9308+out_add:
9309+ old = dy_bradd(br, key);
9310+ if (old)
9311+ /* its ref-count should never be zero here */
9312+ kref_put(&key->dk_kref, dy_bug);
9313+out:
9314+ return key;
9315+}
9316+
9317+/* ---------------------------------------------------------------------- */
9318+/*
9319+ * Aufs prohibits O_DIRECT by defaut even if the branch supports it.
9320+ * This behaviour is neccessary to return an error from open(O_DIRECT) instead
9321+ * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
9322+ * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
9323+ * See the aufs manual in detail.
9324+ *
9325+ * To keep this behaviour, aufs has to set NULL to ->get_xip_mem too, and the
9326+ * performance of fadvise() and madvise() may be affected.
9327+ */
9328+static void dy_adx(struct au_dyaop *dyaop, int do_dx)
9329+{
9330+ if (!do_dx) {
9331+ dyaop->da_op.direct_IO = NULL;
9332+ dyaop->da_op.get_xip_mem = NULL;
9333+ } else {
9334+ dyaop->da_op.direct_IO = aufs_aop.direct_IO;
9335+ dyaop->da_op.get_xip_mem = aufs_aop.get_xip_mem;
9336+ if (!dyaop->da_get_xip_mem)
9337+ dyaop->da_op.get_xip_mem = NULL;
9338+ }
9339+}
9340+
9341+static struct au_dyaop *dy_aget(struct au_branch *br,
9342+ const struct address_space_operations *h_aop,
9343+ int do_dx)
9344+{
9345+ struct au_dyaop *dyaop;
9346+ struct au_dynop op;
9347+
9348+ op.dy_type = AuDy_AOP;
9349+ op.dy_haop = h_aop;
9350+ dyaop = (void *)dy_get(&op, br);
9351+ if (IS_ERR(dyaop))
9352+ goto out;
9353+ dy_adx(dyaop, do_dx);
9354+
9355+out:
9356+ return dyaop;
9357+}
9358+
9359+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
9360+ struct inode *h_inode)
9361+{
9362+ int err, do_dx;
9363+ struct super_block *sb;
9364+ struct au_branch *br;
9365+ struct au_dyaop *dyaop;
9366+
9367+ AuDebugOn(!S_ISREG(h_inode->i_mode));
9368+ IiMustWriteLock(inode);
9369+
9370+ sb = inode->i_sb;
9371+ br = au_sbr(sb, bindex);
9372+ do_dx = !!au_opt_test(au_mntflags(sb), DIO);
9373+ dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
9374+ err = PTR_ERR(dyaop);
9375+ if (IS_ERR(dyaop))
9376+ /* unnecessary to call dy_fput() */
9377+ goto out;
9378+
9379+ err = 0;
9380+ inode->i_mapping->a_ops = &dyaop->da_op;
9381+
9382+out:
9383+ return err;
9384+}
9385+
b752ccd1
AM
9386+/*
9387+ * Is it safe to replace a_ops during the inode/file is in operation?
9388+ * Yes, I hope so.
9389+ */
9390+int au_dy_irefresh(struct inode *inode)
9391+{
9392+ int err;
9393+ aufs_bindex_t bstart;
9394+ struct inode *h_inode;
9395+
9396+ err = 0;
9397+ if (S_ISREG(inode->i_mode)) {
9398+ bstart = au_ibstart(inode);
9399+ h_inode = au_h_iptr(inode, bstart);
9400+ err = au_dy_iaop(inode, bstart, h_inode);
9401+ }
9402+ return err;
9403+}
9404+
4a4d8108
AM
9405+void au_dy_arefresh(int do_dx)
9406+{
9407+ struct au_splhead *spl;
9408+ struct list_head *head;
9409+ struct au_dykey *key;
9410+
9411+ spl = dynop + AuDy_AOP;
9412+ head = &spl->head;
9413+ spin_lock(&spl->spin);
9414+ list_for_each_entry(key, head, dk_list)
9415+ dy_adx((void *)key, do_dx);
9416+ spin_unlock(&spl->spin);
9417+}
9418+
4a4d8108
AM
9419+/* ---------------------------------------------------------------------- */
9420+
9421+void __init au_dy_init(void)
9422+{
9423+ int i;
9424+
9425+ /* make sure that 'struct au_dykey *' can be any type */
9426+ BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
4a4d8108
AM
9427+
9428+ for (i = 0; i < AuDyLast; i++)
9429+ au_spl_init(dynop + i);
9430+}
9431+
9432+void au_dy_fin(void)
9433+{
9434+ int i;
9435+
9436+ for (i = 0; i < AuDyLast; i++)
9437+ WARN_ON(!list_empty(&dynop[i].head));
9438+}
7f207e10
AM
9439diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
9440--- /usr/share/empty/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
9441+++ linux/fs/aufs/dynop.h 2014-01-20 20:16:14.736130059 +0100
9442@@ -0,0 +1,75 @@
4a4d8108 9443+/*
523b37e3 9444+ * Copyright (C) 2010-2014 Junjiro R. Okajima
4a4d8108
AM
9445+ *
9446+ * This program, aufs is free software; you can redistribute it and/or modify
9447+ * it under the terms of the GNU General Public License as published by
9448+ * the Free Software Foundation; either version 2 of the License, or
9449+ * (at your option) any later version.
9450+ *
9451+ * This program is distributed in the hope that it will be useful,
9452+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9453+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9454+ * GNU General Public License for more details.
9455+ *
9456+ * You should have received a copy of the GNU General Public License
523b37e3 9457+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
9458+ */
9459+
9460+/*
9461+ * dynamically customizable operations (for regular files only)
9462+ */
9463+
9464+#ifndef __AUFS_DYNOP_H__
9465+#define __AUFS_DYNOP_H__
9466+
9467+#ifdef __KERNEL__
9468+
4a4d8108
AM
9469+#include "inode.h"
9470+
2cbb1c4b 9471+enum {AuDy_AOP, AuDyLast};
4a4d8108
AM
9472+
9473+struct au_dynop {
9474+ int dy_type;
9475+ union {
9476+ const void *dy_hop;
9477+ const struct address_space_operations *dy_haop;
4a4d8108
AM
9478+ };
9479+};
9480+
9481+struct au_dykey {
9482+ union {
9483+ struct list_head dk_list;
9484+ struct rcu_head dk_rcu;
9485+ };
9486+ struct au_dynop dk_op;
9487+
9488+ /*
9489+ * during I am in the branch local array, kref is gotten. when the
9490+ * branch is removed, kref is put.
9491+ */
9492+ struct kref dk_kref;
9493+};
9494+
9495+/* stop unioning since their sizes are very different from each other */
9496+struct au_dyaop {
9497+ struct au_dykey da_key;
9498+ struct address_space_operations da_op; /* not const */
9499+ int (*da_get_xip_mem)(struct address_space *, pgoff_t, int,
9500+ void **, unsigned long *);
9501+};
9502+
4a4d8108
AM
9503+/* ---------------------------------------------------------------------- */
9504+
9505+/* dynop.c */
9506+struct au_branch;
9507+void au_dy_put(struct au_dykey *key);
9508+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
9509+ struct inode *h_inode);
b752ccd1 9510+int au_dy_irefresh(struct inode *inode);
4a4d8108 9511+void au_dy_arefresh(int do_dio);
4a4d8108
AM
9512+
9513+void __init au_dy_init(void);
9514+void au_dy_fin(void);
9515+
4a4d8108
AM
9516+#endif /* __KERNEL__ */
9517+#endif /* __AUFS_DYNOP_H__ */
7f207e10
AM
9518diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
9519--- /usr/share/empty/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
9520+++ linux/fs/aufs/export.c 2014-01-20 20:16:14.736130059 +0100
9521@@ -0,0 +1,831 @@
4a4d8108 9522+/*
523b37e3 9523+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
9524+ *
9525+ * This program, aufs is free software; you can redistribute it and/or modify
9526+ * it under the terms of the GNU General Public License as published by
9527+ * the Free Software Foundation; either version 2 of the License, or
9528+ * (at your option) any later version.
9529+ *
9530+ * This program is distributed in the hope that it will be useful,
9531+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9532+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9533+ * GNU General Public License for more details.
9534+ *
9535+ * You should have received a copy of the GNU General Public License
523b37e3 9536+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
9537+ */
9538+
9539+/*
9540+ * export via nfs
9541+ */
9542+
9543+#include <linux/exportfs.h>
7eafdf33 9544+#include <linux/fs_struct.h>
4a4d8108
AM
9545+#include <linux/namei.h>
9546+#include <linux/nsproxy.h>
9547+#include <linux/random.h>
9548+#include <linux/writeback.h>
7eafdf33 9549+#include "../fs/mount.h"
4a4d8108
AM
9550+#include "aufs.h"
9551+
9552+union conv {
9553+#ifdef CONFIG_AUFS_INO_T_64
9554+ __u32 a[2];
9555+#else
9556+ __u32 a[1];
9557+#endif
9558+ ino_t ino;
9559+};
9560+
9561+static ino_t decode_ino(__u32 *a)
9562+{
9563+ union conv u;
9564+
9565+ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
9566+ u.a[0] = a[0];
9567+#ifdef CONFIG_AUFS_INO_T_64
9568+ u.a[1] = a[1];
9569+#endif
9570+ return u.ino;
9571+}
9572+
9573+static void encode_ino(__u32 *a, ino_t ino)
9574+{
9575+ union conv u;
9576+
9577+ u.ino = ino;
9578+ a[0] = u.a[0];
9579+#ifdef CONFIG_AUFS_INO_T_64
9580+ a[1] = u.a[1];
9581+#endif
9582+}
9583+
9584+/* NFS file handle */
9585+enum {
9586+ Fh_br_id,
9587+ Fh_sigen,
9588+#ifdef CONFIG_AUFS_INO_T_64
9589+ /* support 64bit inode number */
9590+ Fh_ino1,
9591+ Fh_ino2,
9592+ Fh_dir_ino1,
9593+ Fh_dir_ino2,
9594+#else
9595+ Fh_ino1,
9596+ Fh_dir_ino1,
9597+#endif
9598+ Fh_igen,
9599+ Fh_h_type,
9600+ Fh_tail,
9601+
9602+ Fh_ino = Fh_ino1,
9603+ Fh_dir_ino = Fh_dir_ino1
9604+};
9605+
9606+static int au_test_anon(struct dentry *dentry)
9607+{
027c5e7a 9608+ /* note: read d_flags without d_lock */
4a4d8108
AM
9609+ return !!(dentry->d_flags & DCACHE_DISCONNECTED);
9610+}
9611+
a2a7ad62
AM
9612+int au_test_nfsd(void)
9613+{
9614+ int ret;
9615+ struct task_struct *tsk = current;
9616+ char comm[sizeof(tsk->comm)];
9617+
9618+ ret = 0;
9619+ if (tsk->flags & PF_KTHREAD) {
9620+ get_task_comm(comm, tsk);
9621+ ret = !strcmp(comm, "nfsd");
9622+ }
9623+
9624+ return ret;
9625+}
9626+
4a4d8108
AM
9627+/* ---------------------------------------------------------------------- */
9628+/* inode generation external table */
9629+
b752ccd1 9630+void au_xigen_inc(struct inode *inode)
4a4d8108 9631+{
4a4d8108
AM
9632+ loff_t pos;
9633+ ssize_t sz;
9634+ __u32 igen;
9635+ struct super_block *sb;
9636+ struct au_sbinfo *sbinfo;
9637+
4a4d8108 9638+ sb = inode->i_sb;
b752ccd1 9639+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
1facf9fc 9640+
b752ccd1 9641+ sbinfo = au_sbi(sb);
1facf9fc 9642+ pos = inode->i_ino;
9643+ pos *= sizeof(igen);
9644+ igen = inode->i_generation + 1;
1facf9fc 9645+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
9646+ sizeof(igen), &pos);
9647+ if (sz == sizeof(igen))
b752ccd1 9648+ return; /* success */
1facf9fc 9649+
b752ccd1 9650+ if (unlikely(sz >= 0))
1facf9fc 9651+ AuIOErr("xigen error (%zd)\n", sz);
1facf9fc 9652+}
9653+
9654+int au_xigen_new(struct inode *inode)
9655+{
9656+ int err;
9657+ loff_t pos;
9658+ ssize_t sz;
9659+ struct super_block *sb;
9660+ struct au_sbinfo *sbinfo;
9661+ struct file *file;
9662+
9663+ err = 0;
9664+ /* todo: dirty, at mount time */
9665+ if (inode->i_ino == AUFS_ROOT_INO)
9666+ goto out;
9667+ sb = inode->i_sb;
dece6358 9668+ SiMustAnyLock(sb);
1facf9fc 9669+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
9670+ goto out;
9671+
9672+ err = -EFBIG;
9673+ pos = inode->i_ino;
9674+ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
9675+ AuIOErr1("too large i%lld\n", pos);
9676+ goto out;
9677+ }
9678+ pos *= sizeof(inode->i_generation);
9679+
9680+ err = 0;
9681+ sbinfo = au_sbi(sb);
9682+ file = sbinfo->si_xigen;
9683+ BUG_ON(!file);
9684+
c06a8ce3 9685+ if (vfsub_f_size_read(file)
1facf9fc 9686+ < pos + sizeof(inode->i_generation)) {
9687+ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
9688+ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
9689+ sizeof(inode->i_generation), &pos);
9690+ } else
9691+ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
9692+ sizeof(inode->i_generation), &pos);
9693+ if (sz == sizeof(inode->i_generation))
9694+ goto out; /* success */
9695+
9696+ err = sz;
9697+ if (unlikely(sz >= 0)) {
9698+ err = -EIO;
9699+ AuIOErr("xigen error (%zd)\n", sz);
9700+ }
9701+
4f0767ce 9702+out:
1facf9fc 9703+ return err;
9704+}
9705+
9706+int au_xigen_set(struct super_block *sb, struct file *base)
9707+{
9708+ int err;
9709+ struct au_sbinfo *sbinfo;
9710+ struct file *file;
9711+
dece6358
AM
9712+ SiMustWriteLock(sb);
9713+
1facf9fc 9714+ sbinfo = au_sbi(sb);
9715+ file = au_xino_create2(base, sbinfo->si_xigen);
9716+ err = PTR_ERR(file);
9717+ if (IS_ERR(file))
9718+ goto out;
9719+ err = 0;
9720+ if (sbinfo->si_xigen)
9721+ fput(sbinfo->si_xigen);
9722+ sbinfo->si_xigen = file;
9723+
4f0767ce 9724+out:
1facf9fc 9725+ return err;
9726+}
9727+
9728+void au_xigen_clr(struct super_block *sb)
9729+{
9730+ struct au_sbinfo *sbinfo;
9731+
dece6358
AM
9732+ SiMustWriteLock(sb);
9733+
1facf9fc 9734+ sbinfo = au_sbi(sb);
9735+ if (sbinfo->si_xigen) {
9736+ fput(sbinfo->si_xigen);
9737+ sbinfo->si_xigen = NULL;
9738+ }
9739+}
9740+
9741+/* ---------------------------------------------------------------------- */
9742+
9743+static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
9744+ ino_t dir_ino)
9745+{
9746+ struct dentry *dentry, *d;
9747+ struct inode *inode;
9748+ unsigned int sigen;
9749+
9750+ dentry = NULL;
9751+ inode = ilookup(sb, ino);
9752+ if (!inode)
9753+ goto out;
9754+
9755+ dentry = ERR_PTR(-ESTALE);
9756+ sigen = au_sigen(sb);
9757+ if (unlikely(is_bad_inode(inode)
9758+ || IS_DEADDIR(inode)
537831f9 9759+ || sigen != au_iigen(inode, NULL)))
1facf9fc 9760+ goto out_iput;
9761+
9762+ dentry = NULL;
9763+ if (!dir_ino || S_ISDIR(inode->i_mode))
9764+ dentry = d_find_alias(inode);
9765+ else {
027c5e7a 9766+ spin_lock(&inode->i_lock);
c06a8ce3 9767+ hlist_for_each_entry(d, &inode->i_dentry, d_alias) {
027c5e7a 9768+ spin_lock(&d->d_lock);
1facf9fc 9769+ if (!au_test_anon(d)
9770+ && d->d_parent->d_inode->i_ino == dir_ino) {
027c5e7a
AM
9771+ dentry = dget_dlock(d);
9772+ spin_unlock(&d->d_lock);
1facf9fc 9773+ break;
9774+ }
027c5e7a
AM
9775+ spin_unlock(&d->d_lock);
9776+ }
9777+ spin_unlock(&inode->i_lock);
1facf9fc 9778+ }
027c5e7a 9779+ if (unlikely(dentry && au_digen_test(dentry, sigen))) {
2cbb1c4b 9780+ /* need to refresh */
1facf9fc 9781+ dput(dentry);
2cbb1c4b 9782+ dentry = NULL;
1facf9fc 9783+ }
9784+
4f0767ce 9785+out_iput:
1facf9fc 9786+ iput(inode);
4f0767ce 9787+out:
2cbb1c4b 9788+ AuTraceErrPtr(dentry);
1facf9fc 9789+ return dentry;
9790+}
9791+
9792+/* ---------------------------------------------------------------------- */
9793+
9794+/* todo: dirty? */
9795+/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
4a4d8108
AM
9796+
9797+struct au_compare_mnt_args {
9798+ /* input */
9799+ struct super_block *sb;
9800+
9801+ /* output */
9802+ struct vfsmount *mnt;
9803+};
9804+
9805+static int au_compare_mnt(struct vfsmount *mnt, void *arg)
9806+{
9807+ struct au_compare_mnt_args *a = arg;
9808+
9809+ if (mnt->mnt_sb != a->sb)
9810+ return 0;
9811+ a->mnt = mntget(mnt);
9812+ return 1;
9813+}
9814+
1facf9fc 9815+static struct vfsmount *au_mnt_get(struct super_block *sb)
9816+{
4a4d8108 9817+ int err;
7eafdf33 9818+ struct path root;
4a4d8108
AM
9819+ struct au_compare_mnt_args args = {
9820+ .sb = sb
9821+ };
1facf9fc 9822+
7eafdf33 9823+ get_fs_root(current->fs, &root);
523b37e3 9824+ rcu_read_lock();
7eafdf33 9825+ err = iterate_mounts(au_compare_mnt, &args, root.mnt);
523b37e3 9826+ rcu_read_unlock();
7eafdf33 9827+ path_put(&root);
4a4d8108
AM
9828+ AuDebugOn(!err);
9829+ AuDebugOn(!args.mnt);
9830+ return args.mnt;
1facf9fc 9831+}
9832+
9833+struct au_nfsd_si_lock {
4a4d8108 9834+ unsigned int sigen;
027c5e7a 9835+ aufs_bindex_t bindex, br_id;
1facf9fc 9836+ unsigned char force_lock;
9837+};
9838+
027c5e7a
AM
9839+static int si_nfsd_read_lock(struct super_block *sb,
9840+ struct au_nfsd_si_lock *nsi_lock)
1facf9fc 9841+{
027c5e7a 9842+ int err;
1facf9fc 9843+ aufs_bindex_t bindex;
9844+
9845+ si_read_lock(sb, AuLock_FLUSH);
9846+
9847+ /* branch id may be wrapped around */
027c5e7a 9848+ err = 0;
1facf9fc 9849+ bindex = au_br_index(sb, nsi_lock->br_id);
9850+ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
9851+ goto out; /* success */
9852+
027c5e7a
AM
9853+ err = -ESTALE;
9854+ bindex = -1;
1facf9fc 9855+ if (!nsi_lock->force_lock)
9856+ si_read_unlock(sb);
1facf9fc 9857+
4f0767ce 9858+out:
027c5e7a
AM
9859+ nsi_lock->bindex = bindex;
9860+ return err;
1facf9fc 9861+}
9862+
9863+struct find_name_by_ino {
392086de 9864+ struct dir_context ctx;
1facf9fc 9865+ int called, found;
9866+ ino_t ino;
9867+ char *name;
9868+ int namelen;
9869+};
9870+
9871+static int
392086de
AM
9872+find_name_by_ino(struct dir_context *ctx, const char *name, int namelen,
9873+ loff_t offset, u64 ino, unsigned int d_type)
1facf9fc 9874+{
392086de
AM
9875+ struct find_name_by_ino *a = container_of(ctx, struct find_name_by_ino,
9876+ ctx);
1facf9fc 9877+
9878+ a->called++;
9879+ if (a->ino != ino)
9880+ return 0;
9881+
9882+ memcpy(a->name, name, namelen);
9883+ a->namelen = namelen;
9884+ a->found = 1;
9885+ return 1;
9886+}
9887+
9888+static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
9889+ struct au_nfsd_si_lock *nsi_lock)
9890+{
9891+ struct dentry *dentry, *parent;
9892+ struct file *file;
9893+ struct inode *dir;
392086de
AM
9894+ struct find_name_by_ino arg = {
9895+ .ctx = {
9896+ .actor = au_diractor(find_name_by_ino)
9897+ }
9898+ };
1facf9fc 9899+ int err;
9900+
9901+ parent = path->dentry;
9902+ if (nsi_lock)
9903+ si_read_unlock(parent->d_sb);
4a4d8108 9904+ file = vfsub_dentry_open(path, au_dir_roflags);
1facf9fc 9905+ dentry = (void *)file;
9906+ if (IS_ERR(file))
9907+ goto out;
9908+
9909+ dentry = ERR_PTR(-ENOMEM);
537831f9 9910+ arg.name = (void *)__get_free_page(GFP_NOFS);
1facf9fc 9911+ if (unlikely(!arg.name))
9912+ goto out_file;
9913+ arg.ino = ino;
9914+ arg.found = 0;
9915+ do {
9916+ arg.called = 0;
9917+ /* smp_mb(); */
392086de 9918+ err = vfsub_iterate_dir(file, &arg.ctx);
1facf9fc 9919+ } while (!err && !arg.found && arg.called);
9920+ dentry = ERR_PTR(err);
9921+ if (unlikely(err))
9922+ goto out_name;
1716fcea
AM
9923+ /* instead of ENOENT */
9924+ dentry = ERR_PTR(-ESTALE);
1facf9fc 9925+ if (!arg.found)
9926+ goto out_name;
9927+
b4510431 9928+ /* do not call vfsub_lkup_one() */
1facf9fc 9929+ dir = parent->d_inode;
9930+ mutex_lock(&dir->i_mutex);
9931+ dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
9932+ mutex_unlock(&dir->i_mutex);
9933+ AuTraceErrPtr(dentry);
9934+ if (IS_ERR(dentry))
9935+ goto out_name;
9936+ AuDebugOn(au_test_anon(dentry));
9937+ if (unlikely(!dentry->d_inode)) {
9938+ dput(dentry);
9939+ dentry = ERR_PTR(-ENOENT);
9940+ }
9941+
4f0767ce 9942+out_name:
537831f9 9943+ free_page((unsigned long)arg.name);
4f0767ce 9944+out_file:
1facf9fc 9945+ fput(file);
4f0767ce 9946+out:
1facf9fc 9947+ if (unlikely(nsi_lock
9948+ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
9949+ if (!IS_ERR(dentry)) {
9950+ dput(dentry);
9951+ dentry = ERR_PTR(-ESTALE);
9952+ }
9953+ AuTraceErrPtr(dentry);
9954+ return dentry;
9955+}
9956+
9957+static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
9958+ ino_t dir_ino,
9959+ struct au_nfsd_si_lock *nsi_lock)
9960+{
9961+ struct dentry *dentry;
9962+ struct path path;
9963+
9964+ if (dir_ino != AUFS_ROOT_INO) {
9965+ path.dentry = decode_by_ino(sb, dir_ino, 0);
9966+ dentry = path.dentry;
9967+ if (!path.dentry || IS_ERR(path.dentry))
9968+ goto out;
9969+ AuDebugOn(au_test_anon(path.dentry));
9970+ } else
9971+ path.dentry = dget(sb->s_root);
9972+
9973+ path.mnt = au_mnt_get(sb);
9974+ dentry = au_lkup_by_ino(&path, ino, nsi_lock);
9975+ path_put(&path);
9976+
4f0767ce 9977+out:
1facf9fc 9978+ AuTraceErrPtr(dentry);
9979+ return dentry;
9980+}
9981+
9982+/* ---------------------------------------------------------------------- */
9983+
9984+static int h_acceptable(void *expv, struct dentry *dentry)
9985+{
9986+ return 1;
9987+}
9988+
9989+static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
9990+ char *buf, int len, struct super_block *sb)
9991+{
9992+ char *p;
9993+ int n;
9994+ struct path path;
9995+
9996+ p = d_path(h_rootpath, buf, len);
9997+ if (IS_ERR(p))
9998+ goto out;
9999+ n = strlen(p);
10000+
10001+ path.mnt = h_rootpath->mnt;
10002+ path.dentry = h_parent;
10003+ p = d_path(&path, buf, len);
10004+ if (IS_ERR(p))
10005+ goto out;
10006+ if (n != 1)
10007+ p += n;
10008+
10009+ path.mnt = au_mnt_get(sb);
10010+ path.dentry = sb->s_root;
10011+ p = d_path(&path, buf, len - strlen(p));
10012+ mntput(path.mnt);
10013+ if (IS_ERR(p))
10014+ goto out;
10015+ if (n != 1)
10016+ p[strlen(p)] = '/';
10017+
4f0767ce 10018+out:
1facf9fc 10019+ AuTraceErrPtr(p);
10020+ return p;
10021+}
10022+
10023+static
027c5e7a
AM
10024+struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
10025+ int fh_len, struct au_nfsd_si_lock *nsi_lock)
1facf9fc 10026+{
10027+ struct dentry *dentry, *h_parent, *root;
10028+ struct super_block *h_sb;
10029+ char *pathname, *p;
10030+ struct vfsmount *h_mnt;
10031+ struct au_branch *br;
10032+ int err;
10033+ struct path path;
10034+
027c5e7a 10035+ br = au_sbr(sb, nsi_lock->bindex);
86dc4139 10036+ h_mnt = au_br_mnt(br);
1facf9fc 10037+ h_sb = h_mnt->mnt_sb;
10038+ /* todo: call lower fh_to_dentry()? fh_to_parent()? */
10039+ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
10040+ fh_len - Fh_tail, fh[Fh_h_type],
10041+ h_acceptable, /*context*/NULL);
10042+ dentry = h_parent;
10043+ if (unlikely(!h_parent || IS_ERR(h_parent))) {
10044+ AuWarn1("%s decode_fh failed, %ld\n",
10045+ au_sbtype(h_sb), PTR_ERR(h_parent));
10046+ goto out;
10047+ }
10048+ dentry = NULL;
10049+ if (unlikely(au_test_anon(h_parent))) {
10050+ AuWarn1("%s decode_fh returned a disconnected dentry\n",
10051+ au_sbtype(h_sb));
10052+ goto out_h_parent;
10053+ }
10054+
10055+ dentry = ERR_PTR(-ENOMEM);
10056+ pathname = (void *)__get_free_page(GFP_NOFS);
10057+ if (unlikely(!pathname))
10058+ goto out_h_parent;
10059+
10060+ root = sb->s_root;
10061+ path.mnt = h_mnt;
10062+ di_read_lock_parent(root, !AuLock_IR);
027c5e7a 10063+ path.dentry = au_h_dptr(root, nsi_lock->bindex);
1facf9fc 10064+ di_read_unlock(root, !AuLock_IR);
10065+ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
10066+ dentry = (void *)p;
10067+ if (IS_ERR(p))
10068+ goto out_pathname;
10069+
10070+ si_read_unlock(sb);
10071+ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
10072+ dentry = ERR_PTR(err);
10073+ if (unlikely(err))
10074+ goto out_relock;
10075+
10076+ dentry = ERR_PTR(-ENOENT);
10077+ AuDebugOn(au_test_anon(path.dentry));
10078+ if (unlikely(!path.dentry->d_inode))
10079+ goto out_path;
10080+
10081+ if (ino != path.dentry->d_inode->i_ino)
10082+ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
10083+ else
10084+ dentry = dget(path.dentry);
10085+
4f0767ce 10086+out_path:
1facf9fc 10087+ path_put(&path);
4f0767ce 10088+out_relock:
1facf9fc 10089+ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
10090+ if (!IS_ERR(dentry)) {
10091+ dput(dentry);
10092+ dentry = ERR_PTR(-ESTALE);
10093+ }
4f0767ce 10094+out_pathname:
1facf9fc 10095+ free_page((unsigned long)pathname);
4f0767ce 10096+out_h_parent:
1facf9fc 10097+ dput(h_parent);
4f0767ce 10098+out:
1facf9fc 10099+ AuTraceErrPtr(dentry);
10100+ return dentry;
10101+}
10102+
10103+/* ---------------------------------------------------------------------- */
10104+
10105+static struct dentry *
10106+aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
10107+ int fh_type)
10108+{
10109+ struct dentry *dentry;
10110+ __u32 *fh = fid->raw;
027c5e7a 10111+ struct au_branch *br;
1facf9fc 10112+ ino_t ino, dir_ino;
1facf9fc 10113+ struct au_nfsd_si_lock nsi_lock = {
1facf9fc 10114+ .force_lock = 0
10115+ };
10116+
1facf9fc 10117+ dentry = ERR_PTR(-ESTALE);
4a4d8108
AM
10118+ /* it should never happen, but the file handle is unreliable */
10119+ if (unlikely(fh_len < Fh_tail))
10120+ goto out;
10121+ nsi_lock.sigen = fh[Fh_sigen];
10122+ nsi_lock.br_id = fh[Fh_br_id];
10123+
1facf9fc 10124+ /* branch id may be wrapped around */
027c5e7a
AM
10125+ br = NULL;
10126+ if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
1facf9fc 10127+ goto out;
10128+ nsi_lock.force_lock = 1;
10129+
10130+ /* is this inode still cached? */
10131+ ino = decode_ino(fh + Fh_ino);
4a4d8108
AM
10132+ /* it should never happen */
10133+ if (unlikely(ino == AUFS_ROOT_INO))
10134+ goto out;
10135+
1facf9fc 10136+ dir_ino = decode_ino(fh + Fh_dir_ino);
10137+ dentry = decode_by_ino(sb, ino, dir_ino);
10138+ if (IS_ERR(dentry))
10139+ goto out_unlock;
10140+ if (dentry)
10141+ goto accept;
10142+
10143+ /* is the parent dir cached? */
027c5e7a
AM
10144+ br = au_sbr(sb, nsi_lock.bindex);
10145+ atomic_inc(&br->br_count);
1facf9fc 10146+ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
10147+ if (IS_ERR(dentry))
10148+ goto out_unlock;
10149+ if (dentry)
10150+ goto accept;
10151+
10152+ /* lookup path */
027c5e7a 10153+ dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
1facf9fc 10154+ if (IS_ERR(dentry))
10155+ goto out_unlock;
10156+ if (unlikely(!dentry))
10157+ /* todo?: make it ESTALE */
10158+ goto out_unlock;
10159+
4f0767ce 10160+accept:
027c5e7a
AM
10161+ if (!au_digen_test(dentry, au_sigen(sb))
10162+ && dentry->d_inode->i_generation == fh[Fh_igen])
1facf9fc 10163+ goto out_unlock; /* success */
10164+
10165+ dput(dentry);
10166+ dentry = ERR_PTR(-ESTALE);
4f0767ce 10167+out_unlock:
027c5e7a
AM
10168+ if (br)
10169+ atomic_dec(&br->br_count);
1facf9fc 10170+ si_read_unlock(sb);
4f0767ce 10171+out:
1facf9fc 10172+ AuTraceErrPtr(dentry);
10173+ return dentry;
10174+}
10175+
10176+#if 0 /* reserved for future use */
10177+/* support subtreecheck option */
10178+static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
10179+ int fh_len, int fh_type)
10180+{
10181+ struct dentry *parent;
10182+ __u32 *fh = fid->raw;
10183+ ino_t dir_ino;
10184+
10185+ dir_ino = decode_ino(fh + Fh_dir_ino);
10186+ parent = decode_by_ino(sb, dir_ino, 0);
10187+ if (IS_ERR(parent))
10188+ goto out;
10189+ if (!parent)
10190+ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
10191+ dir_ino, fh, fh_len);
10192+
4f0767ce 10193+out:
1facf9fc 10194+ AuTraceErrPtr(parent);
10195+ return parent;
10196+}
10197+#endif
10198+
10199+/* ---------------------------------------------------------------------- */
10200+
0c3ec466
AM
10201+static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
10202+ struct inode *dir)
1facf9fc 10203+{
10204+ int err;
0c3ec466 10205+ aufs_bindex_t bindex;
1facf9fc 10206+ struct super_block *sb, *h_sb;
0c3ec466
AM
10207+ struct dentry *dentry, *parent, *h_parent;
10208+ struct inode *h_dir;
1facf9fc 10209+ struct au_branch *br;
10210+
1facf9fc 10211+ err = -ENOSPC;
10212+ if (unlikely(*max_len <= Fh_tail)) {
10213+ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
10214+ goto out;
10215+ }
10216+
10217+ err = FILEID_ROOT;
0c3ec466
AM
10218+ if (inode->i_ino == AUFS_ROOT_INO) {
10219+ AuDebugOn(inode->i_ino != AUFS_ROOT_INO);
1facf9fc 10220+ goto out;
10221+ }
10222+
1facf9fc 10223+ h_parent = NULL;
0c3ec466
AM
10224+ sb = inode->i_sb;
10225+ err = si_read_lock(sb, AuLock_FLUSH);
027c5e7a
AM
10226+ if (unlikely(err))
10227+ goto out;
10228+
1facf9fc 10229+#ifdef CONFIG_AUFS_DEBUG
10230+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
10231+ AuWarn1("NFS-exporting requires xino\n");
10232+#endif
027c5e7a 10233+ err = -EIO;
0c3ec466
AM
10234+ parent = NULL;
10235+ ii_read_lock_child(inode);
10236+ bindex = au_ibstart(inode);
10237+ if (!dir) {
10238+ dentry = d_find_alias(inode);
10239+ if (unlikely(!dentry))
10240+ goto out_unlock;
10241+ AuDebugOn(au_test_anon(dentry));
10242+ parent = dget_parent(dentry);
10243+ dput(dentry);
10244+ if (unlikely(!parent))
10245+ goto out_unlock;
10246+ dir = parent->d_inode;
1facf9fc 10247+ }
0c3ec466
AM
10248+
10249+ ii_read_lock_parent(dir);
10250+ h_dir = au_h_iptr(dir, bindex);
10251+ ii_read_unlock(dir);
10252+ if (unlikely(!h_dir))
10253+ goto out_parent;
10254+ h_parent = d_find_alias(h_dir);
1facf9fc 10255+ if (unlikely(!h_parent))
0c3ec466 10256+ goto out_hparent;
1facf9fc 10257+
10258+ err = -EPERM;
10259+ br = au_sbr(sb, bindex);
86dc4139 10260+ h_sb = au_br_sb(br);
1facf9fc 10261+ if (unlikely(!h_sb->s_export_op)) {
10262+ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
0c3ec466 10263+ goto out_hparent;
1facf9fc 10264+ }
10265+
10266+ fh[Fh_br_id] = br->br_id;
10267+ fh[Fh_sigen] = au_sigen(sb);
10268+ encode_ino(fh + Fh_ino, inode->i_ino);
0c3ec466 10269+ encode_ino(fh + Fh_dir_ino, dir->i_ino);
1facf9fc 10270+ fh[Fh_igen] = inode->i_generation;
10271+
10272+ *max_len -= Fh_tail;
10273+ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
10274+ max_len,
10275+ /*connectable or subtreecheck*/0);
10276+ err = fh[Fh_h_type];
10277+ *max_len += Fh_tail;
10278+ /* todo: macros? */
1716fcea 10279+ if (err != FILEID_INVALID)
1facf9fc 10280+ err = 99;
10281+ else
10282+ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
10283+
0c3ec466 10284+out_hparent:
1facf9fc 10285+ dput(h_parent);
0c3ec466 10286+out_parent:
1facf9fc 10287+ dput(parent);
0c3ec466
AM
10288+out_unlock:
10289+ ii_read_unlock(inode);
10290+ si_read_unlock(sb);
4f0767ce 10291+out:
1facf9fc 10292+ if (unlikely(err < 0))
1716fcea 10293+ err = FILEID_INVALID;
1facf9fc 10294+ return err;
10295+}
10296+
10297+/* ---------------------------------------------------------------------- */
10298+
4a4d8108
AM
10299+static int aufs_commit_metadata(struct inode *inode)
10300+{
10301+ int err;
10302+ aufs_bindex_t bindex;
10303+ struct super_block *sb;
10304+ struct inode *h_inode;
10305+ int (*f)(struct inode *inode);
10306+
10307+ sb = inode->i_sb;
e49829fe 10308+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
10309+ ii_write_lock_child(inode);
10310+ bindex = au_ibstart(inode);
10311+ AuDebugOn(bindex < 0);
10312+ h_inode = au_h_iptr(inode, bindex);
10313+
10314+ f = h_inode->i_sb->s_export_op->commit_metadata;
10315+ if (f)
10316+ err = f(h_inode);
10317+ else {
10318+ struct writeback_control wbc = {
10319+ .sync_mode = WB_SYNC_ALL,
10320+ .nr_to_write = 0 /* metadata only */
10321+ };
10322+
10323+ err = sync_inode(h_inode, &wbc);
10324+ }
10325+
10326+ au_cpup_attr_timesizes(inode);
10327+ ii_write_unlock(inode);
10328+ si_read_unlock(sb);
10329+ return err;
10330+}
10331+
10332+/* ---------------------------------------------------------------------- */
10333+
1facf9fc 10334+static struct export_operations aufs_export_op = {
4a4d8108 10335+ .fh_to_dentry = aufs_fh_to_dentry,
1facf9fc 10336+ /* .fh_to_parent = aufs_fh_to_parent, */
4a4d8108
AM
10337+ .encode_fh = aufs_encode_fh,
10338+ .commit_metadata = aufs_commit_metadata
1facf9fc 10339+};
10340+
10341+void au_export_init(struct super_block *sb)
10342+{
10343+ struct au_sbinfo *sbinfo;
10344+ __u32 u;
10345+
10346+ sb->s_export_op = &aufs_export_op;
10347+ sbinfo = au_sbi(sb);
10348+ sbinfo->si_xigen = NULL;
10349+ get_random_bytes(&u, sizeof(u));
10350+ BUILD_BUG_ON(sizeof(u) != sizeof(int));
10351+ atomic_set(&sbinfo->si_xigen_next, u);
10352+}
7f207e10
AM
10353diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
10354--- /usr/share/empty/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
10355+++ linux/fs/aufs/file.c 2014-01-20 20:16:14.736130059 +0100
10356@@ -0,0 +1,724 @@
1facf9fc 10357+/*
523b37e3 10358+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 10359+ *
10360+ * This program, aufs is free software; you can redistribute it and/or modify
10361+ * it under the terms of the GNU General Public License as published by
10362+ * the Free Software Foundation; either version 2 of the License, or
10363+ * (at your option) any later version.
dece6358
AM
10364+ *
10365+ * This program is distributed in the hope that it will be useful,
10366+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10367+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10368+ * GNU General Public License for more details.
10369+ *
10370+ * You should have received a copy of the GNU General Public License
523b37e3 10371+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 10372+ */
10373+
10374+/*
4a4d8108 10375+ * handling file/dir, and address_space operation
1facf9fc 10376+ */
10377+
7eafdf33
AM
10378+#ifdef CONFIG_AUFS_DEBUG
10379+#include <linux/migrate.h>
10380+#endif
4a4d8108 10381+#include <linux/pagemap.h>
1facf9fc 10382+#include "aufs.h"
10383+
4a4d8108
AM
10384+/* drop flags for writing */
10385+unsigned int au_file_roflags(unsigned int flags)
10386+{
10387+ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
10388+ flags |= O_RDONLY | O_NOATIME;
10389+ return flags;
10390+}
10391+
10392+/* common functions to regular file and dir */
10393+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 10394+ struct file *file, int force_wr)
1facf9fc 10395+{
1308ab2a 10396+ struct file *h_file;
4a4d8108
AM
10397+ struct dentry *h_dentry;
10398+ struct inode *h_inode;
10399+ struct super_block *sb;
10400+ struct au_branch *br;
10401+ struct path h_path;
10402+ int err, exec_flag;
1facf9fc 10403+
4a4d8108
AM
10404+ /* a race condition can happen between open and unlink/rmdir */
10405+ h_file = ERR_PTR(-ENOENT);
10406+ h_dentry = au_h_dptr(dentry, bindex);
b752ccd1 10407+ if (au_test_nfsd() && !h_dentry)
4a4d8108
AM
10408+ goto out;
10409+ h_inode = h_dentry->d_inode;
b752ccd1 10410+ if (au_test_nfsd() && !h_inode)
4a4d8108 10411+ goto out;
027c5e7a
AM
10412+ spin_lock(&h_dentry->d_lock);
10413+ err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
10414+ || !h_inode
10415+ /* || !dentry->d_inode->i_nlink */
10416+ ;
10417+ spin_unlock(&h_dentry->d_lock);
10418+ if (unlikely(err))
4a4d8108 10419+ goto out;
1facf9fc 10420+
4a4d8108
AM
10421+ sb = dentry->d_sb;
10422+ br = au_sbr(sb, bindex);
10423+ h_file = ERR_PTR(-EACCES);
2cbb1c4b 10424+ exec_flag = flags & __FMODE_EXEC;
86dc4139 10425+ if (exec_flag && (au_br_mnt(br)->mnt_flags & MNT_NOEXEC))
027c5e7a 10426+ goto out;
1facf9fc 10427+
4a4d8108 10428+ /* drop flags for writing */
392086de
AM
10429+ if (au_test_ro(sb, bindex, dentry->d_inode)) {
10430+ if (force_wr && !(flags & O_WRONLY))
10431+ force_wr = 0;
4a4d8108 10432+ flags = au_file_roflags(flags);
392086de
AM
10433+ if (force_wr) {
10434+ h_file = ERR_PTR(-EROFS);
10435+ flags = au_file_roflags(flags);
10436+ if (unlikely(vfsub_native_ro(h_inode)
10437+ || IS_APPEND(h_inode)))
10438+ goto out;
10439+ flags &= ~O_ACCMODE;
10440+ flags |= O_WRONLY;
10441+ }
10442+ }
4a4d8108
AM
10443+ flags &= ~O_CREAT;
10444+ atomic_inc(&br->br_count);
10445+ h_path.dentry = h_dentry;
86dc4139 10446+ h_path.mnt = au_br_mnt(br);
4a4d8108
AM
10447+ if (!au_special_file(h_inode->i_mode))
10448+ h_file = vfsub_dentry_open(&h_path, flags);
10449+ else {
10450+ /* this block depends upon the configuration */
10451+ di_read_unlock(dentry, AuLock_IR);
10452+ fi_write_unlock(file);
10453+ si_read_unlock(sb);
10454+ h_file = vfsub_dentry_open(&h_path, flags);
10455+ si_noflush_read_lock(sb);
10456+ fi_write_lock(file);
10457+ di_read_lock_child(dentry, AuLock_IR);
dece6358 10458+ }
4a4d8108
AM
10459+ if (IS_ERR(h_file))
10460+ goto out_br;
dece6358 10461+
4a4d8108
AM
10462+ if (exec_flag) {
10463+ err = deny_write_access(h_file);
10464+ if (unlikely(err)) {
10465+ fput(h_file);
10466+ h_file = ERR_PTR(err);
10467+ goto out_br;
10468+ }
10469+ }
953406b4 10470+ fsnotify_open(h_file);
4a4d8108 10471+ goto out; /* success */
1facf9fc 10472+
4f0767ce 10473+out_br:
4a4d8108 10474+ atomic_dec(&br->br_count);
4f0767ce 10475+out:
4a4d8108
AM
10476+ return h_file;
10477+}
1308ab2a 10478+
4a4d8108
AM
10479+int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
10480+ struct au_fidir *fidir)
1facf9fc 10481+{
dece6358 10482+ int err;
1facf9fc 10483+ struct dentry *dentry;
1308ab2a 10484+
4a4d8108
AM
10485+ err = au_finfo_init(file, fidir);
10486+ if (unlikely(err))
10487+ goto out;
1facf9fc 10488+
10489+ dentry = file->f_dentry;
4a4d8108
AM
10490+ di_read_lock_child(dentry, AuLock_IR);
10491+ err = open(file, vfsub_file_flags(file));
10492+ di_read_unlock(dentry, AuLock_IR);
1facf9fc 10493+
4a4d8108
AM
10494+ fi_write_unlock(file);
10495+ if (unlikely(err)) {
10496+ au_fi(file)->fi_hdir = NULL;
10497+ au_finfo_fin(file);
1308ab2a 10498+ }
4a4d8108 10499+
4f0767ce 10500+out:
1308ab2a 10501+ return err;
10502+}
dece6358 10503+
4a4d8108 10504+int au_reopen_nondir(struct file *file)
1308ab2a 10505+{
4a4d8108
AM
10506+ int err;
10507+ aufs_bindex_t bstart;
10508+ struct dentry *dentry;
10509+ struct file *h_file, *h_file_tmp;
1308ab2a 10510+
4a4d8108
AM
10511+ dentry = file->f_dentry;
10512+ AuDebugOn(au_special_file(dentry->d_inode->i_mode));
10513+ bstart = au_dbstart(dentry);
10514+ h_file_tmp = NULL;
10515+ if (au_fbstart(file) == bstart) {
10516+ h_file = au_hf_top(file);
10517+ if (file->f_mode == h_file->f_mode)
10518+ return 0; /* success */
10519+ h_file_tmp = h_file;
10520+ get_file(h_file_tmp);
10521+ au_set_h_fptr(file, bstart, NULL);
10522+ }
10523+ AuDebugOn(au_fi(file)->fi_hdir);
86dc4139
AM
10524+ /*
10525+ * it can happen
10526+ * file exists on both of rw and ro
10527+ * open --> dbstart and fbstart are both 0
10528+ * prepend a branch as rw, "rw" become ro
10529+ * remove rw/file
10530+ * delete the top branch, "rw" becomes rw again
10531+ * --> dbstart is 1, fbstart is still 0
10532+ * write --> fbstart is 0 but dbstart is 1
10533+ */
10534+ /* AuDebugOn(au_fbstart(file) < bstart); */
1308ab2a 10535+
4a4d8108 10536+ h_file = au_h_open(dentry, bstart, vfsub_file_flags(file) & ~O_TRUNC,
392086de 10537+ file, /*force_wr*/0);
4a4d8108 10538+ err = PTR_ERR(h_file);
86dc4139
AM
10539+ if (IS_ERR(h_file)) {
10540+ if (h_file_tmp) {
10541+ atomic_inc(&au_sbr(dentry->d_sb, bstart)->br_count);
10542+ au_set_h_fptr(file, bstart, h_file_tmp);
10543+ h_file_tmp = NULL;
10544+ }
4a4d8108 10545+ goto out; /* todo: close all? */
86dc4139 10546+ }
4a4d8108
AM
10547+
10548+ err = 0;
10549+ au_set_fbstart(file, bstart);
10550+ au_set_h_fptr(file, bstart, h_file);
10551+ au_update_figen(file);
10552+ /* todo: necessary? */
10553+ /* file->f_ra = h_file->f_ra; */
10554+
4f0767ce 10555+out:
4a4d8108
AM
10556+ if (h_file_tmp)
10557+ fput(h_file_tmp);
10558+ return err;
1facf9fc 10559+}
10560+
1308ab2a 10561+/* ---------------------------------------------------------------------- */
10562+
4a4d8108
AM
10563+static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
10564+ struct dentry *hi_wh)
1facf9fc 10565+{
4a4d8108
AM
10566+ int err;
10567+ aufs_bindex_t bstart;
10568+ struct au_dinfo *dinfo;
10569+ struct dentry *h_dentry;
10570+ struct au_hdentry *hdp;
1facf9fc 10571+
4a4d8108
AM
10572+ dinfo = au_di(file->f_dentry);
10573+ AuRwMustWriteLock(&dinfo->di_rwsem);
dece6358 10574+
4a4d8108
AM
10575+ bstart = dinfo->di_bstart;
10576+ dinfo->di_bstart = btgt;
10577+ hdp = dinfo->di_hdentry;
10578+ h_dentry = hdp[0 + btgt].hd_dentry;
10579+ hdp[0 + btgt].hd_dentry = hi_wh;
10580+ err = au_reopen_nondir(file);
10581+ hdp[0 + btgt].hd_dentry = h_dentry;
10582+ dinfo->di_bstart = bstart;
1facf9fc 10583+
1facf9fc 10584+ return err;
10585+}
10586+
4a4d8108 10587+static int au_ready_to_write_wh(struct file *file, loff_t len,
86dc4139 10588+ aufs_bindex_t bcpup, struct au_pin *pin)
1facf9fc 10589+{
4a4d8108 10590+ int err;
027c5e7a 10591+ struct inode *inode, *h_inode;
c2b27bf2
AM
10592+ struct dentry *h_dentry, *hi_wh;
10593+ struct au_cp_generic cpg = {
10594+ .dentry = file->f_dentry,
10595+ .bdst = bcpup,
10596+ .bsrc = -1,
10597+ .len = len,
10598+ .pin = pin
10599+ };
1facf9fc 10600+
c2b27bf2
AM
10601+ au_update_dbstart(cpg.dentry);
10602+ inode = cpg.dentry->d_inode;
027c5e7a 10603+ h_inode = NULL;
c2b27bf2
AM
10604+ if (au_dbstart(cpg.dentry) <= bcpup
10605+ && au_dbend(cpg.dentry) >= bcpup) {
10606+ h_dentry = au_h_dptr(cpg.dentry, bcpup);
027c5e7a
AM
10607+ if (h_dentry)
10608+ h_inode = h_dentry->d_inode;
10609+ }
4a4d8108 10610+ hi_wh = au_hi_wh(inode, bcpup);
027c5e7a 10611+ if (!hi_wh && !h_inode)
c2b27bf2 10612+ err = au_sio_cpup_wh(&cpg, file);
4a4d8108
AM
10613+ else
10614+ /* already copied-up after unlink */
10615+ err = au_reopen_wh(file, bcpup, hi_wh);
1facf9fc 10616+
4a4d8108
AM
10617+ if (!err
10618+ && inode->i_nlink > 1
c2b27bf2
AM
10619+ && au_opt_test(au_mntflags(cpg.dentry->d_sb), PLINK))
10620+ au_plink_append(inode, bcpup, au_h_dptr(cpg.dentry, bcpup));
1308ab2a 10621+
dece6358 10622+ return err;
1facf9fc 10623+}
10624+
4a4d8108
AM
10625+/*
10626+ * prepare the @file for writing.
10627+ */
10628+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
1facf9fc 10629+{
4a4d8108 10630+ int err;
c2b27bf2
AM
10631+ aufs_bindex_t dbstart;
10632+ struct dentry *parent, *h_dentry;
86dc4139 10633+ struct inode *inode;
1facf9fc 10634+ struct super_block *sb;
4a4d8108 10635+ struct file *h_file;
c2b27bf2
AM
10636+ struct au_cp_generic cpg = {
10637+ .dentry = file->f_dentry,
10638+ .bdst = -1,
10639+ .bsrc = -1,
10640+ .len = len,
10641+ .pin = pin,
10642+ .flags = AuCpup_DTIME
10643+ };
1facf9fc 10644+
c2b27bf2
AM
10645+ sb = cpg.dentry->d_sb;
10646+ inode = cpg.dentry->d_inode;
4a4d8108 10647+ AuDebugOn(au_special_file(inode->i_mode));
c2b27bf2
AM
10648+ cpg.bsrc = au_fbstart(file);
10649+ err = au_test_ro(sb, cpg.bsrc, inode);
4a4d8108 10650+ if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
c2b27bf2
AM
10651+ err = au_pin(pin, cpg.dentry, cpg.bsrc, AuOpt_UDBA_NONE,
10652+ /*flags*/0);
1facf9fc 10653+ goto out;
4a4d8108 10654+ }
1facf9fc 10655+
027c5e7a 10656+ /* need to cpup or reopen */
c2b27bf2 10657+ parent = dget_parent(cpg.dentry);
4a4d8108 10658+ di_write_lock_parent(parent);
c2b27bf2
AM
10659+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
10660+ cpg.bdst = err;
4a4d8108
AM
10661+ if (unlikely(err < 0))
10662+ goto out_dgrade;
10663+ err = 0;
10664+
c2b27bf2
AM
10665+ if (!d_unhashed(cpg.dentry) && !au_h_dptr(parent, cpg.bdst)) {
10666+ err = au_cpup_dirs(cpg.dentry, cpg.bdst);
1facf9fc 10667+ if (unlikely(err))
4a4d8108
AM
10668+ goto out_dgrade;
10669+ }
10670+
c2b27bf2 10671+ err = au_pin(pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108
AM
10672+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
10673+ if (unlikely(err))
10674+ goto out_dgrade;
10675+
10676+ h_dentry = au_hf_top(file)->f_dentry;
c2b27bf2
AM
10677+ dbstart = au_dbstart(cpg.dentry);
10678+ if (dbstart <= cpg.bdst) {
10679+ h_dentry = au_h_dptr(cpg.dentry, cpg.bdst);
027c5e7a 10680+ AuDebugOn(!h_dentry);
c2b27bf2 10681+ cpg.bsrc = cpg.bdst;
027c5e7a
AM
10682+ }
10683+
c2b27bf2
AM
10684+ if (dbstart <= cpg.bdst /* just reopen */
10685+ || !d_unhashed(cpg.dentry) /* copyup and reopen */
027c5e7a 10686+ ) {
392086de 10687+ h_file = au_h_open_pre(cpg.dentry, cpg.bsrc, /*force_wr*/0);
86dc4139 10688+ if (IS_ERR(h_file))
027c5e7a 10689+ err = PTR_ERR(h_file);
86dc4139 10690+ else {
027c5e7a 10691+ di_downgrade_lock(parent, AuLock_IR);
c2b27bf2
AM
10692+ if (dbstart > cpg.bdst)
10693+ err = au_sio_cpup_simple(&cpg);
027c5e7a
AM
10694+ if (!err)
10695+ err = au_reopen_nondir(file);
c2b27bf2 10696+ au_h_open_post(cpg.dentry, cpg.bsrc, h_file);
027c5e7a 10697+ }
027c5e7a
AM
10698+ } else { /* copyup as wh and reopen */
10699+ /*
10700+ * since writable hfsplus branch is not supported,
10701+ * h_open_pre/post() are unnecessary.
10702+ */
c2b27bf2 10703+ err = au_ready_to_write_wh(file, len, cpg.bdst, pin);
4a4d8108 10704+ di_downgrade_lock(parent, AuLock_IR);
4a4d8108 10705+ }
4a4d8108
AM
10706+
10707+ if (!err) {
10708+ au_pin_set_parent_lflag(pin, /*lflag*/0);
10709+ goto out_dput; /* success */
10710+ }
10711+ au_unpin(pin);
10712+ goto out_unlock;
1facf9fc 10713+
4f0767ce 10714+out_dgrade:
4a4d8108 10715+ di_downgrade_lock(parent, AuLock_IR);
4f0767ce 10716+out_unlock:
4a4d8108 10717+ di_read_unlock(parent, AuLock_IR);
4f0767ce 10718+out_dput:
4a4d8108 10719+ dput(parent);
4f0767ce 10720+out:
1facf9fc 10721+ return err;
10722+}
10723+
4a4d8108
AM
10724+/* ---------------------------------------------------------------------- */
10725+
10726+int au_do_flush(struct file *file, fl_owner_t id,
10727+ int (*flush)(struct file *file, fl_owner_t id))
1facf9fc 10728+{
4a4d8108 10729+ int err;
1facf9fc 10730+ struct super_block *sb;
4a4d8108 10731+ struct inode *inode;
1facf9fc 10732+
c06a8ce3
AM
10733+ inode = file_inode(file);
10734+ sb = inode->i_sb;
4a4d8108
AM
10735+ si_noflush_read_lock(sb);
10736+ fi_read_lock(file);
b752ccd1 10737+ ii_read_lock_child(inode);
1facf9fc 10738+
4a4d8108
AM
10739+ err = flush(file, id);
10740+ au_cpup_attr_timesizes(inode);
1facf9fc 10741+
b752ccd1 10742+ ii_read_unlock(inode);
4a4d8108 10743+ fi_read_unlock(file);
1308ab2a 10744+ si_read_unlock(sb);
dece6358 10745+ return err;
1facf9fc 10746+}
10747+
4a4d8108
AM
10748+/* ---------------------------------------------------------------------- */
10749+
10750+static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
1facf9fc 10751+{
4a4d8108 10752+ int err;
4a4d8108
AM
10753+ struct au_pin pin;
10754+ struct au_finfo *finfo;
c2b27bf2 10755+ struct dentry *parent, *hi_wh;
4a4d8108 10756+ struct inode *inode;
1facf9fc 10757+ struct super_block *sb;
c2b27bf2
AM
10758+ struct au_cp_generic cpg = {
10759+ .dentry = file->f_dentry,
10760+ .bdst = -1,
10761+ .bsrc = -1,
10762+ .len = -1,
10763+ .pin = &pin,
10764+ .flags = AuCpup_DTIME
10765+ };
1facf9fc 10766+
4a4d8108
AM
10767+ FiMustWriteLock(file);
10768+
10769+ err = 0;
10770+ finfo = au_fi(file);
c2b27bf2
AM
10771+ sb = cpg.dentry->d_sb;
10772+ inode = cpg.dentry->d_inode;
10773+ cpg.bdst = au_ibstart(inode);
10774+ if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry))
1308ab2a 10775+ goto out;
dece6358 10776+
c2b27bf2
AM
10777+ parent = dget_parent(cpg.dentry);
10778+ if (au_test_ro(sb, cpg.bdst, inode)) {
4a4d8108 10779+ di_read_lock_parent(parent, !AuLock_IR);
c2b27bf2
AM
10780+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
10781+ cpg.bdst = err;
4a4d8108
AM
10782+ di_read_unlock(parent, !AuLock_IR);
10783+ if (unlikely(err < 0))
10784+ goto out_parent;
10785+ err = 0;
1facf9fc 10786+ }
1facf9fc 10787+
4a4d8108 10788+ di_read_lock_parent(parent, AuLock_IR);
c2b27bf2 10789+ hi_wh = au_hi_wh(inode, cpg.bdst);
7f207e10
AM
10790+ if (!S_ISDIR(inode->i_mode)
10791+ && au_opt_test(au_mntflags(sb), PLINK)
4a4d8108 10792+ && au_plink_test(inode)
c2b27bf2
AM
10793+ && !d_unhashed(cpg.dentry)
10794+ && cpg.bdst < au_dbstart(cpg.dentry)) {
10795+ err = au_test_and_cpup_dirs(cpg.dentry, cpg.bdst);
4a4d8108
AM
10796+ if (unlikely(err))
10797+ goto out_unlock;
10798+
10799+ /* always superio. */
c2b27bf2 10800+ err = au_pin(&pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108 10801+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 10802+ if (!err) {
c2b27bf2 10803+ err = au_sio_cpup_simple(&cpg);
367653fa
AM
10804+ au_unpin(&pin);
10805+ }
4a4d8108
AM
10806+ } else if (hi_wh) {
10807+ /* already copied-up after unlink */
c2b27bf2 10808+ err = au_reopen_wh(file, cpg.bdst, hi_wh);
4a4d8108
AM
10809+ *need_reopen = 0;
10810+ }
1facf9fc 10811+
4f0767ce 10812+out_unlock:
4a4d8108 10813+ di_read_unlock(parent, AuLock_IR);
4f0767ce 10814+out_parent:
4a4d8108 10815+ dput(parent);
4f0767ce 10816+out:
1308ab2a 10817+ return err;
dece6358 10818+}
1facf9fc 10819+
4a4d8108 10820+static void au_do_refresh_dir(struct file *file)
dece6358 10821+{
4a4d8108
AM
10822+ aufs_bindex_t bindex, bend, new_bindex, brid;
10823+ struct au_hfile *p, tmp, *q;
10824+ struct au_finfo *finfo;
1308ab2a 10825+ struct super_block *sb;
4a4d8108 10826+ struct au_fidir *fidir;
1facf9fc 10827+
4a4d8108 10828+ FiMustWriteLock(file);
1facf9fc 10829+
4a4d8108
AM
10830+ sb = file->f_dentry->d_sb;
10831+ finfo = au_fi(file);
10832+ fidir = finfo->fi_hdir;
10833+ AuDebugOn(!fidir);
10834+ p = fidir->fd_hfile + finfo->fi_btop;
10835+ brid = p->hf_br->br_id;
10836+ bend = fidir->fd_bbot;
10837+ for (bindex = finfo->fi_btop; bindex <= bend; bindex++, p++) {
10838+ if (!p->hf_file)
10839+ continue;
1308ab2a 10840+
4a4d8108
AM
10841+ new_bindex = au_br_index(sb, p->hf_br->br_id);
10842+ if (new_bindex == bindex)
10843+ continue;
10844+ if (new_bindex < 0) {
10845+ au_set_h_fptr(file, bindex, NULL);
10846+ continue;
10847+ }
1308ab2a 10848+
4a4d8108
AM
10849+ /* swap two lower inode, and loop again */
10850+ q = fidir->fd_hfile + new_bindex;
10851+ tmp = *q;
10852+ *q = *p;
10853+ *p = tmp;
10854+ if (tmp.hf_file) {
10855+ bindex--;
10856+ p--;
10857+ }
10858+ }
1308ab2a 10859+
4a4d8108 10860+ p = fidir->fd_hfile;
027c5e7a 10861+ if (!au_test_mmapped(file) && !d_unlinked(file->f_dentry)) {
4a4d8108
AM
10862+ bend = au_sbend(sb);
10863+ for (finfo->fi_btop = 0; finfo->fi_btop <= bend;
10864+ finfo->fi_btop++, p++)
10865+ if (p->hf_file) {
c06a8ce3 10866+ if (file_inode(p->hf_file))
4a4d8108
AM
10867+ break;
10868+ else
10869+ au_hfput(p, file);
10870+ }
10871+ } else {
10872+ bend = au_br_index(sb, brid);
10873+ for (finfo->fi_btop = 0; finfo->fi_btop < bend;
10874+ finfo->fi_btop++, p++)
10875+ if (p->hf_file)
10876+ au_hfput(p, file);
10877+ bend = au_sbend(sb);
10878+ }
1308ab2a 10879+
4a4d8108
AM
10880+ p = fidir->fd_hfile + bend;
10881+ for (fidir->fd_bbot = bend; fidir->fd_bbot >= finfo->fi_btop;
10882+ fidir->fd_bbot--, p--)
10883+ if (p->hf_file) {
c06a8ce3 10884+ if (file_inode(p->hf_file))
4a4d8108
AM
10885+ break;
10886+ else
10887+ au_hfput(p, file);
10888+ }
10889+ AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
1308ab2a 10890+}
10891+
4a4d8108
AM
10892+/*
10893+ * after branch manipulating, refresh the file.
10894+ */
10895+static int refresh_file(struct file *file, int (*reopen)(struct file *file))
1facf9fc 10896+{
4a4d8108
AM
10897+ int err, need_reopen;
10898+ aufs_bindex_t bend, bindex;
10899+ struct dentry *dentry;
1308ab2a 10900+ struct au_finfo *finfo;
4a4d8108 10901+ struct au_hfile *hfile;
1facf9fc 10902+
4a4d8108 10903+ dentry = file->f_dentry;
1308ab2a 10904+ finfo = au_fi(file);
4a4d8108
AM
10905+ if (!finfo->fi_hdir) {
10906+ hfile = &finfo->fi_htop;
10907+ AuDebugOn(!hfile->hf_file);
10908+ bindex = au_br_index(dentry->d_sb, hfile->hf_br->br_id);
10909+ AuDebugOn(bindex < 0);
10910+ if (bindex != finfo->fi_btop)
10911+ au_set_fbstart(file, bindex);
10912+ } else {
10913+ err = au_fidir_realloc(finfo, au_sbend(dentry->d_sb) + 1);
10914+ if (unlikely(err))
10915+ goto out;
10916+ au_do_refresh_dir(file);
10917+ }
1facf9fc 10918+
4a4d8108
AM
10919+ err = 0;
10920+ need_reopen = 1;
10921+ if (!au_test_mmapped(file))
10922+ err = au_file_refresh_by_inode(file, &need_reopen);
027c5e7a 10923+ if (!err && need_reopen && !d_unlinked(dentry))
4a4d8108
AM
10924+ err = reopen(file);
10925+ if (!err) {
10926+ au_update_figen(file);
10927+ goto out; /* success */
10928+ }
10929+
10930+ /* error, close all lower files */
10931+ if (finfo->fi_hdir) {
10932+ bend = au_fbend_dir(file);
10933+ for (bindex = au_fbstart(file); bindex <= bend; bindex++)
10934+ au_set_h_fptr(file, bindex, NULL);
10935+ }
1facf9fc 10936+
4f0767ce 10937+out:
1facf9fc 10938+ return err;
10939+}
10940+
4a4d8108
AM
10941+/* common function to regular file and dir */
10942+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
10943+ int wlock)
dece6358 10944+{
1308ab2a 10945+ int err;
4a4d8108
AM
10946+ unsigned int sigen, figen;
10947+ aufs_bindex_t bstart;
10948+ unsigned char pseudo_link;
10949+ struct dentry *dentry;
10950+ struct inode *inode;
1facf9fc 10951+
4a4d8108
AM
10952+ err = 0;
10953+ dentry = file->f_dentry;
10954+ inode = dentry->d_inode;
10955+ AuDebugOn(au_special_file(inode->i_mode));
10956+ sigen = au_sigen(dentry->d_sb);
10957+ fi_write_lock(file);
10958+ figen = au_figen(file);
10959+ di_write_lock_child(dentry);
10960+ bstart = au_dbstart(dentry);
10961+ pseudo_link = (bstart != au_ibstart(inode));
10962+ if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) {
10963+ if (!wlock) {
10964+ di_downgrade_lock(dentry, AuLock_IR);
10965+ fi_downgrade_lock(file);
10966+ }
10967+ goto out; /* success */
10968+ }
dece6358 10969+
4a4d8108 10970+ AuDbg("sigen %d, figen %d\n", sigen, figen);
027c5e7a 10971+ if (au_digen_test(dentry, sigen)) {
4a4d8108 10972+ err = au_reval_dpath(dentry, sigen);
027c5e7a 10973+ AuDebugOn(!err && au_digen_test(dentry, sigen));
4a4d8108 10974+ }
dece6358 10975+
027c5e7a
AM
10976+ if (!err)
10977+ err = refresh_file(file, reopen);
4a4d8108
AM
10978+ if (!err) {
10979+ if (!wlock) {
10980+ di_downgrade_lock(dentry, AuLock_IR);
10981+ fi_downgrade_lock(file);
10982+ }
10983+ } else {
10984+ di_write_unlock(dentry);
10985+ fi_write_unlock(file);
10986+ }
1facf9fc 10987+
4f0767ce 10988+out:
1308ab2a 10989+ return err;
10990+}
1facf9fc 10991+
4a4d8108
AM
10992+/* ---------------------------------------------------------------------- */
10993+
10994+/* cf. aufs_nopage() */
10995+/* for madvise(2) */
10996+static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
1308ab2a 10997+{
4a4d8108
AM
10998+ unlock_page(page);
10999+ return 0;
11000+}
1facf9fc 11001+
4a4d8108
AM
11002+/* it will never be called, but necessary to support O_DIRECT */
11003+static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb,
11004+ const struct iovec *iov, loff_t offset,
11005+ unsigned long nr_segs)
11006+{ BUG(); return 0; }
1facf9fc 11007+
4a4d8108
AM
11008+/*
11009+ * it will never be called, but madvise and fadvise behaves differently
11010+ * when get_xip_mem is defined
11011+ */
11012+static int aufs_get_xip_mem(struct address_space *mapping, pgoff_t pgoff,
11013+ int create, void **kmem, unsigned long *pfn)
11014+{ BUG(); return 0; }
1facf9fc 11015+
4a4d8108
AM
11016+/* they will never be called. */
11017+#ifdef CONFIG_AUFS_DEBUG
11018+static int aufs_write_begin(struct file *file, struct address_space *mapping,
11019+ loff_t pos, unsigned len, unsigned flags,
11020+ struct page **pagep, void **fsdata)
11021+{ AuUnsupport(); return 0; }
11022+static int aufs_write_end(struct file *file, struct address_space *mapping,
11023+ loff_t pos, unsigned len, unsigned copied,
11024+ struct page *page, void *fsdata)
11025+{ AuUnsupport(); return 0; }
11026+static int aufs_writepage(struct page *page, struct writeback_control *wbc)
11027+{ AuUnsupport(); return 0; }
1308ab2a 11028+
4a4d8108
AM
11029+static int aufs_set_page_dirty(struct page *page)
11030+{ AuUnsupport(); return 0; }
392086de
AM
11031+static void aufs_invalidatepage(struct page *page, unsigned int offset,
11032+ unsigned int length)
4a4d8108
AM
11033+{ AuUnsupport(); }
11034+static int aufs_releasepage(struct page *page, gfp_t gfp)
11035+{ AuUnsupport(); return 0; }
11036+static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
7eafdf33 11037+ struct page *page, enum migrate_mode mode)
4a4d8108
AM
11038+{ AuUnsupport(); return 0; }
11039+static int aufs_launder_page(struct page *page)
11040+{ AuUnsupport(); return 0; }
11041+static int aufs_is_partially_uptodate(struct page *page,
11042+ read_descriptor_t *desc,
11043+ unsigned long from)
11044+{ AuUnsupport(); return 0; }
392086de
AM
11045+static void aufs_is_dirty_writeback(struct page *page, bool *dirty,
11046+ bool *writeback)
11047+{ AuUnsupport(); }
4a4d8108
AM
11048+static int aufs_error_remove_page(struct address_space *mapping,
11049+ struct page *page)
11050+{ AuUnsupport(); return 0; }
b4510431
AM
11051+static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file,
11052+ sector_t *span)
11053+{ AuUnsupport(); return 0; }
11054+static void aufs_swap_deactivate(struct file *file)
11055+{ AuUnsupport(); }
4a4d8108
AM
11056+#endif /* CONFIG_AUFS_DEBUG */
11057+
11058+const struct address_space_operations aufs_aop = {
11059+ .readpage = aufs_readpage,
11060+ .direct_IO = aufs_direct_IO,
11061+ .get_xip_mem = aufs_get_xip_mem,
11062+#ifdef CONFIG_AUFS_DEBUG
11063+ .writepage = aufs_writepage,
4a4d8108
AM
11064+ /* no writepages, because of writepage */
11065+ .set_page_dirty = aufs_set_page_dirty,
11066+ /* no readpages, because of readpage */
11067+ .write_begin = aufs_write_begin,
11068+ .write_end = aufs_write_end,
11069+ /* no bmap, no block device */
11070+ .invalidatepage = aufs_invalidatepage,
11071+ .releasepage = aufs_releasepage,
11072+ .migratepage = aufs_migratepage,
11073+ .launder_page = aufs_launder_page,
11074+ .is_partially_uptodate = aufs_is_partially_uptodate,
392086de 11075+ .is_dirty_writeback = aufs_is_dirty_writeback,
b4510431
AM
11076+ .error_remove_page = aufs_error_remove_page,
11077+ .swap_activate = aufs_swap_activate,
11078+ .swap_deactivate = aufs_swap_deactivate
4a4d8108 11079+#endif /* CONFIG_AUFS_DEBUG */
dece6358 11080+};
7f207e10
AM
11081diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
11082--- /usr/share/empty/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100
523b37e3 11083+++ linux/fs/aufs/file.h 2014-01-20 20:16:14.736130059 +0100
392086de 11084@@ -0,0 +1,312 @@
4a4d8108 11085+/*
523b37e3 11086+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
11087+ *
11088+ * This program, aufs is free software; you can redistribute it and/or modify
11089+ * it under the terms of the GNU General Public License as published by
11090+ * the Free Software Foundation; either version 2 of the License, or
11091+ * (at your option) any later version.
11092+ *
11093+ * This program is distributed in the hope that it will be useful,
11094+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11095+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11096+ * GNU General Public License for more details.
11097+ *
11098+ * You should have received a copy of the GNU General Public License
523b37e3 11099+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 11100+ */
1facf9fc 11101+
4a4d8108
AM
11102+/*
11103+ * file operations
11104+ */
1facf9fc 11105+
4a4d8108
AM
11106+#ifndef __AUFS_FILE_H__
11107+#define __AUFS_FILE_H__
1facf9fc 11108+
4a4d8108 11109+#ifdef __KERNEL__
1facf9fc 11110+
2cbb1c4b 11111+#include <linux/file.h>
4a4d8108
AM
11112+#include <linux/fs.h>
11113+#include <linux/poll.h>
4a4d8108 11114+#include "rwsem.h"
1facf9fc 11115+
4a4d8108
AM
11116+struct au_branch;
11117+struct au_hfile {
11118+ struct file *hf_file;
11119+ struct au_branch *hf_br;
11120+};
1facf9fc 11121+
4a4d8108
AM
11122+struct au_vdir;
11123+struct au_fidir {
11124+ aufs_bindex_t fd_bbot;
11125+ aufs_bindex_t fd_nent;
11126+ struct au_vdir *fd_vdir_cache;
11127+ struct au_hfile fd_hfile[];
11128+};
1facf9fc 11129+
4a4d8108 11130+static inline int au_fidir_sz(int nent)
dece6358 11131+{
4f0767ce
JR
11132+ AuDebugOn(nent < 0);
11133+ return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
4a4d8108 11134+}
1facf9fc 11135+
4a4d8108
AM
11136+struct au_finfo {
11137+ atomic_t fi_generation;
dece6358 11138+
4a4d8108
AM
11139+ struct au_rwsem fi_rwsem;
11140+ aufs_bindex_t fi_btop;
11141+
11142+ /* do not union them */
11143+ struct { /* for non-dir */
11144+ struct au_hfile fi_htop;
2cbb1c4b 11145+ atomic_t fi_mmapped;
4a4d8108
AM
11146+ };
11147+ struct au_fidir *fi_hdir; /* for dir only */
523b37e3
AM
11148+
11149+ struct hlist_node fi_hlist;
11150+ struct file *fi_file; /* very ugly */
4a4d8108 11151+} ____cacheline_aligned_in_smp;
1facf9fc 11152+
4a4d8108 11153+/* ---------------------------------------------------------------------- */
1facf9fc 11154+
4a4d8108
AM
11155+/* file.c */
11156+extern const struct address_space_operations aufs_aop;
11157+unsigned int au_file_roflags(unsigned int flags);
11158+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 11159+ struct file *file, int force_wr);
4a4d8108
AM
11160+int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
11161+ struct au_fidir *fidir);
11162+int au_reopen_nondir(struct file *file);
11163+struct au_pin;
11164+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
11165+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
11166+ int wlock);
11167+int au_do_flush(struct file *file, fl_owner_t id,
11168+ int (*flush)(struct file *file, fl_owner_t id));
1facf9fc 11169+
4a4d8108
AM
11170+/* poll.c */
11171+#ifdef CONFIG_AUFS_POLL
11172+unsigned int aufs_poll(struct file *file, poll_table *wait);
11173+#endif
1facf9fc 11174+
4a4d8108
AM
11175+#ifdef CONFIG_AUFS_BR_HFSPLUS
11176+/* hfsplus.c */
392086de
AM
11177+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
11178+ int force_wr);
4a4d8108
AM
11179+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
11180+ struct file *h_file);
11181+#else
11182+static inline
392086de
AM
11183+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
11184+ int force_wr)
dece6358 11185+{
4a4d8108
AM
11186+ return NULL;
11187+}
1facf9fc 11188+
4a4d8108
AM
11189+AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
11190+ struct file *h_file);
11191+#endif
1facf9fc 11192+
4a4d8108
AM
11193+/* f_op.c */
11194+extern const struct file_operations aufs_file_fop;
4a4d8108
AM
11195+int au_do_open_nondir(struct file *file, int flags);
11196+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
11197+
11198+#ifdef CONFIG_AUFS_SP_IATTR
11199+/* f_op_sp.c */
86dc4139 11200+struct au_finfo *au_fi_sp(struct file *file);
4a4d8108
AM
11201+int au_special_file(umode_t mode);
11202+void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev);
11203+#else
86dc4139
AM
11204+static inline struct au_finfo *au_fi_sp(struct file *file)
11205+{
11206+ return NULL;
11207+}
4a4d8108
AM
11208+AuStubInt0(au_special_file, umode_t mode)
11209+static inline void au_init_special_fop(struct inode *inode, umode_t mode,
11210+ dev_t rdev)
11211+{
11212+ init_special_inode(inode, mode, rdev);
11213+}
11214+#endif
1facf9fc 11215+
4a4d8108
AM
11216+/* finfo.c */
11217+void au_hfput(struct au_hfile *hf, struct file *file);
11218+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
11219+ struct file *h_file);
1facf9fc 11220+
4a4d8108 11221+void au_update_figen(struct file *file);
4a4d8108
AM
11222+struct au_fidir *au_fidir_alloc(struct super_block *sb);
11223+int au_fidir_realloc(struct au_finfo *finfo, int nbr);
1facf9fc 11224+
4a4d8108
AM
11225+void au_fi_init_once(void *_fi);
11226+void au_finfo_fin(struct file *file);
11227+int au_finfo_init(struct file *file, struct au_fidir *fidir);
1facf9fc 11228+
4a4d8108
AM
11229+/* ioctl.c */
11230+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
11231+#ifdef CONFIG_COMPAT
11232+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
11233+ unsigned long arg);
c2b27bf2
AM
11234+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
11235+ unsigned long arg);
b752ccd1 11236+#endif
1facf9fc 11237+
4a4d8108 11238+/* ---------------------------------------------------------------------- */
1facf9fc 11239+
4a4d8108
AM
11240+static inline struct au_finfo *au_fi(struct file *file)
11241+{
86dc4139
AM
11242+ struct au_finfo *finfo;
11243+
11244+ finfo = au_fi_sp(file);
11245+ if (!finfo)
11246+ finfo = file->private_data;
11247+ return finfo;
4a4d8108 11248+}
1facf9fc 11249+
4a4d8108 11250+/* ---------------------------------------------------------------------- */
1facf9fc 11251+
4a4d8108
AM
11252+/*
11253+ * fi_read_lock, fi_write_lock,
11254+ * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
11255+ */
11256+AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
1308ab2a 11257+
4a4d8108
AM
11258+#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
11259+#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
11260+#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
1facf9fc 11261+
1308ab2a 11262+/* ---------------------------------------------------------------------- */
11263+
4a4d8108
AM
11264+/* todo: hard/soft set? */
11265+static inline aufs_bindex_t au_fbstart(struct file *file)
dece6358 11266+{
4a4d8108
AM
11267+ FiMustAnyLock(file);
11268+ return au_fi(file)->fi_btop;
11269+}
dece6358 11270+
4a4d8108
AM
11271+static inline aufs_bindex_t au_fbend_dir(struct file *file)
11272+{
11273+ FiMustAnyLock(file);
11274+ AuDebugOn(!au_fi(file)->fi_hdir);
11275+ return au_fi(file)->fi_hdir->fd_bbot;
11276+}
1facf9fc 11277+
4a4d8108
AM
11278+static inline struct au_vdir *au_fvdir_cache(struct file *file)
11279+{
11280+ FiMustAnyLock(file);
11281+ AuDebugOn(!au_fi(file)->fi_hdir);
11282+ return au_fi(file)->fi_hdir->fd_vdir_cache;
11283+}
1facf9fc 11284+
4a4d8108
AM
11285+static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex)
11286+{
11287+ FiMustWriteLock(file);
11288+ au_fi(file)->fi_btop = bindex;
11289+}
1facf9fc 11290+
4a4d8108
AM
11291+static inline void au_set_fbend_dir(struct file *file, aufs_bindex_t bindex)
11292+{
11293+ FiMustWriteLock(file);
11294+ AuDebugOn(!au_fi(file)->fi_hdir);
11295+ au_fi(file)->fi_hdir->fd_bbot = bindex;
11296+}
1308ab2a 11297+
4a4d8108
AM
11298+static inline void au_set_fvdir_cache(struct file *file,
11299+ struct au_vdir *vdir_cache)
11300+{
11301+ FiMustWriteLock(file);
11302+ AuDebugOn(!au_fi(file)->fi_hdir);
11303+ au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
11304+}
dece6358 11305+
4a4d8108
AM
11306+static inline struct file *au_hf_top(struct file *file)
11307+{
11308+ FiMustAnyLock(file);
11309+ AuDebugOn(au_fi(file)->fi_hdir);
11310+ return au_fi(file)->fi_htop.hf_file;
11311+}
1facf9fc 11312+
4a4d8108
AM
11313+static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
11314+{
11315+ FiMustAnyLock(file);
11316+ AuDebugOn(!au_fi(file)->fi_hdir);
11317+ return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
dece6358
AM
11318+}
11319+
4a4d8108
AM
11320+/* todo: memory barrier? */
11321+static inline unsigned int au_figen(struct file *f)
dece6358 11322+{
4a4d8108
AM
11323+ return atomic_read(&au_fi(f)->fi_generation);
11324+}
dece6358 11325+
2cbb1c4b
JR
11326+static inline void au_set_mmapped(struct file *f)
11327+{
11328+ if (atomic_inc_return(&au_fi(f)->fi_mmapped))
11329+ return;
0c3ec466 11330+ pr_warn("fi_mmapped wrapped around\n");
2cbb1c4b
JR
11331+ while (!atomic_inc_return(&au_fi(f)->fi_mmapped))
11332+ ;
11333+}
11334+
11335+static inline void au_unset_mmapped(struct file *f)
11336+{
11337+ atomic_dec(&au_fi(f)->fi_mmapped);
11338+}
11339+
4a4d8108
AM
11340+static inline int au_test_mmapped(struct file *f)
11341+{
2cbb1c4b
JR
11342+ return atomic_read(&au_fi(f)->fi_mmapped);
11343+}
11344+
11345+/* customize vma->vm_file */
11346+
11347+static inline void au_do_vm_file_reset(struct vm_area_struct *vma,
11348+ struct file *file)
11349+{
53392da6
AM
11350+ struct file *f;
11351+
11352+ f = vma->vm_file;
2cbb1c4b
JR
11353+ get_file(file);
11354+ vma->vm_file = file;
53392da6 11355+ fput(f);
2cbb1c4b
JR
11356+}
11357+
11358+#ifdef CONFIG_MMU
11359+#define AuDbgVmRegion(file, vma) do {} while (0)
11360+
11361+static inline void au_vm_file_reset(struct vm_area_struct *vma,
11362+ struct file *file)
11363+{
11364+ au_do_vm_file_reset(vma, file);
11365+}
11366+#else
11367+#define AuDbgVmRegion(file, vma) \
11368+ AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
11369+
11370+static inline void au_vm_file_reset(struct vm_area_struct *vma,
11371+ struct file *file)
11372+{
53392da6
AM
11373+ struct file *f;
11374+
2cbb1c4b 11375+ au_do_vm_file_reset(vma, file);
53392da6 11376+ f = vma->vm_region->vm_file;
2cbb1c4b
JR
11377+ get_file(file);
11378+ vma->vm_region->vm_file = file;
53392da6 11379+ fput(f);
2cbb1c4b
JR
11380+}
11381+#endif /* CONFIG_MMU */
11382+
11383+/* handle vma->vm_prfile */
17c3ba88 11384+/*static inline void au_vm_prfile_set(struct vm_area_struct *vma,
2cbb1c4b
JR
11385+ struct file *file)
11386+{
2cbb1c4b
JR
11387+ get_file(file);
11388+ vma->vm_prfile = file;
11389+#ifndef CONFIG_MMU
11390+ get_file(file);
11391+ vma->vm_region->vm_prfile = file;
11392+#endif
17c3ba88 11393+}*/
1308ab2a 11394+
4a4d8108
AM
11395+#endif /* __KERNEL__ */
11396+#endif /* __AUFS_FILE_H__ */
7f207e10
AM
11397diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
11398--- /usr/share/empty/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
11399+++ linux/fs/aufs/finfo.c 2014-01-20 20:16:14.736130059 +0100
11400@@ -0,0 +1,156 @@
4a4d8108 11401+/*
523b37e3 11402+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
11403+ *
11404+ * This program, aufs is free software; you can redistribute it and/or modify
11405+ * it under the terms of the GNU General Public License as published by
11406+ * the Free Software Foundation; either version 2 of the License, or
11407+ * (at your option) any later version.
11408+ *
11409+ * This program is distributed in the hope that it will be useful,
11410+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11411+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11412+ * GNU General Public License for more details.
11413+ *
11414+ * You should have received a copy of the GNU General Public License
523b37e3 11415+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 11416+ */
1308ab2a 11417+
4a4d8108
AM
11418+/*
11419+ * file private data
11420+ */
1facf9fc 11421+
4a4d8108 11422+#include "aufs.h"
1facf9fc 11423+
4a4d8108
AM
11424+void au_hfput(struct au_hfile *hf, struct file *file)
11425+{
11426+ /* todo: direct access f_flags */
2cbb1c4b 11427+ if (vfsub_file_flags(file) & __FMODE_EXEC)
4a4d8108
AM
11428+ allow_write_access(hf->hf_file);
11429+ fput(hf->hf_file);
11430+ hf->hf_file = NULL;
e49829fe 11431+ atomic_dec(&hf->hf_br->br_count);
4a4d8108
AM
11432+ hf->hf_br = NULL;
11433+}
1facf9fc 11434+
4a4d8108
AM
11435+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
11436+{
11437+ struct au_finfo *finfo = au_fi(file);
11438+ struct au_hfile *hf;
11439+ struct au_fidir *fidir;
11440+
11441+ fidir = finfo->fi_hdir;
11442+ if (!fidir) {
11443+ AuDebugOn(finfo->fi_btop != bindex);
11444+ hf = &finfo->fi_htop;
11445+ } else
11446+ hf = fidir->fd_hfile + bindex;
11447+
11448+ if (hf && hf->hf_file)
11449+ au_hfput(hf, file);
11450+ if (val) {
11451+ FiMustWriteLock(file);
11452+ hf->hf_file = val;
11453+ hf->hf_br = au_sbr(file->f_dentry->d_sb, bindex);
1308ab2a 11454+ }
4a4d8108 11455+}
1facf9fc 11456+
4a4d8108
AM
11457+void au_update_figen(struct file *file)
11458+{
11459+ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_dentry));
11460+ /* smp_mb(); */ /* atomic_set */
1facf9fc 11461+}
11462+
4a4d8108
AM
11463+/* ---------------------------------------------------------------------- */
11464+
4a4d8108
AM
11465+struct au_fidir *au_fidir_alloc(struct super_block *sb)
11466+{
11467+ struct au_fidir *fidir;
11468+ int nbr;
11469+
11470+ nbr = au_sbend(sb) + 1;
11471+ if (nbr < 2)
11472+ nbr = 2; /* initial allocate for 2 branches */
11473+ fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS);
11474+ if (fidir) {
11475+ fidir->fd_bbot = -1;
11476+ fidir->fd_nent = nbr;
11477+ fidir->fd_vdir_cache = NULL;
11478+ }
11479+
11480+ return fidir;
11481+}
11482+
11483+int au_fidir_realloc(struct au_finfo *finfo, int nbr)
11484+{
11485+ int err;
11486+ struct au_fidir *fidir, *p;
11487+
11488+ AuRwMustWriteLock(&finfo->fi_rwsem);
11489+ fidir = finfo->fi_hdir;
11490+ AuDebugOn(!fidir);
11491+
11492+ err = -ENOMEM;
11493+ p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr),
11494+ GFP_NOFS);
11495+ if (p) {
11496+ p->fd_nent = nbr;
11497+ finfo->fi_hdir = p;
11498+ err = 0;
11499+ }
1facf9fc 11500+
dece6358 11501+ return err;
1facf9fc 11502+}
1308ab2a 11503+
11504+/* ---------------------------------------------------------------------- */
11505+
4a4d8108 11506+void au_finfo_fin(struct file *file)
1308ab2a 11507+{
4a4d8108
AM
11508+ struct au_finfo *finfo;
11509+
7f207e10
AM
11510+ au_nfiles_dec(file->f_dentry->d_sb);
11511+
4a4d8108
AM
11512+ finfo = au_fi(file);
11513+ AuDebugOn(finfo->fi_hdir);
11514+ AuRwDestroy(&finfo->fi_rwsem);
11515+ au_cache_free_finfo(finfo);
1308ab2a 11516+}
1308ab2a 11517+
e49829fe 11518+void au_fi_init_once(void *_finfo)
4a4d8108 11519+{
e49829fe 11520+ struct au_finfo *finfo = _finfo;
2cbb1c4b 11521+ static struct lock_class_key aufs_fi;
1308ab2a 11522+
e49829fe
JR
11523+ au_rw_init(&finfo->fi_rwsem);
11524+ au_rw_class(&finfo->fi_rwsem, &aufs_fi);
4a4d8108 11525+}
1308ab2a 11526+
4a4d8108
AM
11527+int au_finfo_init(struct file *file, struct au_fidir *fidir)
11528+{
1716fcea 11529+ int err;
4a4d8108
AM
11530+ struct au_finfo *finfo;
11531+ struct dentry *dentry;
11532+
11533+ err = -ENOMEM;
11534+ dentry = file->f_dentry;
11535+ finfo = au_cache_alloc_finfo();
11536+ if (unlikely(!finfo))
11537+ goto out;
11538+
11539+ err = 0;
7f207e10 11540+ au_nfiles_inc(dentry->d_sb);
1716fcea
AM
11541+ /* verbose coding for lock class name */
11542+ if (!fidir)
11543+ au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcNonDir_FIINFO);
11544+ else
11545+ au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcDir_FIINFO);
4a4d8108
AM
11546+ au_rw_write_lock(&finfo->fi_rwsem);
11547+ finfo->fi_btop = -1;
11548+ finfo->fi_hdir = fidir;
11549+ atomic_set(&finfo->fi_generation, au_digen(dentry));
11550+ /* smp_mb(); */ /* atomic_set */
11551+
11552+ file->private_data = finfo;
11553+
11554+out:
11555+ return err;
11556+}
7f207e10
AM
11557diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
11558--- /usr/share/empty/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
11559+++ linux/fs/aufs/f_op.c 2014-01-20 20:16:14.736130059 +0100
11560@@ -0,0 +1,718 @@
dece6358 11561+/*
523b37e3 11562+ * Copyright (C) 2005-2014 Junjiro R. Okajima
dece6358
AM
11563+ *
11564+ * This program, aufs is free software; you can redistribute it and/or modify
11565+ * it under the terms of the GNU General Public License as published by
11566+ * the Free Software Foundation; either version 2 of the License, or
11567+ * (at your option) any later version.
11568+ *
11569+ * This program is distributed in the hope that it will be useful,
11570+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11571+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11572+ * GNU General Public License for more details.
11573+ *
11574+ * You should have received a copy of the GNU General Public License
523b37e3 11575+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 11576+ */
1facf9fc 11577+
11578+/*
4a4d8108 11579+ * file and vm operations
1facf9fc 11580+ */
dece6358 11581+
86dc4139 11582+#include <linux/aio.h>
4a4d8108
AM
11583+#include <linux/fs_stack.h>
11584+#include <linux/mman.h>
4a4d8108 11585+#include <linux/security.h>
dece6358
AM
11586+#include "aufs.h"
11587+
4a4d8108 11588+int au_do_open_nondir(struct file *file, int flags)
1facf9fc 11589+{
4a4d8108
AM
11590+ int err;
11591+ aufs_bindex_t bindex;
11592+ struct file *h_file;
11593+ struct dentry *dentry;
11594+ struct au_finfo *finfo;
11595+
11596+ FiMustWriteLock(file);
11597+
523b37e3 11598+ err = 0;
4a4d8108
AM
11599+ dentry = file->f_dentry;
11600+ finfo = au_fi(file);
11601+ memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
2cbb1c4b 11602+ atomic_set(&finfo->fi_mmapped, 0);
4a4d8108 11603+ bindex = au_dbstart(dentry);
392086de 11604+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
4a4d8108
AM
11605+ if (IS_ERR(h_file))
11606+ err = PTR_ERR(h_file);
11607+ else {
11608+ au_set_fbstart(file, bindex);
11609+ au_set_h_fptr(file, bindex, h_file);
11610+ au_update_figen(file);
523b37e3
AM
11611+ finfo->fi_file = file;
11612+ au_sphl_add(&finfo->fi_hlist, &au_sbi(dentry->d_sb)->si_files);
4a4d8108
AM
11613+ /* todo: necessary? */
11614+ /* file->f_ra = h_file->f_ra; */
11615+ }
027c5e7a 11616+
4a4d8108 11617+ return err;
1facf9fc 11618+}
11619+
4a4d8108
AM
11620+static int aufs_open_nondir(struct inode *inode __maybe_unused,
11621+ struct file *file)
1facf9fc 11622+{
4a4d8108 11623+ int err;
1308ab2a 11624+ struct super_block *sb;
1facf9fc 11625+
523b37e3
AM
11626+ AuDbg("%pD, f_flags 0x%x, f_mode 0x%x\n",
11627+ file, vfsub_file_flags(file), file->f_mode);
1facf9fc 11628+
4a4d8108
AM
11629+ sb = file->f_dentry->d_sb;
11630+ si_read_lock(sb, AuLock_FLUSH);
11631+ err = au_do_open(file, au_do_open_nondir, /*fidir*/NULL);
11632+ si_read_unlock(sb);
11633+ return err;
11634+}
1facf9fc 11635+
4a4d8108
AM
11636+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
11637+{
11638+ struct au_finfo *finfo;
11639+ aufs_bindex_t bindex;
1facf9fc 11640+
4a4d8108 11641+ finfo = au_fi(file);
523b37e3 11642+ au_sphl_del(&finfo->fi_hlist, &au_sbi(file->f_dentry->d_sb)->si_files);
4a4d8108 11643+ bindex = finfo->fi_btop;
b4510431 11644+ if (bindex >= 0)
4a4d8108 11645+ au_set_h_fptr(file, bindex, NULL);
7f207e10 11646+
4a4d8108
AM
11647+ au_finfo_fin(file);
11648+ return 0;
1facf9fc 11649+}
11650+
4a4d8108
AM
11651+/* ---------------------------------------------------------------------- */
11652+
11653+static int au_do_flush_nondir(struct file *file, fl_owner_t id)
dece6358 11654+{
1308ab2a 11655+ int err;
4a4d8108
AM
11656+ struct file *h_file;
11657+
11658+ err = 0;
11659+ h_file = au_hf_top(file);
11660+ if (h_file)
11661+ err = vfsub_flush(h_file, id);
11662+ return err;
11663+}
11664+
11665+static int aufs_flush_nondir(struct file *file, fl_owner_t id)
11666+{
11667+ return au_do_flush(file, id, au_do_flush_nondir);
11668+}
11669+
11670+/* ---------------------------------------------------------------------- */
9dbd164d
AM
11671+/*
11672+ * read and write functions acquire [fdi]_rwsem once, but release before
11673+ * mmap_sem. This is because to stop a race condition between mmap(2).
11674+ * Releasing these aufs-rwsem should be safe, no branch-mamagement (by keeping
11675+ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in
11676+ * read functions after [fdi]_rwsem are released, but it should be harmless.
11677+ */
4a4d8108
AM
11678+
11679+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
11680+ loff_t *ppos)
11681+{
11682+ ssize_t err;
dece6358 11683+ struct dentry *dentry;
4a4d8108 11684+ struct file *h_file;
dece6358 11685+ struct super_block *sb;
1facf9fc 11686+
dece6358
AM
11687+ dentry = file->f_dentry;
11688+ sb = dentry->d_sb;
e49829fe 11689+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108 11690+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
dece6358
AM
11691+ if (unlikely(err))
11692+ goto out;
1facf9fc 11693+
4a4d8108 11694+ h_file = au_hf_top(file);
9dbd164d
AM
11695+ get_file(h_file);
11696+ di_read_unlock(dentry, AuLock_IR);
11697+ fi_read_unlock(file);
11698+
11699+ /* filedata may be obsoleted by concurrent copyup, but no problem */
4a4d8108
AM
11700+ err = vfsub_read_u(h_file, buf, count, ppos);
11701+ /* todo: necessary? */
11702+ /* file->f_ra = h_file->f_ra; */
9dbd164d 11703+ /* update without lock, I don't think it a problem */
c06a8ce3 11704+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 11705+ fput(h_file);
1308ab2a 11706+
4f0767ce 11707+out:
dece6358
AM
11708+ si_read_unlock(sb);
11709+ return err;
11710+}
1facf9fc 11711+
e49829fe
JR
11712+/*
11713+ * todo: very ugly
11714+ * it locks both of i_mutex and si_rwsem for read in safe.
11715+ * if the plink maintenance mode continues forever (that is the problem),
11716+ * may loop forever.
11717+ */
11718+static void au_mtx_and_read_lock(struct inode *inode)
11719+{
11720+ int err;
11721+ struct super_block *sb = inode->i_sb;
11722+
11723+ while (1) {
11724+ mutex_lock(&inode->i_mutex);
11725+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
11726+ if (!err)
11727+ break;
11728+ mutex_unlock(&inode->i_mutex);
11729+ si_read_lock(sb, AuLock_NOPLMW);
11730+ si_read_unlock(sb);
11731+ }
11732+}
11733+
4a4d8108
AM
11734+static ssize_t aufs_write(struct file *file, const char __user *ubuf,
11735+ size_t count, loff_t *ppos)
dece6358 11736+{
4a4d8108
AM
11737+ ssize_t err;
11738+ struct au_pin pin;
dece6358 11739+ struct dentry *dentry;
9dbd164d 11740+ struct super_block *sb;
4a4d8108 11741+ struct inode *inode;
4a4d8108
AM
11742+ struct file *h_file;
11743+ char __user *buf = (char __user *)ubuf;
1facf9fc 11744+
dece6358 11745+ dentry = file->f_dentry;
9dbd164d 11746+ sb = dentry->d_sb;
4a4d8108 11747+ inode = dentry->d_inode;
e49829fe 11748+ au_mtx_and_read_lock(inode);
1facf9fc 11749+
4a4d8108
AM
11750+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11751+ if (unlikely(err))
11752+ goto out;
1facf9fc 11753+
4a4d8108
AM
11754+ err = au_ready_to_write(file, -1, &pin);
11755+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
11756+ if (unlikely(err)) {
11757+ di_read_unlock(dentry, AuLock_IR);
11758+ fi_write_unlock(file);
11759+ goto out;
11760+ }
1facf9fc 11761+
4a4d8108 11762+ h_file = au_hf_top(file);
9dbd164d 11763+ get_file(h_file);
4a4d8108 11764+ au_unpin(&pin);
9dbd164d
AM
11765+ di_read_unlock(dentry, AuLock_IR);
11766+ fi_write_unlock(file);
11767+
4a4d8108 11768+ err = vfsub_write_u(h_file, buf, count, ppos);
9dbd164d 11769+ ii_write_lock_child(inode);
4a4d8108 11770+ au_cpup_attr_timesizes(inode);
c06a8ce3 11771+ inode->i_mode = file_inode(h_file)->i_mode;
9dbd164d
AM
11772+ ii_write_unlock(inode);
11773+ fput(h_file);
1facf9fc 11774+
4f0767ce 11775+out:
9dbd164d 11776+ si_read_unlock(sb);
4a4d8108 11777+ mutex_unlock(&inode->i_mutex);
dece6358
AM
11778+ return err;
11779+}
1facf9fc 11780+
4a4d8108
AM
11781+static ssize_t au_do_aio(struct file *h_file, int rw, struct kiocb *kio,
11782+ const struct iovec *iov, unsigned long nv, loff_t pos)
dece6358 11783+{
4a4d8108
AM
11784+ ssize_t err;
11785+ struct file *file;
11786+ ssize_t (*func)(struct kiocb *, const struct iovec *, unsigned long,
11787+ loff_t);
1facf9fc 11788+
4a4d8108
AM
11789+ err = security_file_permission(h_file, rw);
11790+ if (unlikely(err))
11791+ goto out;
1facf9fc 11792+
4a4d8108
AM
11793+ err = -ENOSYS;
11794+ func = NULL;
11795+ if (rw == MAY_READ)
11796+ func = h_file->f_op->aio_read;
11797+ else if (rw == MAY_WRITE)
11798+ func = h_file->f_op->aio_write;
11799+ if (func) {
11800+ file = kio->ki_filp;
11801+ kio->ki_filp = h_file;
2cbb1c4b 11802+ lockdep_off();
4a4d8108 11803+ err = func(kio, iov, nv, pos);
2cbb1c4b 11804+ lockdep_on();
4a4d8108
AM
11805+ kio->ki_filp = file;
11806+ } else
11807+ /* currently there is no such fs */
11808+ WARN_ON_ONCE(1);
1facf9fc 11809+
4f0767ce 11810+out:
dece6358
AM
11811+ return err;
11812+}
1facf9fc 11813+
4a4d8108
AM
11814+static ssize_t aufs_aio_read(struct kiocb *kio, const struct iovec *iov,
11815+ unsigned long nv, loff_t pos)
1facf9fc 11816+{
4a4d8108
AM
11817+ ssize_t err;
11818+ struct file *file, *h_file;
11819+ struct dentry *dentry;
dece6358 11820+ struct super_block *sb;
1facf9fc 11821+
4a4d8108 11822+ file = kio->ki_filp;
dece6358 11823+ dentry = file->f_dentry;
1308ab2a 11824+ sb = dentry->d_sb;
e49829fe 11825+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
11826+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
11827+ if (unlikely(err))
11828+ goto out;
11829+
11830+ h_file = au_hf_top(file);
9dbd164d
AM
11831+ get_file(h_file);
11832+ di_read_unlock(dentry, AuLock_IR);
11833+ fi_read_unlock(file);
11834+
4a4d8108
AM
11835+ err = au_do_aio(h_file, MAY_READ, kio, iov, nv, pos);
11836+ /* todo: necessary? */
11837+ /* file->f_ra = h_file->f_ra; */
9dbd164d 11838+ /* update without lock, I don't think it a problem */
c06a8ce3 11839+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 11840+ fput(h_file);
1facf9fc 11841+
4f0767ce 11842+out:
4a4d8108 11843+ si_read_unlock(sb);
1308ab2a 11844+ return err;
11845+}
1facf9fc 11846+
4a4d8108
AM
11847+static ssize_t aufs_aio_write(struct kiocb *kio, const struct iovec *iov,
11848+ unsigned long nv, loff_t pos)
1308ab2a 11849+{
4a4d8108
AM
11850+ ssize_t err;
11851+ struct au_pin pin;
11852+ struct dentry *dentry;
11853+ struct inode *inode;
4a4d8108 11854+ struct file *file, *h_file;
9dbd164d 11855+ struct super_block *sb;
1308ab2a 11856+
4a4d8108 11857+ file = kio->ki_filp;
1308ab2a 11858+ dentry = file->f_dentry;
9dbd164d 11859+ sb = dentry->d_sb;
1308ab2a 11860+ inode = dentry->d_inode;
e49829fe
JR
11861+ au_mtx_and_read_lock(inode);
11862+
4a4d8108
AM
11863+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11864+ if (unlikely(err))
1308ab2a 11865+ goto out;
1facf9fc 11866+
4a4d8108
AM
11867+ err = au_ready_to_write(file, -1, &pin);
11868+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
11869+ if (unlikely(err)) {
11870+ di_read_unlock(dentry, AuLock_IR);
11871+ fi_write_unlock(file);
11872+ goto out;
11873+ }
1facf9fc 11874+
4a4d8108 11875+ h_file = au_hf_top(file);
9dbd164d
AM
11876+ get_file(h_file);
11877+ au_unpin(&pin);
11878+ di_read_unlock(dentry, AuLock_IR);
11879+ fi_write_unlock(file);
11880+
4a4d8108 11881+ err = au_do_aio(h_file, MAY_WRITE, kio, iov, nv, pos);
9dbd164d 11882+ ii_write_lock_child(inode);
4a4d8108 11883+ au_cpup_attr_timesizes(inode);
c06a8ce3 11884+ inode->i_mode = file_inode(h_file)->i_mode;
9dbd164d
AM
11885+ ii_write_unlock(inode);
11886+ fput(h_file);
1facf9fc 11887+
4f0767ce 11888+out:
9dbd164d 11889+ si_read_unlock(sb);
4a4d8108 11890+ mutex_unlock(&inode->i_mutex);
dece6358 11891+ return err;
1facf9fc 11892+}
11893+
4a4d8108
AM
11894+static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
11895+ struct pipe_inode_info *pipe, size_t len,
11896+ unsigned int flags)
1facf9fc 11897+{
4a4d8108
AM
11898+ ssize_t err;
11899+ struct file *h_file;
11900+ struct dentry *dentry;
dece6358 11901+ struct super_block *sb;
1facf9fc 11902+
dece6358 11903+ dentry = file->f_dentry;
dece6358 11904+ sb = dentry->d_sb;
e49829fe 11905+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
11906+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
11907+ if (unlikely(err))
dece6358 11908+ goto out;
1facf9fc 11909+
4a4d8108
AM
11910+ err = -EINVAL;
11911+ h_file = au_hf_top(file);
9dbd164d 11912+ get_file(h_file);
4a4d8108 11913+ if (au_test_loopback_kthread()) {
87a755f4
AM
11914+ au_warn_loopback(h_file->f_dentry->d_sb);
11915+ if (file->f_mapping != h_file->f_mapping) {
11916+ file->f_mapping = h_file->f_mapping;
11917+ smp_mb(); /* unnecessary? */
11918+ }
1308ab2a 11919+ }
9dbd164d
AM
11920+ di_read_unlock(dentry, AuLock_IR);
11921+ fi_read_unlock(file);
11922+
4a4d8108
AM
11923+ err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
11924+ /* todo: necessasry? */
11925+ /* file->f_ra = h_file->f_ra; */
9dbd164d 11926+ /* update without lock, I don't think it a problem */
c06a8ce3 11927+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 11928+ fput(h_file);
1facf9fc 11929+
4f0767ce 11930+out:
4a4d8108 11931+ si_read_unlock(sb);
dece6358 11932+ return err;
1facf9fc 11933+}
11934+
4a4d8108
AM
11935+static ssize_t
11936+aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
11937+ size_t len, unsigned int flags)
1facf9fc 11938+{
4a4d8108
AM
11939+ ssize_t err;
11940+ struct au_pin pin;
11941+ struct dentry *dentry;
11942+ struct inode *inode;
4a4d8108 11943+ struct file *h_file;
9dbd164d 11944+ struct super_block *sb;
1facf9fc 11945+
4a4d8108 11946+ dentry = file->f_dentry;
9dbd164d 11947+ sb = dentry->d_sb;
4a4d8108 11948+ inode = dentry->d_inode;
e49829fe 11949+ au_mtx_and_read_lock(inode);
9dbd164d 11950+
4a4d8108
AM
11951+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11952+ if (unlikely(err))
11953+ goto out;
1facf9fc 11954+
4a4d8108
AM
11955+ err = au_ready_to_write(file, -1, &pin);
11956+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
11957+ if (unlikely(err)) {
11958+ di_read_unlock(dentry, AuLock_IR);
11959+ fi_write_unlock(file);
11960+ goto out;
11961+ }
1facf9fc 11962+
4a4d8108 11963+ h_file = au_hf_top(file);
9dbd164d 11964+ get_file(h_file);
4a4d8108 11965+ au_unpin(&pin);
9dbd164d
AM
11966+ di_read_unlock(dentry, AuLock_IR);
11967+ fi_write_unlock(file);
11968+
4a4d8108 11969+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
9dbd164d 11970+ ii_write_lock_child(inode);
4a4d8108 11971+ au_cpup_attr_timesizes(inode);
c06a8ce3 11972+ inode->i_mode = file_inode(h_file)->i_mode;
9dbd164d
AM
11973+ ii_write_unlock(inode);
11974+ fput(h_file);
1facf9fc 11975+
4f0767ce 11976+out:
9dbd164d 11977+ si_read_unlock(sb);
4a4d8108
AM
11978+ mutex_unlock(&inode->i_mutex);
11979+ return err;
11980+}
1facf9fc 11981+
4a4d8108
AM
11982+/* ---------------------------------------------------------------------- */
11983+
9dbd164d
AM
11984+/*
11985+ * The locking order around current->mmap_sem.
11986+ * - in most and regular cases
11987+ * file I/O syscall -- aufs_read() or something
11988+ * -- si_rwsem for read -- mmap_sem
11989+ * (Note that [fdi]i_rwsem are released before mmap_sem).
11990+ * - in mmap case
11991+ * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem
11992+ * This AB-BA order is definitly bad, but is not a problem since "si_rwsem for
11993+ * read" allows muliple processes to acquire it and [fdi]i_rwsem are not held in
11994+ * file I/O. Aufs needs to stop lockdep in aufs_mmap() though.
11995+ * It means that when aufs acquires si_rwsem for write, the process should never
11996+ * acquire mmap_sem.
11997+ *
392086de 11998+ * Actually aufs_iterate() holds [fdi]i_rwsem before mmap_sem, but this is not a
9dbd164d
AM
11999+ * problem either since any directory is not able to be mmap-ed.
12000+ * The similar scenario is applied to aufs_readlink() too.
12001+ */
12002+
2dfbb274
AM
12003+/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
12004+#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b)
12005+
12006+static unsigned long au_arch_prot_conv(unsigned long flags)
12007+{
12008+ /* currently ppc64 only */
12009+#ifdef CONFIG_PPC64
12010+ /* cf. linux/arch/powerpc/include/asm/mman.h */
12011+ AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO);
12012+ return AuConv_VM_PROT(flags, SAO);
12013+#else
12014+ AuDebugOn(arch_calc_vm_prot_bits(-1));
12015+ return 0;
12016+#endif
12017+}
12018+
12019+static unsigned long au_prot_conv(unsigned long flags)
12020+{
12021+ return AuConv_VM_PROT(flags, READ)
12022+ | AuConv_VM_PROT(flags, WRITE)
12023+ | AuConv_VM_PROT(flags, EXEC)
12024+ | au_arch_prot_conv(flags);
12025+}
12026+
12027+/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */
12028+#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b)
12029+
12030+static unsigned long au_flag_conv(unsigned long flags)
12031+{
12032+ return AuConv_VM_MAP(flags, GROWSDOWN)
12033+ | AuConv_VM_MAP(flags, DENYWRITE)
2dfbb274
AM
12034+ | AuConv_VM_MAP(flags, LOCKED);
12035+}
12036+
9dbd164d 12037+static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
dece6358 12038+{
4a4d8108
AM
12039+ int err;
12040+ aufs_bindex_t bstart;
12041+ const unsigned char wlock
9dbd164d 12042+ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
4a4d8108
AM
12043+ struct dentry *dentry;
12044+ struct super_block *sb;
9dbd164d
AM
12045+ struct file *h_file;
12046+ struct au_branch *br;
12047+ struct au_pin pin;
12048+
12049+ AuDbgVmRegion(file, vma);
1308ab2a 12050+
4a4d8108
AM
12051+ dentry = file->f_dentry;
12052+ sb = dentry->d_sb;
9dbd164d 12053+ lockdep_off();
e49829fe 12054+ si_read_lock(sb, AuLock_NOPLMW);
4a4d8108
AM
12055+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
12056+ if (unlikely(err))
12057+ goto out;
12058+
4a4d8108 12059+ if (wlock) {
4a4d8108
AM
12060+ err = au_ready_to_write(file, -1, &pin);
12061+ di_write_unlock(dentry);
9dbd164d
AM
12062+ if (unlikely(err)) {
12063+ fi_write_unlock(file);
12064+ goto out;
12065+ }
4a4d8108
AM
12066+ au_unpin(&pin);
12067+ } else
12068+ di_write_unlock(dentry);
9dbd164d 12069+
4a4d8108 12070+ bstart = au_fbstart(file);
9dbd164d
AM
12071+ br = au_sbr(sb, bstart);
12072+ h_file = au_hf_top(file);
12073+ get_file(h_file);
2cbb1c4b 12074+ au_set_mmapped(file);
4a4d8108 12075+ fi_write_unlock(file);
9dbd164d 12076+ lockdep_on();
1308ab2a 12077+
9dbd164d 12078+ au_vm_file_reset(vma, h_file);
2dfbb274
AM
12079+ err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
12080+ au_flag_conv(vma->vm_flags));
9dbd164d
AM
12081+ if (!err)
12082+ err = h_file->f_op->mmap(h_file, vma);
2cbb1c4b
JR
12083+ if (unlikely(err))
12084+ goto out_reset;
4a4d8108 12085+
17c3ba88 12086+ // au_vm_prfile_set(vma, file);
4a4d8108 12087+ /* update without lock, I don't think it a problem */
c06a8ce3 12088+ fsstack_copy_attr_atime(file_inode(file), file_inode(h_file));
2cbb1c4b 12089+ goto out_fput; /* success */
4a4d8108 12090+
2cbb1c4b
JR
12091+out_reset:
12092+ au_unset_mmapped(file);
12093+ au_vm_file_reset(vma, file);
12094+out_fput:
9dbd164d
AM
12095+ fput(h_file);
12096+ lockdep_off();
4f0767ce 12097+out:
9dbd164d
AM
12098+ si_read_unlock(sb);
12099+ lockdep_on();
12100+ AuTraceErr(err);
4a4d8108
AM
12101+ return err;
12102+}
12103+
12104+/* ---------------------------------------------------------------------- */
12105+
1e00d052
AM
12106+static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end,
12107+ int datasync)
4a4d8108
AM
12108+{
12109+ int err;
12110+ struct au_pin pin;
b752ccd1 12111+ struct dentry *dentry;
4a4d8108
AM
12112+ struct inode *inode;
12113+ struct file *h_file;
12114+ struct super_block *sb;
12115+
b752ccd1 12116+ dentry = file->f_dentry;
4a4d8108 12117+ inode = dentry->d_inode;
4a4d8108 12118+ sb = dentry->d_sb;
1e00d052 12119+ mutex_lock(&inode->i_mutex);
e49829fe
JR
12120+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
12121+ if (unlikely(err))
12122+ goto out;
4a4d8108
AM
12123+
12124+ err = 0; /* -EBADF; */ /* posix? */
12125+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
e49829fe 12126+ goto out_si;
4a4d8108
AM
12127+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
12128+ if (unlikely(err))
e49829fe 12129+ goto out_si;
4a4d8108
AM
12130+
12131+ err = au_ready_to_write(file, -1, &pin);
12132+ di_downgrade_lock(dentry, AuLock_IR);
12133+ if (unlikely(err))
12134+ goto out_unlock;
12135+ au_unpin(&pin);
12136+
12137+ err = -EINVAL;
12138+ h_file = au_hf_top(file);
53392da6
AM
12139+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
12140+ au_cpup_attr_timesizes(inode);
4a4d8108 12141+
4f0767ce 12142+out_unlock:
4a4d8108 12143+ di_read_unlock(dentry, AuLock_IR);
1308ab2a 12144+ fi_write_unlock(file);
e49829fe 12145+out_si:
953406b4 12146+ si_read_unlock(sb);
e49829fe 12147+out:
1e00d052 12148+ mutex_unlock(&inode->i_mutex);
4a4d8108 12149+ return err;
dece6358
AM
12150+}
12151+
4a4d8108
AM
12152+/* no one supports this operation, currently */
12153+#if 0
12154+static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync)
dece6358 12155+{
4a4d8108
AM
12156+ int err;
12157+ struct au_pin pin;
1308ab2a 12158+ struct dentry *dentry;
4a4d8108
AM
12159+ struct inode *inode;
12160+ struct file *file, *h_file;
1308ab2a 12161+
4a4d8108 12162+ file = kio->ki_filp;
1308ab2a 12163+ dentry = file->f_dentry;
4a4d8108 12164+ inode = dentry->d_inode;
e49829fe 12165+ au_mtx_and_read_lock(inode);
4a4d8108
AM
12166+
12167+ err = 0; /* -EBADF; */ /* posix? */
12168+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
12169+ goto out;
12170+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
12171+ if (unlikely(err))
1308ab2a 12172+ goto out;
12173+
4a4d8108
AM
12174+ err = au_ready_to_write(file, -1, &pin);
12175+ di_downgrade_lock(dentry, AuLock_IR);
12176+ if (unlikely(err))
12177+ goto out_unlock;
12178+ au_unpin(&pin);
1308ab2a 12179+
4a4d8108
AM
12180+ err = -ENOSYS;
12181+ h_file = au_hf_top(file);
523b37e3 12182+ if (h_file->f_op->aio_fsync) {
4a4d8108 12183+ struct mutex *h_mtx;
1308ab2a 12184+
c06a8ce3 12185+ h_mtx = &file_inode(h_file)->i_mutex;
4a4d8108
AM
12186+ if (!is_sync_kiocb(kio)) {
12187+ get_file(h_file);
12188+ fput(file);
12189+ }
12190+ kio->ki_filp = h_file;
12191+ err = h_file->f_op->aio_fsync(kio, datasync);
12192+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
12193+ if (!err)
12194+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
12195+ /*ignore*/
12196+ au_cpup_attr_timesizes(inode);
12197+ mutex_unlock(h_mtx);
12198+ }
1308ab2a 12199+
4f0767ce 12200+out_unlock:
4a4d8108
AM
12201+ di_read_unlock(dentry, AuLock_IR);
12202+ fi_write_unlock(file);
4f0767ce 12203+out:
e49829fe 12204+ si_read_unlock(inode->sb);
4a4d8108
AM
12205+ mutex_unlock(&inode->i_mutex);
12206+ return err;
dece6358 12207+}
4a4d8108 12208+#endif
dece6358 12209+
4a4d8108 12210+static int aufs_fasync(int fd, struct file *file, int flag)
dece6358 12211+{
4a4d8108
AM
12212+ int err;
12213+ struct file *h_file;
12214+ struct dentry *dentry;
12215+ struct super_block *sb;
1308ab2a 12216+
4a4d8108
AM
12217+ dentry = file->f_dentry;
12218+ sb = dentry->d_sb;
e49829fe 12219+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
12220+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
12221+ if (unlikely(err))
12222+ goto out;
12223+
12224+ h_file = au_hf_top(file);
523b37e3 12225+ if (h_file->f_op->fasync)
4a4d8108
AM
12226+ err = h_file->f_op->fasync(fd, h_file, flag);
12227+
12228+ di_read_unlock(dentry, AuLock_IR);
12229+ fi_read_unlock(file);
1308ab2a 12230+
4f0767ce 12231+out:
4a4d8108 12232+ si_read_unlock(sb);
1308ab2a 12233+ return err;
dece6358 12234+}
4a4d8108
AM
12235+
12236+/* ---------------------------------------------------------------------- */
12237+
12238+/* no one supports this operation, currently */
12239+#if 0
12240+static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
12241+ size_t len, loff_t *pos , int more)
12242+{
12243+}
12244+#endif
12245+
12246+/* ---------------------------------------------------------------------- */
12247+
12248+const struct file_operations aufs_file_fop = {
12249+ .owner = THIS_MODULE,
2cbb1c4b 12250+
027c5e7a 12251+ .llseek = default_llseek,
4a4d8108
AM
12252+
12253+ .read = aufs_read,
12254+ .write = aufs_write,
12255+ .aio_read = aufs_aio_read,
12256+ .aio_write = aufs_aio_write,
12257+#ifdef CONFIG_AUFS_POLL
12258+ .poll = aufs_poll,
12259+#endif
12260+ .unlocked_ioctl = aufs_ioctl_nondir,
b752ccd1 12261+#ifdef CONFIG_COMPAT
c2b27bf2 12262+ .compat_ioctl = aufs_compat_ioctl_nondir,
b752ccd1 12263+#endif
4a4d8108
AM
12264+ .mmap = aufs_mmap,
12265+ .open = aufs_open_nondir,
12266+ .flush = aufs_flush_nondir,
12267+ .release = aufs_release_nondir,
12268+ .fsync = aufs_fsync_nondir,
12269+ /* .aio_fsync = aufs_aio_fsync_nondir, */
12270+ .fasync = aufs_fasync,
12271+ /* .sendpage = aufs_sendpage, */
12272+ .splice_write = aufs_splice_write,
12273+ .splice_read = aufs_splice_read,
12274+#if 0
12275+ .aio_splice_write = aufs_aio_splice_write,
12276+ .aio_splice_read = aufs_aio_splice_read
12277+#endif
12278+};
7f207e10
AM
12279diff -urN /usr/share/empty/fs/aufs/f_op_sp.c linux/fs/aufs/f_op_sp.c
12280--- /usr/share/empty/fs/aufs/f_op_sp.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
12281+++ linux/fs/aufs/f_op_sp.c 2014-01-20 20:16:14.736130059 +0100
12282@@ -0,0 +1,382 @@
1308ab2a 12283+/*
523b37e3 12284+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1308ab2a 12285+ *
12286+ * This program, aufs is free software; you can redistribute it and/or modify
12287+ * it under the terms of the GNU General Public License as published by
12288+ * the Free Software Foundation; either version 2 of the License, or
12289+ * (at your option) any later version.
12290+ *
12291+ * This program is distributed in the hope that it will be useful,
12292+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12293+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12294+ * GNU General Public License for more details.
12295+ *
12296+ * You should have received a copy of the GNU General Public License
523b37e3 12297+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1308ab2a 12298+ */
dece6358 12299+
1308ab2a 12300+/*
4a4d8108
AM
12301+ * file operations for special files.
12302+ * while they exist in aufs virtually,
12303+ * their file I/O is handled out of aufs.
1308ab2a 12304+ */
12305+
86dc4139 12306+#include <linux/aio.h>
4a4d8108 12307+#include "aufs.h"
1308ab2a 12308+
86dc4139
AM
12309+/*
12310+ * I don't think the size of this list grows much.
12311+ * so here is a very simple list implemented in order to find finfo matching a
12312+ * given file.
12313+ */
12314+static struct au_sphlhead au_finfo_sp = {
12315+ .spin = __SPIN_LOCK_INITIALIZER(au_finfo_sp.spin),
12316+ .head = HLIST_HEAD_INIT
12317+};
12318+
12319+struct au_finfo_sp {
12320+ struct hlist_node hlist;
c2b27bf2 12321+ struct file *file;
86dc4139
AM
12322+ struct au_finfo *finfo;
12323+};
12324+
12325+struct au_finfo *au_fi_sp(struct file *file)
12326+{
12327+ struct au_finfo *finfo;
12328+ struct au_finfo_sp *sp;
12329+
12330+ finfo = NULL;
12331+ spin_lock(&au_finfo_sp.spin);
12332+ hlist_for_each_entry(sp, &au_finfo_sp.head, hlist) {
12333+ if (sp->file != file)
12334+ continue;
12335+ finfo = sp->finfo;
12336+ break;
12337+ }
12338+ spin_unlock(&au_finfo_sp.spin);
12339+
12340+ return finfo;
12341+}
12342+
12343+static int au_fi_sp_add(struct file *file)
12344+{
12345+ int err;
12346+ struct au_finfo_sp *sp;
12347+
12348+ err = -ENOMEM;
12349+ sp = kmalloc(sizeof(*sp), GFP_NOFS);
12350+ if (sp) {
12351+ err = 0;
12352+ sp->file = file;
12353+ sp->finfo = file->private_data;
12354+ spin_lock(&au_finfo_sp.spin);
12355+ hlist_add_head(&sp->hlist, &au_finfo_sp.head);
12356+ spin_unlock(&au_finfo_sp.spin);
12357+ }
12358+ return err;
12359+}
12360+
12361+static void au_fi_sp_del(struct file *file)
12362+{
12363+ struct au_finfo_sp *sp, *do_free;
12364+
12365+ do_free = NULL;
12366+ spin_lock(&au_finfo_sp.spin);
12367+ hlist_for_each_entry(sp, &au_finfo_sp.head, hlist) {
12368+ if (sp->file != file)
12369+ continue;
12370+ hlist_del(&sp->hlist);
12371+ do_free = sp;
12372+ break;
12373+ }
12374+ spin_unlock(&au_finfo_sp.spin);
12375+ kfree(do_free);
12376+}
12377+
12378+/* ---------------------------------------------------------------------- */
12379+
4a4d8108
AM
12380+static ssize_t aufs_aio_read_sp(struct kiocb *kio, const struct iovec *iov,
12381+ unsigned long nv, loff_t pos)
dece6358 12382+{
4a4d8108
AM
12383+ ssize_t err;
12384+ aufs_bindex_t bstart;
12385+ unsigned char wbr;
12386+ struct file *file, *h_file;
12387+ struct super_block *sb;
1308ab2a 12388+
4a4d8108
AM
12389+ file = kio->ki_filp;
12390+ sb = file->f_dentry->d_sb;
12391+ si_read_lock(sb, AuLock_FLUSH);
12392+ fi_read_lock(file);
12393+ bstart = au_fbstart(file);
12394+ h_file = au_hf_top(file);
12395+ fi_read_unlock(file);
12396+ wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
12397+ si_read_unlock(sb);
12398+
12399+ /* do not change the file in kio */
12400+ AuDebugOn(!h_file->f_op || !h_file->f_op->aio_read);
12401+ err = h_file->f_op->aio_read(kio, iov, nv, pos);
12402+ if (err > 0 && wbr)
12403+ file_accessed(h_file);
12404+
12405+ return err;
12406+}
12407+
12408+static ssize_t aufs_aio_write_sp(struct kiocb *kio, const struct iovec *iov,
12409+ unsigned long nv, loff_t pos)
12410+{
12411+ ssize_t err;
12412+ aufs_bindex_t bstart;
12413+ unsigned char wbr;
12414+ struct super_block *sb;
12415+ struct file *file, *h_file;
12416+
12417+ file = kio->ki_filp;
12418+ sb = file->f_dentry->d_sb;
12419+ si_read_lock(sb, AuLock_FLUSH);
12420+ fi_read_lock(file);
12421+ bstart = au_fbstart(file);
12422+ h_file = au_hf_top(file);
12423+ fi_read_unlock(file);
12424+ wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
12425+ si_read_unlock(sb);
12426+
12427+ /* do not change the file in kio */
12428+ AuDebugOn(!h_file->f_op || !h_file->f_op->aio_write);
12429+ err = h_file->f_op->aio_write(kio, iov, nv, pos);
4a4d8108
AM
12430+ return err;
12431+}
12432+
12433+/* ---------------------------------------------------------------------- */
12434+
12435+static int aufs_release_sp(struct inode *inode, struct file *file)
12436+{
12437+ int err;
12438+ struct file *h_file;
12439+
12440+ fi_read_lock(file);
12441+ h_file = au_hf_top(file);
12442+ fi_read_unlock(file);
12443+ /* close this fifo in aufs */
12444+ err = h_file->f_op->release(inode, file); /* ignore */
12445+ aufs_release_nondir(inode, file); /* ignore */
86dc4139 12446+ au_fi_sp_del(file);
4a4d8108
AM
12447+ return err;
12448+}
12449+
12450+/* ---------------------------------------------------------------------- */
12451+
12452+/* currently, support only FIFO */
4f0767ce
JR
12453+enum {
12454+ AuSp_FIFO, AuSp_FIFO_R, AuSp_FIFO_W, AuSp_FIFO_RW,
12455+ /* AuSp_SOCK, AuSp_CHR, AuSp_BLK, */
12456+ AuSp_Last
12457+};
4a4d8108
AM
12458+static int aufs_open_sp(struct inode *inode, struct file *file);
12459+static struct au_sp_fop {
12460+ int done;
12461+ struct file_operations fop; /* not 'const' */
12462+ spinlock_t spin;
12463+} au_sp_fop[AuSp_Last] = {
12464+ [AuSp_FIFO] = {
12465+ .fop = {
12466+ .owner = THIS_MODULE,
12467+ .open = aufs_open_sp
12468+ }
12469+ }
12470+};
12471+
12472+static void au_init_fop_sp(struct file *file)
12473+{
12474+ struct au_sp_fop *p;
12475+ int i;
12476+ struct file *h_file;
12477+
12478+ p = au_sp_fop;
12479+ if (unlikely(!p->done)) {
12480+ /* initialize first time only */
12481+ static DEFINE_SPINLOCK(spin);
12482+
12483+ spin_lock(&spin);
12484+ if (!p->done) {
12485+ BUILD_BUG_ON(sizeof(au_sp_fop)/sizeof(*au_sp_fop)
12486+ != AuSp_Last);
12487+ for (i = 0; i < AuSp_Last; i++)
12488+ spin_lock_init(&p[i].spin);
12489+ p->done = 1;
12490+ }
12491+ spin_unlock(&spin);
12492+ }
12493+
12494+ switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) {
12495+ case FMODE_READ:
12496+ i = AuSp_FIFO_R;
12497+ break;
12498+ case FMODE_WRITE:
12499+ i = AuSp_FIFO_W;
12500+ break;
12501+ case FMODE_READ | FMODE_WRITE:
12502+ i = AuSp_FIFO_RW;
12503+ break;
12504+ default:
12505+ BUG();
12506+ }
12507+
12508+ p += i;
12509+ if (unlikely(!p->done)) {
12510+ /* initialize first time only */
12511+ h_file = au_hf_top(file);
12512+ spin_lock(&p->spin);
12513+ if (!p->done) {
12514+ p->fop = *h_file->f_op;
12515+ p->fop.owner = THIS_MODULE;
12516+ if (p->fop.aio_read)
12517+ p->fop.aio_read = aufs_aio_read_sp;
12518+ if (p->fop.aio_write)
12519+ p->fop.aio_write = aufs_aio_write_sp;
12520+ p->fop.release = aufs_release_sp;
12521+ p->done = 1;
12522+ }
12523+ spin_unlock(&p->spin);
12524+ }
12525+ file->f_op = &p->fop;
12526+}
12527+
12528+static int au_cpup_sp(struct dentry *dentry)
12529+{
12530+ int err;
4a4d8108
AM
12531+ struct au_pin pin;
12532+ struct au_wr_dir_args wr_dir_args = {
12533+ .force_btgt = -1,
12534+ .flags = 0
12535+ };
c2b27bf2
AM
12536+ struct au_cp_generic cpg = {
12537+ .dentry = dentry,
12538+ .bdst = -1,
12539+ .bsrc = -1,
12540+ .len = -1,
12541+ .pin = &pin,
12542+ .flags = AuCpup_DTIME
12543+ };
4a4d8108 12544+
523b37e3 12545+ AuDbg("%pd\n", dentry);
4a4d8108
AM
12546+
12547+ di_read_unlock(dentry, AuLock_IR);
12548+ di_write_lock_child(dentry);
12549+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
12550+ if (unlikely(err < 0))
12551+ goto out;
c2b27bf2 12552+ cpg.bdst = err;
4a4d8108 12553+ err = 0;
c2b27bf2 12554+ if (cpg.bdst == au_dbstart(dentry))
4a4d8108
AM
12555+ goto out; /* success */
12556+
c2b27bf2 12557+ err = au_pin(&pin, dentry, cpg.bdst, au_opt_udba(dentry->d_sb),
4a4d8108
AM
12558+ AuPin_MNT_WRITE);
12559+ if (!err) {
c2b27bf2 12560+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
12561+ au_unpin(&pin);
12562+ }
12563+
4f0767ce 12564+out:
4a4d8108
AM
12565+ di_downgrade_lock(dentry, AuLock_IR);
12566+ return err;
12567+}
12568+
12569+static int au_do_open_sp(struct file *file, int flags)
12570+{
12571+ int err;
12572+ struct dentry *dentry;
12573+ struct super_block *sb;
12574+ struct file *h_file;
12575+ struct inode *h_inode;
12576+
86dc4139
AM
12577+ err = au_fi_sp_add(file);
12578+ if (unlikely(err))
12579+ goto out;
12580+
4a4d8108 12581+ dentry = file->f_dentry;
523b37e3 12582+ AuDbg("%pd\n", dentry);
4a4d8108
AM
12583+
12584+ /*
12585+ * try copying-up.
12586+ * operate on the ro branch is not an error.
12587+ */
12588+ au_cpup_sp(dentry); /* ignore */
12589+
12590+ /* prepare h_file */
12591+ err = au_do_open_nondir(file, vfsub_file_flags(file));
12592+ if (unlikely(err))
86dc4139 12593+ goto out_del;
4a4d8108
AM
12594+
12595+ sb = dentry->d_sb;
12596+ h_file = au_hf_top(file);
c06a8ce3 12597+ h_inode = file_inode(h_file);
4a4d8108
AM
12598+ di_read_unlock(dentry, AuLock_IR);
12599+ fi_write_unlock(file);
12600+ si_read_unlock(sb);
12601+ /* open this fifo in aufs */
c06a8ce3 12602+ err = h_inode->i_fop->open(file_inode(file), file);
4a4d8108
AM
12603+ si_noflush_read_lock(sb);
12604+ fi_write_lock(file);
12605+ di_read_lock_child(dentry, AuLock_IR);
86dc4139 12606+ if (!err) {
4a4d8108 12607+ au_init_fop_sp(file);
86dc4139
AM
12608+ goto out; /* success */
12609+ }
4a4d8108 12610+
86dc4139
AM
12611+out_del:
12612+ au_fi_sp_del(file);
4f0767ce 12613+out:
4a4d8108
AM
12614+ return err;
12615+}
12616+
12617+static int aufs_open_sp(struct inode *inode, struct file *file)
12618+{
12619+ int err;
12620+ struct super_block *sb;
12621+
12622+ sb = file->f_dentry->d_sb;
12623+ si_read_lock(sb, AuLock_FLUSH);
12624+ err = au_do_open(file, au_do_open_sp, /*fidir*/NULL);
12625+ si_read_unlock(sb);
12626+ return err;
12627+}
12628+
12629+/* ---------------------------------------------------------------------- */
12630+
12631+void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev)
12632+{
12633+ init_special_inode(inode, mode, rdev);
12634+
12635+ switch (mode & S_IFMT) {
12636+ case S_IFIFO:
12637+ inode->i_fop = &au_sp_fop[AuSp_FIFO].fop;
12638+ /*FALLTHROUGH*/
12639+ case S_IFCHR:
12640+ case S_IFBLK:
12641+ case S_IFSOCK:
12642+ break;
12643+ default:
12644+ AuDebugOn(1);
12645+ }
12646+}
12647+
12648+int au_special_file(umode_t mode)
12649+{
12650+ int ret;
12651+
12652+ ret = 0;
12653+ switch (mode & S_IFMT) {
12654+ case S_IFIFO:
12655+#if 0
12656+ case S_IFCHR:
12657+ case S_IFBLK:
12658+ case S_IFSOCK:
12659+#endif
12660+ ret = 1;
12661+ }
12662+
12663+ return ret;
12664+}
7f207e10
AM
12665diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
12666--- /usr/share/empty/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
12667+++ linux/fs/aufs/fstype.h 2014-01-20 20:16:14.739463504 +0100
12668@@ -0,0 +1,469 @@
4a4d8108 12669+/*
523b37e3 12670+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
12671+ *
12672+ * This program, aufs is free software; you can redistribute it and/or modify
12673+ * it under the terms of the GNU General Public License as published by
12674+ * the Free Software Foundation; either version 2 of the License, or
12675+ * (at your option) any later version.
12676+ *
12677+ * This program is distributed in the hope that it will be useful,
12678+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12679+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12680+ * GNU General Public License for more details.
12681+ *
12682+ * You should have received a copy of the GNU General Public License
523b37e3 12683+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
12684+ */
12685+
12686+/*
12687+ * judging filesystem type
12688+ */
12689+
12690+#ifndef __AUFS_FSTYPE_H__
12691+#define __AUFS_FSTYPE_H__
12692+
12693+#ifdef __KERNEL__
12694+
12695+#include <linux/fs.h>
12696+#include <linux/magic.h>
12697+#include <linux/romfs_fs.h>
4a4d8108
AM
12698+
12699+static inline int au_test_aufs(struct super_block *sb)
12700+{
12701+ return sb->s_magic == AUFS_SUPER_MAGIC;
12702+}
12703+
12704+static inline const char *au_sbtype(struct super_block *sb)
12705+{
12706+ return sb->s_type->name;
12707+}
1308ab2a 12708+
12709+static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
12710+{
12711+#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE)
12712+ return sb->s_magic == ROMFS_MAGIC;
dece6358
AM
12713+#else
12714+ return 0;
12715+#endif
12716+}
12717+
1308ab2a 12718+static inline int au_test_romfs(struct super_block *sb __maybe_unused)
dece6358 12719+{
1308ab2a 12720+#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE)
12721+ return sb->s_magic == ISOFS_SUPER_MAGIC;
dece6358
AM
12722+#else
12723+ return 0;
12724+#endif
12725+}
12726+
1308ab2a 12727+static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
dece6358 12728+{
1308ab2a 12729+#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE)
12730+ return sb->s_magic == CRAMFS_MAGIC;
12731+#endif
12732+ return 0;
12733+}
12734+
12735+static inline int au_test_nfs(struct super_block *sb __maybe_unused)
12736+{
12737+#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE)
12738+ return sb->s_magic == NFS_SUPER_MAGIC;
dece6358
AM
12739+#else
12740+ return 0;
12741+#endif
12742+}
12743+
1308ab2a 12744+static inline int au_test_fuse(struct super_block *sb __maybe_unused)
dece6358 12745+{
1308ab2a 12746+#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE)
12747+ return sb->s_magic == FUSE_SUPER_MAGIC;
dece6358
AM
12748+#else
12749+ return 0;
12750+#endif
12751+}
12752+
1308ab2a 12753+static inline int au_test_xfs(struct super_block *sb __maybe_unused)
dece6358 12754+{
1308ab2a 12755+#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE)
12756+ return sb->s_magic == XFS_SB_MAGIC;
dece6358
AM
12757+#else
12758+ return 0;
12759+#endif
12760+}
12761+
1308ab2a 12762+static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
dece6358 12763+{
1308ab2a 12764+#ifdef CONFIG_TMPFS
12765+ return sb->s_magic == TMPFS_MAGIC;
12766+#else
12767+ return 0;
dece6358 12768+#endif
dece6358
AM
12769+}
12770+
1308ab2a 12771+static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
1facf9fc 12772+{
1308ab2a 12773+#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE)
12774+ return !strcmp(au_sbtype(sb), "ecryptfs");
12775+#else
12776+ return 0;
12777+#endif
1facf9fc 12778+}
12779+
1308ab2a 12780+static inline int au_test_ocfs2(struct super_block *sb __maybe_unused)
1facf9fc 12781+{
1308ab2a 12782+#if defined(CONFIG_OCFS2_FS) || defined(CONFIG_OCFS2_FS_MODULE)
12783+ return sb->s_magic == OCFS2_SUPER_MAGIC;
12784+#else
12785+ return 0;
12786+#endif
1facf9fc 12787+}
12788+
1308ab2a 12789+static inline int au_test_ocfs2_dlmfs(struct super_block *sb __maybe_unused)
1facf9fc 12790+{
1308ab2a 12791+#if defined(CONFIG_OCFS2_FS_O2CB) || defined(CONFIG_OCFS2_FS_O2CB_MODULE)
12792+ return sb->s_magic == DLMFS_MAGIC;
12793+#else
12794+ return 0;
12795+#endif
1facf9fc 12796+}
12797+
1308ab2a 12798+static inline int au_test_coda(struct super_block *sb __maybe_unused)
1facf9fc 12799+{
1308ab2a 12800+#if defined(CONFIG_CODA_FS) || defined(CONFIG_CODA_FS_MODULE)
12801+ return sb->s_magic == CODA_SUPER_MAGIC;
12802+#else
12803+ return 0;
12804+#endif
12805+}
12806+
12807+static inline int au_test_v9fs(struct super_block *sb __maybe_unused)
12808+{
12809+#if defined(CONFIG_9P_FS) || defined(CONFIG_9P_FS_MODULE)
12810+ return sb->s_magic == V9FS_MAGIC;
12811+#else
12812+ return 0;
12813+#endif
12814+}
12815+
12816+static inline int au_test_ext4(struct super_block *sb __maybe_unused)
12817+{
c2b27bf2 12818+#if defined(CONFIG_EXT4_FS) || defined(CONFIG_EXT4_FS_MODULE)
1308ab2a 12819+ return sb->s_magic == EXT4_SUPER_MAGIC;
12820+#else
12821+ return 0;
12822+#endif
12823+}
12824+
12825+static inline int au_test_sysv(struct super_block *sb __maybe_unused)
12826+{
12827+#if defined(CONFIG_SYSV_FS) || defined(CONFIG_SYSV_FS_MODULE)
12828+ return !strcmp(au_sbtype(sb), "sysv");
12829+#else
12830+ return 0;
12831+#endif
12832+}
12833+
12834+static inline int au_test_ramfs(struct super_block *sb)
12835+{
12836+ return sb->s_magic == RAMFS_MAGIC;
12837+}
12838+
12839+static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
12840+{
12841+#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE)
12842+ return sb->s_magic == UBIFS_SUPER_MAGIC;
12843+#else
12844+ return 0;
12845+#endif
12846+}
12847+
12848+static inline int au_test_procfs(struct super_block *sb __maybe_unused)
12849+{
12850+#ifdef CONFIG_PROC_FS
12851+ return sb->s_magic == PROC_SUPER_MAGIC;
12852+#else
12853+ return 0;
12854+#endif
12855+}
12856+
12857+static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
12858+{
12859+#ifdef CONFIG_SYSFS
12860+ return sb->s_magic == SYSFS_MAGIC;
12861+#else
12862+ return 0;
12863+#endif
12864+}
12865+
12866+static inline int au_test_configfs(struct super_block *sb __maybe_unused)
12867+{
12868+#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE)
12869+ return sb->s_magic == CONFIGFS_MAGIC;
12870+#else
12871+ return 0;
12872+#endif
12873+}
12874+
12875+static inline int au_test_minix(struct super_block *sb __maybe_unused)
12876+{
12877+#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE)
12878+ return sb->s_magic == MINIX3_SUPER_MAGIC
12879+ || sb->s_magic == MINIX2_SUPER_MAGIC
12880+ || sb->s_magic == MINIX2_SUPER_MAGIC2
12881+ || sb->s_magic == MINIX_SUPER_MAGIC
12882+ || sb->s_magic == MINIX_SUPER_MAGIC2;
12883+#else
12884+ return 0;
12885+#endif
12886+}
12887+
12888+static inline int au_test_cifs(struct super_block *sb __maybe_unused)
12889+{
12890+#if defined(CONFIG_CIFS_FS) || defined(CONFIGCIFS_FS_MODULE)
12891+ return sb->s_magic == CIFS_MAGIC_NUMBER;
12892+#else
12893+ return 0;
12894+#endif
12895+}
12896+
12897+static inline int au_test_fat(struct super_block *sb __maybe_unused)
12898+{
12899+#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE)
12900+ return sb->s_magic == MSDOS_SUPER_MAGIC;
12901+#else
12902+ return 0;
12903+#endif
12904+}
12905+
12906+static inline int au_test_msdos(struct super_block *sb)
12907+{
12908+ return au_test_fat(sb);
12909+}
12910+
12911+static inline int au_test_vfat(struct super_block *sb)
12912+{
12913+ return au_test_fat(sb);
12914+}
12915+
12916+static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
12917+{
12918+#ifdef CONFIG_SECURITYFS
12919+ return sb->s_magic == SECURITYFS_MAGIC;
12920+#else
12921+ return 0;
12922+#endif
12923+}
12924+
12925+static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
12926+{
12927+#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE)
12928+ return sb->s_magic == SQUASHFS_MAGIC;
12929+#else
12930+ return 0;
12931+#endif
12932+}
12933+
12934+static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
12935+{
12936+#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE)
12937+ return sb->s_magic == BTRFS_SUPER_MAGIC;
12938+#else
12939+ return 0;
12940+#endif
12941+}
12942+
12943+static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
12944+{
12945+#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE)
12946+ return sb->s_magic == XENFS_SUPER_MAGIC;
12947+#else
12948+ return 0;
12949+#endif
12950+}
12951+
12952+static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
12953+{
12954+#ifdef CONFIG_DEBUG_FS
12955+ return sb->s_magic == DEBUGFS_MAGIC;
12956+#else
12957+ return 0;
12958+#endif
12959+}
12960+
12961+static inline int au_test_nilfs(struct super_block *sb __maybe_unused)
12962+{
12963+#if defined(CONFIG_NILFS) || defined(CONFIG_NILFS_MODULE)
12964+ return sb->s_magic == NILFS_SUPER_MAGIC;
12965+#else
12966+ return 0;
12967+#endif
12968+}
12969+
4a4d8108
AM
12970+static inline int au_test_hfsplus(struct super_block *sb __maybe_unused)
12971+{
12972+#if defined(CONFIG_HFSPLUS_FS) || defined(CONFIG_HFSPLUS_FS_MODULE)
12973+ return sb->s_magic == HFSPLUS_SUPER_MAGIC;
12974+#else
12975+ return 0;
12976+#endif
12977+}
12978+
1308ab2a 12979+/* ---------------------------------------------------------------------- */
12980+/*
12981+ * they can't be an aufs branch.
12982+ */
12983+static inline int au_test_fs_unsuppoted(struct super_block *sb)
12984+{
12985+ return
12986+#ifndef CONFIG_AUFS_BR_RAMFS
12987+ au_test_ramfs(sb) ||
12988+#endif
12989+ au_test_procfs(sb)
12990+ || au_test_sysfs(sb)
12991+ || au_test_configfs(sb)
12992+ || au_test_debugfs(sb)
12993+ || au_test_securityfs(sb)
12994+ || au_test_xenfs(sb)
12995+ || au_test_ecryptfs(sb)
12996+ /* || !strcmp(au_sbtype(sb), "unionfs") */
12997+ || au_test_aufs(sb); /* will be supported in next version */
12998+}
12999+
1308ab2a 13000+static inline int au_test_fs_remote(struct super_block *sb)
13001+{
13002+ return !au_test_tmpfs(sb)
13003+#ifdef CONFIG_AUFS_BR_RAMFS
13004+ && !au_test_ramfs(sb)
13005+#endif
13006+ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
13007+}
13008+
13009+/* ---------------------------------------------------------------------- */
13010+
13011+/*
13012+ * Note: these functions (below) are created after reading ->getattr() in all
13013+ * filesystems under linux/fs. it means we have to do so in every update...
13014+ */
13015+
13016+/*
13017+ * some filesystems require getattr to refresh the inode attributes before
13018+ * referencing.
13019+ * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
13020+ * and leave the work for d_revalidate()
13021+ */
13022+static inline int au_test_fs_refresh_iattr(struct super_block *sb)
13023+{
13024+ return au_test_nfs(sb)
13025+ || au_test_fuse(sb)
1308ab2a 13026+ /* || au_test_ocfs2(sb) */ /* untested */
13027+ /* || au_test_btrfs(sb) */ /* untested */
13028+ /* || au_test_coda(sb) */ /* untested */
13029+ /* || au_test_v9fs(sb) */ /* untested */
13030+ ;
13031+}
13032+
13033+/*
13034+ * filesystems which don't maintain i_size or i_blocks.
13035+ */
13036+static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
13037+{
13038+ return au_test_xfs(sb)
4a4d8108
AM
13039+ || au_test_btrfs(sb)
13040+ || au_test_ubifs(sb)
13041+ || au_test_hfsplus(sb) /* maintained, but incorrect */
1308ab2a 13042+ /* || au_test_ext4(sb) */ /* untested */
13043+ /* || au_test_ocfs2(sb) */ /* untested */
13044+ /* || au_test_ocfs2_dlmfs(sb) */ /* untested */
13045+ /* || au_test_sysv(sb) */ /* untested */
1308ab2a 13046+ /* || au_test_minix(sb) */ /* untested */
13047+ ;
13048+}
13049+
13050+/*
13051+ * filesystems which don't store the correct value in some of their inode
13052+ * attributes.
13053+ */
13054+static inline int au_test_fs_bad_iattr(struct super_block *sb)
13055+{
13056+ return au_test_fs_bad_iattr_size(sb)
13057+ /* || au_test_cifs(sb) */ /* untested */
13058+ || au_test_fat(sb)
13059+ || au_test_msdos(sb)
13060+ || au_test_vfat(sb);
1facf9fc 13061+}
13062+
13063+/* they don't check i_nlink in link(2) */
13064+static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
13065+{
13066+ return au_test_tmpfs(sb)
13067+#ifdef CONFIG_AUFS_BR_RAMFS
13068+ || au_test_ramfs(sb)
13069+#endif
4a4d8108 13070+ || au_test_ubifs(sb)
4a4d8108 13071+ || au_test_hfsplus(sb);
1facf9fc 13072+}
13073+
13074+/*
13075+ * filesystems which sets S_NOATIME and S_NOCMTIME.
13076+ */
13077+static inline int au_test_fs_notime(struct super_block *sb)
13078+{
13079+ return au_test_nfs(sb)
13080+ || au_test_fuse(sb)
dece6358 13081+ || au_test_ubifs(sb)
1facf9fc 13082+ /* || au_test_cifs(sb) */ /* untested */
1facf9fc 13083+ ;
13084+}
13085+
13086+/*
13087+ * filesystems which requires replacing i_mapping.
13088+ */
13089+static inline int au_test_fs_bad_mapping(struct super_block *sb)
13090+{
dece6358
AM
13091+ return au_test_fuse(sb)
13092+ || au_test_ubifs(sb);
1facf9fc 13093+}
13094+
13095+/* temporary support for i#1 in cramfs */
13096+static inline int au_test_fs_unique_ino(struct inode *inode)
13097+{
13098+ if (au_test_cramfs(inode->i_sb))
13099+ return inode->i_ino != 1;
13100+ return 1;
13101+}
13102+
13103+/* ---------------------------------------------------------------------- */
13104+
13105+/*
13106+ * the filesystem where the xino files placed must support i/o after unlink and
13107+ * maintain i_size and i_blocks.
13108+ */
13109+static inline int au_test_fs_bad_xino(struct super_block *sb)
13110+{
13111+ return au_test_fs_remote(sb)
13112+ || au_test_fs_bad_iattr_size(sb)
1facf9fc 13113+ /* don't want unnecessary work for xino */
13114+ || au_test_aufs(sb)
1308ab2a 13115+ || au_test_ecryptfs(sb)
13116+ || au_test_nilfs(sb);
1facf9fc 13117+}
13118+
13119+static inline int au_test_fs_trunc_xino(struct super_block *sb)
13120+{
13121+ return au_test_tmpfs(sb)
13122+ || au_test_ramfs(sb);
13123+}
13124+
13125+/*
13126+ * test if the @sb is real-readonly.
13127+ */
13128+static inline int au_test_fs_rr(struct super_block *sb)
13129+{
13130+ return au_test_squashfs(sb)
13131+ || au_test_iso9660(sb)
13132+ || au_test_cramfs(sb)
13133+ || au_test_romfs(sb);
13134+}
13135+
13136+#endif /* __KERNEL__ */
13137+#endif /* __AUFS_FSTYPE_H__ */
7f207e10
AM
13138diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
13139--- /usr/share/empty/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
13140+++ linux/fs/aufs/hfsnotify.c 2014-01-20 20:16:14.739463504 +0100
13141@@ -0,0 +1,295 @@
1facf9fc 13142+/*
523b37e3 13143+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 13144+ *
13145+ * This program, aufs is free software; you can redistribute it and/or modify
13146+ * it under the terms of the GNU General Public License as published by
13147+ * the Free Software Foundation; either version 2 of the License, or
13148+ * (at your option) any later version.
dece6358
AM
13149+ *
13150+ * This program is distributed in the hope that it will be useful,
13151+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13152+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13153+ * GNU General Public License for more details.
13154+ *
13155+ * You should have received a copy of the GNU General Public License
523b37e3 13156+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 13157+ */
13158+
13159+/*
4a4d8108 13160+ * fsnotify for the lower directories
1facf9fc 13161+ */
13162+
13163+#include "aufs.h"
13164+
4a4d8108
AM
13165+/* FS_IN_IGNORED is unnecessary */
13166+static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE
13167+ | FS_CREATE | FS_EVENT_ON_CHILD);
7f207e10 13168+static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
7eafdf33 13169+static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0);
1facf9fc 13170+
0c5527e5 13171+static void au_hfsn_free_mark(struct fsnotify_mark *mark)
1facf9fc 13172+{
0c5527e5
AM
13173+ struct au_hnotify *hn = container_of(mark, struct au_hnotify,
13174+ hn_mark);
4a4d8108 13175+ AuDbg("here\n");
7eafdf33
AM
13176+ au_cache_free_hnotify(hn);
13177+ smp_mb__before_atomic_dec();
1716fcea
AM
13178+ if (atomic64_dec_and_test(&au_hfsn_ifree))
13179+ wake_up(&au_hfsn_wq);
4a4d8108 13180+}
1facf9fc 13181+
027c5e7a 13182+static int au_hfsn_alloc(struct au_hinode *hinode)
4a4d8108 13183+{
1716fcea 13184+ int err;
027c5e7a
AM
13185+ struct au_hnotify *hn;
13186+ struct super_block *sb;
13187+ struct au_branch *br;
0c5527e5 13188+ struct fsnotify_mark *mark;
027c5e7a 13189+ aufs_bindex_t bindex;
1facf9fc 13190+
027c5e7a
AM
13191+ hn = hinode->hi_notify;
13192+ sb = hn->hn_aufs_inode->i_sb;
13193+ bindex = au_br_index(sb, hinode->hi_id);
13194+ br = au_sbr(sb, bindex);
1716fcea
AM
13195+ AuDebugOn(!br->br_hfsn);
13196+
0c5527e5
AM
13197+ mark = &hn->hn_mark;
13198+ fsnotify_init_mark(mark, au_hfsn_free_mark);
13199+ mark->mask = AuHfsnMask;
7f207e10
AM
13200+ /*
13201+ * by udba rename or rmdir, aufs assign a new inode to the known
13202+ * h_inode, so specify 1 to allow dups.
13203+ */
1716fcea 13204+ err = fsnotify_add_mark(mark, br->br_hfsn->hfsn_group, hinode->hi_inode,
027c5e7a 13205+ /*mnt*/NULL, /*allow_dups*/1);
1716fcea
AM
13206+ /* even if err */
13207+ fsnotify_put_mark(mark);
13208+
13209+ return err;
1facf9fc 13210+}
13211+
7eafdf33 13212+static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn)
1facf9fc 13213+{
0c5527e5 13214+ struct fsnotify_mark *mark;
7eafdf33 13215+ unsigned long long ull;
1716fcea 13216+ struct fsnotify_group *group;
7eafdf33
AM
13217+
13218+ ull = atomic64_inc_return(&au_hfsn_ifree);
13219+ BUG_ON(!ull);
953406b4 13220+
0c5527e5 13221+ mark = &hn->hn_mark;
1716fcea
AM
13222+ spin_lock(&mark->lock);
13223+ group = mark->group;
13224+ fsnotify_get_group(group);
13225+ spin_unlock(&mark->lock);
13226+ fsnotify_destroy_mark(mark, group);
13227+ fsnotify_put_group(group);
7f207e10 13228+
7eafdf33
AM
13229+ /* free hn by myself */
13230+ return 0;
1facf9fc 13231+}
13232+
13233+/* ---------------------------------------------------------------------- */
13234+
4a4d8108 13235+static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
1facf9fc 13236+{
0c5527e5 13237+ struct fsnotify_mark *mark;
1facf9fc 13238+
0c5527e5
AM
13239+ mark = &hinode->hi_notify->hn_mark;
13240+ spin_lock(&mark->lock);
1facf9fc 13241+ if (do_set) {
0c5527e5
AM
13242+ AuDebugOn(mark->mask & AuHfsnMask);
13243+ mark->mask |= AuHfsnMask;
1facf9fc 13244+ } else {
0c5527e5
AM
13245+ AuDebugOn(!(mark->mask & AuHfsnMask));
13246+ mark->mask &= ~AuHfsnMask;
1facf9fc 13247+ }
0c5527e5 13248+ spin_unlock(&mark->lock);
4a4d8108 13249+ /* fsnotify_recalc_inode_mask(hinode->hi_inode); */
1facf9fc 13250+}
13251+
4a4d8108 13252+/* ---------------------------------------------------------------------- */
1facf9fc 13253+
4a4d8108
AM
13254+/* #define AuDbgHnotify */
13255+#ifdef AuDbgHnotify
13256+static char *au_hfsn_name(u32 mask)
13257+{
13258+#ifdef CONFIG_AUFS_DEBUG
c06a8ce3
AM
13259+#define test_ret(flag) \
13260+ do { \
13261+ if (mask & flag) \
13262+ return #flag; \
13263+ } while (0)
4a4d8108
AM
13264+ test_ret(FS_ACCESS);
13265+ test_ret(FS_MODIFY);
13266+ test_ret(FS_ATTRIB);
13267+ test_ret(FS_CLOSE_WRITE);
13268+ test_ret(FS_CLOSE_NOWRITE);
13269+ test_ret(FS_OPEN);
13270+ test_ret(FS_MOVED_FROM);
13271+ test_ret(FS_MOVED_TO);
13272+ test_ret(FS_CREATE);
13273+ test_ret(FS_DELETE);
13274+ test_ret(FS_DELETE_SELF);
13275+ test_ret(FS_MOVE_SELF);
13276+ test_ret(FS_UNMOUNT);
13277+ test_ret(FS_Q_OVERFLOW);
13278+ test_ret(FS_IN_IGNORED);
13279+ test_ret(FS_IN_ISDIR);
13280+ test_ret(FS_IN_ONESHOT);
13281+ test_ret(FS_EVENT_ON_CHILD);
13282+ return "";
13283+#undef test_ret
13284+#else
13285+ return "??";
13286+#endif
1facf9fc 13287+}
4a4d8108 13288+#endif
1facf9fc 13289+
13290+/* ---------------------------------------------------------------------- */
13291+
1716fcea
AM
13292+static void au_hfsn_free_group(struct fsnotify_group *group)
13293+{
13294+ struct au_br_hfsnotify *hfsn = group->private;
13295+
13296+ AuDbg("here\n");
13297+ kfree(hfsn);
13298+}
13299+
4a4d8108 13300+static int au_hfsn_handle_event(struct fsnotify_group *group,
0c5527e5
AM
13301+ struct fsnotify_mark *inode_mark,
13302+ struct fsnotify_mark *vfsmount_mark,
4a4d8108 13303+ struct fsnotify_event *event)
1facf9fc 13304+{
13305+ int err;
4a4d8108
AM
13306+ struct au_hnotify *hnotify;
13307+ struct inode *h_dir, *h_inode;
13308+ __u32 mask;
0c3ec466 13309+ struct qstr h_child_qstr = QSTR_INIT(event->file_name, event->name_len);
4a4d8108
AM
13310+
13311+ AuDebugOn(event->data_type != FSNOTIFY_EVENT_INODE);
1facf9fc 13312+
13313+ err = 0;
0c5527e5 13314+ /* if FS_UNMOUNT happens, there must be another bug */
4a4d8108
AM
13315+ mask = event->mask;
13316+ AuDebugOn(mask & FS_UNMOUNT);
0c5527e5 13317+ if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
1facf9fc 13318+ goto out;
1facf9fc 13319+
4a4d8108
AM
13320+ h_dir = event->to_tell;
13321+ h_inode = event->inode;
13322+#ifdef AuDbgHnotify
392086de 13323+ au_debug_on();
4a4d8108
AM
13324+ if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
13325+ || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
13326+ AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
13327+ h_dir->i_ino, mask, au_hfsn_name(mask),
13328+ AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
13329+ /* WARN_ON(1); */
1facf9fc 13330+ }
392086de 13331+ au_debug_off();
1facf9fc 13332+#endif
4a4d8108 13333+
0c5527e5
AM
13334+ AuDebugOn(!inode_mark);
13335+ hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
13336+ err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode);
1facf9fc 13337+
4a4d8108
AM
13338+out:
13339+ return err;
13340+}
1facf9fc 13341+
027c5e7a 13342+/* isn't it waste to ask every registered 'group'? */
7f207e10 13343+/* copied from linux/fs/notify/inotify/inotify_fsnotiry.c */
4a4d8108 13344+/* it should be exported to modules */
7f207e10
AM
13345+static bool au_hfsn_should_send_event(struct fsnotify_group *group,
13346+ struct inode *h_inode,
0c5527e5
AM
13347+ struct fsnotify_mark *inode_mark,
13348+ struct fsnotify_mark *vfsmount_mark,
13349+ __u32 mask, void *data, int data_type)
4a4d8108 13350+{
4a4d8108 13351+ mask = (mask & ~FS_EVENT_ON_CHILD);
7f207e10 13352+ return inode_mark->mask & mask;
4a4d8108
AM
13353+}
13354+
13355+static struct fsnotify_ops au_hfsn_ops = {
13356+ .should_send_event = au_hfsn_should_send_event,
1716fcea
AM
13357+ .handle_event = au_hfsn_handle_event,
13358+ .free_group_priv = au_hfsn_free_group
4a4d8108
AM
13359+};
13360+
13361+/* ---------------------------------------------------------------------- */
13362+
027c5e7a
AM
13363+static void au_hfsn_fin_br(struct au_branch *br)
13364+{
1716fcea 13365+ struct au_br_hfsnotify *hfsn;
027c5e7a 13366+
1716fcea
AM
13367+ hfsn = br->br_hfsn;
13368+ if (hfsn)
13369+ fsnotify_put_group(hfsn->hfsn_group);
027c5e7a
AM
13370+}
13371+
1716fcea 13372+static int au_hfsn_init_br(struct au_branch *br, int perm)
4a4d8108
AM
13373+{
13374+ int err;
1716fcea
AM
13375+ struct fsnotify_group *group;
13376+ struct au_br_hfsnotify *hfsn;
1facf9fc 13377+
4a4d8108 13378+ err = 0;
1716fcea
AM
13379+ br->br_hfsn = NULL;
13380+ if (!au_br_hnotifyable(perm))
027c5e7a 13381+ goto out;
027c5e7a 13382+
1716fcea
AM
13383+ err = -ENOMEM;
13384+ hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS);
13385+ if (unlikely(!hfsn))
027c5e7a
AM
13386+ goto out;
13387+
1716fcea
AM
13388+ err = 0;
13389+ group = fsnotify_alloc_group(&au_hfsn_ops);
13390+ if (IS_ERR(group)) {
13391+ err = PTR_ERR(group);
0c5527e5 13392+ pr_err("fsnotify_alloc_group() failed, %d\n", err);
1716fcea 13393+ goto out_hfsn;
4a4d8108 13394+ }
1facf9fc 13395+
1716fcea
AM
13396+ group->private = hfsn;
13397+ hfsn->hfsn_group = group;
13398+ br->br_hfsn = hfsn;
13399+ goto out; /* success */
13400+
13401+out_hfsn:
13402+ kfree(hfsn);
027c5e7a 13403+out:
1716fcea
AM
13404+ return err;
13405+}
13406+
13407+static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm)
13408+{
13409+ int err;
13410+
13411+ err = 0;
13412+ if (!br->br_hfsn)
13413+ err = au_hfsn_init_br(br, perm);
13414+
1facf9fc 13415+ return err;
13416+}
13417+
7eafdf33
AM
13418+/* ---------------------------------------------------------------------- */
13419+
13420+static void au_hfsn_fin(void)
13421+{
13422+ AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree));
13423+ wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree));
13424+}
13425+
4a4d8108
AM
13426+const struct au_hnotify_op au_hnotify_op = {
13427+ .ctl = au_hfsn_ctl,
13428+ .alloc = au_hfsn_alloc,
13429+ .free = au_hfsn_free,
1facf9fc 13430+
7eafdf33
AM
13431+ .fin = au_hfsn_fin,
13432+
027c5e7a
AM
13433+ .reset_br = au_hfsn_reset_br,
13434+ .fin_br = au_hfsn_fin_br,
13435+ .init_br = au_hfsn_init_br
4a4d8108 13436+};
7f207e10
AM
13437diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c
13438--- /usr/share/empty/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
13439+++ linux/fs/aufs/hfsplus.c 2014-01-20 20:16:14.739463504 +0100
13440@@ -0,0 +1,56 @@
4a4d8108 13441+/*
523b37e3 13442+ * Copyright (C) 2010-2014 Junjiro R. Okajima
4a4d8108
AM
13443+ *
13444+ * This program, aufs is free software; you can redistribute it and/or modify
13445+ * it under the terms of the GNU General Public License as published by
13446+ * the Free Software Foundation; either version 2 of the License, or
13447+ * (at your option) any later version.
13448+ *
13449+ * This program is distributed in the hope that it will be useful,
13450+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13451+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13452+ * GNU General Public License for more details.
13453+ *
13454+ * You should have received a copy of the GNU General Public License
523b37e3 13455+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 13456+ */
1facf9fc 13457+
4a4d8108
AM
13458+/*
13459+ * special support for filesystems which aqucires an inode mutex
13460+ * at final closing a file, eg, hfsplus.
13461+ *
13462+ * This trick is very simple and stupid, just to open the file before really
13463+ * neceeary open to tell hfsplus that this is not the final closing.
13464+ * The caller should call au_h_open_pre() after acquiring the inode mutex,
13465+ * and au_h_open_post() after releasing it.
13466+ */
1facf9fc 13467+
4a4d8108 13468+#include "aufs.h"
1facf9fc 13469+
392086de
AM
13470+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
13471+ int force_wr)
4a4d8108
AM
13472+{
13473+ struct file *h_file;
13474+ struct dentry *h_dentry;
1facf9fc 13475+
4a4d8108
AM
13476+ h_dentry = au_h_dptr(dentry, bindex);
13477+ AuDebugOn(!h_dentry);
13478+ AuDebugOn(!h_dentry->d_inode);
4a4d8108
AM
13479+
13480+ h_file = NULL;
13481+ if (au_test_hfsplus(h_dentry->d_sb)
13482+ && S_ISREG(h_dentry->d_inode->i_mode))
13483+ h_file = au_h_open(dentry, bindex,
13484+ O_RDONLY | O_NOATIME | O_LARGEFILE,
392086de 13485+ /*file*/NULL, force_wr);
4a4d8108 13486+ return h_file;
1facf9fc 13487+}
13488+
4a4d8108
AM
13489+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
13490+ struct file *h_file)
13491+{
13492+ if (h_file) {
13493+ fput(h_file);
13494+ au_sbr_put(dentry->d_sb, bindex);
13495+ }
13496+}
7f207e10
AM
13497diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
13498--- /usr/share/empty/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100
f6b6e03d 13499+++ linux/fs/aufs/hnotify.c 2014-01-27 23:16:52.711753818 +0100
523b37e3 13500@@ -0,0 +1,710 @@
e49829fe 13501+/*
523b37e3 13502+ * Copyright (C) 2005-2014 Junjiro R. Okajima
e49829fe
JR
13503+ *
13504+ * This program, aufs is free software; you can redistribute it and/or modify
13505+ * it under the terms of the GNU General Public License as published by
13506+ * the Free Software Foundation; either version 2 of the License, or
13507+ * (at your option) any later version.
13508+ *
13509+ * This program is distributed in the hope that it will be useful,
13510+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13511+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13512+ * GNU General Public License for more details.
13513+ *
13514+ * You should have received a copy of the GNU General Public License
523b37e3 13515+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
13516+ */
13517+
13518+/*
7f207e10 13519+ * abstraction to notify the direct changes on lower directories
e49829fe
JR
13520+ */
13521+
13522+#include "aufs.h"
13523+
027c5e7a 13524+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
e49829fe
JR
13525+{
13526+ int err;
7f207e10 13527+ struct au_hnotify *hn;
1facf9fc 13528+
4a4d8108
AM
13529+ err = -ENOMEM;
13530+ hn = au_cache_alloc_hnotify();
13531+ if (hn) {
13532+ hn->hn_aufs_inode = inode;
027c5e7a
AM
13533+ hinode->hi_notify = hn;
13534+ err = au_hnotify_op.alloc(hinode);
13535+ AuTraceErr(err);
13536+ if (unlikely(err)) {
13537+ hinode->hi_notify = NULL;
4a4d8108
AM
13538+ au_cache_free_hnotify(hn);
13539+ /*
13540+ * The upper dir was removed by udba, but the same named
13541+ * dir left. In this case, aufs assignes a new inode
13542+ * number and set the monitor again.
13543+ * For the lower dir, the old monitnor is still left.
13544+ */
13545+ if (err == -EEXIST)
13546+ err = 0;
13547+ }
1308ab2a 13548+ }
1308ab2a 13549+
027c5e7a 13550+ AuTraceErr(err);
1308ab2a 13551+ return err;
dece6358 13552+}
1facf9fc 13553+
4a4d8108 13554+void au_hn_free(struct au_hinode *hinode)
dece6358 13555+{
4a4d8108 13556+ struct au_hnotify *hn;
1facf9fc 13557+
4a4d8108
AM
13558+ hn = hinode->hi_notify;
13559+ if (hn) {
4a4d8108 13560+ hinode->hi_notify = NULL;
7eafdf33
AM
13561+ if (au_hnotify_op.free(hinode, hn))
13562+ au_cache_free_hnotify(hn);
4a4d8108
AM
13563+ }
13564+}
dece6358 13565+
4a4d8108 13566+/* ---------------------------------------------------------------------- */
dece6358 13567+
4a4d8108
AM
13568+void au_hn_ctl(struct au_hinode *hinode, int do_set)
13569+{
13570+ if (hinode->hi_notify)
13571+ au_hnotify_op.ctl(hinode, do_set);
13572+}
13573+
13574+void au_hn_reset(struct inode *inode, unsigned int flags)
13575+{
13576+ aufs_bindex_t bindex, bend;
13577+ struct inode *hi;
13578+ struct dentry *iwhdentry;
1facf9fc 13579+
1308ab2a 13580+ bend = au_ibend(inode);
4a4d8108
AM
13581+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
13582+ hi = au_h_iptr(inode, bindex);
13583+ if (!hi)
13584+ continue;
1308ab2a 13585+
4a4d8108
AM
13586+ /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */
13587+ iwhdentry = au_hi_wh(inode, bindex);
13588+ if (iwhdentry)
13589+ dget(iwhdentry);
13590+ au_igrab(hi);
13591+ au_set_h_iptr(inode, bindex, NULL, 0);
13592+ au_set_h_iptr(inode, bindex, au_igrab(hi),
13593+ flags & ~AuHi_XINO);
13594+ iput(hi);
13595+ dput(iwhdentry);
13596+ /* mutex_unlock(&hi->i_mutex); */
1facf9fc 13597+ }
1facf9fc 13598+}
13599+
1308ab2a 13600+/* ---------------------------------------------------------------------- */
1facf9fc 13601+
4a4d8108 13602+static int hn_xino(struct inode *inode, struct inode *h_inode)
1facf9fc 13603+{
4a4d8108
AM
13604+ int err;
13605+ aufs_bindex_t bindex, bend, bfound, bstart;
13606+ struct inode *h_i;
1facf9fc 13607+
4a4d8108
AM
13608+ err = 0;
13609+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 13610+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
13611+ goto out;
13612+ }
1facf9fc 13613+
4a4d8108
AM
13614+ bfound = -1;
13615+ bend = au_ibend(inode);
13616+ bstart = au_ibstart(inode);
13617+#if 0 /* reserved for future use */
13618+ if (bindex == bend) {
13619+ /* keep this ino in rename case */
13620+ goto out;
13621+ }
13622+#endif
13623+ for (bindex = bstart; bindex <= bend; bindex++)
13624+ if (au_h_iptr(inode, bindex) == h_inode) {
13625+ bfound = bindex;
13626+ break;
13627+ }
13628+ if (bfound < 0)
1308ab2a 13629+ goto out;
1facf9fc 13630+
4a4d8108
AM
13631+ for (bindex = bstart; bindex <= bend; bindex++) {
13632+ h_i = au_h_iptr(inode, bindex);
13633+ if (!h_i)
13634+ continue;
1facf9fc 13635+
4a4d8108
AM
13636+ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
13637+ /* ignore this error */
13638+ /* bad action? */
1facf9fc 13639+ }
1facf9fc 13640+
4a4d8108 13641+ /* children inode number will be broken */
1facf9fc 13642+
4f0767ce 13643+out:
4a4d8108
AM
13644+ AuTraceErr(err);
13645+ return err;
1facf9fc 13646+}
13647+
4a4d8108 13648+static int hn_gen_tree(struct dentry *dentry)
1facf9fc 13649+{
4a4d8108
AM
13650+ int err, i, j, ndentry;
13651+ struct au_dcsub_pages dpages;
13652+ struct au_dpage *dpage;
13653+ struct dentry **dentries;
1facf9fc 13654+
4a4d8108
AM
13655+ err = au_dpages_init(&dpages, GFP_NOFS);
13656+ if (unlikely(err))
13657+ goto out;
13658+ err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
13659+ if (unlikely(err))
13660+ goto out_dpages;
1facf9fc 13661+
4a4d8108
AM
13662+ for (i = 0; i < dpages.ndpage; i++) {
13663+ dpage = dpages.dpages + i;
13664+ dentries = dpage->dentries;
13665+ ndentry = dpage->ndentry;
13666+ for (j = 0; j < ndentry; j++) {
13667+ struct dentry *d;
13668+
13669+ d = dentries[j];
13670+ if (IS_ROOT(d))
13671+ continue;
13672+
4a4d8108
AM
13673+ au_digen_dec(d);
13674+ if (d->d_inode)
13675+ /* todo: reset children xino?
13676+ cached children only? */
13677+ au_iigen_dec(d->d_inode);
1308ab2a 13678+ }
dece6358 13679+ }
1facf9fc 13680+
4f0767ce 13681+out_dpages:
4a4d8108 13682+ au_dpages_free(&dpages);
dece6358 13683+
027c5e7a 13684+#if 0
4a4d8108
AM
13685+ /* discard children */
13686+ dentry_unhash(dentry);
13687+ dput(dentry);
027c5e7a 13688+#endif
4f0767ce 13689+out:
dece6358
AM
13690+ return err;
13691+}
13692+
1308ab2a 13693+/*
4a4d8108 13694+ * return 0 if processed.
1308ab2a 13695+ */
4a4d8108
AM
13696+static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
13697+ const unsigned int isdir)
dece6358 13698+{
1308ab2a 13699+ int err;
4a4d8108
AM
13700+ struct dentry *d;
13701+ struct qstr *dname;
1facf9fc 13702+
4a4d8108
AM
13703+ err = 1;
13704+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 13705+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
13706+ err = 0;
13707+ goto out;
13708+ }
dece6358 13709+
4a4d8108
AM
13710+ if (!isdir) {
13711+ AuDebugOn(!name);
13712+ au_iigen_dec(inode);
027c5e7a 13713+ spin_lock(&inode->i_lock);
c06a8ce3 13714+ hlist_for_each_entry(d, &inode->i_dentry, d_alias) {
027c5e7a 13715+ spin_lock(&d->d_lock);
4a4d8108
AM
13716+ dname = &d->d_name;
13717+ if (dname->len != nlen
027c5e7a
AM
13718+ && memcmp(dname->name, name, nlen)) {
13719+ spin_unlock(&d->d_lock);
4a4d8108 13720+ continue;
027c5e7a 13721+ }
4a4d8108 13722+ err = 0;
4a4d8108
AM
13723+ au_digen_dec(d);
13724+ spin_unlock(&d->d_lock);
13725+ break;
1facf9fc 13726+ }
027c5e7a 13727+ spin_unlock(&inode->i_lock);
1308ab2a 13728+ } else {
027c5e7a 13729+ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
4a4d8108
AM
13730+ d = d_find_alias(inode);
13731+ if (!d) {
13732+ au_iigen_dec(inode);
13733+ goto out;
13734+ }
1facf9fc 13735+
027c5e7a 13736+ spin_lock(&d->d_lock);
4a4d8108 13737+ dname = &d->d_name;
027c5e7a
AM
13738+ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
13739+ spin_unlock(&d->d_lock);
4a4d8108 13740+ err = hn_gen_tree(d);
027c5e7a
AM
13741+ spin_lock(&d->d_lock);
13742+ }
13743+ spin_unlock(&d->d_lock);
4a4d8108
AM
13744+ dput(d);
13745+ }
1facf9fc 13746+
4f0767ce 13747+out:
4a4d8108 13748+ AuTraceErr(err);
1308ab2a 13749+ return err;
13750+}
dece6358 13751+
4a4d8108 13752+static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
1facf9fc 13753+{
4a4d8108
AM
13754+ int err;
13755+ struct inode *inode;
1facf9fc 13756+
4a4d8108
AM
13757+ inode = dentry->d_inode;
13758+ if (IS_ROOT(dentry)
13759+ /* || (inode && inode->i_ino == AUFS_ROOT_INO) */
13760+ ) {
0c3ec466 13761+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
13762+ return 0;
13763+ }
1308ab2a 13764+
4a4d8108
AM
13765+ err = 0;
13766+ if (!isdir) {
4a4d8108
AM
13767+ au_digen_dec(dentry);
13768+ if (inode)
13769+ au_iigen_dec(inode);
13770+ } else {
027c5e7a 13771+ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
4a4d8108
AM
13772+ if (inode)
13773+ err = hn_gen_tree(dentry);
13774+ }
13775+
13776+ AuTraceErr(err);
13777+ return err;
1facf9fc 13778+}
13779+
4a4d8108 13780+/* ---------------------------------------------------------------------- */
1facf9fc 13781+
4a4d8108
AM
13782+/* hnotify job flags */
13783+#define AuHnJob_XINO0 1
13784+#define AuHnJob_GEN (1 << 1)
13785+#define AuHnJob_DIRENT (1 << 2)
13786+#define AuHnJob_ISDIR (1 << 3)
13787+#define AuHnJob_TRYXINO0 (1 << 4)
13788+#define AuHnJob_MNTPNT (1 << 5)
13789+#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name)
7f207e10
AM
13790+#define au_fset_hnjob(flags, name) \
13791+ do { (flags) |= AuHnJob_##name; } while (0)
13792+#define au_fclr_hnjob(flags, name) \
13793+ do { (flags) &= ~AuHnJob_##name; } while (0)
1facf9fc 13794+
4a4d8108
AM
13795+enum {
13796+ AuHn_CHILD,
13797+ AuHn_PARENT,
13798+ AuHnLast
13799+};
1facf9fc 13800+
4a4d8108
AM
13801+struct au_hnotify_args {
13802+ struct inode *h_dir, *dir, *h_child_inode;
13803+ u32 mask;
13804+ unsigned int flags[AuHnLast];
13805+ unsigned int h_child_nlen;
13806+ char h_child_name[];
13807+};
1facf9fc 13808+
4a4d8108
AM
13809+struct hn_job_args {
13810+ unsigned int flags;
13811+ struct inode *inode, *h_inode, *dir, *h_dir;
13812+ struct dentry *dentry;
13813+ char *h_name;
13814+ int h_nlen;
13815+};
1308ab2a 13816+
4a4d8108
AM
13817+static int hn_job(struct hn_job_args *a)
13818+{
13819+ const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
1308ab2a 13820+
4a4d8108
AM
13821+ /* reset xino */
13822+ if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
13823+ hn_xino(a->inode, a->h_inode); /* ignore this error */
1308ab2a 13824+
4a4d8108
AM
13825+ if (au_ftest_hnjob(a->flags, TRYXINO0)
13826+ && a->inode
13827+ && a->h_inode) {
13828+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
13829+ if (!a->h_inode->i_nlink)
13830+ hn_xino(a->inode, a->h_inode); /* ignore this error */
13831+ mutex_unlock(&a->h_inode->i_mutex);
1308ab2a 13832+ }
1facf9fc 13833+
4a4d8108
AM
13834+ /* make the generation obsolete */
13835+ if (au_ftest_hnjob(a->flags, GEN)) {
13836+ int err = -1;
13837+ if (a->inode)
13838+ err = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
13839+ isdir);
13840+ if (err && a->dentry)
13841+ hn_gen_by_name(a->dentry, isdir);
13842+ /* ignore this error */
1facf9fc 13843+ }
1facf9fc 13844+
4a4d8108
AM
13845+ /* make dir entries obsolete */
13846+ if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
13847+ struct au_vdir *vdir;
1facf9fc 13848+
4a4d8108
AM
13849+ vdir = au_ivdir(a->inode);
13850+ if (vdir)
13851+ vdir->vd_jiffy = 0;
13852+ /* IMustLock(a->inode); */
13853+ /* a->inode->i_version++; */
13854+ }
1facf9fc 13855+
4a4d8108
AM
13856+ /* can do nothing but warn */
13857+ if (au_ftest_hnjob(a->flags, MNTPNT)
13858+ && a->dentry
13859+ && d_mountpoint(a->dentry))
523b37e3 13860+ pr_warn("mount-point %pd is removed or renamed\n", a->dentry);
1facf9fc 13861+
4a4d8108 13862+ return 0;
1308ab2a 13863+}
1facf9fc 13864+
1308ab2a 13865+/* ---------------------------------------------------------------------- */
1facf9fc 13866+
4a4d8108
AM
13867+static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
13868+ struct inode *dir)
1308ab2a 13869+{
4a4d8108
AM
13870+ struct dentry *dentry, *d, *parent;
13871+ struct qstr *dname;
1308ab2a 13872+
4a4d8108
AM
13873+ parent = d_find_alias(dir);
13874+ if (!parent)
13875+ return NULL;
1308ab2a 13876+
4a4d8108 13877+ dentry = NULL;
027c5e7a 13878+ spin_lock(&parent->d_lock);
4a4d8108 13879+ list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) {
523b37e3 13880+ /* AuDbg("%pd\n", d); */
027c5e7a 13881+ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
4a4d8108
AM
13882+ dname = &d->d_name;
13883+ if (dname->len != nlen || memcmp(dname->name, name, nlen))
027c5e7a
AM
13884+ goto cont_unlock;
13885+ if (au_di(d))
13886+ au_digen_dec(d);
13887+ else
13888+ goto cont_unlock;
392086de 13889+ if (d_count(d)) {
027c5e7a 13890+ dentry = dget_dlock(d);
4a4d8108 13891+ spin_unlock(&d->d_lock);
027c5e7a 13892+ break;
dece6358 13893+ }
1facf9fc 13894+
f6b6e03d 13895+cont_unlock:
027c5e7a 13896+ spin_unlock(&d->d_lock);
1308ab2a 13897+ }
027c5e7a 13898+ spin_unlock(&parent->d_lock);
4a4d8108 13899+ dput(parent);
1facf9fc 13900+
4a4d8108
AM
13901+ if (dentry)
13902+ di_write_lock_child(dentry);
1308ab2a 13903+
4a4d8108
AM
13904+ return dentry;
13905+}
dece6358 13906+
4a4d8108
AM
13907+static struct inode *lookup_wlock_by_ino(struct super_block *sb,
13908+ aufs_bindex_t bindex, ino_t h_ino)
13909+{
13910+ struct inode *inode;
13911+ ino_t ino;
13912+ int err;
13913+
13914+ inode = NULL;
13915+ err = au_xino_read(sb, bindex, h_ino, &ino);
13916+ if (!err && ino)
13917+ inode = ilookup(sb, ino);
13918+ if (!inode)
13919+ goto out;
13920+
13921+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 13922+ pr_warn("wrong root branch\n");
4a4d8108
AM
13923+ iput(inode);
13924+ inode = NULL;
13925+ goto out;
1308ab2a 13926+ }
13927+
4a4d8108 13928+ ii_write_lock_child(inode);
1308ab2a 13929+
4f0767ce 13930+out:
4a4d8108 13931+ return inode;
dece6358
AM
13932+}
13933+
4a4d8108 13934+static void au_hn_bh(void *_args)
1facf9fc 13935+{
4a4d8108
AM
13936+ struct au_hnotify_args *a = _args;
13937+ struct super_block *sb;
13938+ aufs_bindex_t bindex, bend, bfound;
13939+ unsigned char xino, try_iput;
1facf9fc 13940+ int err;
1308ab2a 13941+ struct inode *inode;
4a4d8108
AM
13942+ ino_t h_ino;
13943+ struct hn_job_args args;
13944+ struct dentry *dentry;
13945+ struct au_sbinfo *sbinfo;
1facf9fc 13946+
4a4d8108
AM
13947+ AuDebugOn(!_args);
13948+ AuDebugOn(!a->h_dir);
13949+ AuDebugOn(!a->dir);
13950+ AuDebugOn(!a->mask);
13951+ AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
13952+ a->mask, a->dir->i_ino, a->h_dir->i_ino,
13953+ a->h_child_inode ? a->h_child_inode->i_ino : 0);
1facf9fc 13954+
4a4d8108
AM
13955+ inode = NULL;
13956+ dentry = NULL;
13957+ /*
13958+ * do not lock a->dir->i_mutex here
13959+ * because of d_revalidate() may cause a deadlock.
13960+ */
13961+ sb = a->dir->i_sb;
13962+ AuDebugOn(!sb);
13963+ sbinfo = au_sbi(sb);
13964+ AuDebugOn(!sbinfo);
7f207e10 13965+ si_write_lock(sb, AuLock_NOPLMW);
1facf9fc 13966+
4a4d8108
AM
13967+ ii_read_lock_parent(a->dir);
13968+ bfound = -1;
13969+ bend = au_ibend(a->dir);
13970+ for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
13971+ if (au_h_iptr(a->dir, bindex) == a->h_dir) {
13972+ bfound = bindex;
13973+ break;
13974+ }
13975+ ii_read_unlock(a->dir);
13976+ if (unlikely(bfound < 0))
13977+ goto out;
1facf9fc 13978+
4a4d8108
AM
13979+ xino = !!au_opt_test(au_mntflags(sb), XINO);
13980+ h_ino = 0;
13981+ if (a->h_child_inode)
13982+ h_ino = a->h_child_inode->i_ino;
1facf9fc 13983+
4a4d8108
AM
13984+ if (a->h_child_nlen
13985+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
13986+ || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
13987+ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
13988+ a->dir);
13989+ try_iput = 0;
13990+ if (dentry)
13991+ inode = dentry->d_inode;
13992+ if (xino && !inode && h_ino
13993+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
13994+ || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
13995+ || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
13996+ inode = lookup_wlock_by_ino(sb, bfound, h_ino);
13997+ try_iput = 1;
13998+ }
1facf9fc 13999+
4a4d8108
AM
14000+ args.flags = a->flags[AuHn_CHILD];
14001+ args.dentry = dentry;
14002+ args.inode = inode;
14003+ args.h_inode = a->h_child_inode;
14004+ args.dir = a->dir;
14005+ args.h_dir = a->h_dir;
14006+ args.h_name = a->h_child_name;
14007+ args.h_nlen = a->h_child_nlen;
14008+ err = hn_job(&args);
14009+ if (dentry) {
027c5e7a 14010+ if (au_di(dentry))
4a4d8108
AM
14011+ di_write_unlock(dentry);
14012+ dput(dentry);
14013+ }
14014+ if (inode && try_iput) {
14015+ ii_write_unlock(inode);
14016+ iput(inode);
14017+ }
1facf9fc 14018+
4a4d8108
AM
14019+ ii_write_lock_parent(a->dir);
14020+ args.flags = a->flags[AuHn_PARENT];
14021+ args.dentry = NULL;
14022+ args.inode = a->dir;
14023+ args.h_inode = a->h_dir;
14024+ args.dir = NULL;
14025+ args.h_dir = NULL;
14026+ args.h_name = NULL;
14027+ args.h_nlen = 0;
14028+ err = hn_job(&args);
14029+ ii_write_unlock(a->dir);
1facf9fc 14030+
4f0767ce 14031+out:
4a4d8108
AM
14032+ iput(a->h_child_inode);
14033+ iput(a->h_dir);
14034+ iput(a->dir);
027c5e7a
AM
14035+ si_write_unlock(sb);
14036+ au_nwt_done(&sbinfo->si_nowait);
1308ab2a 14037+ kfree(a);
dece6358 14038+}
1facf9fc 14039+
4a4d8108
AM
14040+/* ---------------------------------------------------------------------- */
14041+
14042+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
14043+ struct qstr *h_child_qstr, struct inode *h_child_inode)
dece6358 14044+{
4a4d8108 14045+ int err, len;
53392da6 14046+ unsigned int flags[AuHnLast], f;
4a4d8108
AM
14047+ unsigned char isdir, isroot, wh;
14048+ struct inode *dir;
14049+ struct au_hnotify_args *args;
14050+ char *p, *h_child_name;
dece6358 14051+
1308ab2a 14052+ err = 0;
4a4d8108
AM
14053+ AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
14054+ dir = igrab(hnotify->hn_aufs_inode);
14055+ if (!dir)
14056+ goto out;
1facf9fc 14057+
4a4d8108
AM
14058+ isroot = (dir->i_ino == AUFS_ROOT_INO);
14059+ wh = 0;
14060+ h_child_name = (void *)h_child_qstr->name;
14061+ len = h_child_qstr->len;
14062+ if (h_child_name) {
14063+ if (len > AUFS_WH_PFX_LEN
14064+ && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
14065+ h_child_name += AUFS_WH_PFX_LEN;
14066+ len -= AUFS_WH_PFX_LEN;
14067+ wh = 1;
14068+ }
1facf9fc 14069+ }
dece6358 14070+
4a4d8108
AM
14071+ isdir = 0;
14072+ if (h_child_inode)
14073+ isdir = !!S_ISDIR(h_child_inode->i_mode);
14074+ flags[AuHn_PARENT] = AuHnJob_ISDIR;
14075+ flags[AuHn_CHILD] = 0;
14076+ if (isdir)
14077+ flags[AuHn_CHILD] = AuHnJob_ISDIR;
14078+ au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
14079+ au_fset_hnjob(flags[AuHn_CHILD], GEN);
14080+ switch (mask & FS_EVENTS_POSS_ON_CHILD) {
14081+ case FS_MOVED_FROM:
14082+ case FS_MOVED_TO:
14083+ au_fset_hnjob(flags[AuHn_CHILD], XINO0);
14084+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
14085+ /*FALLTHROUGH*/
14086+ case FS_CREATE:
14087+ AuDebugOn(!h_child_name || !h_child_inode);
14088+ break;
1facf9fc 14089+
4a4d8108
AM
14090+ case FS_DELETE:
14091+ /*
14092+ * aufs never be able to get this child inode.
14093+ * revalidation should be in d_revalidate()
14094+ * by checking i_nlink, i_generation or d_unhashed().
14095+ */
14096+ AuDebugOn(!h_child_name);
14097+ au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
14098+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
14099+ break;
dece6358 14100+
4a4d8108
AM
14101+ default:
14102+ AuDebugOn(1);
14103+ }
1308ab2a 14104+
4a4d8108
AM
14105+ if (wh)
14106+ h_child_inode = NULL;
1308ab2a 14107+
4a4d8108
AM
14108+ err = -ENOMEM;
14109+ /* iput() and kfree() will be called in au_hnotify() */
4a4d8108 14110+ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
4a4d8108
AM
14111+ if (unlikely(!args)) {
14112+ AuErr1("no memory\n");
14113+ iput(dir);
14114+ goto out;
14115+ }
14116+ args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
14117+ args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
14118+ args->mask = mask;
14119+ args->dir = dir;
14120+ args->h_dir = igrab(h_dir);
14121+ if (h_child_inode)
14122+ h_child_inode = igrab(h_child_inode); /* can be NULL */
14123+ args->h_child_inode = h_child_inode;
14124+ args->h_child_nlen = len;
14125+ if (len) {
14126+ p = (void *)args;
14127+ p += sizeof(*args);
14128+ memcpy(p, h_child_name, len);
14129+ p[len] = 0;
1308ab2a 14130+ }
1308ab2a 14131+
53392da6
AM
14132+ f = 0;
14133+ if (!dir->i_nlink)
14134+ f = AuWkq_NEST;
14135+ err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
4a4d8108
AM
14136+ if (unlikely(err)) {
14137+ pr_err("wkq %d\n", err);
14138+ iput(args->h_child_inode);
14139+ iput(args->h_dir);
14140+ iput(args->dir);
14141+ kfree(args);
1facf9fc 14142+ }
1facf9fc 14143+
4a4d8108 14144+out:
1facf9fc 14145+ return err;
14146+}
14147+
027c5e7a
AM
14148+/* ---------------------------------------------------------------------- */
14149+
14150+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
14151+{
14152+ int err;
14153+
14154+ AuDebugOn(!(udba & AuOptMask_UDBA));
14155+
14156+ err = 0;
14157+ if (au_hnotify_op.reset_br)
14158+ err = au_hnotify_op.reset_br(udba, br, perm);
14159+
14160+ return err;
14161+}
14162+
14163+int au_hnotify_init_br(struct au_branch *br, int perm)
14164+{
14165+ int err;
14166+
14167+ err = 0;
14168+ if (au_hnotify_op.init_br)
14169+ err = au_hnotify_op.init_br(br, perm);
14170+
14171+ return err;
14172+}
14173+
14174+void au_hnotify_fin_br(struct au_branch *br)
14175+{
14176+ if (au_hnotify_op.fin_br)
14177+ au_hnotify_op.fin_br(br);
14178+}
14179+
4a4d8108
AM
14180+static void au_hn_destroy_cache(void)
14181+{
14182+ kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]);
14183+ au_cachep[AuCache_HNOTIFY] = NULL;
14184+}
1308ab2a 14185+
4a4d8108 14186+int __init au_hnotify_init(void)
1facf9fc 14187+{
1308ab2a 14188+ int err;
1308ab2a 14189+
4a4d8108
AM
14190+ err = -ENOMEM;
14191+ au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify);
14192+ if (au_cachep[AuCache_HNOTIFY]) {
027c5e7a
AM
14193+ err = 0;
14194+ if (au_hnotify_op.init)
14195+ err = au_hnotify_op.init();
4a4d8108
AM
14196+ if (unlikely(err))
14197+ au_hn_destroy_cache();
1308ab2a 14198+ }
1308ab2a 14199+ AuTraceErr(err);
4a4d8108 14200+ return err;
1308ab2a 14201+}
14202+
4a4d8108 14203+void au_hnotify_fin(void)
1308ab2a 14204+{
027c5e7a
AM
14205+ if (au_hnotify_op.fin)
14206+ au_hnotify_op.fin();
4a4d8108
AM
14207+ /* cf. au_cache_fin() */
14208+ if (au_cachep[AuCache_HNOTIFY])
14209+ au_hn_destroy_cache();
dece6358 14210+}
7f207e10
AM
14211diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
14212--- /usr/share/empty/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
14213+++ linux/fs/aufs/iinfo.c 2014-01-20 20:16:14.739463504 +0100
14214@@ -0,0 +1,275 @@
dece6358 14215+/*
523b37e3 14216+ * Copyright (C) 2005-2014 Junjiro R. Okajima
dece6358
AM
14217+ *
14218+ * This program, aufs is free software; you can redistribute it and/or modify
14219+ * it under the terms of the GNU General Public License as published by
14220+ * the Free Software Foundation; either version 2 of the License, or
14221+ * (at your option) any later version.
14222+ *
14223+ * This program is distributed in the hope that it will be useful,
14224+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14225+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14226+ * GNU General Public License for more details.
14227+ *
14228+ * You should have received a copy of the GNU General Public License
523b37e3 14229+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 14230+ */
1facf9fc 14231+
dece6358 14232+/*
4a4d8108 14233+ * inode private data
dece6358 14234+ */
1facf9fc 14235+
1308ab2a 14236+#include "aufs.h"
1facf9fc 14237+
4a4d8108 14238+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 14239+{
4a4d8108 14240+ struct inode *h_inode;
1facf9fc 14241+
4a4d8108 14242+ IiMustAnyLock(inode);
1facf9fc 14243+
4a4d8108
AM
14244+ h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode;
14245+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
14246+ return h_inode;
14247+}
1facf9fc 14248+
4a4d8108
AM
14249+/* todo: hard/soft set? */
14250+void au_hiput(struct au_hinode *hinode)
14251+{
14252+ au_hn_free(hinode);
14253+ dput(hinode->hi_whdentry);
14254+ iput(hinode->hi_inode);
14255+}
1facf9fc 14256+
4a4d8108
AM
14257+unsigned int au_hi_flags(struct inode *inode, int isdir)
14258+{
14259+ unsigned int flags;
14260+ const unsigned int mnt_flags = au_mntflags(inode->i_sb);
1facf9fc 14261+
4a4d8108
AM
14262+ flags = 0;
14263+ if (au_opt_test(mnt_flags, XINO))
14264+ au_fset_hi(flags, XINO);
14265+ if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY))
14266+ au_fset_hi(flags, HNOTIFY);
14267+ return flags;
1facf9fc 14268+}
14269+
4a4d8108
AM
14270+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
14271+ struct inode *h_inode, unsigned int flags)
1308ab2a 14272+{
4a4d8108
AM
14273+ struct au_hinode *hinode;
14274+ struct inode *hi;
14275+ struct au_iinfo *iinfo = au_ii(inode);
1facf9fc 14276+
4a4d8108 14277+ IiMustWriteLock(inode);
dece6358 14278+
4a4d8108
AM
14279+ hinode = iinfo->ii_hinode + bindex;
14280+ hi = hinode->hi_inode;
14281+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
14282+
14283+ if (hi)
14284+ au_hiput(hinode);
14285+ hinode->hi_inode = h_inode;
14286+ if (h_inode) {
14287+ int err;
14288+ struct super_block *sb = inode->i_sb;
14289+ struct au_branch *br;
14290+
027c5e7a
AM
14291+ AuDebugOn(inode->i_mode
14292+ && (h_inode->i_mode & S_IFMT)
14293+ != (inode->i_mode & S_IFMT));
4a4d8108
AM
14294+ if (bindex == iinfo->ii_bstart)
14295+ au_cpup_igen(inode, h_inode);
14296+ br = au_sbr(sb, bindex);
14297+ hinode->hi_id = br->br_id;
14298+ if (au_ftest_hi(flags, XINO)) {
14299+ err = au_xino_write(sb, bindex, h_inode->i_ino,
14300+ inode->i_ino);
14301+ if (unlikely(err))
14302+ AuIOErr1("failed au_xino_write() %d\n", err);
14303+ }
14304+
14305+ if (au_ftest_hi(flags, HNOTIFY)
14306+ && au_br_hnotifyable(br->br_perm)) {
027c5e7a 14307+ err = au_hn_alloc(hinode, inode);
4a4d8108
AM
14308+ if (unlikely(err))
14309+ AuIOErr1("au_hn_alloc() %d\n", err);
1308ab2a 14310+ }
14311+ }
4a4d8108 14312+}
dece6358 14313+
4a4d8108
AM
14314+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
14315+ struct dentry *h_wh)
14316+{
14317+ struct au_hinode *hinode;
dece6358 14318+
4a4d8108
AM
14319+ IiMustWriteLock(inode);
14320+
14321+ hinode = au_ii(inode)->ii_hinode + bindex;
14322+ AuDebugOn(hinode->hi_whdentry);
14323+ hinode->hi_whdentry = h_wh;
1facf9fc 14324+}
14325+
537831f9 14326+void au_update_iigen(struct inode *inode, int half)
1308ab2a 14327+{
537831f9
AM
14328+ struct au_iinfo *iinfo;
14329+ struct au_iigen *iigen;
14330+ unsigned int sigen;
14331+
14332+ sigen = au_sigen(inode->i_sb);
14333+ iinfo = au_ii(inode);
14334+ iigen = &iinfo->ii_generation;
14335+ spin_lock(&iinfo->ii_genspin);
14336+ iigen->ig_generation = sigen;
14337+ if (half)
14338+ au_ig_fset(iigen->ig_flags, HALF_REFRESHED);
14339+ else
14340+ au_ig_fclr(iigen->ig_flags, HALF_REFRESHED);
14341+ spin_unlock(&iinfo->ii_genspin);
4a4d8108 14342+}
1facf9fc 14343+
4a4d8108
AM
14344+/* it may be called at remount time, too */
14345+void au_update_ibrange(struct inode *inode, int do_put_zero)
14346+{
14347+ struct au_iinfo *iinfo;
027c5e7a 14348+ aufs_bindex_t bindex, bend;
1facf9fc 14349+
4a4d8108 14350+ iinfo = au_ii(inode);
027c5e7a 14351+ if (!iinfo)
4a4d8108 14352+ return;
1facf9fc 14353+
4a4d8108 14354+ IiMustWriteLock(inode);
1facf9fc 14355+
027c5e7a 14356+ if (do_put_zero && iinfo->ii_bstart >= 0) {
4a4d8108
AM
14357+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
14358+ bindex++) {
14359+ struct inode *h_i;
1facf9fc 14360+
4a4d8108 14361+ h_i = iinfo->ii_hinode[0 + bindex].hi_inode;
027c5e7a
AM
14362+ if (h_i && !h_i->i_nlink)
14363+ au_set_h_iptr(inode, bindex, NULL, 0);
14364+ }
4a4d8108
AM
14365+ }
14366+
027c5e7a
AM
14367+ iinfo->ii_bstart = -1;
14368+ iinfo->ii_bend = -1;
14369+ bend = au_sbend(inode->i_sb);
14370+ for (bindex = 0; bindex <= bend; bindex++)
14371+ if (iinfo->ii_hinode[0 + bindex].hi_inode) {
14372+ iinfo->ii_bstart = bindex;
4a4d8108 14373+ break;
027c5e7a
AM
14374+ }
14375+ if (iinfo->ii_bstart >= 0)
14376+ for (bindex = bend; bindex >= iinfo->ii_bstart; bindex--)
14377+ if (iinfo->ii_hinode[0 + bindex].hi_inode) {
14378+ iinfo->ii_bend = bindex;
14379+ break;
14380+ }
14381+ AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend);
1308ab2a 14382+}
1facf9fc 14383+
dece6358 14384+/* ---------------------------------------------------------------------- */
1facf9fc 14385+
4a4d8108 14386+void au_icntnr_init_once(void *_c)
dece6358 14387+{
4a4d8108
AM
14388+ struct au_icntnr *c = _c;
14389+ struct au_iinfo *iinfo = &c->iinfo;
e49829fe 14390+ static struct lock_class_key aufs_ii;
1facf9fc 14391+
537831f9 14392+ spin_lock_init(&iinfo->ii_genspin);
4a4d8108 14393+ au_rw_init(&iinfo->ii_rwsem);
e49829fe 14394+ au_rw_class(&iinfo->ii_rwsem, &aufs_ii);
4a4d8108
AM
14395+ inode_init_once(&c->vfs_inode);
14396+}
1facf9fc 14397+
4a4d8108
AM
14398+int au_iinfo_init(struct inode *inode)
14399+{
14400+ struct au_iinfo *iinfo;
14401+ struct super_block *sb;
14402+ int nbr, i;
1facf9fc 14403+
4a4d8108
AM
14404+ sb = inode->i_sb;
14405+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
14406+ nbr = au_sbend(sb) + 1;
14407+ if (unlikely(nbr <= 0))
14408+ nbr = 1;
14409+ iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
14410+ if (iinfo->ii_hinode) {
7f207e10 14411+ au_ninodes_inc(sb);
4a4d8108
AM
14412+ for (i = 0; i < nbr; i++)
14413+ iinfo->ii_hinode[i].hi_id = -1;
1facf9fc 14414+
537831f9 14415+ iinfo->ii_generation.ig_generation = au_sigen(sb);
4a4d8108
AM
14416+ iinfo->ii_bstart = -1;
14417+ iinfo->ii_bend = -1;
14418+ iinfo->ii_vdir = NULL;
14419+ return 0;
1308ab2a 14420+ }
4a4d8108
AM
14421+ return -ENOMEM;
14422+}
1facf9fc 14423+
4a4d8108
AM
14424+int au_ii_realloc(struct au_iinfo *iinfo, int nbr)
14425+{
14426+ int err, sz;
14427+ struct au_hinode *hip;
1facf9fc 14428+
4a4d8108
AM
14429+ AuRwMustWriteLock(&iinfo->ii_rwsem);
14430+
14431+ err = -ENOMEM;
14432+ sz = sizeof(*hip) * (iinfo->ii_bend + 1);
14433+ if (!sz)
14434+ sz = sizeof(*hip);
14435+ hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS);
14436+ if (hip) {
14437+ iinfo->ii_hinode = hip;
14438+ err = 0;
1308ab2a 14439+ }
4a4d8108 14440+
1308ab2a 14441+ return err;
1facf9fc 14442+}
14443+
4a4d8108 14444+void au_iinfo_fin(struct inode *inode)
1facf9fc 14445+{
4a4d8108
AM
14446+ struct au_iinfo *iinfo;
14447+ struct au_hinode *hi;
14448+ struct super_block *sb;
b752ccd1
AM
14449+ aufs_bindex_t bindex, bend;
14450+ const unsigned char unlinked = !inode->i_nlink;
1308ab2a 14451+
4a4d8108
AM
14452+ iinfo = au_ii(inode);
14453+ /* bad_inode case */
14454+ if (!iinfo)
14455+ return;
1308ab2a 14456+
b752ccd1 14457+ sb = inode->i_sb;
7f207e10 14458+ au_ninodes_dec(sb);
b752ccd1
AM
14459+ if (si_pid_test(sb))
14460+ au_xino_delete_inode(inode, unlinked);
14461+ else {
14462+ /*
14463+ * it is safe to hide the dependency between sbinfo and
14464+ * sb->s_umount.
14465+ */
14466+ lockdep_off();
14467+ si_noflush_read_lock(sb);
14468+ au_xino_delete_inode(inode, unlinked);
14469+ si_read_unlock(sb);
14470+ lockdep_on();
14471+ }
14472+
4a4d8108
AM
14473+ if (iinfo->ii_vdir)
14474+ au_vdir_free(iinfo->ii_vdir);
1308ab2a 14475+
b752ccd1
AM
14476+ bindex = iinfo->ii_bstart;
14477+ if (bindex >= 0) {
14478+ hi = iinfo->ii_hinode + bindex;
4a4d8108 14479+ bend = iinfo->ii_bend;
b752ccd1
AM
14480+ while (bindex++ <= bend) {
14481+ if (hi->hi_inode)
4a4d8108 14482+ au_hiput(hi);
4a4d8108
AM
14483+ hi++;
14484+ }
14485+ }
4a4d8108 14486+ kfree(iinfo->ii_hinode);
027c5e7a 14487+ iinfo->ii_hinode = NULL;
4a4d8108 14488+ AuRwDestroy(&iinfo->ii_rwsem);
dece6358 14489+}
7f207e10
AM
14490diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
14491--- /usr/share/empty/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
14492+++ linux/fs/aufs/inode.c 2014-01-20 20:16:14.739463504 +0100
14493@@ -0,0 +1,491 @@
4a4d8108 14494+/*
523b37e3 14495+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
14496+ *
14497+ * This program, aufs is free software; you can redistribute it and/or modify
14498+ * it under the terms of the GNU General Public License as published by
14499+ * the Free Software Foundation; either version 2 of the License, or
14500+ * (at your option) any later version.
14501+ *
14502+ * This program is distributed in the hope that it will be useful,
14503+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14504+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14505+ * GNU General Public License for more details.
14506+ *
14507+ * You should have received a copy of the GNU General Public License
523b37e3 14508+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 14509+ */
1facf9fc 14510+
4a4d8108
AM
14511+/*
14512+ * inode functions
14513+ */
1facf9fc 14514+
4a4d8108 14515+#include "aufs.h"
1308ab2a 14516+
4a4d8108
AM
14517+struct inode *au_igrab(struct inode *inode)
14518+{
14519+ if (inode) {
14520+ AuDebugOn(!atomic_read(&inode->i_count));
027c5e7a 14521+ ihold(inode);
1facf9fc 14522+ }
4a4d8108
AM
14523+ return inode;
14524+}
1facf9fc 14525+
4a4d8108
AM
14526+static void au_refresh_hinode_attr(struct inode *inode, int do_version)
14527+{
14528+ au_cpup_attr_all(inode, /*force*/0);
537831f9 14529+ au_update_iigen(inode, /*half*/1);
4a4d8108
AM
14530+ if (do_version)
14531+ inode->i_version++;
dece6358 14532+}
1facf9fc 14533+
027c5e7a 14534+static int au_ii_refresh(struct inode *inode, int *update)
dece6358 14535+{
4a4d8108 14536+ int err, e;
027c5e7a 14537+ umode_t type;
4a4d8108 14538+ aufs_bindex_t bindex, new_bindex;
1308ab2a 14539+ struct super_block *sb;
4a4d8108 14540+ struct au_iinfo *iinfo;
027c5e7a 14541+ struct au_hinode *p, *q, tmp;
1facf9fc 14542+
4a4d8108 14543+ IiMustWriteLock(inode);
1facf9fc 14544+
027c5e7a 14545+ *update = 0;
4a4d8108 14546+ sb = inode->i_sb;
027c5e7a 14547+ type = inode->i_mode & S_IFMT;
4a4d8108
AM
14548+ iinfo = au_ii(inode);
14549+ err = au_ii_realloc(iinfo, au_sbend(sb) + 1);
14550+ if (unlikely(err))
1308ab2a 14551+ goto out;
1facf9fc 14552+
027c5e7a 14553+ AuDebugOn(iinfo->ii_bstart < 0);
4a4d8108 14554+ p = iinfo->ii_hinode + iinfo->ii_bstart;
4a4d8108
AM
14555+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
14556+ bindex++, p++) {
14557+ if (!p->hi_inode)
14558+ continue;
1facf9fc 14559+
027c5e7a 14560+ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT));
4a4d8108
AM
14561+ new_bindex = au_br_index(sb, p->hi_id);
14562+ if (new_bindex == bindex)
14563+ continue;
1facf9fc 14564+
4a4d8108 14565+ if (new_bindex < 0) {
027c5e7a 14566+ *update = 1;
4a4d8108
AM
14567+ au_hiput(p);
14568+ p->hi_inode = NULL;
14569+ continue;
1308ab2a 14570+ }
4a4d8108
AM
14571+
14572+ if (new_bindex < iinfo->ii_bstart)
14573+ iinfo->ii_bstart = new_bindex;
14574+ if (iinfo->ii_bend < new_bindex)
14575+ iinfo->ii_bend = new_bindex;
14576+ /* swap two lower inode, and loop again */
14577+ q = iinfo->ii_hinode + new_bindex;
14578+ tmp = *q;
14579+ *q = *p;
14580+ *p = tmp;
14581+ if (tmp.hi_inode) {
14582+ bindex--;
14583+ p--;
1308ab2a 14584+ }
14585+ }
4a4d8108
AM
14586+ au_update_ibrange(inode, /*do_put_zero*/0);
14587+ e = au_dy_irefresh(inode);
14588+ if (unlikely(e && !err))
14589+ err = e;
1facf9fc 14590+
4f0767ce 14591+out:
027c5e7a
AM
14592+ AuTraceErr(err);
14593+ return err;
14594+}
14595+
14596+int au_refresh_hinode_self(struct inode *inode)
14597+{
14598+ int err, update;
14599+
14600+ err = au_ii_refresh(inode, &update);
14601+ if (!err)
14602+ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
14603+
14604+ AuTraceErr(err);
4a4d8108
AM
14605+ return err;
14606+}
1facf9fc 14607+
4a4d8108
AM
14608+int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
14609+{
027c5e7a 14610+ int err, e, update;
4a4d8108 14611+ unsigned int flags;
027c5e7a 14612+ umode_t mode;
4a4d8108 14613+ aufs_bindex_t bindex, bend;
027c5e7a 14614+ unsigned char isdir;
4a4d8108
AM
14615+ struct au_hinode *p;
14616+ struct au_iinfo *iinfo;
1facf9fc 14617+
027c5e7a 14618+ err = au_ii_refresh(inode, &update);
4a4d8108
AM
14619+ if (unlikely(err))
14620+ goto out;
14621+
14622+ update = 0;
14623+ iinfo = au_ii(inode);
14624+ p = iinfo->ii_hinode + iinfo->ii_bstart;
027c5e7a
AM
14625+ mode = (inode->i_mode & S_IFMT);
14626+ isdir = S_ISDIR(mode);
4a4d8108
AM
14627+ flags = au_hi_flags(inode, isdir);
14628+ bend = au_dbend(dentry);
14629+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
14630+ struct inode *h_i;
14631+ struct dentry *h_d;
14632+
14633+ h_d = au_h_dptr(dentry, bindex);
14634+ if (!h_d || !h_d->d_inode)
14635+ continue;
14636+
027c5e7a 14637+ AuDebugOn(mode != (h_d->d_inode->i_mode & S_IFMT));
4a4d8108
AM
14638+ if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) {
14639+ h_i = au_h_iptr(inode, bindex);
14640+ if (h_i) {
14641+ if (h_i == h_d->d_inode)
14642+ continue;
14643+ err = -EIO;
14644+ break;
14645+ }
14646+ }
14647+ if (bindex < iinfo->ii_bstart)
14648+ iinfo->ii_bstart = bindex;
14649+ if (iinfo->ii_bend < bindex)
14650+ iinfo->ii_bend = bindex;
14651+ au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags);
14652+ update = 1;
1308ab2a 14653+ }
4a4d8108
AM
14654+ au_update_ibrange(inode, /*do_put_zero*/0);
14655+ e = au_dy_irefresh(inode);
14656+ if (unlikely(e && !err))
14657+ err = e;
027c5e7a
AM
14658+ if (!err)
14659+ au_refresh_hinode_attr(inode, update && isdir);
4a4d8108 14660+
4f0767ce 14661+out:
4a4d8108 14662+ AuTraceErr(err);
1308ab2a 14663+ return err;
dece6358
AM
14664+}
14665+
4a4d8108 14666+static int set_inode(struct inode *inode, struct dentry *dentry)
dece6358 14667+{
4a4d8108
AM
14668+ int err;
14669+ unsigned int flags;
14670+ umode_t mode;
14671+ aufs_bindex_t bindex, bstart, btail;
14672+ unsigned char isdir;
14673+ struct dentry *h_dentry;
14674+ struct inode *h_inode;
14675+ struct au_iinfo *iinfo;
dece6358 14676+
4a4d8108 14677+ IiMustWriteLock(inode);
dece6358 14678+
4a4d8108
AM
14679+ err = 0;
14680+ isdir = 0;
14681+ bstart = au_dbstart(dentry);
14682+ h_inode = au_h_dptr(dentry, bstart)->d_inode;
14683+ mode = h_inode->i_mode;
14684+ switch (mode & S_IFMT) {
14685+ case S_IFREG:
14686+ btail = au_dbtail(dentry);
14687+ inode->i_op = &aufs_iop;
14688+ inode->i_fop = &aufs_file_fop;
14689+ err = au_dy_iaop(inode, bstart, h_inode);
14690+ if (unlikely(err))
14691+ goto out;
14692+ break;
14693+ case S_IFDIR:
14694+ isdir = 1;
14695+ btail = au_dbtaildir(dentry);
14696+ inode->i_op = &aufs_dir_iop;
14697+ inode->i_fop = &aufs_dir_fop;
14698+ break;
14699+ case S_IFLNK:
14700+ btail = au_dbtail(dentry);
14701+ inode->i_op = &aufs_symlink_iop;
14702+ break;
14703+ case S_IFBLK:
14704+ case S_IFCHR:
14705+ case S_IFIFO:
14706+ case S_IFSOCK:
14707+ btail = au_dbtail(dentry);
14708+ inode->i_op = &aufs_iop;
14709+ au_init_special_fop(inode, mode, h_inode->i_rdev);
14710+ break;
14711+ default:
14712+ AuIOErr("Unknown file type 0%o\n", mode);
14713+ err = -EIO;
1308ab2a 14714+ goto out;
4a4d8108 14715+ }
dece6358 14716+
4a4d8108
AM
14717+ /* do not set hnotify for whiteouted dirs (SHWH mode) */
14718+ flags = au_hi_flags(inode, isdir);
14719+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
14720+ && au_ftest_hi(flags, HNOTIFY)
14721+ && dentry->d_name.len > AUFS_WH_PFX_LEN
14722+ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
14723+ au_fclr_hi(flags, HNOTIFY);
14724+ iinfo = au_ii(inode);
14725+ iinfo->ii_bstart = bstart;
14726+ iinfo->ii_bend = btail;
14727+ for (bindex = bstart; bindex <= btail; bindex++) {
14728+ h_dentry = au_h_dptr(dentry, bindex);
14729+ if (h_dentry)
14730+ au_set_h_iptr(inode, bindex,
14731+ au_igrab(h_dentry->d_inode), flags);
14732+ }
14733+ au_cpup_attr_all(inode, /*force*/1);
dece6358 14734+
4f0767ce 14735+out:
4a4d8108
AM
14736+ return err;
14737+}
dece6358 14738+
027c5e7a
AM
14739+/*
14740+ * successful returns with iinfo write_locked
14741+ * minus: errno
14742+ * zero: success, matched
14743+ * plus: no error, but unmatched
14744+ */
14745+static int reval_inode(struct inode *inode, struct dentry *dentry)
4a4d8108
AM
14746+{
14747+ int err;
537831f9
AM
14748+ unsigned int gen;
14749+ struct au_iigen iigen;
4a4d8108
AM
14750+ aufs_bindex_t bindex, bend;
14751+ struct inode *h_inode, *h_dinode;
dece6358 14752+
4a4d8108
AM
14753+ /*
14754+ * before this function, if aufs got any iinfo lock, it must be only
14755+ * one, the parent dir.
14756+ * it can happen by UDBA and the obsoleted inode number.
14757+ */
14758+ err = -EIO;
14759+ if (unlikely(inode->i_ino == parent_ino(dentry)))
14760+ goto out;
14761+
027c5e7a 14762+ err = 1;
4a4d8108
AM
14763+ ii_write_lock_new_child(inode);
14764+ h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode;
14765+ bend = au_ibend(inode);
14766+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
14767+ h_inode = au_h_iptr(inode, bindex);
537831f9
AM
14768+ if (!h_inode || h_inode != h_dinode)
14769+ continue;
14770+
14771+ err = 0;
14772+ gen = au_iigen(inode, &iigen);
14773+ if (gen == au_digen(dentry)
14774+ && !au_ig_ftest(iigen.ig_flags, HALF_REFRESHED))
4a4d8108 14775+ break;
537831f9
AM
14776+
14777+ /* fully refresh inode using dentry */
14778+ err = au_refresh_hinode(inode, dentry);
14779+ if (!err)
14780+ au_update_iigen(inode, /*half*/0);
14781+ break;
1facf9fc 14782+ }
dece6358 14783+
4a4d8108
AM
14784+ if (unlikely(err))
14785+ ii_write_unlock(inode);
4f0767ce 14786+out:
1facf9fc 14787+ return err;
14788+}
1facf9fc 14789+
4a4d8108
AM
14790+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
14791+ unsigned int d_type, ino_t *ino)
1facf9fc 14792+{
4a4d8108
AM
14793+ int err;
14794+ struct mutex *mtx;
1facf9fc 14795+
b752ccd1 14796+ /* prevent hardlinked inode number from race condition */
4a4d8108 14797+ mtx = NULL;
b752ccd1 14798+ if (d_type != DT_DIR) {
4a4d8108
AM
14799+ mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx;
14800+ mutex_lock(mtx);
14801+ }
14802+ err = au_xino_read(sb, bindex, h_ino, ino);
14803+ if (unlikely(err))
14804+ goto out;
1308ab2a 14805+
4a4d8108
AM
14806+ if (!*ino) {
14807+ err = -EIO;
14808+ *ino = au_xino_new_ino(sb);
14809+ if (unlikely(!*ino))
1facf9fc 14810+ goto out;
4a4d8108
AM
14811+ err = au_xino_write(sb, bindex, h_ino, *ino);
14812+ if (unlikely(err))
1308ab2a 14813+ goto out;
1308ab2a 14814+ }
1facf9fc 14815+
4f0767ce 14816+out:
b752ccd1 14817+ if (mtx)
4a4d8108 14818+ mutex_unlock(mtx);
1facf9fc 14819+ return err;
14820+}
14821+
4a4d8108
AM
14822+/* successful returns with iinfo write_locked */
14823+/* todo: return with unlocked? */
14824+struct inode *au_new_inode(struct dentry *dentry, int must_new)
1facf9fc 14825+{
b752ccd1 14826+ struct inode *inode, *h_inode;
4a4d8108
AM
14827+ struct dentry *h_dentry;
14828+ struct super_block *sb;
b752ccd1 14829+ struct mutex *mtx;
4a4d8108 14830+ ino_t h_ino, ino;
1716fcea 14831+ int err;
4a4d8108 14832+ aufs_bindex_t bstart;
1facf9fc 14833+
4a4d8108
AM
14834+ sb = dentry->d_sb;
14835+ bstart = au_dbstart(dentry);
14836+ h_dentry = au_h_dptr(dentry, bstart);
b752ccd1
AM
14837+ h_inode = h_dentry->d_inode;
14838+ h_ino = h_inode->i_ino;
14839+
14840+ /*
14841+ * stop 'race'-ing between hardlinks under different
14842+ * parents.
14843+ */
14844+ mtx = NULL;
14845+ if (!S_ISDIR(h_inode->i_mode))
14846+ mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;
14847+
4f0767ce 14848+new_ino:
b752ccd1
AM
14849+ if (mtx)
14850+ mutex_lock(mtx);
4a4d8108
AM
14851+ err = au_xino_read(sb, bstart, h_ino, &ino);
14852+ inode = ERR_PTR(err);
14853+ if (unlikely(err))
14854+ goto out;
b752ccd1 14855+
4a4d8108
AM
14856+ if (!ino) {
14857+ ino = au_xino_new_ino(sb);
14858+ if (unlikely(!ino)) {
14859+ inode = ERR_PTR(-EIO);
dece6358
AM
14860+ goto out;
14861+ }
14862+ }
1facf9fc 14863+
4a4d8108
AM
14864+ AuDbg("i%lu\n", (unsigned long)ino);
14865+ inode = au_iget_locked(sb, ino);
14866+ err = PTR_ERR(inode);
14867+ if (IS_ERR(inode))
1facf9fc 14868+ goto out;
1facf9fc 14869+
4a4d8108
AM
14870+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
14871+ if (inode->i_state & I_NEW) {
1716fcea
AM
14872+ /* verbose coding for lock class name */
14873+ if (unlikely(S_ISLNK(h_inode->i_mode)))
14874+ au_rw_class(&au_ii(inode)->ii_rwsem,
14875+ au_lc_key + AuLcSymlink_IIINFO);
14876+ else if (unlikely(S_ISDIR(h_inode->i_mode)))
14877+ au_rw_class(&au_ii(inode)->ii_rwsem,
14878+ au_lc_key + AuLcDir_IIINFO);
14879+ else /* likely */
14880+ au_rw_class(&au_ii(inode)->ii_rwsem,
14881+ au_lc_key + AuLcNonDir_IIINFO);
2dfbb274 14882+
4a4d8108
AM
14883+ ii_write_lock_new_child(inode);
14884+ err = set_inode(inode, dentry);
14885+ if (!err) {
14886+ unlock_new_inode(inode);
14887+ goto out; /* success */
14888+ }
1308ab2a 14889+
027c5e7a
AM
14890+ /*
14891+ * iget_failed() calls iput(), but we need to call
14892+ * ii_write_unlock() after iget_failed(). so dirty hack for
14893+ * i_count.
14894+ */
14895+ atomic_inc(&inode->i_count);
4a4d8108 14896+ iget_failed(inode);
027c5e7a
AM
14897+ ii_write_unlock(inode);
14898+ au_xino_write(sb, bstart, h_ino, /*ino*/0);
14899+ /* ignore this error */
14900+ goto out_iput;
14901+ } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) {
b752ccd1
AM
14902+ /*
14903+ * horrible race condition between lookup, readdir and copyup
14904+ * (or something).
14905+ */
14906+ if (mtx)
14907+ mutex_unlock(mtx);
027c5e7a
AM
14908+ err = reval_inode(inode, dentry);
14909+ if (unlikely(err < 0)) {
14910+ mtx = NULL;
14911+ goto out_iput;
14912+ }
14913+
b752ccd1
AM
14914+ if (!err) {
14915+ mtx = NULL;
4a4d8108 14916+ goto out; /* success */
b752ccd1
AM
14917+ } else if (mtx)
14918+ mutex_lock(mtx);
4a4d8108
AM
14919+ }
14920+
14921+ if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode)))
14922+ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
523b37e3
AM
14923+ " b%d, %s, %pd, hi%lu, i%lu.\n",
14924+ bstart, au_sbtype(h_dentry->d_sb), dentry,
4a4d8108
AM
14925+ (unsigned long)h_ino, (unsigned long)ino);
14926+ ino = 0;
14927+ err = au_xino_write(sb, bstart, h_ino, /*ino*/0);
14928+ if (!err) {
14929+ iput(inode);
b752ccd1
AM
14930+ if (mtx)
14931+ mutex_unlock(mtx);
4a4d8108
AM
14932+ goto new_ino;
14933+ }
1308ab2a 14934+
4f0767ce 14935+out_iput:
4a4d8108 14936+ iput(inode);
4a4d8108 14937+ inode = ERR_PTR(err);
4f0767ce 14938+out:
b752ccd1
AM
14939+ if (mtx)
14940+ mutex_unlock(mtx);
4a4d8108 14941+ return inode;
1facf9fc 14942+}
14943+
4a4d8108 14944+/* ---------------------------------------------------------------------- */
1facf9fc 14945+
4a4d8108
AM
14946+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
14947+ struct inode *inode)
14948+{
14949+ int err;
1facf9fc 14950+
4a4d8108 14951+ err = au_br_rdonly(au_sbr(sb, bindex));
1facf9fc 14952+
4a4d8108
AM
14953+ /* pseudo-link after flushed may happen out of bounds */
14954+ if (!err
14955+ && inode
14956+ && au_ibstart(inode) <= bindex
14957+ && bindex <= au_ibend(inode)) {
14958+ /*
14959+ * permission check is unnecessary since vfsub routine
14960+ * will be called later
14961+ */
14962+ struct inode *hi = au_h_iptr(inode, bindex);
14963+ if (hi)
14964+ err = IS_IMMUTABLE(hi) ? -EROFS : 0;
1facf9fc 14965+ }
14966+
4a4d8108
AM
14967+ return err;
14968+}
dece6358 14969+
4a4d8108
AM
14970+int au_test_h_perm(struct inode *h_inode, int mask)
14971+{
2dfbb274 14972+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
4a4d8108
AM
14973+ return 0;
14974+ return inode_permission(h_inode, mask);
14975+}
1facf9fc 14976+
4a4d8108
AM
14977+int au_test_h_perm_sio(struct inode *h_inode, int mask)
14978+{
14979+ if (au_test_nfs(h_inode->i_sb)
14980+ && (mask & MAY_WRITE)
14981+ && S_ISDIR(h_inode->i_mode))
14982+ mask |= MAY_READ; /* force permission check */
14983+ return au_test_h_perm(h_inode, mask);
1facf9fc 14984+}
7f207e10
AM
14985diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
14986--- /usr/share/empty/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
14987+++ linux/fs/aufs/inode.h 2014-01-20 20:16:14.739463504 +0100
14988@@ -0,0 +1,599 @@
4a4d8108 14989+/*
523b37e3 14990+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
14991+ *
14992+ * This program, aufs is free software; you can redistribute it and/or modify
14993+ * it under the terms of the GNU General Public License as published by
14994+ * the Free Software Foundation; either version 2 of the License, or
14995+ * (at your option) any later version.
14996+ *
14997+ * This program is distributed in the hope that it will be useful,
14998+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14999+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15000+ * GNU General Public License for more details.
15001+ *
15002+ * You should have received a copy of the GNU General Public License
523b37e3 15003+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 15004+ */
1facf9fc 15005+
1308ab2a 15006+/*
4a4d8108 15007+ * inode operations
1308ab2a 15008+ */
dece6358 15009+
4a4d8108
AM
15010+#ifndef __AUFS_INODE_H__
15011+#define __AUFS_INODE_H__
dece6358 15012+
4a4d8108 15013+#ifdef __KERNEL__
1308ab2a 15014+
4a4d8108 15015+#include <linux/fsnotify.h>
4a4d8108 15016+#include "rwsem.h"
1308ab2a 15017+
4a4d8108 15018+struct vfsmount;
1facf9fc 15019+
4a4d8108
AM
15020+struct au_hnotify {
15021+#ifdef CONFIG_AUFS_HNOTIFY
15022+#ifdef CONFIG_AUFS_HFSNOTIFY
7f207e10 15023+ /* never use fsnotify_add_vfsmount_mark() */
0c5527e5 15024+ struct fsnotify_mark hn_mark;
4a4d8108 15025+#endif
7f207e10 15026+ struct inode *hn_aufs_inode; /* no get/put */
4a4d8108
AM
15027+#endif
15028+} ____cacheline_aligned_in_smp;
1facf9fc 15029+
4a4d8108
AM
15030+struct au_hinode {
15031+ struct inode *hi_inode;
15032+ aufs_bindex_t hi_id;
15033+#ifdef CONFIG_AUFS_HNOTIFY
15034+ struct au_hnotify *hi_notify;
15035+#endif
dece6358 15036+
4a4d8108
AM
15037+ /* reference to the copied-up whiteout with get/put */
15038+ struct dentry *hi_whdentry;
15039+};
dece6358 15040+
537831f9
AM
15041+/* ig_flags */
15042+#define AuIG_HALF_REFRESHED 1
15043+#define au_ig_ftest(flags, name) ((flags) & AuIG_##name)
15044+#define au_ig_fset(flags, name) \
15045+ do { (flags) |= AuIG_##name; } while (0)
15046+#define au_ig_fclr(flags, name) \
15047+ do { (flags) &= ~AuIG_##name; } while (0)
15048+
15049+struct au_iigen {
15050+ __u32 ig_generation, ig_flags;
15051+};
15052+
4a4d8108
AM
15053+struct au_vdir;
15054+struct au_iinfo {
537831f9 15055+ spinlock_t ii_genspin;
7a9e40b8 15056+ struct au_iigen ii_generation;
4a4d8108 15057+ struct super_block *ii_hsb1; /* no get/put */
1facf9fc 15058+
4a4d8108
AM
15059+ struct au_rwsem ii_rwsem;
15060+ aufs_bindex_t ii_bstart, ii_bend;
15061+ __u32 ii_higen;
15062+ struct au_hinode *ii_hinode;
15063+ struct au_vdir *ii_vdir;
15064+};
1facf9fc 15065+
4a4d8108
AM
15066+struct au_icntnr {
15067+ struct au_iinfo iinfo;
15068+ struct inode vfs_inode;
15069+} ____cacheline_aligned_in_smp;
1308ab2a 15070+
4a4d8108
AM
15071+/* au_pin flags */
15072+#define AuPin_DI_LOCKED 1
15073+#define AuPin_MNT_WRITE (1 << 1)
15074+#define au_ftest_pin(flags, name) ((flags) & AuPin_##name)
7f207e10
AM
15075+#define au_fset_pin(flags, name) \
15076+ do { (flags) |= AuPin_##name; } while (0)
15077+#define au_fclr_pin(flags, name) \
15078+ do { (flags) &= ~AuPin_##name; } while (0)
4a4d8108
AM
15079+
15080+struct au_pin {
15081+ /* input */
15082+ struct dentry *dentry;
15083+ unsigned int udba;
15084+ unsigned char lsc_di, lsc_hi, flags;
15085+ aufs_bindex_t bindex;
15086+
15087+ /* output */
15088+ struct dentry *parent;
15089+ struct au_hinode *hdir;
15090+ struct vfsmount *h_mnt;
86dc4139
AM
15091+
15092+ /* temporary unlock/relock for copyup */
15093+ struct dentry *h_dentry, *h_parent;
15094+ struct au_branch *br;
15095+ struct task_struct *task;
4a4d8108 15096+};
1facf9fc 15097+
86dc4139
AM
15098+void au_pin_hdir_unlock(struct au_pin *p);
15099+int au_pin_hdir_relock(struct au_pin *p);
15100+void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task);
15101+void au_pin_hdir_acquire_nest(struct au_pin *p);
15102+void au_pin_hdir_release(struct au_pin *p);
15103+
1308ab2a 15104+/* ---------------------------------------------------------------------- */
15105+
4a4d8108 15106+static inline struct au_iinfo *au_ii(struct inode *inode)
1facf9fc 15107+{
4a4d8108 15108+ struct au_iinfo *iinfo;
1facf9fc 15109+
4a4d8108
AM
15110+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
15111+ if (iinfo->ii_hinode)
15112+ return iinfo;
15113+ return NULL; /* debugging bad_inode case */
15114+}
1facf9fc 15115+
4a4d8108 15116+/* ---------------------------------------------------------------------- */
1facf9fc 15117+
4a4d8108
AM
15118+/* inode.c */
15119+struct inode *au_igrab(struct inode *inode);
027c5e7a 15120+int au_refresh_hinode_self(struct inode *inode);
4a4d8108
AM
15121+int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
15122+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
15123+ unsigned int d_type, ino_t *ino);
15124+struct inode *au_new_inode(struct dentry *dentry, int must_new);
15125+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
15126+ struct inode *inode);
15127+int au_test_h_perm(struct inode *h_inode, int mask);
15128+int au_test_h_perm_sio(struct inode *h_inode, int mask);
1facf9fc 15129+
4a4d8108
AM
15130+static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex,
15131+ ino_t h_ino, unsigned int d_type, ino_t *ino)
15132+{
15133+#ifdef CONFIG_AUFS_SHWH
15134+ return au_ino(sb, bindex, h_ino, d_type, ino);
15135+#else
15136+ return 0;
15137+#endif
15138+}
1facf9fc 15139+
4a4d8108
AM
15140+/* i_op.c */
15141+extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
1308ab2a 15142+
4a4d8108
AM
15143+/* au_wr_dir flags */
15144+#define AuWrDir_ADD_ENTRY 1
86dc4139
AM
15145+#define AuWrDir_TMP_WHENTRY (1 << 1)
15146+#define AuWrDir_ISDIR (1 << 2)
4a4d8108 15147+#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
7f207e10
AM
15148+#define au_fset_wrdir(flags, name) \
15149+ do { (flags) |= AuWrDir_##name; } while (0)
15150+#define au_fclr_wrdir(flags, name) \
15151+ do { (flags) &= ~AuWrDir_##name; } while (0)
1facf9fc 15152+
4a4d8108
AM
15153+struct au_wr_dir_args {
15154+ aufs_bindex_t force_btgt;
15155+ unsigned char flags;
15156+};
15157+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
15158+ struct au_wr_dir_args *args);
dece6358 15159+
4a4d8108
AM
15160+struct dentry *au_pinned_h_parent(struct au_pin *pin);
15161+void au_pin_init(struct au_pin *pin, struct dentry *dentry,
15162+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
15163+ unsigned int udba, unsigned char flags);
15164+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
15165+ unsigned int udba, unsigned char flags) __must_check;
15166+int au_do_pin(struct au_pin *pin) __must_check;
15167+void au_unpin(struct au_pin *pin);
1facf9fc 15168+
4a4d8108
AM
15169+/* i_op_add.c */
15170+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
15171+ struct dentry *h_parent, int isdir);
7eafdf33
AM
15172+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
15173+ dev_t dev);
4a4d8108 15174+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
7eafdf33 15175+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 15176+ bool want_excl);
4a4d8108
AM
15177+int aufs_link(struct dentry *src_dentry, struct inode *dir,
15178+ struct dentry *dentry);
7eafdf33 15179+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
1facf9fc 15180+
4a4d8108
AM
15181+/* i_op_del.c */
15182+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
15183+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
15184+ struct dentry *h_parent, int isdir);
15185+int aufs_unlink(struct inode *dir, struct dentry *dentry);
15186+int aufs_rmdir(struct inode *dir, struct dentry *dentry);
1308ab2a 15187+
4a4d8108
AM
15188+/* i_op_ren.c */
15189+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
15190+int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
15191+ struct inode *dir, struct dentry *dentry);
1facf9fc 15192+
4a4d8108
AM
15193+/* iinfo.c */
15194+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
15195+void au_hiput(struct au_hinode *hinode);
15196+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
15197+ struct dentry *h_wh);
15198+unsigned int au_hi_flags(struct inode *inode, int isdir);
1308ab2a 15199+
4a4d8108
AM
15200+/* hinode flags */
15201+#define AuHi_XINO 1
15202+#define AuHi_HNOTIFY (1 << 1)
15203+#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
7f207e10
AM
15204+#define au_fset_hi(flags, name) \
15205+ do { (flags) |= AuHi_##name; } while (0)
15206+#define au_fclr_hi(flags, name) \
15207+ do { (flags) &= ~AuHi_##name; } while (0)
1facf9fc 15208+
4a4d8108
AM
15209+#ifndef CONFIG_AUFS_HNOTIFY
15210+#undef AuHi_HNOTIFY
15211+#define AuHi_HNOTIFY 0
15212+#endif
1facf9fc 15213+
4a4d8108
AM
15214+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
15215+ struct inode *h_inode, unsigned int flags);
1facf9fc 15216+
537831f9 15217+void au_update_iigen(struct inode *inode, int half);
4a4d8108 15218+void au_update_ibrange(struct inode *inode, int do_put_zero);
1facf9fc 15219+
4a4d8108
AM
15220+void au_icntnr_init_once(void *_c);
15221+int au_iinfo_init(struct inode *inode);
15222+void au_iinfo_fin(struct inode *inode);
15223+int au_ii_realloc(struct au_iinfo *iinfo, int nbr);
1308ab2a 15224+
e49829fe 15225+#ifdef CONFIG_PROC_FS
4a4d8108 15226+/* plink.c */
e49829fe
JR
15227+int au_plink_maint(struct super_block *sb, int flags);
15228+void au_plink_maint_leave(struct au_sbinfo *sbinfo);
15229+int au_plink_maint_enter(struct super_block *sb);
4a4d8108
AM
15230+#ifdef CONFIG_AUFS_DEBUG
15231+void au_plink_list(struct super_block *sb);
15232+#else
15233+AuStubVoid(au_plink_list, struct super_block *sb)
15234+#endif
15235+int au_plink_test(struct inode *inode);
15236+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
15237+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
15238+ struct dentry *h_dentry);
e49829fe
JR
15239+void au_plink_put(struct super_block *sb, int verbose);
15240+void au_plink_clean(struct super_block *sb, int verbose);
4a4d8108 15241+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
e49829fe
JR
15242+#else
15243+AuStubInt0(au_plink_maint, struct super_block *sb, int flags);
15244+AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo);
15245+AuStubInt0(au_plink_maint_enter, struct super_block *sb);
15246+AuStubVoid(au_plink_list, struct super_block *sb);
15247+AuStubInt0(au_plink_test, struct inode *inode);
15248+AuStub(struct dentry *, au_plink_lkup, return NULL,
15249+ struct inode *inode, aufs_bindex_t bindex);
15250+AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex,
15251+ struct dentry *h_dentry);
15252+AuStubVoid(au_plink_put, struct super_block *sb, int verbose);
15253+AuStubVoid(au_plink_clean, struct super_block *sb, int verbose);
15254+AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id);
15255+#endif /* CONFIG_PROC_FS */
1facf9fc 15256+
4a4d8108 15257+/* ---------------------------------------------------------------------- */
1308ab2a 15258+
4a4d8108
AM
15259+/* lock subclass for iinfo */
15260+enum {
15261+ AuLsc_II_CHILD, /* child first */
15262+ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */
15263+ AuLsc_II_CHILD3, /* copyup dirs */
15264+ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
15265+ AuLsc_II_PARENT2,
15266+ AuLsc_II_PARENT3, /* copyup dirs */
15267+ AuLsc_II_NEW_CHILD
15268+};
1308ab2a 15269+
1facf9fc 15270+/*
4a4d8108
AM
15271+ * ii_read_lock_child, ii_write_lock_child,
15272+ * ii_read_lock_child2, ii_write_lock_child2,
15273+ * ii_read_lock_child3, ii_write_lock_child3,
15274+ * ii_read_lock_parent, ii_write_lock_parent,
15275+ * ii_read_lock_parent2, ii_write_lock_parent2,
15276+ * ii_read_lock_parent3, ii_write_lock_parent3,
15277+ * ii_read_lock_new_child, ii_write_lock_new_child,
1facf9fc 15278+ */
4a4d8108
AM
15279+#define AuReadLockFunc(name, lsc) \
15280+static inline void ii_read_lock_##name(struct inode *i) \
15281+{ \
15282+ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
15283+}
15284+
15285+#define AuWriteLockFunc(name, lsc) \
15286+static inline void ii_write_lock_##name(struct inode *i) \
15287+{ \
15288+ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
15289+}
15290+
15291+#define AuRWLockFuncs(name, lsc) \
15292+ AuReadLockFunc(name, lsc) \
15293+ AuWriteLockFunc(name, lsc)
15294+
15295+AuRWLockFuncs(child, CHILD);
15296+AuRWLockFuncs(child2, CHILD2);
15297+AuRWLockFuncs(child3, CHILD3);
15298+AuRWLockFuncs(parent, PARENT);
15299+AuRWLockFuncs(parent2, PARENT2);
15300+AuRWLockFuncs(parent3, PARENT3);
15301+AuRWLockFuncs(new_child, NEW_CHILD);
15302+
15303+#undef AuReadLockFunc
15304+#undef AuWriteLockFunc
15305+#undef AuRWLockFuncs
1facf9fc 15306+
15307+/*
4a4d8108 15308+ * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
1facf9fc 15309+ */
4a4d8108 15310+AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
1facf9fc 15311+
4a4d8108
AM
15312+#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
15313+#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
15314+#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
1facf9fc 15315+
4a4d8108 15316+/* ---------------------------------------------------------------------- */
1308ab2a 15317+
027c5e7a
AM
15318+static inline void au_icntnr_init(struct au_icntnr *c)
15319+{
15320+#ifdef CONFIG_AUFS_DEBUG
15321+ c->vfs_inode.i_mode = 0;
15322+#endif
15323+}
15324+
537831f9 15325+static inline unsigned int au_iigen(struct inode *inode, struct au_iigen *iigen)
4a4d8108 15326+{
537831f9
AM
15327+ unsigned int gen;
15328+ struct au_iinfo *iinfo;
15329+
15330+ iinfo = au_ii(inode);
15331+ spin_lock(&iinfo->ii_genspin);
15332+ if (iigen)
15333+ *iigen = iinfo->ii_generation;
15334+ gen = iinfo->ii_generation.ig_generation;
15335+ spin_unlock(&iinfo->ii_genspin);
15336+
15337+ return gen;
4a4d8108 15338+}
1308ab2a 15339+
4a4d8108
AM
15340+/* tiny test for inode number */
15341+/* tmpfs generation is too rough */
15342+static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
15343+{
15344+ struct au_iinfo *iinfo;
1308ab2a 15345+
4a4d8108
AM
15346+ iinfo = au_ii(inode);
15347+ AuRwMustAnyLock(&iinfo->ii_rwsem);
15348+ return !(iinfo->ii_hsb1 == h_inode->i_sb
15349+ && iinfo->ii_higen == h_inode->i_generation);
15350+}
1308ab2a 15351+
4a4d8108
AM
15352+static inline void au_iigen_dec(struct inode *inode)
15353+{
537831f9
AM
15354+ struct au_iinfo *iinfo;
15355+
15356+ iinfo = au_ii(inode);
15357+ spin_lock(&iinfo->ii_genspin);
15358+ iinfo->ii_generation.ig_generation--;
15359+ spin_unlock(&iinfo->ii_genspin);
027c5e7a
AM
15360+}
15361+
15362+static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
15363+{
15364+ int err;
15365+
15366+ err = 0;
537831f9 15367+ if (unlikely(inode && au_iigen(inode, NULL) != sigen))
027c5e7a
AM
15368+ err = -EIO;
15369+
15370+ return err;
4a4d8108 15371+}
1308ab2a 15372+
4a4d8108 15373+/* ---------------------------------------------------------------------- */
1308ab2a 15374+
4a4d8108
AM
15375+static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
15376+ aufs_bindex_t bindex)
15377+{
15378+ IiMustAnyLock(inode);
15379+ return au_ii(inode)->ii_hinode[0 + bindex].hi_id;
15380+}
1308ab2a 15381+
4a4d8108
AM
15382+static inline aufs_bindex_t au_ibstart(struct inode *inode)
15383+{
15384+ IiMustAnyLock(inode);
15385+ return au_ii(inode)->ii_bstart;
15386+}
1308ab2a 15387+
4a4d8108
AM
15388+static inline aufs_bindex_t au_ibend(struct inode *inode)
15389+{
15390+ IiMustAnyLock(inode);
15391+ return au_ii(inode)->ii_bend;
15392+}
1308ab2a 15393+
4a4d8108
AM
15394+static inline struct au_vdir *au_ivdir(struct inode *inode)
15395+{
15396+ IiMustAnyLock(inode);
15397+ return au_ii(inode)->ii_vdir;
15398+}
1308ab2a 15399+
4a4d8108
AM
15400+static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
15401+{
15402+ IiMustAnyLock(inode);
15403+ return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry;
15404+}
1308ab2a 15405+
4a4d8108 15406+static inline void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 15407+{
4a4d8108
AM
15408+ IiMustWriteLock(inode);
15409+ au_ii(inode)->ii_bstart = bindex;
15410+}
1308ab2a 15411+
4a4d8108
AM
15412+static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex)
15413+{
15414+ IiMustWriteLock(inode);
15415+ au_ii(inode)->ii_bend = bindex;
1308ab2a 15416+}
15417+
4a4d8108
AM
15418+static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
15419+{
15420+ IiMustWriteLock(inode);
15421+ au_ii(inode)->ii_vdir = vdir;
15422+}
1facf9fc 15423+
4a4d8108 15424+static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 15425+{
4a4d8108
AM
15426+ IiMustAnyLock(inode);
15427+ return au_ii(inode)->ii_hinode + bindex;
15428+}
dece6358 15429+
4a4d8108 15430+/* ---------------------------------------------------------------------- */
1facf9fc 15431+
4a4d8108
AM
15432+static inline struct dentry *au_pinned_parent(struct au_pin *pin)
15433+{
15434+ if (pin)
15435+ return pin->parent;
15436+ return NULL;
1facf9fc 15437+}
15438+
4a4d8108 15439+static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
1facf9fc 15440+{
4a4d8108
AM
15441+ if (pin && pin->hdir)
15442+ return pin->hdir->hi_inode;
15443+ return NULL;
1308ab2a 15444+}
1facf9fc 15445+
4a4d8108
AM
15446+static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
15447+{
15448+ if (pin)
15449+ return pin->hdir;
15450+ return NULL;
15451+}
1facf9fc 15452+
4a4d8108 15453+static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
1308ab2a 15454+{
4a4d8108
AM
15455+ if (pin)
15456+ pin->dentry = dentry;
15457+}
1308ab2a 15458+
4a4d8108
AM
15459+static inline void au_pin_set_parent_lflag(struct au_pin *pin,
15460+ unsigned char lflag)
15461+{
15462+ if (pin) {
7f207e10 15463+ if (lflag)
4a4d8108 15464+ au_fset_pin(pin->flags, DI_LOCKED);
7f207e10 15465+ else
4a4d8108 15466+ au_fclr_pin(pin->flags, DI_LOCKED);
1308ab2a 15467+ }
4a4d8108
AM
15468+}
15469+
15470+static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
15471+{
15472+ if (pin) {
15473+ dput(pin->parent);
15474+ pin->parent = dget(parent);
1facf9fc 15475+ }
4a4d8108 15476+}
1facf9fc 15477+
4a4d8108
AM
15478+/* ---------------------------------------------------------------------- */
15479+
027c5e7a 15480+struct au_branch;
4a4d8108
AM
15481+#ifdef CONFIG_AUFS_HNOTIFY
15482+struct au_hnotify_op {
15483+ void (*ctl)(struct au_hinode *hinode, int do_set);
027c5e7a 15484+ int (*alloc)(struct au_hinode *hinode);
7eafdf33
AM
15485+
15486+ /*
15487+ * if it returns true, the the caller should free hinode->hi_notify,
15488+ * otherwise ->free() frees it.
15489+ */
15490+ int (*free)(struct au_hinode *hinode,
15491+ struct au_hnotify *hn) __must_check;
4a4d8108
AM
15492+
15493+ void (*fin)(void);
15494+ int (*init)(void);
027c5e7a
AM
15495+
15496+ int (*reset_br)(unsigned int udba, struct au_branch *br, int perm);
15497+ void (*fin_br)(struct au_branch *br);
15498+ int (*init_br)(struct au_branch *br, int perm);
4a4d8108
AM
15499+};
15500+
15501+/* hnotify.c */
027c5e7a 15502+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
4a4d8108
AM
15503+void au_hn_free(struct au_hinode *hinode);
15504+void au_hn_ctl(struct au_hinode *hinode, int do_set);
15505+void au_hn_reset(struct inode *inode, unsigned int flags);
15506+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
15507+ struct qstr *h_child_qstr, struct inode *h_child_inode);
027c5e7a
AM
15508+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm);
15509+int au_hnotify_init_br(struct au_branch *br, int perm);
15510+void au_hnotify_fin_br(struct au_branch *br);
4a4d8108
AM
15511+int __init au_hnotify_init(void);
15512+void au_hnotify_fin(void);
15513+
7f207e10 15514+/* hfsnotify.c */
4a4d8108
AM
15515+extern const struct au_hnotify_op au_hnotify_op;
15516+
15517+static inline
15518+void au_hn_init(struct au_hinode *hinode)
15519+{
15520+ hinode->hi_notify = NULL;
1308ab2a 15521+}
15522+
53392da6
AM
15523+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
15524+{
15525+ return hinode->hi_notify;
15526+}
15527+
4a4d8108
AM
15528+#else
15529+static inline
15530+int au_hn_alloc(struct au_hinode *hinode __maybe_unused,
027c5e7a 15531+ struct inode *inode __maybe_unused)
1308ab2a 15532+{
4a4d8108
AM
15533+ return -EOPNOTSUPP;
15534+}
1308ab2a 15535+
53392da6
AM
15536+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
15537+{
15538+ return NULL;
15539+}
15540+
4a4d8108
AM
15541+AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused)
15542+AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused,
15543+ int do_set __maybe_unused)
15544+AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused,
15545+ unsigned int flags __maybe_unused)
027c5e7a
AM
15546+AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused,
15547+ struct au_branch *br __maybe_unused,
15548+ int perm __maybe_unused)
15549+AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused,
15550+ int perm __maybe_unused)
15551+AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused)
4a4d8108
AM
15552+AuStubInt0(__init au_hnotify_init, void)
15553+AuStubVoid(au_hnotify_fin, void)
15554+AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused)
15555+#endif /* CONFIG_AUFS_HNOTIFY */
15556+
15557+static inline void au_hn_suspend(struct au_hinode *hdir)
15558+{
15559+ au_hn_ctl(hdir, /*do_set*/0);
1308ab2a 15560+}
15561+
4a4d8108 15562+static inline void au_hn_resume(struct au_hinode *hdir)
1308ab2a 15563+{
4a4d8108
AM
15564+ au_hn_ctl(hdir, /*do_set*/1);
15565+}
1308ab2a 15566+
4a4d8108
AM
15567+static inline void au_hn_imtx_lock(struct au_hinode *hdir)
15568+{
15569+ mutex_lock(&hdir->hi_inode->i_mutex);
15570+ au_hn_suspend(hdir);
15571+}
dece6358 15572+
4a4d8108
AM
15573+static inline void au_hn_imtx_lock_nested(struct au_hinode *hdir,
15574+ unsigned int sc __maybe_unused)
15575+{
15576+ mutex_lock_nested(&hdir->hi_inode->i_mutex, sc);
15577+ au_hn_suspend(hdir);
1facf9fc 15578+}
1facf9fc 15579+
4a4d8108
AM
15580+static inline void au_hn_imtx_unlock(struct au_hinode *hdir)
15581+{
15582+ au_hn_resume(hdir);
15583+ mutex_unlock(&hdir->hi_inode->i_mutex);
15584+}
15585+
15586+#endif /* __KERNEL__ */
15587+#endif /* __AUFS_INODE_H__ */
7f207e10
AM
15588diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c
15589--- /usr/share/empty/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
15590+++ linux/fs/aufs/ioctl.c 2014-01-20 20:16:14.739463504 +0100
15591@@ -0,0 +1,201 @@
4a4d8108 15592+/*
523b37e3 15593+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
15594+ *
15595+ * This program, aufs is free software; you can redistribute it and/or modify
15596+ * it under the terms of the GNU General Public License as published by
15597+ * the Free Software Foundation; either version 2 of the License, or
15598+ * (at your option) any later version.
15599+ *
15600+ * This program is distributed in the hope that it will be useful,
15601+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15602+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15603+ * GNU General Public License for more details.
15604+ *
15605+ * You should have received a copy of the GNU General Public License
523b37e3 15606+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
15607+ */
15608+
15609+/*
15610+ * ioctl
15611+ * plink-management and readdir in userspace.
15612+ * assist the pathconf(3) wrapper library.
c2b27bf2 15613+ * move-down
4a4d8108
AM
15614+ */
15615+
c2b27bf2
AM
15616+#include <linux/compat.h>
15617+#include <linux/file.h>
4a4d8108
AM
15618+#include "aufs.h"
15619+
1e00d052 15620+static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
4a4d8108
AM
15621+{
15622+ int err, fd;
15623+ aufs_bindex_t wbi, bindex, bend;
15624+ struct file *h_file;
15625+ struct super_block *sb;
15626+ struct dentry *root;
1e00d052
AM
15627+ struct au_branch *br;
15628+ struct aufs_wbr_fd wbrfd = {
15629+ .oflags = au_dir_roflags,
15630+ .brid = -1
15631+ };
15632+ const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY
15633+ | O_NOATIME | O_CLOEXEC;
4a4d8108 15634+
1e00d052
AM
15635+ AuDebugOn(wbrfd.oflags & ~valid);
15636+
15637+ if (arg) {
15638+ err = copy_from_user(&wbrfd, arg, sizeof(wbrfd));
15639+ if (unlikely(err)) {
15640+ err = -EFAULT;
15641+ goto out;
15642+ }
15643+
15644+ err = -EINVAL;
15645+ AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid);
15646+ wbrfd.oflags |= au_dir_roflags;
15647+ AuDbg("0%o\n", wbrfd.oflags);
15648+ if (unlikely(wbrfd.oflags & ~valid))
15649+ goto out;
15650+ }
15651+
15652+ fd = get_unused_fd();
15653+ err = fd;
15654+ if (unlikely(fd < 0))
4a4d8108 15655+ goto out;
4a4d8108 15656+
1e00d052 15657+ h_file = ERR_PTR(-EINVAL);
4a4d8108 15658+ wbi = 0;
1e00d052 15659+ br = NULL;
4a4d8108
AM
15660+ sb = path->dentry->d_sb;
15661+ root = sb->s_root;
15662+ aufs_read_lock(root, AuLock_IR);
1e00d052
AM
15663+ bend = au_sbend(sb);
15664+ if (wbrfd.brid >= 0) {
15665+ wbi = au_br_index(sb, wbrfd.brid);
15666+ if (unlikely(wbi < 0 || wbi > bend))
15667+ goto out_unlock;
15668+ }
15669+
15670+ h_file = ERR_PTR(-ENOENT);
15671+ br = au_sbr(sb, wbi);
15672+ if (!au_br_writable(br->br_perm)) {
15673+ if (arg)
15674+ goto out_unlock;
15675+
15676+ bindex = wbi + 1;
15677+ wbi = -1;
15678+ for (; bindex <= bend; bindex++) {
15679+ br = au_sbr(sb, bindex);
15680+ if (au_br_writable(br->br_perm)) {
4a4d8108 15681+ wbi = bindex;
1e00d052 15682+ br = au_sbr(sb, wbi);
4a4d8108
AM
15683+ break;
15684+ }
15685+ }
4a4d8108
AM
15686+ }
15687+ AuDbg("wbi %d\n", wbi);
1e00d052 15688+ if (wbi >= 0)
392086de
AM
15689+ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL,
15690+ /*force_wr*/0);
1e00d052
AM
15691+
15692+out_unlock:
4a4d8108
AM
15693+ aufs_read_unlock(root, AuLock_IR);
15694+ err = PTR_ERR(h_file);
15695+ if (IS_ERR(h_file))
15696+ goto out_fd;
15697+
1e00d052 15698+ atomic_dec(&br->br_count); /* cf. au_h_open() */
4a4d8108
AM
15699+ fd_install(fd, h_file);
15700+ err = fd;
15701+ goto out; /* success */
15702+
4f0767ce 15703+out_fd:
4a4d8108 15704+ put_unused_fd(fd);
4f0767ce 15705+out:
1e00d052 15706+ AuTraceErr(err);
4a4d8108
AM
15707+ return err;
15708+}
15709+
15710+/* ---------------------------------------------------------------------- */
15711+
15712+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
15713+{
15714+ long err;
15715+
15716+ switch (cmd) {
4a4d8108
AM
15717+ case AUFS_CTL_RDU:
15718+ case AUFS_CTL_RDU_INO:
15719+ err = au_rdu_ioctl(file, cmd, arg);
15720+ break;
15721+
15722+ case AUFS_CTL_WBR_FD:
1e00d052 15723+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
15724+ break;
15725+
027c5e7a
AM
15726+ case AUFS_CTL_IBUSY:
15727+ err = au_ibusy_ioctl(file, arg);
15728+ break;
15729+
4a4d8108
AM
15730+ default:
15731+ /* do not call the lower */
15732+ AuDbg("0x%x\n", cmd);
15733+ err = -ENOTTY;
15734+ }
15735+
15736+ AuTraceErr(err);
15737+ return err;
15738+}
15739+
15740+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
15741+{
15742+ long err;
15743+
15744+ switch (cmd) {
c2b27bf2 15745+ case AUFS_CTL_MVDOWN:
c2b27bf2
AM
15746+ err = au_mvdown(file->f_dentry, (void __user *)arg);
15747+ break;
15748+
4a4d8108 15749+ case AUFS_CTL_WBR_FD:
1e00d052 15750+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
15751+ break;
15752+
15753+ default:
15754+ /* do not call the lower */
15755+ AuDbg("0x%x\n", cmd);
15756+ err = -ENOTTY;
15757+ }
15758+
15759+ AuTraceErr(err);
15760+ return err;
15761+}
b752ccd1
AM
15762+
15763+#ifdef CONFIG_COMPAT
15764+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
15765+ unsigned long arg)
15766+{
15767+ long err;
15768+
15769+ switch (cmd) {
15770+ case AUFS_CTL_RDU:
15771+ case AUFS_CTL_RDU_INO:
15772+ err = au_rdu_compat_ioctl(file, cmd, arg);
15773+ break;
15774+
027c5e7a
AM
15775+ case AUFS_CTL_IBUSY:
15776+ err = au_ibusy_compat_ioctl(file, arg);
15777+ break;
15778+
b752ccd1
AM
15779+ default:
15780+ err = aufs_ioctl_dir(file, cmd, arg);
15781+ }
15782+
15783+ AuTraceErr(err);
15784+ return err;
15785+}
15786+
b752ccd1
AM
15787+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
15788+ unsigned long arg)
15789+{
15790+ return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg));
15791+}
15792+#endif
7f207e10
AM
15793diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
15794--- /usr/share/empty/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
15795+++ linux/fs/aufs/i_op_add.c 2014-01-20 20:16:14.739463504 +0100
15796@@ -0,0 +1,762 @@
4a4d8108 15797+/*
523b37e3 15798+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
15799+ *
15800+ * This program, aufs is free software; you can redistribute it and/or modify
15801+ * it under the terms of the GNU General Public License as published by
15802+ * the Free Software Foundation; either version 2 of the License, or
15803+ * (at your option) any later version.
15804+ *
15805+ * This program is distributed in the hope that it will be useful,
15806+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15807+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15808+ * GNU General Public License for more details.
15809+ *
15810+ * You should have received a copy of the GNU General Public License
523b37e3 15811+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
15812+ */
15813+
15814+/*
15815+ * inode operations (add entry)
15816+ */
15817+
15818+#include "aufs.h"
15819+
15820+/*
15821+ * final procedure of adding a new entry, except link(2).
15822+ * remove whiteout, instantiate, copyup the parent dir's times and size
15823+ * and update version.
15824+ * if it failed, re-create the removed whiteout.
15825+ */
15826+static int epilog(struct inode *dir, aufs_bindex_t bindex,
15827+ struct dentry *wh_dentry, struct dentry *dentry)
15828+{
15829+ int err, rerr;
15830+ aufs_bindex_t bwh;
15831+ struct path h_path;
15832+ struct inode *inode, *h_dir;
15833+ struct dentry *wh;
15834+
15835+ bwh = -1;
15836+ if (wh_dentry) {
15837+ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
15838+ IMustLock(h_dir);
15839+ AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
15840+ bwh = au_dbwh(dentry);
15841+ h_path.dentry = wh_dentry;
15842+ h_path.mnt = au_sbr_mnt(dir->i_sb, bindex);
15843+ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
15844+ dentry);
15845+ if (unlikely(err))
15846+ goto out;
15847+ }
15848+
15849+ inode = au_new_inode(dentry, /*must_new*/1);
15850+ if (!IS_ERR(inode)) {
15851+ d_instantiate(dentry, inode);
15852+ dir = dentry->d_parent->d_inode; /* dir inode is locked */
15853+ IMustLock(dir);
15854+ if (au_ibstart(dir) == au_dbstart(dentry))
15855+ au_cpup_attr_timesizes(dir);
15856+ dir->i_version++;
15857+ return 0; /* success */
15858+ }
15859+
15860+ err = PTR_ERR(inode);
15861+ if (!wh_dentry)
15862+ goto out;
15863+
15864+ /* revert */
15865+ /* dir inode is locked */
15866+ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
15867+ rerr = PTR_ERR(wh);
15868+ if (IS_ERR(wh)) {
523b37e3
AM
15869+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n",
15870+ dentry, err, rerr);
4a4d8108
AM
15871+ err = -EIO;
15872+ } else
15873+ dput(wh);
15874+
4f0767ce 15875+out:
4a4d8108
AM
15876+ return err;
15877+}
15878+
027c5e7a
AM
15879+static int au_d_may_add(struct dentry *dentry)
15880+{
15881+ int err;
15882+
15883+ err = 0;
15884+ if (unlikely(d_unhashed(dentry)))
15885+ err = -ENOENT;
15886+ if (unlikely(dentry->d_inode))
15887+ err = -EEXIST;
15888+ return err;
15889+}
15890+
4a4d8108
AM
15891+/*
15892+ * simple tests for the adding inode operations.
15893+ * following the checks in vfs, plus the parent-child relationship.
15894+ */
15895+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
15896+ struct dentry *h_parent, int isdir)
15897+{
15898+ int err;
15899+ umode_t h_mode;
15900+ struct dentry *h_dentry;
15901+ struct inode *h_inode;
15902+
15903+ err = -ENAMETOOLONG;
15904+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
15905+ goto out;
15906+
15907+ h_dentry = au_h_dptr(dentry, bindex);
15908+ h_inode = h_dentry->d_inode;
15909+ if (!dentry->d_inode) {
15910+ err = -EEXIST;
15911+ if (unlikely(h_inode))
15912+ goto out;
15913+ } else {
15914+ /* rename(2) case */
15915+ err = -EIO;
15916+ if (unlikely(!h_inode || !h_inode->i_nlink))
15917+ goto out;
15918+
15919+ h_mode = h_inode->i_mode;
15920+ if (!isdir) {
15921+ err = -EISDIR;
15922+ if (unlikely(S_ISDIR(h_mode)))
15923+ goto out;
15924+ } else if (unlikely(!S_ISDIR(h_mode))) {
15925+ err = -ENOTDIR;
15926+ goto out;
15927+ }
15928+ }
15929+
15930+ err = 0;
15931+ /* expected parent dir is locked */
15932+ if (unlikely(h_parent != h_dentry->d_parent))
15933+ err = -EIO;
15934+
4f0767ce 15935+out:
4a4d8108
AM
15936+ AuTraceErr(err);
15937+ return err;
15938+}
15939+
15940+/*
15941+ * initial procedure of adding a new entry.
15942+ * prepare writable branch and the parent dir, lock it,
15943+ * and lookup whiteout for the new entry.
15944+ */
15945+static struct dentry*
15946+lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
15947+ struct dentry *src_dentry, struct au_pin *pin,
15948+ struct au_wr_dir_args *wr_dir_args)
15949+{
15950+ struct dentry *wh_dentry, *h_parent;
15951+ struct super_block *sb;
15952+ struct au_branch *br;
15953+ int err;
15954+ unsigned int udba;
15955+ aufs_bindex_t bcpup;
15956+
523b37e3 15957+ AuDbg("%pd\n", dentry);
4a4d8108
AM
15958+
15959+ err = au_wr_dir(dentry, src_dentry, wr_dir_args);
15960+ bcpup = err;
15961+ wh_dentry = ERR_PTR(err);
15962+ if (unlikely(err < 0))
15963+ goto out;
15964+
15965+ sb = dentry->d_sb;
15966+ udba = au_opt_udba(sb);
15967+ err = au_pin(pin, dentry, bcpup, udba,
15968+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
15969+ wh_dentry = ERR_PTR(err);
15970+ if (unlikely(err))
15971+ goto out;
15972+
15973+ h_parent = au_pinned_h_parent(pin);
15974+ if (udba != AuOpt_UDBA_NONE
15975+ && au_dbstart(dentry) == bcpup)
15976+ err = au_may_add(dentry, bcpup, h_parent,
15977+ au_ftest_wrdir(wr_dir_args->flags, ISDIR));
15978+ else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
15979+ err = -ENAMETOOLONG;
15980+ wh_dentry = ERR_PTR(err);
15981+ if (unlikely(err))
15982+ goto out_unpin;
15983+
15984+ br = au_sbr(sb, bcpup);
15985+ if (dt) {
15986+ struct path tmp = {
15987+ .dentry = h_parent,
86dc4139 15988+ .mnt = au_br_mnt(br)
4a4d8108
AM
15989+ };
15990+ au_dtime_store(dt, au_pinned_parent(pin), &tmp);
15991+ }
15992+
15993+ wh_dentry = NULL;
15994+ if (bcpup != au_dbwh(dentry))
15995+ goto out; /* success */
15996+
15997+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
15998+
4f0767ce 15999+out_unpin:
4a4d8108
AM
16000+ if (IS_ERR(wh_dentry))
16001+ au_unpin(pin);
4f0767ce 16002+out:
4a4d8108
AM
16003+ return wh_dentry;
16004+}
16005+
16006+/* ---------------------------------------------------------------------- */
16007+
16008+enum { Mknod, Symlink, Creat };
16009+struct simple_arg {
16010+ int type;
16011+ union {
16012+ struct {
7eafdf33 16013+ umode_t mode;
b4510431 16014+ bool want_excl;
4a4d8108
AM
16015+ } c;
16016+ struct {
16017+ const char *symname;
16018+ } s;
16019+ struct {
7eafdf33 16020+ umode_t mode;
4a4d8108
AM
16021+ dev_t dev;
16022+ } m;
16023+ } u;
16024+};
16025+
16026+static int add_simple(struct inode *dir, struct dentry *dentry,
16027+ struct simple_arg *arg)
16028+{
16029+ int err;
16030+ aufs_bindex_t bstart;
16031+ unsigned char created;
4a4d8108
AM
16032+ struct dentry *wh_dentry, *parent;
16033+ struct inode *h_dir;
c2b27bf2
AM
16034+ /* to reuduce stack size */
16035+ struct {
16036+ struct au_dtime dt;
16037+ struct au_pin pin;
16038+ struct path h_path;
16039+ struct au_wr_dir_args wr_dir_args;
16040+ } *a;
4a4d8108 16041+
523b37e3 16042+ AuDbg("%pd\n", dentry);
4a4d8108
AM
16043+ IMustLock(dir);
16044+
c2b27bf2
AM
16045+ err = -ENOMEM;
16046+ a = kmalloc(sizeof(*a), GFP_NOFS);
16047+ if (unlikely(!a))
16048+ goto out;
16049+ a->wr_dir_args.force_btgt = -1;
16050+ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY;
16051+
4a4d8108 16052+ parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
16053+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
16054+ if (unlikely(err))
c2b27bf2 16055+ goto out_free;
027c5e7a
AM
16056+ err = au_d_may_add(dentry);
16057+ if (unlikely(err))
16058+ goto out_unlock;
4a4d8108 16059+ di_write_lock_parent(parent);
c2b27bf2
AM
16060+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
16061+ &a->pin, &a->wr_dir_args);
4a4d8108
AM
16062+ err = PTR_ERR(wh_dentry);
16063+ if (IS_ERR(wh_dentry))
027c5e7a 16064+ goto out_parent;
4a4d8108
AM
16065+
16066+ bstart = au_dbstart(dentry);
c2b27bf2
AM
16067+ a->h_path.dentry = au_h_dptr(dentry, bstart);
16068+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
16069+ h_dir = au_pinned_h_dir(&a->pin);
4a4d8108
AM
16070+ switch (arg->type) {
16071+ case Creat:
c2b27bf2 16072+ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode,
537831f9 16073+ arg->u.c.want_excl);
4a4d8108
AM
16074+ break;
16075+ case Symlink:
c2b27bf2 16076+ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname);
4a4d8108
AM
16077+ break;
16078+ case Mknod:
c2b27bf2
AM
16079+ err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode,
16080+ arg->u.m.dev);
4a4d8108
AM
16081+ break;
16082+ default:
16083+ BUG();
16084+ }
16085+ created = !err;
16086+ if (!err)
16087+ err = epilog(dir, bstart, wh_dentry, dentry);
16088+
16089+ /* revert */
c2b27bf2 16090+ if (unlikely(created && err && a->h_path.dentry->d_inode)) {
4a4d8108 16091+ int rerr;
523b37e3
AM
16092+ /* no delegation since it is just created */
16093+ rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL,
16094+ /*force*/0);
4a4d8108 16095+ if (rerr) {
523b37e3
AM
16096+ AuIOErr("%pd revert failure(%d, %d)\n",
16097+ dentry, err, rerr);
4a4d8108
AM
16098+ err = -EIO;
16099+ }
c2b27bf2 16100+ au_dtime_revert(&a->dt);
4a4d8108
AM
16101+ }
16102+
c2b27bf2 16103+ au_unpin(&a->pin);
4a4d8108
AM
16104+ dput(wh_dentry);
16105+
027c5e7a
AM
16106+out_parent:
16107+ di_write_unlock(parent);
16108+out_unlock:
4a4d8108
AM
16109+ if (unlikely(err)) {
16110+ au_update_dbstart(dentry);
16111+ d_drop(dentry);
16112+ }
4a4d8108 16113+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
16114+out_free:
16115+ kfree(a);
027c5e7a 16116+out:
4a4d8108
AM
16117+ return err;
16118+}
16119+
7eafdf33
AM
16120+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
16121+ dev_t dev)
4a4d8108
AM
16122+{
16123+ struct simple_arg arg = {
16124+ .type = Mknod,
16125+ .u.m = {
16126+ .mode = mode,
16127+ .dev = dev
16128+ }
16129+ };
16130+ return add_simple(dir, dentry, &arg);
16131+}
16132+
16133+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
16134+{
16135+ struct simple_arg arg = {
16136+ .type = Symlink,
16137+ .u.s.symname = symname
16138+ };
16139+ return add_simple(dir, dentry, &arg);
16140+}
16141+
7eafdf33 16142+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 16143+ bool want_excl)
4a4d8108
AM
16144+{
16145+ struct simple_arg arg = {
16146+ .type = Creat,
16147+ .u.c = {
b4510431
AM
16148+ .mode = mode,
16149+ .want_excl = want_excl
4a4d8108
AM
16150+ }
16151+ };
16152+ return add_simple(dir, dentry, &arg);
16153+}
16154+
16155+/* ---------------------------------------------------------------------- */
16156+
16157+struct au_link_args {
16158+ aufs_bindex_t bdst, bsrc;
16159+ struct au_pin pin;
16160+ struct path h_path;
16161+ struct dentry *src_parent, *parent;
16162+};
16163+
16164+static int au_cpup_before_link(struct dentry *src_dentry,
16165+ struct au_link_args *a)
16166+{
16167+ int err;
16168+ struct dentry *h_src_dentry;
c2b27bf2
AM
16169+ struct au_cp_generic cpg = {
16170+ .dentry = src_dentry,
16171+ .bdst = a->bdst,
16172+ .bsrc = a->bsrc,
16173+ .len = -1,
16174+ .pin = &a->pin,
16175+ .flags = AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */
16176+ };
4a4d8108
AM
16177+
16178+ di_read_lock_parent(a->src_parent, AuLock_IR);
16179+ err = au_test_and_cpup_dirs(src_dentry, a->bdst);
16180+ if (unlikely(err))
16181+ goto out;
16182+
16183+ h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
4a4d8108
AM
16184+ err = au_pin(&a->pin, src_dentry, a->bdst,
16185+ au_opt_udba(src_dentry->d_sb),
16186+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
16187+ if (unlikely(err))
16188+ goto out;
367653fa 16189+
c2b27bf2 16190+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
16191+ au_unpin(&a->pin);
16192+
4f0767ce 16193+out:
4a4d8108
AM
16194+ di_read_unlock(a->src_parent, AuLock_IR);
16195+ return err;
16196+}
16197+
86dc4139
AM
16198+static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry,
16199+ struct au_link_args *a)
4a4d8108
AM
16200+{
16201+ int err;
16202+ unsigned char plink;
86dc4139 16203+ aufs_bindex_t bend;
4a4d8108 16204+ struct dentry *h_src_dentry;
523b37e3 16205+ struct inode *h_inode, *inode, *delegated;
4a4d8108
AM
16206+ struct super_block *sb;
16207+ struct file *h_file;
16208+
16209+ plink = 0;
16210+ h_inode = NULL;
16211+ sb = src_dentry->d_sb;
16212+ inode = src_dentry->d_inode;
16213+ if (au_ibstart(inode) <= a->bdst)
16214+ h_inode = au_h_iptr(inode, a->bdst);
16215+ if (!h_inode || !h_inode->i_nlink) {
16216+ /* copyup src_dentry as the name of dentry. */
86dc4139
AM
16217+ bend = au_dbend(dentry);
16218+ if (bend < a->bsrc)
16219+ au_set_dbend(dentry, a->bsrc);
16220+ au_set_h_dptr(dentry, a->bsrc,
16221+ dget(au_h_dptr(src_dentry, a->bsrc)));
16222+ dget(a->h_path.dentry);
16223+ au_set_h_dptr(dentry, a->bdst, NULL);
16224+ dentry->d_inode = src_dentry->d_inode; /* tmp */
392086de 16225+ h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0);
86dc4139 16226+ if (IS_ERR(h_file))
4a4d8108 16227+ err = PTR_ERR(h_file);
86dc4139 16228+ else {
c2b27bf2
AM
16229+ struct au_cp_generic cpg = {
16230+ .dentry = dentry,
16231+ .bdst = a->bdst,
16232+ .bsrc = -1,
16233+ .len = -1,
16234+ .pin = &a->pin,
16235+ .flags = AuCpup_KEEPLINO
16236+ };
16237+ err = au_sio_cpup_simple(&cpg);
86dc4139
AM
16238+ au_h_open_post(dentry, a->bsrc, h_file);
16239+ if (!err) {
16240+ dput(a->h_path.dentry);
16241+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
16242+ } else
16243+ au_set_h_dptr(dentry, a->bdst,
16244+ a->h_path.dentry);
16245+ }
16246+ dentry->d_inode = NULL; /* restore */
16247+ au_set_h_dptr(dentry, a->bsrc, NULL);
16248+ au_set_dbend(dentry, bend);
4a4d8108
AM
16249+ } else {
16250+ /* the inode of src_dentry already exists on a.bdst branch */
16251+ h_src_dentry = d_find_alias(h_inode);
16252+ if (!h_src_dentry && au_plink_test(inode)) {
16253+ plink = 1;
16254+ h_src_dentry = au_plink_lkup(inode, a->bdst);
16255+ err = PTR_ERR(h_src_dentry);
16256+ if (IS_ERR(h_src_dentry))
16257+ goto out;
16258+
16259+ if (unlikely(!h_src_dentry->d_inode)) {
16260+ dput(h_src_dentry);
16261+ h_src_dentry = NULL;
16262+ }
16263+
16264+ }
16265+ if (h_src_dentry) {
523b37e3 16266+ delegated = NULL;
4a4d8108 16267+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
16268+ &a->h_path, &delegated);
16269+ if (unlikely(err == -EWOULDBLOCK)) {
16270+ pr_warn("cannot retry for NFSv4 delegation"
16271+ " for an internal link\n");
16272+ iput(delegated);
16273+ }
4a4d8108
AM
16274+ dput(h_src_dentry);
16275+ } else {
16276+ AuIOErr("no dentry found for hi%lu on b%d\n",
16277+ h_inode->i_ino, a->bdst);
16278+ err = -EIO;
16279+ }
16280+ }
16281+
16282+ if (!err && !plink)
16283+ au_plink_append(inode, a->bdst, a->h_path.dentry);
16284+
16285+out:
2cbb1c4b 16286+ AuTraceErr(err);
4a4d8108
AM
16287+ return err;
16288+}
16289+
16290+int aufs_link(struct dentry *src_dentry, struct inode *dir,
16291+ struct dentry *dentry)
16292+{
16293+ int err, rerr;
16294+ struct au_dtime dt;
16295+ struct au_link_args *a;
16296+ struct dentry *wh_dentry, *h_src_dentry;
523b37e3 16297+ struct inode *inode, *delegated;
4a4d8108
AM
16298+ struct super_block *sb;
16299+ struct au_wr_dir_args wr_dir_args = {
16300+ /* .force_btgt = -1, */
16301+ .flags = AuWrDir_ADD_ENTRY
16302+ };
16303+
16304+ IMustLock(dir);
16305+ inode = src_dentry->d_inode;
16306+ IMustLock(inode);
16307+
4a4d8108
AM
16308+ err = -ENOMEM;
16309+ a = kzalloc(sizeof(*a), GFP_NOFS);
16310+ if (unlikely(!a))
16311+ goto out;
16312+
16313+ a->parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
16314+ err = aufs_read_and_write_lock2(dentry, src_dentry,
16315+ AuLock_NOPLM | AuLock_GEN);
e49829fe
JR
16316+ if (unlikely(err))
16317+ goto out_kfree;
027c5e7a
AM
16318+ err = au_d_hashed_positive(src_dentry);
16319+ if (unlikely(err))
16320+ goto out_unlock;
16321+ err = au_d_may_add(dentry);
16322+ if (unlikely(err))
16323+ goto out_unlock;
e49829fe 16324+
4a4d8108 16325+ a->src_parent = dget_parent(src_dentry);
2cbb1c4b 16326+ wr_dir_args.force_btgt = au_ibstart(inode);
4a4d8108
AM
16327+
16328+ di_write_lock_parent(a->parent);
16329+ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
16330+ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
16331+ &wr_dir_args);
16332+ err = PTR_ERR(wh_dentry);
16333+ if (IS_ERR(wh_dentry))
027c5e7a 16334+ goto out_parent;
4a4d8108
AM
16335+
16336+ err = 0;
16337+ sb = dentry->d_sb;
16338+ a->bdst = au_dbstart(dentry);
16339+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
16340+ a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
2cbb1c4b
JR
16341+ a->bsrc = au_ibstart(inode);
16342+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
16343+ if (!h_src_dentry) {
16344+ a->bsrc = au_dbstart(src_dentry);
16345+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
16346+ AuDebugOn(!h_src_dentry);
16347+ } else if (IS_ERR(h_src_dentry))
16348+ goto out_parent;
16349+
4a4d8108
AM
16350+ if (au_opt_test(au_mntflags(sb), PLINK)) {
16351+ if (a->bdst < a->bsrc
16352+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
86dc4139 16353+ err = au_cpup_or_link(src_dentry, dentry, a);
523b37e3
AM
16354+ else {
16355+ delegated = NULL;
4a4d8108 16356+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
16357+ &a->h_path, &delegated);
16358+ if (unlikely(err == -EWOULDBLOCK)) {
16359+ pr_warn("cannot retry for NFSv4 delegation"
16360+ " for an internal link\n");
16361+ iput(delegated);
16362+ }
16363+ }
2cbb1c4b 16364+ dput(h_src_dentry);
4a4d8108
AM
16365+ } else {
16366+ /*
16367+ * copyup src_dentry to the branch we process,
16368+ * and then link(2) to it.
16369+ */
2cbb1c4b 16370+ dput(h_src_dentry);
4a4d8108
AM
16371+ if (a->bdst < a->bsrc
16372+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
16373+ au_unpin(&a->pin);
16374+ di_write_unlock(a->parent);
16375+ err = au_cpup_before_link(src_dentry, a);
16376+ di_write_lock_parent(a->parent);
16377+ if (!err)
16378+ err = au_pin(&a->pin, dentry, a->bdst,
16379+ au_opt_udba(sb),
16380+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
16381+ if (unlikely(err))
16382+ goto out_wh;
16383+ }
16384+ if (!err) {
16385+ h_src_dentry = au_h_dptr(src_dentry, a->bdst);
16386+ err = -ENOENT;
523b37e3
AM
16387+ if (h_src_dentry && h_src_dentry->d_inode) {
16388+ delegated = NULL;
4a4d8108
AM
16389+ err = vfsub_link(h_src_dentry,
16390+ au_pinned_h_dir(&a->pin),
523b37e3
AM
16391+ &a->h_path, &delegated);
16392+ if (unlikely(err == -EWOULDBLOCK)) {
16393+ pr_warn("cannot retry"
16394+ " for NFSv4 delegation"
16395+ " for an internal link\n");
16396+ iput(delegated);
16397+ }
16398+ }
4a4d8108
AM
16399+ }
16400+ }
16401+ if (unlikely(err))
16402+ goto out_unpin;
16403+
16404+ if (wh_dentry) {
16405+ a->h_path.dentry = wh_dentry;
16406+ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
16407+ dentry);
16408+ if (unlikely(err))
16409+ goto out_revert;
16410+ }
16411+
16412+ dir->i_version++;
16413+ if (au_ibstart(dir) == au_dbstart(dentry))
16414+ au_cpup_attr_timesizes(dir);
16415+ inc_nlink(inode);
16416+ inode->i_ctime = dir->i_ctime;
027c5e7a
AM
16417+ d_instantiate(dentry, au_igrab(inode));
16418+ if (d_unhashed(a->h_path.dentry))
4a4d8108
AM
16419+ /* some filesystem calls d_drop() */
16420+ d_drop(dentry);
16421+ goto out_unpin; /* success */
16422+
4f0767ce 16423+out_revert:
523b37e3
AM
16424+ /* no delegation since it is just created */
16425+ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path,
16426+ /*delegated*/NULL, /*force*/0);
027c5e7a 16427+ if (unlikely(rerr)) {
523b37e3 16428+ AuIOErr("%pd reverting failed(%d, %d)\n", dentry, err, rerr);
027c5e7a
AM
16429+ err = -EIO;
16430+ }
4a4d8108 16431+ au_dtime_revert(&dt);
4f0767ce 16432+out_unpin:
4a4d8108 16433+ au_unpin(&a->pin);
4f0767ce 16434+out_wh:
4a4d8108 16435+ dput(wh_dentry);
027c5e7a
AM
16436+out_parent:
16437+ di_write_unlock(a->parent);
16438+ dput(a->src_parent);
4f0767ce 16439+out_unlock:
4a4d8108
AM
16440+ if (unlikely(err)) {
16441+ au_update_dbstart(dentry);
16442+ d_drop(dentry);
16443+ }
4a4d8108 16444+ aufs_read_and_write_unlock2(dentry, src_dentry);
e49829fe 16445+out_kfree:
4a4d8108 16446+ kfree(a);
4f0767ce 16447+out:
86dc4139 16448+ AuTraceErr(err);
4a4d8108
AM
16449+ return err;
16450+}
16451+
7eafdf33 16452+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
4a4d8108
AM
16453+{
16454+ int err, rerr;
16455+ aufs_bindex_t bindex;
16456+ unsigned char diropq;
16457+ struct path h_path;
16458+ struct dentry *wh_dentry, *parent, *opq_dentry;
16459+ struct mutex *h_mtx;
16460+ struct super_block *sb;
16461+ struct {
16462+ struct au_pin pin;
16463+ struct au_dtime dt;
16464+ } *a; /* reduce the stack usage */
16465+ struct au_wr_dir_args wr_dir_args = {
16466+ .force_btgt = -1,
16467+ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
16468+ };
16469+
16470+ IMustLock(dir);
16471+
16472+ err = -ENOMEM;
16473+ a = kmalloc(sizeof(*a), GFP_NOFS);
16474+ if (unlikely(!a))
16475+ goto out;
16476+
027c5e7a
AM
16477+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
16478+ if (unlikely(err))
16479+ goto out_free;
16480+ err = au_d_may_add(dentry);
16481+ if (unlikely(err))
16482+ goto out_unlock;
16483+
4a4d8108
AM
16484+ parent = dentry->d_parent; /* dir inode is locked */
16485+ di_write_lock_parent(parent);
16486+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
16487+ &a->pin, &wr_dir_args);
16488+ err = PTR_ERR(wh_dentry);
16489+ if (IS_ERR(wh_dentry))
027c5e7a 16490+ goto out_parent;
4a4d8108
AM
16491+
16492+ sb = dentry->d_sb;
16493+ bindex = au_dbstart(dentry);
16494+ h_path.dentry = au_h_dptr(dentry, bindex);
16495+ h_path.mnt = au_sbr_mnt(sb, bindex);
16496+ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
16497+ if (unlikely(err))
027c5e7a 16498+ goto out_unpin;
4a4d8108
AM
16499+
16500+ /* make the dir opaque */
16501+ diropq = 0;
16502+ h_mtx = &h_path.dentry->d_inode->i_mutex;
16503+ if (wh_dentry
16504+ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
16505+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
16506+ opq_dentry = au_diropq_create(dentry, bindex);
16507+ mutex_unlock(h_mtx);
16508+ err = PTR_ERR(opq_dentry);
16509+ if (IS_ERR(opq_dentry))
16510+ goto out_dir;
16511+ dput(opq_dentry);
16512+ diropq = 1;
16513+ }
16514+
16515+ err = epilog(dir, bindex, wh_dentry, dentry);
16516+ if (!err) {
16517+ inc_nlink(dir);
027c5e7a 16518+ goto out_unpin; /* success */
4a4d8108
AM
16519+ }
16520+
16521+ /* revert */
16522+ if (diropq) {
16523+ AuLabel(revert opq);
16524+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
16525+ rerr = au_diropq_remove(dentry, bindex);
16526+ mutex_unlock(h_mtx);
16527+ if (rerr) {
523b37e3
AM
16528+ AuIOErr("%pd reverting diropq failed(%d, %d)\n",
16529+ dentry, err, rerr);
4a4d8108
AM
16530+ err = -EIO;
16531+ }
16532+ }
16533+
4f0767ce 16534+out_dir:
4a4d8108
AM
16535+ AuLabel(revert dir);
16536+ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
16537+ if (rerr) {
523b37e3
AM
16538+ AuIOErr("%pd reverting dir failed(%d, %d)\n",
16539+ dentry, err, rerr);
4a4d8108
AM
16540+ err = -EIO;
16541+ }
4a4d8108 16542+ au_dtime_revert(&a->dt);
027c5e7a 16543+out_unpin:
4a4d8108
AM
16544+ au_unpin(&a->pin);
16545+ dput(wh_dentry);
027c5e7a
AM
16546+out_parent:
16547+ di_write_unlock(parent);
16548+out_unlock:
4a4d8108
AM
16549+ if (unlikely(err)) {
16550+ au_update_dbstart(dentry);
16551+ d_drop(dentry);
16552+ }
4a4d8108 16553+ aufs_read_unlock(dentry, AuLock_DW);
027c5e7a 16554+out_free:
4a4d8108 16555+ kfree(a);
4f0767ce 16556+out:
4a4d8108
AM
16557+ return err;
16558+}
7f207e10
AM
16559diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
16560--- /usr/share/empty/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
f6b6e03d 16561+++ linux/fs/aufs/i_op.c 2014-01-27 23:16:52.715087263 +0100
523b37e3 16562@@ -0,0 +1,1127 @@
4a4d8108 16563+/*
523b37e3 16564+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
16565+ *
16566+ * This program, aufs is free software; you can redistribute it and/or modify
16567+ * it under the terms of the GNU General Public License as published by
16568+ * the Free Software Foundation; either version 2 of the License, or
16569+ * (at your option) any later version.
16570+ *
16571+ * This program is distributed in the hope that it will be useful,
16572+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16573+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16574+ * GNU General Public License for more details.
16575+ *
16576+ * You should have received a copy of the GNU General Public License
523b37e3 16577+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 16578+ */
1facf9fc 16579+
1308ab2a 16580+/*
4a4d8108 16581+ * inode operations (except add/del/rename)
1308ab2a 16582+ */
4a4d8108
AM
16583+
16584+#include <linux/device_cgroup.h>
16585+#include <linux/fs_stack.h>
92d182d2 16586+#include <linux/mm.h>
4a4d8108
AM
16587+#include <linux/namei.h>
16588+#include <linux/security.h>
4a4d8108
AM
16589+#include "aufs.h"
16590+
1e00d052 16591+static int h_permission(struct inode *h_inode, int mask,
4a4d8108 16592+ struct vfsmount *h_mnt, int brperm)
1facf9fc 16593+{
1308ab2a 16594+ int err;
4a4d8108 16595+ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
1facf9fc 16596+
4a4d8108
AM
16597+ err = -EACCES;
16598+ if ((write_mask && IS_IMMUTABLE(h_inode))
16599+ || ((mask & MAY_EXEC)
16600+ && S_ISREG(h_inode->i_mode)
16601+ && ((h_mnt->mnt_flags & MNT_NOEXEC)
16602+ || !(h_inode->i_mode & S_IXUGO))))
16603+ goto out;
16604+
16605+ /*
16606+ * - skip the lower fs test in the case of write to ro branch.
16607+ * - nfs dir permission write check is optimized, but a policy for
16608+ * link/rename requires a real check.
16609+ */
16610+ if ((write_mask && !au_br_writable(brperm))
16611+ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
16612+ && write_mask && !(mask & MAY_READ))
16613+ || !h_inode->i_op->permission) {
16614+ /* AuLabel(generic_permission); */
1e00d052 16615+ err = generic_permission(h_inode, mask);
1308ab2a 16616+ } else {
4a4d8108 16617+ /* AuLabel(h_inode->permission); */
1e00d052 16618+ err = h_inode->i_op->permission(h_inode, mask);
4a4d8108
AM
16619+ AuTraceErr(err);
16620+ }
1facf9fc 16621+
4a4d8108
AM
16622+ if (!err)
16623+ err = devcgroup_inode_permission(h_inode, mask);
7f207e10 16624+ if (!err)
4a4d8108 16625+ err = security_inode_permission(h_inode, mask);
4a4d8108
AM
16626+
16627+#if 0
16628+ if (!err) {
16629+ /* todo: do we need to call ima_path_check()? */
16630+ struct path h_path = {
16631+ .dentry =
16632+ .mnt = h_mnt
16633+ };
16634+ err = ima_path_check(&h_path,
16635+ mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
16636+ IMA_COUNT_LEAVE);
1308ab2a 16637+ }
4a4d8108 16638+#endif
dece6358 16639+
4f0767ce 16640+out:
1308ab2a 16641+ return err;
16642+}
dece6358 16643+
1e00d052 16644+static int aufs_permission(struct inode *inode, int mask)
1308ab2a 16645+{
16646+ int err;
4a4d8108
AM
16647+ aufs_bindex_t bindex, bend;
16648+ const unsigned char isdir = !!S_ISDIR(inode->i_mode),
16649+ write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
16650+ struct inode *h_inode;
16651+ struct super_block *sb;
16652+ struct au_branch *br;
1facf9fc 16653+
027c5e7a 16654+ /* todo: support rcu-walk? */
1e00d052 16655+ if (mask & MAY_NOT_BLOCK)
027c5e7a
AM
16656+ return -ECHILD;
16657+
4a4d8108
AM
16658+ sb = inode->i_sb;
16659+ si_read_lock(sb, AuLock_FLUSH);
16660+ ii_read_lock_child(inode);
027c5e7a
AM
16661+#if 0
16662+ err = au_iigen_test(inode, au_sigen(sb));
16663+ if (unlikely(err))
16664+ goto out;
16665+#endif
dece6358 16666+
4a4d8108
AM
16667+ if (!isdir || write_mask) {
16668+ err = au_busy_or_stale();
16669+ h_inode = au_h_iptr(inode, au_ibstart(inode));
16670+ if (unlikely(!h_inode
16671+ || (h_inode->i_mode & S_IFMT)
16672+ != (inode->i_mode & S_IFMT)))
16673+ goto out;
1facf9fc 16674+
4a4d8108
AM
16675+ err = 0;
16676+ bindex = au_ibstart(inode);
16677+ br = au_sbr(sb, bindex);
86dc4139 16678+ err = h_permission(h_inode, mask, au_br_mnt(br), br->br_perm);
4a4d8108
AM
16679+ if (write_mask
16680+ && !err
16681+ && !special_file(h_inode->i_mode)) {
16682+ /* test whether the upper writable branch exists */
16683+ err = -EROFS;
16684+ for (; bindex >= 0; bindex--)
16685+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
16686+ err = 0;
16687+ break;
16688+ }
16689+ }
16690+ goto out;
16691+ }
dece6358 16692+
4a4d8108 16693+ /* non-write to dir */
1308ab2a 16694+ err = 0;
4a4d8108
AM
16695+ bend = au_ibend(inode);
16696+ for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) {
16697+ h_inode = au_h_iptr(inode, bindex);
16698+ if (h_inode) {
16699+ err = au_busy_or_stale();
16700+ if (unlikely(!S_ISDIR(h_inode->i_mode)))
16701+ break;
16702+
16703+ br = au_sbr(sb, bindex);
86dc4139 16704+ err = h_permission(h_inode, mask, au_br_mnt(br),
4a4d8108
AM
16705+ br->br_perm);
16706+ }
16707+ }
1308ab2a 16708+
4f0767ce 16709+out:
4a4d8108
AM
16710+ ii_read_unlock(inode);
16711+ si_read_unlock(sb);
1308ab2a 16712+ return err;
16713+}
16714+
4a4d8108 16715+/* ---------------------------------------------------------------------- */
1facf9fc 16716+
4a4d8108 16717+static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
b4510431 16718+ unsigned int flags)
4a4d8108
AM
16719+{
16720+ struct dentry *ret, *parent;
b752ccd1 16721+ struct inode *inode;
4a4d8108 16722+ struct super_block *sb;
1716fcea 16723+ int err, npositive;
dece6358 16724+
4a4d8108 16725+ IMustLock(dir);
1308ab2a 16726+
537831f9
AM
16727+ /* todo: support rcu-walk? */
16728+ ret = ERR_PTR(-ECHILD);
16729+ if (flags & LOOKUP_RCU)
16730+ goto out;
16731+
16732+ ret = ERR_PTR(-ENAMETOOLONG);
16733+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
16734+ goto out;
16735+
4a4d8108 16736+ sb = dir->i_sb;
7f207e10
AM
16737+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
16738+ ret = ERR_PTR(err);
16739+ if (unlikely(err))
16740+ goto out;
16741+
4a4d8108
AM
16742+ err = au_di_init(dentry);
16743+ ret = ERR_PTR(err);
16744+ if (unlikely(err))
7f207e10 16745+ goto out_si;
1308ab2a 16746+
9dbd164d 16747+ inode = NULL;
027c5e7a 16748+ npositive = 0; /* suppress a warning */
4a4d8108
AM
16749+ parent = dentry->d_parent; /* dir inode is locked */
16750+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
16751+ err = au_alive_dir(parent);
16752+ if (!err)
16753+ err = au_digen_test(parent, au_sigen(sb));
16754+ if (!err) {
16755+ npositive = au_lkup_dentry(dentry, au_dbstart(parent),
537831f9 16756+ /*type*/0);
027c5e7a
AM
16757+ err = npositive;
16758+ }
4a4d8108 16759+ di_read_unlock(parent, AuLock_IR);
4a4d8108
AM
16760+ ret = ERR_PTR(err);
16761+ if (unlikely(err < 0))
16762+ goto out_unlock;
1308ab2a 16763+
4a4d8108 16764+ if (npositive) {
b752ccd1 16765+ inode = au_new_inode(dentry, /*must_new*/0);
4a4d8108 16766+ ret = (void *)inode;
1facf9fc 16767+ }
9dbd164d
AM
16768+ if (IS_ERR(inode)) {
16769+ inode = NULL;
4a4d8108 16770+ goto out_unlock;
9dbd164d 16771+ }
4a4d8108
AM
16772+
16773+ ret = d_splice_alias(inode, dentry);
537831f9
AM
16774+#if 0
16775+ if (unlikely(d_need_lookup(dentry))) {
16776+ spin_lock(&dentry->d_lock);
16777+ dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
16778+ spin_unlock(&dentry->d_lock);
16779+ } else
16780+#endif
7f207e10 16781+ if (unlikely(IS_ERR(ret) && inode)) {
4a4d8108 16782+ ii_write_unlock(inode);
7f207e10 16783+ iput(inode);
2dfbb274 16784+ inode = NULL;
7f207e10 16785+ }
1facf9fc 16786+
4f0767ce 16787+out_unlock:
4a4d8108 16788+ di_write_unlock(dentry);
2dfbb274 16789+ if (inode) {
1716fcea
AM
16790+ /* verbose coding for lock class name */
16791+ if (unlikely(S_ISLNK(inode->i_mode)))
16792+ au_rw_class(&au_di(dentry)->di_rwsem,
16793+ au_lc_key + AuLcSymlink_DIINFO);
16794+ else if (unlikely(S_ISDIR(inode->i_mode)))
16795+ au_rw_class(&au_di(dentry)->di_rwsem,
16796+ au_lc_key + AuLcDir_DIINFO);
16797+ else /* likely */
16798+ au_rw_class(&au_di(dentry)->di_rwsem,
16799+ au_lc_key + AuLcNonDir_DIINFO);
9dbd164d 16800+ }
7f207e10 16801+out_si:
4a4d8108 16802+ si_read_unlock(sb);
7f207e10 16803+out:
4a4d8108
AM
16804+ return ret;
16805+}
1facf9fc 16806+
4a4d8108 16807+/* ---------------------------------------------------------------------- */
1facf9fc 16808+
4a4d8108
AM
16809+static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
16810+ const unsigned char add_entry, aufs_bindex_t bcpup,
16811+ aufs_bindex_t bstart)
16812+{
16813+ int err;
16814+ struct dentry *h_parent;
16815+ struct inode *h_dir;
1facf9fc 16816+
027c5e7a 16817+ if (add_entry)
4a4d8108 16818+ IMustLock(parent->d_inode);
027c5e7a 16819+ else
4a4d8108
AM
16820+ di_write_lock_parent(parent);
16821+
16822+ err = 0;
16823+ if (!au_h_dptr(parent, bcpup)) {
c2b27bf2
AM
16824+ if (bstart > bcpup)
16825+ err = au_cpup_dirs(dentry, bcpup);
16826+ else if (bstart < bcpup)
4a4d8108
AM
16827+ err = au_cpdown_dirs(dentry, bcpup);
16828+ else
c2b27bf2 16829+ BUG();
4a4d8108
AM
16830+ }
16831+ if (!err && add_entry) {
16832+ h_parent = au_h_dptr(parent, bcpup);
16833+ h_dir = h_parent->d_inode;
16834+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
86dc4139
AM
16835+ err = au_lkup_neg(dentry, bcpup,
16836+ au_ftest_wrdir(add_entry, TMP_WHENTRY));
4a4d8108
AM
16837+ /* todo: no unlock here */
16838+ mutex_unlock(&h_dir->i_mutex);
027c5e7a
AM
16839+
16840+ AuDbg("bcpup %d\n", bcpup);
16841+ if (!err) {
16842+ if (!dentry->d_inode)
16843+ au_set_h_dptr(dentry, bstart, NULL);
4a4d8108
AM
16844+ au_update_dbrange(dentry, /*do_put_zero*/0);
16845+ }
1308ab2a 16846+ }
1facf9fc 16847+
4a4d8108
AM
16848+ if (!add_entry)
16849+ di_write_unlock(parent);
16850+ if (!err)
16851+ err = bcpup; /* success */
1308ab2a 16852+
027c5e7a 16853+ AuTraceErr(err);
4a4d8108
AM
16854+ return err;
16855+}
1facf9fc 16856+
4a4d8108
AM
16857+/*
16858+ * decide the branch and the parent dir where we will create a new entry.
16859+ * returns new bindex or an error.
16860+ * copyup the parent dir if needed.
16861+ */
16862+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
16863+ struct au_wr_dir_args *args)
16864+{
16865+ int err;
392086de 16866+ unsigned int flags;
4a4d8108 16867+ aufs_bindex_t bcpup, bstart, src_bstart;
86dc4139
AM
16868+ const unsigned char add_entry
16869+ = au_ftest_wrdir(args->flags, ADD_ENTRY)
16870+ | au_ftest_wrdir(args->flags, TMP_WHENTRY);
4a4d8108
AM
16871+ struct super_block *sb;
16872+ struct dentry *parent;
16873+ struct au_sbinfo *sbinfo;
1facf9fc 16874+
4a4d8108
AM
16875+ sb = dentry->d_sb;
16876+ sbinfo = au_sbi(sb);
16877+ parent = dget_parent(dentry);
16878+ bstart = au_dbstart(dentry);
16879+ bcpup = bstart;
16880+ if (args->force_btgt < 0) {
16881+ if (src_dentry) {
16882+ src_bstart = au_dbstart(src_dentry);
16883+ if (src_bstart < bstart)
16884+ bcpup = src_bstart;
16885+ } else if (add_entry) {
392086de
AM
16886+ flags = 0;
16887+ if (au_ftest_wrdir(args->flags, ISDIR))
16888+ au_fset_wbr(flags, DIR);
16889+ err = AuWbrCreate(sbinfo, dentry, flags);
4a4d8108
AM
16890+ bcpup = err;
16891+ }
1facf9fc 16892+
4a4d8108
AM
16893+ if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) {
16894+ if (add_entry)
16895+ err = AuWbrCopyup(sbinfo, dentry);
16896+ else {
16897+ if (!IS_ROOT(dentry)) {
16898+ di_read_lock_parent(parent, !AuLock_IR);
16899+ err = AuWbrCopyup(sbinfo, dentry);
16900+ di_read_unlock(parent, !AuLock_IR);
16901+ } else
16902+ err = AuWbrCopyup(sbinfo, dentry);
16903+ }
16904+ bcpup = err;
16905+ if (unlikely(err < 0))
16906+ goto out;
16907+ }
16908+ } else {
16909+ bcpup = args->force_btgt;
16910+ AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode));
1308ab2a 16911+ }
027c5e7a 16912+
4a4d8108
AM
16913+ AuDbg("bstart %d, bcpup %d\n", bstart, bcpup);
16914+ err = bcpup;
16915+ if (bcpup == bstart)
16916+ goto out; /* success */
4a4d8108
AM
16917+
16918+ /* copyup the new parent into the branch we process */
16919+ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart);
027c5e7a
AM
16920+ if (err >= 0) {
16921+ if (!dentry->d_inode) {
16922+ au_set_h_dptr(dentry, bstart, NULL);
16923+ au_set_dbstart(dentry, bcpup);
16924+ au_set_dbend(dentry, bcpup);
16925+ }
16926+ AuDebugOn(add_entry && !au_h_dptr(dentry, bcpup));
16927+ }
86dc4139
AM
16928+
16929+out:
16930+ dput(parent);
16931+ return err;
16932+}
16933+
16934+/* ---------------------------------------------------------------------- */
16935+
16936+void au_pin_hdir_unlock(struct au_pin *p)
16937+{
16938+ if (p->hdir)
16939+ au_hn_imtx_unlock(p->hdir);
16940+}
16941+
16942+static int au_pin_hdir_lock(struct au_pin *p)
16943+{
16944+ int err;
16945+
16946+ err = 0;
16947+ if (!p->hdir)
16948+ goto out;
16949+
16950+ /* even if an error happens later, keep this lock */
16951+ au_hn_imtx_lock_nested(p->hdir, p->lsc_hi);
16952+
16953+ err = -EBUSY;
16954+ if (unlikely(p->hdir->hi_inode != p->h_parent->d_inode))
16955+ goto out;
16956+
16957+ err = 0;
16958+ if (p->h_dentry)
16959+ err = au_h_verify(p->h_dentry, p->udba, p->hdir->hi_inode,
16960+ p->h_parent, p->br);
16961+
16962+out:
16963+ return err;
16964+}
16965+
16966+int au_pin_hdir_relock(struct au_pin *p)
16967+{
16968+ int err, i;
16969+ struct inode *h_i;
16970+ struct dentry *h_d[] = {
16971+ p->h_dentry,
16972+ p->h_parent
16973+ };
16974+
16975+ err = au_pin_hdir_lock(p);
16976+ if (unlikely(err))
16977+ goto out;
16978+
16979+ for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) {
16980+ if (!h_d[i])
16981+ continue;
16982+ h_i = h_d[i]->d_inode;
16983+ if (h_i)
16984+ err = !h_i->i_nlink;
16985+ }
16986+
16987+out:
16988+ return err;
16989+}
16990+
16991+void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task)
16992+{
16993+#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP)
16994+ p->hdir->hi_inode->i_mutex.owner = task;
16995+#endif
16996+}
16997+
16998+void au_pin_hdir_acquire_nest(struct au_pin *p)
16999+{
17000+ if (p->hdir) {
17001+ mutex_acquire_nest(&p->hdir->hi_inode->i_mutex.dep_map,
17002+ p->lsc_hi, 0, NULL, _RET_IP_);
17003+ au_pin_hdir_set_owner(p, current);
17004+ }
dece6358 17005+}
1facf9fc 17006+
86dc4139
AM
17007+void au_pin_hdir_release(struct au_pin *p)
17008+{
17009+ if (p->hdir) {
17010+ au_pin_hdir_set_owner(p, p->task);
17011+ mutex_release(&p->hdir->hi_inode->i_mutex.dep_map, 1, _RET_IP_);
17012+ }
17013+}
1308ab2a 17014+
4a4d8108 17015+struct dentry *au_pinned_h_parent(struct au_pin *pin)
1308ab2a 17016+{
4a4d8108
AM
17017+ if (pin && pin->parent)
17018+ return au_h_dptr(pin->parent, pin->bindex);
17019+ return NULL;
dece6358 17020+}
1facf9fc 17021+
4a4d8108 17022+void au_unpin(struct au_pin *p)
dece6358 17023+{
86dc4139
AM
17024+ if (p->hdir)
17025+ au_pin_hdir_unlock(p);
e49829fe 17026+ if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE))
b4510431 17027+ vfsub_mnt_drop_write(p->h_mnt);
4a4d8108
AM
17028+ if (!p->hdir)
17029+ return;
1facf9fc 17030+
4a4d8108
AM
17031+ if (!au_ftest_pin(p->flags, DI_LOCKED))
17032+ di_read_unlock(p->parent, AuLock_IR);
17033+ iput(p->hdir->hi_inode);
17034+ dput(p->parent);
17035+ p->parent = NULL;
17036+ p->hdir = NULL;
17037+ p->h_mnt = NULL;
86dc4139 17038+ /* do not clear p->task */
4a4d8108 17039+}
1308ab2a 17040+
4a4d8108
AM
17041+int au_do_pin(struct au_pin *p)
17042+{
17043+ int err;
17044+ struct super_block *sb;
4a4d8108
AM
17045+ struct inode *h_dir;
17046+
17047+ err = 0;
17048+ sb = p->dentry->d_sb;
86dc4139 17049+ p->br = au_sbr(sb, p->bindex);
4a4d8108
AM
17050+ if (IS_ROOT(p->dentry)) {
17051+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 17052+ p->h_mnt = au_br_mnt(p->br);
b4510431 17053+ err = vfsub_mnt_want_write(p->h_mnt);
4a4d8108
AM
17054+ if (unlikely(err)) {
17055+ au_fclr_pin(p->flags, MNT_WRITE);
17056+ goto out_err;
17057+ }
17058+ }
dece6358 17059+ goto out;
1facf9fc 17060+ }
17061+
86dc4139 17062+ p->h_dentry = NULL;
4a4d8108 17063+ if (p->bindex <= au_dbend(p->dentry))
86dc4139 17064+ p->h_dentry = au_h_dptr(p->dentry, p->bindex);
dece6358 17065+
4a4d8108
AM
17066+ p->parent = dget_parent(p->dentry);
17067+ if (!au_ftest_pin(p->flags, DI_LOCKED))
17068+ di_read_lock(p->parent, AuLock_IR, p->lsc_di);
dece6358 17069+
4a4d8108 17070+ h_dir = NULL;
86dc4139 17071+ p->h_parent = au_h_dptr(p->parent, p->bindex);
4a4d8108
AM
17072+ p->hdir = au_hi(p->parent->d_inode, p->bindex);
17073+ if (p->hdir)
17074+ h_dir = p->hdir->hi_inode;
dece6358 17075+
b752ccd1
AM
17076+ /*
17077+ * udba case, or
17078+ * if DI_LOCKED is not set, then p->parent may be different
17079+ * and h_parent can be NULL.
17080+ */
86dc4139 17081+ if (unlikely(!p->hdir || !h_dir || !p->h_parent)) {
e49829fe 17082+ err = -EBUSY;
4a4d8108
AM
17083+ if (!au_ftest_pin(p->flags, DI_LOCKED))
17084+ di_read_unlock(p->parent, AuLock_IR);
17085+ dput(p->parent);
17086+ p->parent = NULL;
17087+ goto out_err;
17088+ }
1308ab2a 17089+
4a4d8108 17090+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 17091+ p->h_mnt = au_br_mnt(p->br);
b4510431 17092+ err = vfsub_mnt_want_write(p->h_mnt);
dece6358 17093+ if (unlikely(err)) {
4a4d8108 17094+ au_fclr_pin(p->flags, MNT_WRITE);
86dc4139
AM
17095+ if (!au_ftest_pin(p->flags, DI_LOCKED))
17096+ di_read_unlock(p->parent, AuLock_IR);
17097+ dput(p->parent);
17098+ p->parent = NULL;
17099+ goto out_err;
dece6358
AM
17100+ }
17101+ }
4a4d8108 17102+
86dc4139
AM
17103+ au_igrab(h_dir);
17104+ err = au_pin_hdir_lock(p);
17105+ if (!err)
17106+ goto out; /* success */
17107+
4f0767ce 17108+out_err:
4a4d8108
AM
17109+ pr_err("err %d\n", err);
17110+ err = au_busy_or_stale();
4f0767ce 17111+out:
1facf9fc 17112+ return err;
17113+}
17114+
4a4d8108
AM
17115+void au_pin_init(struct au_pin *p, struct dentry *dentry,
17116+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
17117+ unsigned int udba, unsigned char flags)
17118+{
17119+ p->dentry = dentry;
17120+ p->udba = udba;
17121+ p->lsc_di = lsc_di;
17122+ p->lsc_hi = lsc_hi;
17123+ p->flags = flags;
17124+ p->bindex = bindex;
17125+
17126+ p->parent = NULL;
17127+ p->hdir = NULL;
17128+ p->h_mnt = NULL;
86dc4139
AM
17129+
17130+ p->h_dentry = NULL;
17131+ p->h_parent = NULL;
17132+ p->br = NULL;
17133+ p->task = current;
4a4d8108
AM
17134+}
17135+
17136+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
17137+ unsigned int udba, unsigned char flags)
17138+{
17139+ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
17140+ udba, flags);
17141+ return au_do_pin(pin);
17142+}
17143+
dece6358
AM
17144+/* ---------------------------------------------------------------------- */
17145+
1308ab2a 17146+/*
4a4d8108
AM
17147+ * ->setattr() and ->getattr() are called in various cases.
17148+ * chmod, stat: dentry is revalidated.
17149+ * fchmod, fstat: file and dentry are not revalidated, additionally they may be
17150+ * unhashed.
17151+ * for ->setattr(), ia->ia_file is passed from ftruncate only.
1308ab2a 17152+ */
027c5e7a 17153+/* todo: consolidate with do_refresh() and simple_reval_dpath() */
4a4d8108 17154+static int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
1facf9fc 17155+{
4a4d8108
AM
17156+ int err;
17157+ struct inode *inode;
17158+ struct dentry *parent;
1facf9fc 17159+
1308ab2a 17160+ err = 0;
4a4d8108 17161+ inode = dentry->d_inode;
027c5e7a 17162+ if (au_digen_test(dentry, sigen)) {
4a4d8108
AM
17163+ parent = dget_parent(dentry);
17164+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 17165+ err = au_refresh_dentry(dentry, parent);
4a4d8108
AM
17166+ di_read_unlock(parent, AuLock_IR);
17167+ dput(parent);
dece6358 17168+ }
1facf9fc 17169+
4a4d8108 17170+ AuTraceErr(err);
1308ab2a 17171+ return err;
17172+}
dece6358 17173+
4a4d8108
AM
17174+#define AuIcpup_DID_CPUP 1
17175+#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
7f207e10
AM
17176+#define au_fset_icpup(flags, name) \
17177+ do { (flags) |= AuIcpup_##name; } while (0)
17178+#define au_fclr_icpup(flags, name) \
17179+ do { (flags) &= ~AuIcpup_##name; } while (0)
1308ab2a 17180+
4a4d8108
AM
17181+struct au_icpup_args {
17182+ unsigned char flags;
17183+ unsigned char pin_flags;
17184+ aufs_bindex_t btgt;
17185+ unsigned int udba;
17186+ struct au_pin pin;
17187+ struct path h_path;
17188+ struct inode *h_inode;
17189+};
1308ab2a 17190+
4a4d8108
AM
17191+static int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
17192+ struct au_icpup_args *a)
1308ab2a 17193+{
17194+ int err;
4a4d8108 17195+ loff_t sz;
e49829fe 17196+ aufs_bindex_t bstart, ibstart;
4a4d8108
AM
17197+ struct dentry *hi_wh, *parent;
17198+ struct inode *inode;
4a4d8108
AM
17199+ struct au_wr_dir_args wr_dir_args = {
17200+ .force_btgt = -1,
17201+ .flags = 0
17202+ };
17203+
17204+ bstart = au_dbstart(dentry);
17205+ inode = dentry->d_inode;
17206+ if (S_ISDIR(inode->i_mode))
17207+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
17208+ /* plink or hi_wh() case */
e49829fe 17209+ ibstart = au_ibstart(inode);
027c5e7a 17210+ if (bstart != ibstart && !au_test_ro(inode->i_sb, ibstart, inode))
e49829fe 17211+ wr_dir_args.force_btgt = ibstart;
4a4d8108
AM
17212+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
17213+ if (unlikely(err < 0))
17214+ goto out;
17215+ a->btgt = err;
17216+ if (err != bstart)
17217+ au_fset_icpup(a->flags, DID_CPUP);
17218+
17219+ err = 0;
17220+ a->pin_flags = AuPin_MNT_WRITE;
17221+ parent = NULL;
17222+ if (!IS_ROOT(dentry)) {
17223+ au_fset_pin(a->pin_flags, DI_LOCKED);
17224+ parent = dget_parent(dentry);
17225+ di_write_lock_parent(parent);
17226+ }
17227+
17228+ err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags);
17229+ if (unlikely(err))
17230+ goto out_parent;
17231+
17232+ a->h_path.dentry = au_h_dptr(dentry, bstart);
17233+ a->h_inode = a->h_path.dentry->d_inode;
17234+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
17235+ sz = -1;
17236+ if ((ia->ia_valid & ATTR_SIZE) && ia->ia_size < i_size_read(a->h_inode))
17237+ sz = ia->ia_size;
86dc4139 17238+ mutex_unlock(&a->h_inode->i_mutex);
4a4d8108 17239+
4a4d8108 17240+ hi_wh = NULL;
027c5e7a 17241+ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) {
4a4d8108
AM
17242+ hi_wh = au_hi_wh(inode, a->btgt);
17243+ if (!hi_wh) {
c2b27bf2
AM
17244+ struct au_cp_generic cpg = {
17245+ .dentry = dentry,
17246+ .bdst = a->btgt,
17247+ .bsrc = -1,
17248+ .len = sz,
17249+ .pin = &a->pin
17250+ };
17251+ err = au_sio_cpup_wh(&cpg, /*file*/NULL);
4a4d8108
AM
17252+ if (unlikely(err))
17253+ goto out_unlock;
17254+ hi_wh = au_hi_wh(inode, a->btgt);
17255+ /* todo: revalidate hi_wh? */
17256+ }
17257+ }
17258+
17259+ if (parent) {
17260+ au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
17261+ di_downgrade_lock(parent, AuLock_IR);
17262+ dput(parent);
17263+ parent = NULL;
17264+ }
17265+ if (!au_ftest_icpup(a->flags, DID_CPUP))
17266+ goto out; /* success */
17267+
17268+ if (!d_unhashed(dentry)) {
c2b27bf2
AM
17269+ struct au_cp_generic cpg = {
17270+ .dentry = dentry,
17271+ .bdst = a->btgt,
17272+ .bsrc = bstart,
17273+ .len = sz,
17274+ .pin = &a->pin,
17275+ .flags = AuCpup_DTIME | AuCpup_HOPEN
17276+ };
17277+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
17278+ if (!err)
17279+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
17280+ } else if (!hi_wh)
17281+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
17282+ else
17283+ a->h_path.dentry = hi_wh; /* do not dget here */
1308ab2a 17284+
4f0767ce 17285+out_unlock:
4a4d8108 17286+ a->h_inode = a->h_path.dentry->d_inode;
86dc4139 17287+ if (!err)
dece6358 17288+ goto out; /* success */
4a4d8108 17289+ au_unpin(&a->pin);
4f0767ce 17290+out_parent:
4a4d8108
AM
17291+ if (parent) {
17292+ di_write_unlock(parent);
17293+ dput(parent);
17294+ }
4f0767ce 17295+out:
86dc4139
AM
17296+ if (!err)
17297+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
1facf9fc 17298+ return err;
17299+}
17300+
4a4d8108 17301+static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
1facf9fc 17302+{
4a4d8108 17303+ int err;
523b37e3 17304+ struct inode *inode, *delegated;
4a4d8108
AM
17305+ struct super_block *sb;
17306+ struct file *file;
17307+ struct au_icpup_args *a;
1facf9fc 17308+
4a4d8108
AM
17309+ inode = dentry->d_inode;
17310+ IMustLock(inode);
dece6358 17311+
4a4d8108
AM
17312+ err = -ENOMEM;
17313+ a = kzalloc(sizeof(*a), GFP_NOFS);
17314+ if (unlikely(!a))
17315+ goto out;
1facf9fc 17316+
4a4d8108
AM
17317+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
17318+ ia->ia_valid &= ~ATTR_MODE;
dece6358 17319+
4a4d8108
AM
17320+ file = NULL;
17321+ sb = dentry->d_sb;
e49829fe
JR
17322+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
17323+ if (unlikely(err))
17324+ goto out_kfree;
17325+
4a4d8108
AM
17326+ if (ia->ia_valid & ATTR_FILE) {
17327+ /* currently ftruncate(2) only */
17328+ AuDebugOn(!S_ISREG(inode->i_mode));
17329+ file = ia->ia_file;
17330+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
17331+ if (unlikely(err))
17332+ goto out_si;
17333+ ia->ia_file = au_hf_top(file);
17334+ a->udba = AuOpt_UDBA_NONE;
17335+ } else {
17336+ /* fchmod() doesn't pass ia_file */
17337+ a->udba = au_opt_udba(sb);
027c5e7a
AM
17338+ di_write_lock_child(dentry);
17339+ /* no d_unlinked(), to set UDBA_NONE for root */
4a4d8108
AM
17340+ if (d_unhashed(dentry))
17341+ a->udba = AuOpt_UDBA_NONE;
4a4d8108
AM
17342+ if (a->udba != AuOpt_UDBA_NONE) {
17343+ AuDebugOn(IS_ROOT(dentry));
17344+ err = au_reval_for_attr(dentry, au_sigen(sb));
17345+ if (unlikely(err))
17346+ goto out_dentry;
17347+ }
dece6358 17348+ }
dece6358 17349+
4a4d8108
AM
17350+ err = au_pin_and_icpup(dentry, ia, a);
17351+ if (unlikely(err < 0))
17352+ goto out_dentry;
17353+ if (au_ftest_icpup(a->flags, DID_CPUP)) {
17354+ ia->ia_file = NULL;
17355+ ia->ia_valid &= ~ATTR_FILE;
1308ab2a 17356+ }
dece6358 17357+
4a4d8108
AM
17358+ a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
17359+ if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME))
17360+ == (ATTR_MODE | ATTR_CTIME)) {
7eafdf33 17361+ err = security_path_chmod(&a->h_path, ia->ia_mode);
4a4d8108
AM
17362+ if (unlikely(err))
17363+ goto out_unlock;
17364+ } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
17365+ && (ia->ia_valid & ATTR_CTIME)) {
86dc4139 17366+ err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid);
4a4d8108
AM
17367+ if (unlikely(err))
17368+ goto out_unlock;
17369+ }
dece6358 17370+
4a4d8108
AM
17371+ if (ia->ia_valid & ATTR_SIZE) {
17372+ struct file *f;
1308ab2a 17373+
953406b4 17374+ if (ia->ia_size < i_size_read(inode))
4a4d8108 17375+ /* unmap only */
953406b4 17376+ truncate_setsize(inode, ia->ia_size);
1308ab2a 17377+
4a4d8108
AM
17378+ f = NULL;
17379+ if (ia->ia_valid & ATTR_FILE)
17380+ f = ia->ia_file;
17381+ mutex_unlock(&a->h_inode->i_mutex);
17382+ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
17383+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
523b37e3
AM
17384+ } else {
17385+ delegated = NULL;
17386+ while (1) {
17387+ err = vfsub_notify_change(&a->h_path, ia, &delegated);
17388+ if (delegated) {
17389+ err = break_deleg_wait(&delegated);
17390+ if (!err)
17391+ continue;
17392+ }
17393+ break;
17394+ }
17395+ }
4a4d8108
AM
17396+ if (!err)
17397+ au_cpup_attr_changeable(inode);
1308ab2a 17398+
4f0767ce 17399+out_unlock:
4a4d8108
AM
17400+ mutex_unlock(&a->h_inode->i_mutex);
17401+ au_unpin(&a->pin);
027c5e7a
AM
17402+ if (unlikely(err))
17403+ au_update_dbstart(dentry);
4f0767ce 17404+out_dentry:
4a4d8108
AM
17405+ di_write_unlock(dentry);
17406+ if (file) {
17407+ fi_write_unlock(file);
17408+ ia->ia_file = file;
17409+ ia->ia_valid |= ATTR_FILE;
17410+ }
4f0767ce 17411+out_si:
4a4d8108 17412+ si_read_unlock(sb);
e49829fe 17413+out_kfree:
4a4d8108 17414+ kfree(a);
4f0767ce 17415+out:
4a4d8108
AM
17416+ AuTraceErr(err);
17417+ return err;
1facf9fc 17418+}
17419+
4a4d8108
AM
17420+static void au_refresh_iattr(struct inode *inode, struct kstat *st,
17421+ unsigned int nlink)
1facf9fc 17422+{
9dbd164d
AM
17423+ unsigned int n;
17424+
4a4d8108 17425+ inode->i_mode = st->mode;
86dc4139
AM
17426+ /* don't i_[ug]id_write() here */
17427+ inode->i_uid = st->uid;
17428+ inode->i_gid = st->gid;
4a4d8108
AM
17429+ inode->i_atime = st->atime;
17430+ inode->i_mtime = st->mtime;
17431+ inode->i_ctime = st->ctime;
1facf9fc 17432+
4a4d8108
AM
17433+ au_cpup_attr_nlink(inode, /*force*/0);
17434+ if (S_ISDIR(inode->i_mode)) {
9dbd164d
AM
17435+ n = inode->i_nlink;
17436+ n -= nlink;
17437+ n += st->nlink;
f6b6e03d 17438+ smp_mb(); /* for i_nlink */
7eafdf33 17439+ /* 0 can happen */
92d182d2 17440+ set_nlink(inode, n);
4a4d8108 17441+ }
1facf9fc 17442+
4a4d8108
AM
17443+ spin_lock(&inode->i_lock);
17444+ inode->i_blocks = st->blocks;
17445+ i_size_write(inode, st->size);
17446+ spin_unlock(&inode->i_lock);
1facf9fc 17447+}
17448+
4a4d8108
AM
17449+static int aufs_getattr(struct vfsmount *mnt __maybe_unused,
17450+ struct dentry *dentry, struct kstat *st)
1facf9fc 17451+{
4a4d8108
AM
17452+ int err;
17453+ unsigned int mnt_flags;
17454+ aufs_bindex_t bindex;
17455+ unsigned char udba_none, positive;
17456+ struct super_block *sb, *h_sb;
17457+ struct inode *inode;
c06a8ce3 17458+ struct path h_path;
1facf9fc 17459+
4a4d8108
AM
17460+ sb = dentry->d_sb;
17461+ inode = dentry->d_inode;
7f207e10
AM
17462+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
17463+ if (unlikely(err))
17464+ goto out;
4a4d8108
AM
17465+ mnt_flags = au_mntflags(sb);
17466+ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
1facf9fc 17467+
4a4d8108 17468+ /* support fstat(2) */
027c5e7a 17469+ if (!d_unlinked(dentry) && !udba_none) {
4a4d8108 17470+ unsigned int sigen = au_sigen(sb);
027c5e7a
AM
17471+ err = au_digen_test(dentry, sigen);
17472+ if (!err) {
4a4d8108 17473+ di_read_lock_child(dentry, AuLock_IR);
027c5e7a
AM
17474+ err = au_dbrange_test(dentry);
17475+ if (unlikely(err))
17476+ goto out_unlock;
17477+ } else {
4a4d8108
AM
17478+ AuDebugOn(IS_ROOT(dentry));
17479+ di_write_lock_child(dentry);
027c5e7a
AM
17480+ err = au_dbrange_test(dentry);
17481+ if (!err)
17482+ err = au_reval_for_attr(dentry, sigen);
4a4d8108
AM
17483+ di_downgrade_lock(dentry, AuLock_IR);
17484+ if (unlikely(err))
7f207e10 17485+ goto out_unlock;
4a4d8108
AM
17486+ }
17487+ } else
17488+ di_read_lock_child(dentry, AuLock_IR);
1facf9fc 17489+
4a4d8108 17490+ bindex = au_ibstart(inode);
c06a8ce3
AM
17491+ h_path.mnt = au_sbr_mnt(sb, bindex);
17492+ h_sb = h_path.mnt->mnt_sb;
4a4d8108
AM
17493+ if (!au_test_fs_bad_iattr(h_sb) && udba_none)
17494+ goto out_fill; /* success */
1facf9fc 17495+
c06a8ce3 17496+ h_path.dentry = NULL;
4a4d8108 17497+ if (au_dbstart(dentry) == bindex)
c06a8ce3 17498+ h_path.dentry = dget(au_h_dptr(dentry, bindex));
4a4d8108 17499+ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
c06a8ce3
AM
17500+ h_path.dentry = au_plink_lkup(inode, bindex);
17501+ if (IS_ERR(h_path.dentry))
4a4d8108
AM
17502+ goto out_fill; /* pretending success */
17503+ }
17504+ /* illegally overlapped or something */
c06a8ce3 17505+ if (unlikely(!h_path.dentry))
4a4d8108
AM
17506+ goto out_fill; /* pretending success */
17507+
c06a8ce3 17508+ positive = !!h_path.dentry->d_inode;
4a4d8108 17509+ if (positive)
c06a8ce3
AM
17510+ err = vfs_getattr(&h_path, st);
17511+ dput(h_path.dentry);
4a4d8108
AM
17512+ if (!err) {
17513+ if (positive)
c06a8ce3
AM
17514+ au_refresh_iattr(inode, st,
17515+ h_path.dentry->d_inode->i_nlink);
4a4d8108 17516+ goto out_fill; /* success */
1facf9fc 17517+ }
7f207e10
AM
17518+ AuTraceErr(err);
17519+ goto out_unlock;
4a4d8108 17520+
4f0767ce 17521+out_fill:
4a4d8108 17522+ generic_fillattr(inode, st);
7f207e10 17523+out_unlock:
4a4d8108
AM
17524+ di_read_unlock(dentry, AuLock_IR);
17525+ si_read_unlock(sb);
7f207e10
AM
17526+out:
17527+ AuTraceErr(err);
4a4d8108 17528+ return err;
1facf9fc 17529+}
17530+
17531+/* ---------------------------------------------------------------------- */
17532+
4a4d8108
AM
17533+static int h_readlink(struct dentry *dentry, int bindex, char __user *buf,
17534+ int bufsiz)
1facf9fc 17535+{
17536+ int err;
4a4d8108
AM
17537+ struct super_block *sb;
17538+ struct dentry *h_dentry;
1facf9fc 17539+
4a4d8108
AM
17540+ err = -EINVAL;
17541+ h_dentry = au_h_dptr(dentry, bindex);
17542+ if (unlikely(!h_dentry->d_inode->i_op->readlink))
17543+ goto out;
1facf9fc 17544+
4a4d8108
AM
17545+ err = security_inode_readlink(h_dentry);
17546+ if (unlikely(err))
dece6358 17547+ goto out;
1facf9fc 17548+
4a4d8108
AM
17549+ sb = dentry->d_sb;
17550+ if (!au_test_ro(sb, bindex, dentry->d_inode)) {
17551+ vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry);
17552+ fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode);
1facf9fc 17553+ }
4a4d8108 17554+ err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz);
1facf9fc 17555+
4f0767ce 17556+out:
4a4d8108
AM
17557+ return err;
17558+}
1facf9fc 17559+
4a4d8108
AM
17560+static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
17561+{
17562+ int err;
1facf9fc 17563+
027c5e7a
AM
17564+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
17565+ if (unlikely(err))
17566+ goto out;
17567+ err = au_d_hashed_positive(dentry);
17568+ if (!err)
17569+ err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz);
4a4d8108 17570+ aufs_read_unlock(dentry, AuLock_IR);
1facf9fc 17571+
027c5e7a 17572+out:
4a4d8108
AM
17573+ return err;
17574+}
1facf9fc 17575+
4a4d8108
AM
17576+static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd)
17577+{
17578+ int err;
4a4d8108 17579+ mm_segment_t old_fs;
b752ccd1
AM
17580+ union {
17581+ char *k;
17582+ char __user *u;
17583+ } buf;
1facf9fc 17584+
4a4d8108 17585+ err = -ENOMEM;
537831f9 17586+ buf.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 17587+ if (unlikely(!buf.k))
4a4d8108 17588+ goto out;
1facf9fc 17589+
027c5e7a
AM
17590+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
17591+ if (unlikely(err))
17592+ goto out_name;
17593+
17594+ err = au_d_hashed_positive(dentry);
17595+ if (!err) {
17596+ old_fs = get_fs();
17597+ set_fs(KERNEL_DS);
17598+ err = h_readlink(dentry, au_dbstart(dentry), buf.u, PATH_MAX);
17599+ set_fs(old_fs);
17600+ }
4a4d8108 17601+ aufs_read_unlock(dentry, AuLock_IR);
1facf9fc 17602+
4a4d8108 17603+ if (err >= 0) {
b752ccd1 17604+ buf.k[err] = 0;
4a4d8108 17605+ /* will be freed by put_link */
b752ccd1 17606+ nd_set_link(nd, buf.k);
4a4d8108 17607+ return NULL; /* success */
1308ab2a 17608+ }
1facf9fc 17609+
027c5e7a 17610+out_name:
537831f9 17611+ free_page((unsigned long)buf.k);
4f0767ce 17612+out:
4a4d8108
AM
17613+ AuTraceErr(err);
17614+ return ERR_PTR(err);
17615+}
1facf9fc 17616+
4a4d8108
AM
17617+static void aufs_put_link(struct dentry *dentry __maybe_unused,
17618+ struct nameidata *nd, void *cookie __maybe_unused)
17619+{
537831f9
AM
17620+ char *p;
17621+
17622+ p = nd_get_link(nd);
17623+ if (!IS_ERR_OR_NULL(p))
17624+ free_page((unsigned long)p);
4a4d8108 17625+}
1facf9fc 17626+
4a4d8108 17627+/* ---------------------------------------------------------------------- */
1facf9fc 17628+
0c3ec466 17629+static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags)
4a4d8108 17630+{
0c3ec466
AM
17631+ int err;
17632+ struct super_block *sb;
17633+ struct inode *h_inode;
17634+
17635+ sb = inode->i_sb;
17636+ /* mmap_sem might be acquired already, cf. aufs_mmap() */
17637+ lockdep_off();
17638+ si_read_lock(sb, AuLock_FLUSH);
17639+ ii_write_lock_child(inode);
17640+ lockdep_on();
17641+ h_inode = au_h_iptr(inode, au_ibstart(inode));
17642+ err = vfsub_update_time(h_inode, ts, flags);
17643+ lockdep_off();
17644+ ii_write_unlock(inode);
17645+ si_read_unlock(sb);
17646+ lockdep_on();
17647+ return err;
4a4d8108 17648+}
1facf9fc 17649+
4a4d8108 17650+/* ---------------------------------------------------------------------- */
1308ab2a 17651+
4a4d8108
AM
17652+struct inode_operations aufs_symlink_iop = {
17653+ .permission = aufs_permission,
17654+ .setattr = aufs_setattr,
17655+ .getattr = aufs_getattr,
0c3ec466 17656+
4a4d8108
AM
17657+ .readlink = aufs_readlink,
17658+ .follow_link = aufs_follow_link,
0c3ec466
AM
17659+ .put_link = aufs_put_link,
17660+
17661+ /* .update_time = aufs_update_time */
4a4d8108
AM
17662+};
17663+
17664+struct inode_operations aufs_dir_iop = {
17665+ .create = aufs_create,
17666+ .lookup = aufs_lookup,
17667+ .link = aufs_link,
17668+ .unlink = aufs_unlink,
17669+ .symlink = aufs_symlink,
17670+ .mkdir = aufs_mkdir,
17671+ .rmdir = aufs_rmdir,
17672+ .mknod = aufs_mknod,
17673+ .rename = aufs_rename,
17674+
17675+ .permission = aufs_permission,
17676+ .setattr = aufs_setattr,
0c3ec466
AM
17677+ .getattr = aufs_getattr,
17678+
17679+ .update_time = aufs_update_time
b4510431 17680+ /* no support for atomic_open() */
4a4d8108
AM
17681+};
17682+
17683+struct inode_operations aufs_iop = {
17684+ .permission = aufs_permission,
17685+ .setattr = aufs_setattr,
17686+ .getattr = aufs_getattr,
0c3ec466
AM
17687+
17688+ .update_time = aufs_update_time
4a4d8108 17689+};
7f207e10
AM
17690diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
17691--- /usr/share/empty/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
17692+++ linux/fs/aufs/i_op_del.c 2014-01-20 20:16:14.739463504 +0100
17693@@ -0,0 +1,506 @@
1facf9fc 17694+/*
523b37e3 17695+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 17696+ *
17697+ * This program, aufs is free software; you can redistribute it and/or modify
17698+ * it under the terms of the GNU General Public License as published by
17699+ * the Free Software Foundation; either version 2 of the License, or
17700+ * (at your option) any later version.
dece6358
AM
17701+ *
17702+ * This program is distributed in the hope that it will be useful,
17703+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17704+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17705+ * GNU General Public License for more details.
17706+ *
17707+ * You should have received a copy of the GNU General Public License
523b37e3 17708+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 17709+ */
17710+
17711+/*
4a4d8108 17712+ * inode operations (del entry)
1308ab2a 17713+ */
dece6358 17714+
1308ab2a 17715+#include "aufs.h"
dece6358 17716+
4a4d8108
AM
17717+/*
17718+ * decide if a new whiteout for @dentry is necessary or not.
17719+ * when it is necessary, prepare the parent dir for the upper branch whose
17720+ * branch index is @bcpup for creation. the actual creation of the whiteout will
17721+ * be done by caller.
17722+ * return value:
17723+ * 0: wh is unnecessary
17724+ * plus: wh is necessary
17725+ * minus: error
17726+ */
17727+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
1308ab2a 17728+{
4a4d8108
AM
17729+ int need_wh, err;
17730+ aufs_bindex_t bstart;
17731+ struct super_block *sb;
dece6358 17732+
4a4d8108
AM
17733+ sb = dentry->d_sb;
17734+ bstart = au_dbstart(dentry);
17735+ if (*bcpup < 0) {
17736+ *bcpup = bstart;
17737+ if (au_test_ro(sb, bstart, dentry->d_inode)) {
17738+ err = AuWbrCopyup(au_sbi(sb), dentry);
17739+ *bcpup = err;
17740+ if (unlikely(err < 0))
17741+ goto out;
17742+ }
17743+ } else
17744+ AuDebugOn(bstart < *bcpup
17745+ || au_test_ro(sb, *bcpup, dentry->d_inode));
17746+ AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
1308ab2a 17747+
4a4d8108
AM
17748+ if (*bcpup != bstart) {
17749+ err = au_cpup_dirs(dentry, *bcpup);
17750+ if (unlikely(err))
17751+ goto out;
17752+ need_wh = 1;
17753+ } else {
027c5e7a 17754+ struct au_dinfo *dinfo, *tmp;
4a4d8108 17755+
027c5e7a
AM
17756+ need_wh = -ENOMEM;
17757+ dinfo = au_di(dentry);
17758+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
17759+ if (tmp) {
17760+ au_di_cp(tmp, dinfo);
17761+ au_di_swap(tmp, dinfo);
17762+ /* returns the number of positive dentries */
537831f9 17763+ need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0);
027c5e7a
AM
17764+ au_di_swap(tmp, dinfo);
17765+ au_rw_write_unlock(&tmp->di_rwsem);
17766+ au_di_free(tmp);
4a4d8108
AM
17767+ }
17768+ }
17769+ AuDbg("need_wh %d\n", need_wh);
17770+ err = need_wh;
17771+
4f0767ce 17772+out:
4a4d8108 17773+ return err;
1facf9fc 17774+}
17775+
4a4d8108
AM
17776+/*
17777+ * simple tests for the del-entry operations.
17778+ * following the checks in vfs, plus the parent-child relationship.
17779+ */
17780+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
17781+ struct dentry *h_parent, int isdir)
1facf9fc 17782+{
4a4d8108
AM
17783+ int err;
17784+ umode_t h_mode;
17785+ struct dentry *h_dentry, *h_latest;
1308ab2a 17786+ struct inode *h_inode;
1facf9fc 17787+
4a4d8108
AM
17788+ h_dentry = au_h_dptr(dentry, bindex);
17789+ h_inode = h_dentry->d_inode;
17790+ if (dentry->d_inode) {
17791+ err = -ENOENT;
17792+ if (unlikely(!h_inode || !h_inode->i_nlink))
17793+ goto out;
1facf9fc 17794+
4a4d8108
AM
17795+ h_mode = h_inode->i_mode;
17796+ if (!isdir) {
17797+ err = -EISDIR;
17798+ if (unlikely(S_ISDIR(h_mode)))
17799+ goto out;
17800+ } else if (unlikely(!S_ISDIR(h_mode))) {
17801+ err = -ENOTDIR;
17802+ goto out;
17803+ }
17804+ } else {
17805+ /* rename(2) case */
17806+ err = -EIO;
17807+ if (unlikely(h_inode))
17808+ goto out;
17809+ }
1facf9fc 17810+
4a4d8108
AM
17811+ err = -ENOENT;
17812+ /* expected parent dir is locked */
17813+ if (unlikely(h_parent != h_dentry->d_parent))
17814+ goto out;
17815+ err = 0;
17816+
17817+ /*
17818+ * rmdir a dir may break the consistency on some filesystem.
17819+ * let's try heavy test.
17820+ */
17821+ err = -EACCES;
17822+ if (unlikely(au_test_h_perm(h_parent->d_inode, MAY_EXEC | MAY_WRITE)))
17823+ goto out;
17824+
17825+ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent,
17826+ au_sbr(dentry->d_sb, bindex));
17827+ err = -EIO;
17828+ if (IS_ERR(h_latest))
17829+ goto out;
17830+ if (h_latest == h_dentry)
17831+ err = 0;
17832+ dput(h_latest);
17833+
4f0767ce 17834+out:
4a4d8108 17835+ return err;
1308ab2a 17836+}
1facf9fc 17837+
4a4d8108
AM
17838+/*
17839+ * decide the branch where we operate for @dentry. the branch index will be set
17840+ * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
17841+ * dir for reverting.
17842+ * when a new whiteout is necessary, create it.
17843+ */
17844+static struct dentry*
17845+lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
17846+ struct au_dtime *dt, struct au_pin *pin)
1308ab2a 17847+{
4a4d8108
AM
17848+ struct dentry *wh_dentry;
17849+ struct super_block *sb;
17850+ struct path h_path;
17851+ int err, need_wh;
17852+ unsigned int udba;
17853+ aufs_bindex_t bcpup;
dece6358 17854+
4a4d8108
AM
17855+ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
17856+ wh_dentry = ERR_PTR(need_wh);
17857+ if (unlikely(need_wh < 0))
17858+ goto out;
17859+
17860+ sb = dentry->d_sb;
17861+ udba = au_opt_udba(sb);
17862+ bcpup = *rbcpup;
17863+ err = au_pin(pin, dentry, bcpup, udba,
17864+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17865+ wh_dentry = ERR_PTR(err);
17866+ if (unlikely(err))
17867+ goto out;
17868+
17869+ h_path.dentry = au_pinned_h_parent(pin);
17870+ if (udba != AuOpt_UDBA_NONE
17871+ && au_dbstart(dentry) == bcpup) {
17872+ err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
17873+ wh_dentry = ERR_PTR(err);
17874+ if (unlikely(err))
17875+ goto out_unpin;
17876+ }
17877+
17878+ h_path.mnt = au_sbr_mnt(sb, bcpup);
17879+ au_dtime_store(dt, au_pinned_parent(pin), &h_path);
17880+ wh_dentry = NULL;
17881+ if (!need_wh)
17882+ goto out; /* success, no need to create whiteout */
17883+
17884+ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
17885+ if (IS_ERR(wh_dentry))
17886+ goto out_unpin;
17887+
17888+ /* returns with the parent is locked and wh_dentry is dget-ed */
17889+ goto out; /* success */
17890+
4f0767ce 17891+out_unpin:
4a4d8108 17892+ au_unpin(pin);
4f0767ce 17893+out:
4a4d8108 17894+ return wh_dentry;
1facf9fc 17895+}
17896+
4a4d8108
AM
17897+/*
17898+ * when removing a dir, rename it to a unique temporary whiteout-ed name first
17899+ * in order to be revertible and save time for removing many child whiteouts
17900+ * under the dir.
17901+ * returns 1 when there are too many child whiteout and caller should remove
17902+ * them asynchronously. returns 0 when the number of children is enough small to
17903+ * remove now or the branch fs is a remote fs.
17904+ * otherwise return an error.
17905+ */
17906+static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
17907+ struct au_nhash *whlist, struct inode *dir)
1facf9fc 17908+{
4a4d8108
AM
17909+ int rmdir_later, err, dirwh;
17910+ struct dentry *h_dentry;
17911+ struct super_block *sb;
17912+
17913+ sb = dentry->d_sb;
17914+ SiMustAnyLock(sb);
17915+ h_dentry = au_h_dptr(dentry, bindex);
17916+ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
17917+ if (unlikely(err))
17918+ goto out;
17919+
17920+ /* stop monitoring */
17921+ au_hn_free(au_hi(dentry->d_inode, bindex));
17922+
17923+ if (!au_test_fs_remote(h_dentry->d_sb)) {
17924+ dirwh = au_sbi(sb)->si_dirwh;
17925+ rmdir_later = (dirwh <= 1);
17926+ if (!rmdir_later)
17927+ rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
17928+ dirwh);
17929+ if (rmdir_later)
17930+ return rmdir_later;
17931+ }
1facf9fc 17932+
4a4d8108
AM
17933+ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
17934+ if (unlikely(err)) {
523b37e3
AM
17935+ AuIOErr("rmdir %pd, b%d failed, %d. ignored\n",
17936+ h_dentry, bindex, err);
4a4d8108
AM
17937+ err = 0;
17938+ }
dece6358 17939+
4f0767ce 17940+out:
4a4d8108
AM
17941+ AuTraceErr(err);
17942+ return err;
17943+}
1308ab2a 17944+
4a4d8108
AM
17945+/*
17946+ * final procedure for deleting a entry.
17947+ * maintain dentry and iattr.
17948+ */
17949+static void epilog(struct inode *dir, struct dentry *dentry,
17950+ aufs_bindex_t bindex)
17951+{
17952+ struct inode *inode;
1308ab2a 17953+
4a4d8108
AM
17954+ inode = dentry->d_inode;
17955+ d_drop(dentry);
17956+ inode->i_ctime = dir->i_ctime;
1308ab2a 17957+
4a4d8108
AM
17958+ if (au_ibstart(dir) == bindex)
17959+ au_cpup_attr_timesizes(dir);
17960+ dir->i_version++;
1facf9fc 17961+}
17962+
4a4d8108
AM
17963+/*
17964+ * when an error happened, remove the created whiteout and revert everything.
17965+ */
7f207e10
AM
17966+static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex,
17967+ aufs_bindex_t bwh, struct dentry *wh_dentry,
17968+ struct dentry *dentry, struct au_dtime *dt)
1facf9fc 17969+{
4a4d8108
AM
17970+ int rerr;
17971+ struct path h_path = {
17972+ .dentry = wh_dentry,
7f207e10 17973+ .mnt = au_sbr_mnt(dir->i_sb, bindex)
4a4d8108 17974+ };
dece6358 17975+
7f207e10 17976+ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
4a4d8108
AM
17977+ if (!rerr) {
17978+ au_set_dbwh(dentry, bwh);
17979+ au_dtime_revert(dt);
17980+ return 0;
17981+ }
dece6358 17982+
523b37e3 17983+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", dentry, err, rerr);
4a4d8108 17984+ return -EIO;
1facf9fc 17985+}
17986+
4a4d8108 17987+/* ---------------------------------------------------------------------- */
1facf9fc 17988+
4a4d8108 17989+int aufs_unlink(struct inode *dir, struct dentry *dentry)
1308ab2a 17990+{
4a4d8108
AM
17991+ int err;
17992+ aufs_bindex_t bwh, bindex, bstart;
523b37e3 17993+ struct inode *inode, *h_dir, *delegated;
4a4d8108 17994+ struct dentry *parent, *wh_dentry;
c2b27bf2
AM
17995+ /* to reuduce stack size */
17996+ struct {
17997+ struct au_dtime dt;
17998+ struct au_pin pin;
17999+ struct path h_path;
18000+ } *a;
1facf9fc 18001+
4a4d8108 18002+ IMustLock(dir);
027c5e7a 18003+
c2b27bf2
AM
18004+ err = -ENOMEM;
18005+ a = kmalloc(sizeof(*a), GFP_NOFS);
18006+ if (unlikely(!a))
18007+ goto out;
18008+
027c5e7a
AM
18009+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
18010+ if (unlikely(err))
c2b27bf2 18011+ goto out_free;
027c5e7a
AM
18012+ err = au_d_hashed_positive(dentry);
18013+ if (unlikely(err))
18014+ goto out_unlock;
4a4d8108 18015+ inode = dentry->d_inode;
4a4d8108 18016+ IMustLock(inode);
027c5e7a
AM
18017+ err = -EISDIR;
18018+ if (unlikely(S_ISDIR(inode->i_mode)))
18019+ goto out_unlock; /* possible? */
1facf9fc 18020+
4a4d8108
AM
18021+ bstart = au_dbstart(dentry);
18022+ bwh = au_dbwh(dentry);
18023+ bindex = -1;
027c5e7a
AM
18024+ parent = dentry->d_parent; /* dir inode is locked */
18025+ di_write_lock_parent(parent);
c2b27bf2
AM
18026+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &a->dt,
18027+ &a->pin);
4a4d8108
AM
18028+ err = PTR_ERR(wh_dentry);
18029+ if (IS_ERR(wh_dentry))
027c5e7a 18030+ goto out_parent;
1facf9fc 18031+
c2b27bf2
AM
18032+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
18033+ a->h_path.dentry = au_h_dptr(dentry, bstart);
18034+ dget(a->h_path.dentry);
4a4d8108 18035+ if (bindex == bstart) {
c2b27bf2 18036+ h_dir = au_pinned_h_dir(&a->pin);
523b37e3
AM
18037+ delegated = NULL;
18038+ err = vfsub_unlink(h_dir, &a->h_path, &delegated, /*force*/0);
18039+ if (unlikely(err == -EWOULDBLOCK)) {
18040+ pr_warn("cannot retry for NFSv4 delegation"
18041+ " for an internal unlink\n");
18042+ iput(delegated);
18043+ }
4a4d8108
AM
18044+ } else {
18045+ /* dir inode is locked */
18046+ h_dir = wh_dentry->d_parent->d_inode;
18047+ IMustLock(h_dir);
18048+ err = 0;
18049+ }
dece6358 18050+
4a4d8108 18051+ if (!err) {
7f207e10 18052+ vfsub_drop_nlink(inode);
4a4d8108
AM
18053+ epilog(dir, dentry, bindex);
18054+
18055+ /* update target timestamps */
18056+ if (bindex == bstart) {
c2b27bf2
AM
18057+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL);
18058+ /*ignore*/
18059+ inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
4a4d8108
AM
18060+ } else
18061+ /* todo: this timestamp may be reverted later */
18062+ inode->i_ctime = h_dir->i_ctime;
027c5e7a 18063+ goto out_unpin; /* success */
1facf9fc 18064+ }
18065+
4a4d8108
AM
18066+ /* revert */
18067+ if (wh_dentry) {
18068+ int rerr;
18069+
c2b27bf2
AM
18070+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
18071+ &a->dt);
4a4d8108
AM
18072+ if (rerr)
18073+ err = rerr;
dece6358 18074+ }
1facf9fc 18075+
027c5e7a 18076+out_unpin:
c2b27bf2 18077+ au_unpin(&a->pin);
4a4d8108 18078+ dput(wh_dentry);
c2b27bf2 18079+ dput(a->h_path.dentry);
027c5e7a 18080+out_parent:
4a4d8108 18081+ di_write_unlock(parent);
027c5e7a 18082+out_unlock:
4a4d8108 18083+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
18084+out_free:
18085+ kfree(a);
027c5e7a 18086+out:
4a4d8108 18087+ return err;
dece6358
AM
18088+}
18089+
4a4d8108 18090+int aufs_rmdir(struct inode *dir, struct dentry *dentry)
1308ab2a 18091+{
4a4d8108
AM
18092+ int err, rmdir_later;
18093+ aufs_bindex_t bwh, bindex, bstart;
4a4d8108
AM
18094+ struct inode *inode;
18095+ struct dentry *parent, *wh_dentry, *h_dentry;
18096+ struct au_whtmp_rmdir *args;
c2b27bf2
AM
18097+ /* to reuduce stack size */
18098+ struct {
18099+ struct au_dtime dt;
18100+ struct au_pin pin;
18101+ } *a;
1facf9fc 18102+
4a4d8108 18103+ IMustLock(dir);
027c5e7a 18104+
c2b27bf2
AM
18105+ err = -ENOMEM;
18106+ a = kmalloc(sizeof(*a), GFP_NOFS);
18107+ if (unlikely(!a))
18108+ goto out;
18109+
027c5e7a
AM
18110+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
18111+ if (unlikely(err))
c2b27bf2 18112+ goto out_free;
53392da6
AM
18113+ err = au_alive_dir(dentry);
18114+ if (unlikely(err))
027c5e7a 18115+ goto out_unlock;
53392da6 18116+ inode = dentry->d_inode;
4a4d8108 18117+ IMustLock(inode);
027c5e7a
AM
18118+ err = -ENOTDIR;
18119+ if (unlikely(!S_ISDIR(inode->i_mode)))
18120+ goto out_unlock; /* possible? */
dece6358 18121+
4a4d8108
AM
18122+ err = -ENOMEM;
18123+ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
18124+ if (unlikely(!args))
18125+ goto out_unlock;
dece6358 18126+
4a4d8108
AM
18127+ parent = dentry->d_parent; /* dir inode is locked */
18128+ di_write_lock_parent(parent);
18129+ err = au_test_empty(dentry, &args->whlist);
18130+ if (unlikely(err))
027c5e7a 18131+ goto out_parent;
1facf9fc 18132+
4a4d8108
AM
18133+ bstart = au_dbstart(dentry);
18134+ bwh = au_dbwh(dentry);
18135+ bindex = -1;
c2b27bf2
AM
18136+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &a->dt,
18137+ &a->pin);
4a4d8108
AM
18138+ err = PTR_ERR(wh_dentry);
18139+ if (IS_ERR(wh_dentry))
027c5e7a 18140+ goto out_parent;
1facf9fc 18141+
4a4d8108
AM
18142+ h_dentry = au_h_dptr(dentry, bstart);
18143+ dget(h_dentry);
18144+ rmdir_later = 0;
18145+ if (bindex == bstart) {
18146+ err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir);
18147+ if (err > 0) {
18148+ rmdir_later = err;
18149+ err = 0;
18150+ }
18151+ } else {
18152+ /* stop monitoring */
18153+ au_hn_free(au_hi(inode, bstart));
18154+
18155+ /* dir inode is locked */
18156+ IMustLock(wh_dentry->d_parent->d_inode);
1facf9fc 18157+ err = 0;
18158+ }
18159+
4a4d8108 18160+ if (!err) {
027c5e7a 18161+ vfsub_dead_dir(inode);
4a4d8108
AM
18162+ au_set_dbdiropq(dentry, -1);
18163+ epilog(dir, dentry, bindex);
1308ab2a 18164+
4a4d8108
AM
18165+ if (rmdir_later) {
18166+ au_whtmp_kick_rmdir(dir, bstart, h_dentry, args);
18167+ args = NULL;
18168+ }
1308ab2a 18169+
4a4d8108 18170+ goto out_unpin; /* success */
1facf9fc 18171+ }
18172+
4a4d8108
AM
18173+ /* revert */
18174+ AuLabel(revert);
18175+ if (wh_dentry) {
18176+ int rerr;
1308ab2a 18177+
c2b27bf2
AM
18178+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
18179+ &a->dt);
4a4d8108
AM
18180+ if (rerr)
18181+ err = rerr;
1facf9fc 18182+ }
18183+
4f0767ce 18184+out_unpin:
c2b27bf2 18185+ au_unpin(&a->pin);
4a4d8108
AM
18186+ dput(wh_dentry);
18187+ dput(h_dentry);
027c5e7a 18188+out_parent:
4a4d8108
AM
18189+ di_write_unlock(parent);
18190+ if (args)
18191+ au_whtmp_rmdir_free(args);
4f0767ce 18192+out_unlock:
4a4d8108 18193+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
18194+out_free:
18195+ kfree(a);
4f0767ce 18196+out:
4a4d8108
AM
18197+ AuTraceErr(err);
18198+ return err;
dece6358 18199+}
7f207e10
AM
18200diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
18201--- /usr/share/empty/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
18202+++ linux/fs/aufs/i_op_ren.c 2014-01-20 20:16:14.739463504 +0100
18203@@ -0,0 +1,1032 @@
1facf9fc 18204+/*
523b37e3 18205+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 18206+ *
18207+ * This program, aufs is free software; you can redistribute it and/or modify
18208+ * it under the terms of the GNU General Public License as published by
18209+ * the Free Software Foundation; either version 2 of the License, or
18210+ * (at your option) any later version.
dece6358
AM
18211+ *
18212+ * This program is distributed in the hope that it will be useful,
18213+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18214+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18215+ * GNU General Public License for more details.
18216+ *
18217+ * You should have received a copy of the GNU General Public License
523b37e3 18218+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 18219+ */
18220+
18221+/*
4a4d8108
AM
18222+ * inode operation (rename entry)
18223+ * todo: this is crazy monster
1facf9fc 18224+ */
18225+
18226+#include "aufs.h"
18227+
4a4d8108
AM
18228+enum { AuSRC, AuDST, AuSrcDst };
18229+enum { AuPARENT, AuCHILD, AuParentChild };
1facf9fc 18230+
4a4d8108
AM
18231+#define AuRen_ISDIR 1
18232+#define AuRen_ISSAMEDIR (1 << 1)
18233+#define AuRen_WHSRC (1 << 2)
18234+#define AuRen_WHDST (1 << 3)
18235+#define AuRen_MNT_WRITE (1 << 4)
18236+#define AuRen_DT_DSTDIR (1 << 5)
18237+#define AuRen_DIROPQ (1 << 6)
18238+#define AuRen_CPUP (1 << 7)
18239+#define au_ftest_ren(flags, name) ((flags) & AuRen_##name)
7f207e10
AM
18240+#define au_fset_ren(flags, name) \
18241+ do { (flags) |= AuRen_##name; } while (0)
18242+#define au_fclr_ren(flags, name) \
18243+ do { (flags) &= ~AuRen_##name; } while (0)
1facf9fc 18244+
4a4d8108
AM
18245+struct au_ren_args {
18246+ struct {
18247+ struct dentry *dentry, *h_dentry, *parent, *h_parent,
18248+ *wh_dentry;
18249+ struct inode *dir, *inode;
18250+ struct au_hinode *hdir;
18251+ struct au_dtime dt[AuParentChild];
18252+ aufs_bindex_t bstart;
18253+ } sd[AuSrcDst];
1facf9fc 18254+
4a4d8108
AM
18255+#define src_dentry sd[AuSRC].dentry
18256+#define src_dir sd[AuSRC].dir
18257+#define src_inode sd[AuSRC].inode
18258+#define src_h_dentry sd[AuSRC].h_dentry
18259+#define src_parent sd[AuSRC].parent
18260+#define src_h_parent sd[AuSRC].h_parent
18261+#define src_wh_dentry sd[AuSRC].wh_dentry
18262+#define src_hdir sd[AuSRC].hdir
18263+#define src_h_dir sd[AuSRC].hdir->hi_inode
18264+#define src_dt sd[AuSRC].dt
18265+#define src_bstart sd[AuSRC].bstart
1facf9fc 18266+
4a4d8108
AM
18267+#define dst_dentry sd[AuDST].dentry
18268+#define dst_dir sd[AuDST].dir
18269+#define dst_inode sd[AuDST].inode
18270+#define dst_h_dentry sd[AuDST].h_dentry
18271+#define dst_parent sd[AuDST].parent
18272+#define dst_h_parent sd[AuDST].h_parent
18273+#define dst_wh_dentry sd[AuDST].wh_dentry
18274+#define dst_hdir sd[AuDST].hdir
18275+#define dst_h_dir sd[AuDST].hdir->hi_inode
18276+#define dst_dt sd[AuDST].dt
18277+#define dst_bstart sd[AuDST].bstart
18278+
18279+ struct dentry *h_trap;
18280+ struct au_branch *br;
18281+ struct au_hinode *src_hinode;
18282+ struct path h_path;
18283+ struct au_nhash whlist;
027c5e7a 18284+ aufs_bindex_t btgt, src_bwh, src_bdiropq;
1facf9fc 18285+
1308ab2a 18286+ unsigned int flags;
1facf9fc 18287+
4a4d8108
AM
18288+ struct au_whtmp_rmdir *thargs;
18289+ struct dentry *h_dst;
18290+};
1308ab2a 18291+
4a4d8108 18292+/* ---------------------------------------------------------------------- */
1308ab2a 18293+
4a4d8108
AM
18294+/*
18295+ * functions for reverting.
18296+ * when an error happened in a single rename systemcall, we should revert
18297+ * everything as if nothing happend.
18298+ * we don't need to revert the copied-up/down the parent dir since they are
18299+ * harmless.
18300+ */
1facf9fc 18301+
4a4d8108
AM
18302+#define RevertFailure(fmt, ...) do { \
18303+ AuIOErr("revert failure: " fmt " (%d, %d)\n", \
18304+ ##__VA_ARGS__, err, rerr); \
18305+ err = -EIO; \
18306+} while (0)
1facf9fc 18307+
4a4d8108 18308+static void au_ren_rev_diropq(int err, struct au_ren_args *a)
1facf9fc 18309+{
4a4d8108 18310+ int rerr;
1facf9fc 18311+
4a4d8108
AM
18312+ au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
18313+ rerr = au_diropq_remove(a->src_dentry, a->btgt);
18314+ au_hn_imtx_unlock(a->src_hinode);
027c5e7a 18315+ au_set_dbdiropq(a->src_dentry, a->src_bdiropq);
4a4d8108 18316+ if (rerr)
523b37e3 18317+ RevertFailure("remove diropq %pd", a->src_dentry);
4a4d8108 18318+}
1facf9fc 18319+
4a4d8108
AM
18320+static void au_ren_rev_rename(int err, struct au_ren_args *a)
18321+{
18322+ int rerr;
523b37e3 18323+ struct inode *delegated;
1facf9fc 18324+
b4510431
AM
18325+ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name,
18326+ a->src_h_parent);
4a4d8108
AM
18327+ rerr = PTR_ERR(a->h_path.dentry);
18328+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 18329+ RevertFailure("lkup one %pd", a->src_dentry);
4a4d8108 18330+ return;
1facf9fc 18331+ }
18332+
523b37e3 18333+ delegated = NULL;
4a4d8108
AM
18334+ rerr = vfsub_rename(a->dst_h_dir,
18335+ au_h_dptr(a->src_dentry, a->btgt),
523b37e3
AM
18336+ a->src_h_dir, &a->h_path, &delegated);
18337+ if (unlikely(rerr == -EWOULDBLOCK)) {
18338+ pr_warn("cannot retry for NFSv4 delegation"
18339+ " for an internal rename\n");
18340+ iput(delegated);
18341+ }
4a4d8108
AM
18342+ d_drop(a->h_path.dentry);
18343+ dput(a->h_path.dentry);
18344+ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
18345+ if (rerr)
523b37e3 18346+ RevertFailure("rename %pd", a->src_dentry);
1facf9fc 18347+}
18348+
4a4d8108 18349+static void au_ren_rev_cpup(int err, struct au_ren_args *a)
1facf9fc 18350+{
4a4d8108 18351+ int rerr;
1facf9fc 18352+
4a4d8108 18353+ a->h_path.dentry = a->dst_h_dentry;
523b37e3
AM
18354+ /* no delegation since it is just created */
18355+ rerr = vfsub_unlink(a->dst_h_dir, &a->h_path, /*delegated*/NULL,
18356+ /*force*/0);
4a4d8108
AM
18357+ au_set_h_dptr(a->src_dentry, a->btgt, NULL);
18358+ au_set_dbstart(a->src_dentry, a->src_bstart);
18359+ if (rerr)
523b37e3 18360+ RevertFailure("unlink %pd", a->dst_h_dentry);
1facf9fc 18361+}
18362+
4a4d8108 18363+static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
1facf9fc 18364+{
4a4d8108 18365+ int rerr;
523b37e3 18366+ struct inode *delegated;
dece6358 18367+
b4510431
AM
18368+ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name,
18369+ a->dst_h_parent);
4a4d8108
AM
18370+ rerr = PTR_ERR(a->h_path.dentry);
18371+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 18372+ RevertFailure("lkup one %pd", a->dst_dentry);
4a4d8108
AM
18373+ return;
18374+ }
18375+ if (a->h_path.dentry->d_inode) {
18376+ d_drop(a->h_path.dentry);
18377+ dput(a->h_path.dentry);
18378+ return;
dece6358
AM
18379+ }
18380+
523b37e3
AM
18381+ delegated = NULL;
18382+ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path,
18383+ &delegated);
18384+ if (unlikely(rerr == -EWOULDBLOCK)) {
18385+ pr_warn("cannot retry for NFSv4 delegation"
18386+ " for an internal rename\n");
18387+ iput(delegated);
18388+ }
4a4d8108
AM
18389+ d_drop(a->h_path.dentry);
18390+ dput(a->h_path.dentry);
18391+ if (!rerr)
18392+ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
18393+ else
523b37e3 18394+ RevertFailure("rename %pd", a->h_dst);
4a4d8108 18395+}
1308ab2a 18396+
4a4d8108
AM
18397+static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
18398+{
18399+ int rerr;
1308ab2a 18400+
4a4d8108
AM
18401+ a->h_path.dentry = a->src_wh_dentry;
18402+ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
027c5e7a 18403+ au_set_dbwh(a->src_dentry, a->src_bwh);
4a4d8108 18404+ if (rerr)
523b37e3 18405+ RevertFailure("unlink %pd", a->src_wh_dentry);
4a4d8108 18406+}
4a4d8108 18407+#undef RevertFailure
1facf9fc 18408+
1308ab2a 18409+/* ---------------------------------------------------------------------- */
18410+
4a4d8108
AM
18411+/*
18412+ * when we have to copyup the renaming entry, do it with the rename-target name
18413+ * in order to minimize the cost (the later actual rename is unnecessary).
18414+ * otherwise rename it on the target branch.
18415+ */
18416+static int au_ren_or_cpup(struct au_ren_args *a)
1facf9fc 18417+{
dece6358 18418+ int err;
4a4d8108 18419+ struct dentry *d;
523b37e3 18420+ struct inode *delegated;
1facf9fc 18421+
4a4d8108
AM
18422+ d = a->src_dentry;
18423+ if (au_dbstart(d) == a->btgt) {
18424+ a->h_path.dentry = a->dst_h_dentry;
18425+ if (au_ftest_ren(a->flags, DIROPQ)
18426+ && au_dbdiropq(d) == a->btgt)
18427+ au_fclr_ren(a->flags, DIROPQ);
18428+ AuDebugOn(au_dbstart(d) != a->btgt);
523b37e3 18429+ delegated = NULL;
4a4d8108 18430+ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
523b37e3
AM
18431+ a->dst_h_dir, &a->h_path, &delegated);
18432+ if (unlikely(err == -EWOULDBLOCK)) {
18433+ pr_warn("cannot retry for NFSv4 delegation"
18434+ " for an internal rename\n");
18435+ iput(delegated);
18436+ }
c2b27bf2 18437+ } else
86dc4139 18438+ BUG();
1308ab2a 18439+
027c5e7a
AM
18440+ if (!err && a->h_dst)
18441+ /* it will be set to dinfo later */
18442+ dget(a->h_dst);
1facf9fc 18443+
dece6358
AM
18444+ return err;
18445+}
1facf9fc 18446+
4a4d8108
AM
18447+/* cf. aufs_rmdir() */
18448+static int au_ren_del_whtmp(struct au_ren_args *a)
dece6358 18449+{
4a4d8108
AM
18450+ int err;
18451+ struct inode *dir;
1facf9fc 18452+
4a4d8108
AM
18453+ dir = a->dst_dir;
18454+ SiMustAnyLock(dir->i_sb);
18455+ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
18456+ au_sbi(dir->i_sb)->si_dirwh)
18457+ || au_test_fs_remote(a->h_dst->d_sb)) {
18458+ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
18459+ if (unlikely(err))
523b37e3
AM
18460+ pr_warn("failed removing whtmp dir %pd (%d), "
18461+ "ignored.\n", a->h_dst, err);
4a4d8108
AM
18462+ } else {
18463+ au_nhash_wh_free(&a->thargs->whlist);
18464+ a->thargs->whlist = a->whlist;
18465+ a->whlist.nh_num = 0;
18466+ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
18467+ dput(a->h_dst);
18468+ a->thargs = NULL;
18469+ }
18470+
18471+ return 0;
1308ab2a 18472+}
1facf9fc 18473+
4a4d8108
AM
18474+/* make it 'opaque' dir. */
18475+static int au_ren_diropq(struct au_ren_args *a)
18476+{
18477+ int err;
18478+ struct dentry *diropq;
1facf9fc 18479+
4a4d8108 18480+ err = 0;
027c5e7a 18481+ a->src_bdiropq = au_dbdiropq(a->src_dentry);
4a4d8108
AM
18482+ a->src_hinode = au_hi(a->src_inode, a->btgt);
18483+ au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
18484+ diropq = au_diropq_create(a->src_dentry, a->btgt);
18485+ au_hn_imtx_unlock(a->src_hinode);
18486+ if (IS_ERR(diropq))
18487+ err = PTR_ERR(diropq);
18488+ dput(diropq);
1facf9fc 18489+
4a4d8108
AM
18490+ return err;
18491+}
1facf9fc 18492+
4a4d8108
AM
18493+static int do_rename(struct au_ren_args *a)
18494+{
18495+ int err;
18496+ struct dentry *d, *h_d;
1facf9fc 18497+
4a4d8108
AM
18498+ /* prepare workqueue args for asynchronous rmdir */
18499+ h_d = a->dst_h_dentry;
18500+ if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) {
18501+ err = -ENOMEM;
18502+ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS);
18503+ if (unlikely(!a->thargs))
18504+ goto out;
18505+ a->h_dst = dget(h_d);
18506+ }
1facf9fc 18507+
4a4d8108
AM
18508+ /* create whiteout for src_dentry */
18509+ if (au_ftest_ren(a->flags, WHSRC)) {
027c5e7a
AM
18510+ a->src_bwh = au_dbwh(a->src_dentry);
18511+ AuDebugOn(a->src_bwh >= 0);
4a4d8108
AM
18512+ a->src_wh_dentry
18513+ = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent);
18514+ err = PTR_ERR(a->src_wh_dentry);
18515+ if (IS_ERR(a->src_wh_dentry))
18516+ goto out_thargs;
18517+ }
1facf9fc 18518+
4a4d8108
AM
18519+ /* lookup whiteout for dentry */
18520+ if (au_ftest_ren(a->flags, WHDST)) {
18521+ h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name,
18522+ a->br);
18523+ err = PTR_ERR(h_d);
18524+ if (IS_ERR(h_d))
18525+ goto out_whsrc;
18526+ if (!h_d->d_inode)
18527+ dput(h_d);
18528+ else
18529+ a->dst_wh_dentry = h_d;
18530+ }
1facf9fc 18531+
4a4d8108
AM
18532+ /* rename dentry to tmpwh */
18533+ if (a->thargs) {
18534+ err = au_whtmp_ren(a->dst_h_dentry, a->br);
18535+ if (unlikely(err))
18536+ goto out_whdst;
dece6358 18537+
4a4d8108
AM
18538+ d = a->dst_dentry;
18539+ au_set_h_dptr(d, a->btgt, NULL);
86dc4139 18540+ err = au_lkup_neg(d, a->btgt, /*wh*/0);
4a4d8108
AM
18541+ if (unlikely(err))
18542+ goto out_whtmp;
18543+ a->dst_h_dentry = au_h_dptr(d, a->btgt);
18544+ }
1facf9fc 18545+
c2b27bf2 18546+ BUG_ON(a->dst_h_dentry->d_inode && a->src_bstart != a->btgt);
1facf9fc 18547+
4a4d8108
AM
18548+ /* rename by vfs_rename or cpup */
18549+ d = a->dst_dentry;
18550+ if (au_ftest_ren(a->flags, ISDIR)
18551+ && (a->dst_wh_dentry
18552+ || au_dbdiropq(d) == a->btgt
18553+ /* hide the lower to keep xino */
18554+ || a->btgt < au_dbend(d)
18555+ || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ)))
18556+ au_fset_ren(a->flags, DIROPQ);
18557+ err = au_ren_or_cpup(a);
18558+ if (unlikely(err))
18559+ /* leave the copied-up one */
18560+ goto out_whtmp;
1308ab2a 18561+
4a4d8108
AM
18562+ /* make dir opaque */
18563+ if (au_ftest_ren(a->flags, DIROPQ)) {
18564+ err = au_ren_diropq(a);
18565+ if (unlikely(err))
18566+ goto out_rename;
18567+ }
1308ab2a 18568+
4a4d8108
AM
18569+ /* update target timestamps */
18570+ AuDebugOn(au_dbstart(a->src_dentry) != a->btgt);
18571+ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
18572+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
18573+ a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
1facf9fc 18574+
4a4d8108
AM
18575+ /* remove whiteout for dentry */
18576+ if (a->dst_wh_dentry) {
18577+ a->h_path.dentry = a->dst_wh_dentry;
18578+ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
18579+ a->dst_dentry);
18580+ if (unlikely(err))
18581+ goto out_diropq;
18582+ }
1facf9fc 18583+
4a4d8108
AM
18584+ /* remove whtmp */
18585+ if (a->thargs)
18586+ au_ren_del_whtmp(a); /* ignore this error */
1308ab2a 18587+
4a4d8108
AM
18588+ err = 0;
18589+ goto out_success;
18590+
4f0767ce 18591+out_diropq:
4a4d8108
AM
18592+ if (au_ftest_ren(a->flags, DIROPQ))
18593+ au_ren_rev_diropq(err, a);
4f0767ce 18594+out_rename:
4a4d8108
AM
18595+ if (!au_ftest_ren(a->flags, CPUP))
18596+ au_ren_rev_rename(err, a);
18597+ else
18598+ au_ren_rev_cpup(err, a);
027c5e7a 18599+ dput(a->h_dst);
4f0767ce 18600+out_whtmp:
4a4d8108
AM
18601+ if (a->thargs)
18602+ au_ren_rev_whtmp(err, a);
4f0767ce 18603+out_whdst:
4a4d8108
AM
18604+ dput(a->dst_wh_dentry);
18605+ a->dst_wh_dentry = NULL;
4f0767ce 18606+out_whsrc:
4a4d8108
AM
18607+ if (a->src_wh_dentry)
18608+ au_ren_rev_whsrc(err, a);
4f0767ce 18609+out_success:
4a4d8108
AM
18610+ dput(a->src_wh_dentry);
18611+ dput(a->dst_wh_dentry);
4f0767ce 18612+out_thargs:
4a4d8108
AM
18613+ if (a->thargs) {
18614+ dput(a->h_dst);
18615+ au_whtmp_rmdir_free(a->thargs);
18616+ a->thargs = NULL;
18617+ }
4f0767ce 18618+out:
4a4d8108 18619+ return err;
dece6358 18620+}
1facf9fc 18621+
1308ab2a 18622+/* ---------------------------------------------------------------------- */
1facf9fc 18623+
4a4d8108
AM
18624+/*
18625+ * test if @dentry dir can be rename destination or not.
18626+ * success means, it is a logically empty dir.
18627+ */
18628+static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
1308ab2a 18629+{
4a4d8108 18630+ return au_test_empty(dentry, whlist);
1308ab2a 18631+}
1facf9fc 18632+
4a4d8108
AM
18633+/*
18634+ * test if @dentry dir can be rename source or not.
18635+ * if it can, return 0 and @children is filled.
18636+ * success means,
18637+ * - it is a logically empty dir.
18638+ * - or, it exists on writable branch and has no children including whiteouts
18639+ * on the lower branch.
18640+ */
18641+static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt)
18642+{
18643+ int err;
18644+ unsigned int rdhash;
18645+ aufs_bindex_t bstart;
1facf9fc 18646+
4a4d8108
AM
18647+ bstart = au_dbstart(dentry);
18648+ if (bstart != btgt) {
18649+ struct au_nhash whlist;
dece6358 18650+
4a4d8108
AM
18651+ SiMustAnyLock(dentry->d_sb);
18652+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
18653+ if (!rdhash)
18654+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL,
18655+ dentry));
18656+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
18657+ if (unlikely(err))
18658+ goto out;
18659+ err = au_test_empty(dentry, &whlist);
18660+ au_nhash_wh_free(&whlist);
18661+ goto out;
18662+ }
dece6358 18663+
4a4d8108
AM
18664+ if (bstart == au_dbtaildir(dentry))
18665+ return 0; /* success */
dece6358 18666+
4a4d8108 18667+ err = au_test_empty_lower(dentry);
1facf9fc 18668+
4f0767ce 18669+out:
4a4d8108
AM
18670+ if (err == -ENOTEMPTY) {
18671+ AuWarn1("renaming dir who has child(ren) on multiple branches,"
18672+ " is not supported\n");
18673+ err = -EXDEV;
18674+ }
18675+ return err;
18676+}
1308ab2a 18677+
4a4d8108
AM
18678+/* side effect: sets whlist and h_dentry */
18679+static int au_ren_may_dir(struct au_ren_args *a)
1308ab2a 18680+{
4a4d8108
AM
18681+ int err;
18682+ unsigned int rdhash;
18683+ struct dentry *d;
1facf9fc 18684+
4a4d8108
AM
18685+ d = a->dst_dentry;
18686+ SiMustAnyLock(d->d_sb);
1facf9fc 18687+
4a4d8108
AM
18688+ err = 0;
18689+ if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) {
18690+ rdhash = au_sbi(d->d_sb)->si_rdhash;
18691+ if (!rdhash)
18692+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d));
18693+ err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS);
18694+ if (unlikely(err))
18695+ goto out;
1308ab2a 18696+
4a4d8108
AM
18697+ au_set_dbstart(d, a->dst_bstart);
18698+ err = may_rename_dstdir(d, &a->whlist);
18699+ au_set_dbstart(d, a->btgt);
18700+ }
18701+ a->dst_h_dentry = au_h_dptr(d, au_dbstart(d));
18702+ if (unlikely(err))
18703+ goto out;
18704+
18705+ d = a->src_dentry;
18706+ a->src_h_dentry = au_h_dptr(d, au_dbstart(d));
18707+ if (au_ftest_ren(a->flags, ISDIR)) {
18708+ err = may_rename_srcdir(d, a->btgt);
18709+ if (unlikely(err)) {
18710+ au_nhash_wh_free(&a->whlist);
18711+ a->whlist.nh_num = 0;
18712+ }
18713+ }
4f0767ce 18714+out:
4a4d8108 18715+ return err;
1facf9fc 18716+}
18717+
4a4d8108 18718+/* ---------------------------------------------------------------------- */
1facf9fc 18719+
4a4d8108
AM
18720+/*
18721+ * simple tests for rename.
18722+ * following the checks in vfs, plus the parent-child relationship.
18723+ */
18724+static int au_may_ren(struct au_ren_args *a)
18725+{
18726+ int err, isdir;
18727+ struct inode *h_inode;
1facf9fc 18728+
4a4d8108
AM
18729+ if (a->src_bstart == a->btgt) {
18730+ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
18731+ au_ftest_ren(a->flags, ISDIR));
18732+ if (unlikely(err))
18733+ goto out;
18734+ err = -EINVAL;
18735+ if (unlikely(a->src_h_dentry == a->h_trap))
18736+ goto out;
18737+ }
1facf9fc 18738+
4a4d8108
AM
18739+ err = 0;
18740+ if (a->dst_bstart != a->btgt)
18741+ goto out;
1facf9fc 18742+
027c5e7a
AM
18743+ err = -ENOTEMPTY;
18744+ if (unlikely(a->dst_h_dentry == a->h_trap))
18745+ goto out;
18746+
4a4d8108
AM
18747+ err = -EIO;
18748+ h_inode = a->dst_h_dentry->d_inode;
18749+ isdir = !!au_ftest_ren(a->flags, ISDIR);
18750+ if (!a->dst_dentry->d_inode) {
18751+ if (unlikely(h_inode))
18752+ goto out;
18753+ err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent,
18754+ isdir);
18755+ } else {
18756+ if (unlikely(!h_inode || !h_inode->i_nlink))
18757+ goto out;
18758+ err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent,
18759+ isdir);
18760+ if (unlikely(err))
18761+ goto out;
4a4d8108 18762+ }
1facf9fc 18763+
4f0767ce 18764+out:
4a4d8108
AM
18765+ if (unlikely(err == -ENOENT || err == -EEXIST))
18766+ err = -EIO;
18767+ AuTraceErr(err);
18768+ return err;
18769+}
1facf9fc 18770+
1308ab2a 18771+/* ---------------------------------------------------------------------- */
1facf9fc 18772+
4a4d8108
AM
18773+/*
18774+ * locking order
18775+ * (VFS)
18776+ * - src_dir and dir by lock_rename()
18777+ * - inode if exitsts
18778+ * (aufs)
18779+ * - lock all
18780+ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
18781+ * + si_read_lock
18782+ * + di_write_lock2_child()
18783+ * + di_write_lock_child()
18784+ * + ii_write_lock_child()
18785+ * + di_write_lock_child2()
18786+ * + ii_write_lock_child2()
18787+ * + src_parent and parent
18788+ * + di_write_lock_parent()
18789+ * + ii_write_lock_parent()
18790+ * + di_write_lock_parent2()
18791+ * + ii_write_lock_parent2()
18792+ * + lower src_dir and dir by vfsub_lock_rename()
18793+ * + verify the every relationships between child and parent. if any
18794+ * of them failed, unlock all and return -EBUSY.
18795+ */
18796+static void au_ren_unlock(struct au_ren_args *a)
1308ab2a 18797+{
4a4d8108
AM
18798+ vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
18799+ a->dst_h_parent, a->dst_hdir);
86dc4139
AM
18800+ if (au_ftest_ren(a->flags, MNT_WRITE))
18801+ vfsub_mnt_drop_write(au_br_mnt(a->br));
1308ab2a 18802+}
18803+
4a4d8108 18804+static int au_ren_lock(struct au_ren_args *a)
1308ab2a 18805+{
4a4d8108
AM
18806+ int err;
18807+ unsigned int udba;
1308ab2a 18808+
4a4d8108
AM
18809+ err = 0;
18810+ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
18811+ a->src_hdir = au_hi(a->src_dir, a->btgt);
18812+ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
18813+ a->dst_hdir = au_hi(a->dst_dir, a->btgt);
86dc4139
AM
18814+
18815+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
18816+ if (unlikely(err))
18817+ goto out;
18818+ au_fset_ren(a->flags, MNT_WRITE);
4a4d8108
AM
18819+ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
18820+ a->dst_h_parent, a->dst_hdir);
18821+ udba = au_opt_udba(a->src_dentry->d_sb);
18822+ if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode
18823+ || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode))
18824+ err = au_busy_or_stale();
18825+ if (!err && au_dbstart(a->src_dentry) == a->btgt)
18826+ err = au_h_verify(a->src_h_dentry, udba,
18827+ a->src_h_parent->d_inode, a->src_h_parent,
18828+ a->br);
18829+ if (!err && au_dbstart(a->dst_dentry) == a->btgt)
18830+ err = au_h_verify(a->dst_h_dentry, udba,
18831+ a->dst_h_parent->d_inode, a->dst_h_parent,
18832+ a->br);
86dc4139 18833+ if (!err)
4a4d8108 18834+ goto out; /* success */
4a4d8108
AM
18835+
18836+ err = au_busy_or_stale();
4a4d8108 18837+ au_ren_unlock(a);
86dc4139 18838+
4f0767ce 18839+out:
4a4d8108 18840+ return err;
1facf9fc 18841+}
18842+
18843+/* ---------------------------------------------------------------------- */
18844+
4a4d8108 18845+static void au_ren_refresh_dir(struct au_ren_args *a)
1facf9fc 18846+{
4a4d8108 18847+ struct inode *dir;
dece6358 18848+
4a4d8108
AM
18849+ dir = a->dst_dir;
18850+ dir->i_version++;
18851+ if (au_ftest_ren(a->flags, ISDIR)) {
18852+ /* is this updating defined in POSIX? */
18853+ au_cpup_attr_timesizes(a->src_inode);
18854+ au_cpup_attr_nlink(dir, /*force*/1);
4a4d8108 18855+ }
027c5e7a 18856+
4a4d8108
AM
18857+ if (au_ibstart(dir) == a->btgt)
18858+ au_cpup_attr_timesizes(dir);
dece6358 18859+
4a4d8108
AM
18860+ if (au_ftest_ren(a->flags, ISSAMEDIR))
18861+ return;
dece6358 18862+
4a4d8108
AM
18863+ dir = a->src_dir;
18864+ dir->i_version++;
18865+ if (au_ftest_ren(a->flags, ISDIR))
18866+ au_cpup_attr_nlink(dir, /*force*/1);
18867+ if (au_ibstart(dir) == a->btgt)
18868+ au_cpup_attr_timesizes(dir);
1facf9fc 18869+}
18870+
4a4d8108 18871+static void au_ren_refresh(struct au_ren_args *a)
1facf9fc 18872+{
4a4d8108
AM
18873+ aufs_bindex_t bend, bindex;
18874+ struct dentry *d, *h_d;
18875+ struct inode *i, *h_i;
18876+ struct super_block *sb;
dece6358 18877+
027c5e7a
AM
18878+ d = a->dst_dentry;
18879+ d_drop(d);
18880+ if (a->h_dst)
18881+ /* already dget-ed by au_ren_or_cpup() */
18882+ au_set_h_dptr(d, a->btgt, a->h_dst);
18883+
18884+ i = a->dst_inode;
18885+ if (i) {
18886+ if (!au_ftest_ren(a->flags, ISDIR))
18887+ vfsub_drop_nlink(i);
18888+ else {
18889+ vfsub_dead_dir(i);
18890+ au_cpup_attr_timesizes(i);
18891+ }
18892+ au_update_dbrange(d, /*do_put_zero*/1);
18893+ } else {
18894+ bend = a->btgt;
18895+ for (bindex = au_dbstart(d); bindex < bend; bindex++)
18896+ au_set_h_dptr(d, bindex, NULL);
18897+ bend = au_dbend(d);
18898+ for (bindex = a->btgt + 1; bindex <= bend; bindex++)
18899+ au_set_h_dptr(d, bindex, NULL);
18900+ au_update_dbrange(d, /*do_put_zero*/0);
18901+ }
18902+
4a4d8108
AM
18903+ d = a->src_dentry;
18904+ au_set_dbwh(d, -1);
18905+ bend = au_dbend(d);
18906+ for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
18907+ h_d = au_h_dptr(d, bindex);
18908+ if (h_d)
18909+ au_set_h_dptr(d, bindex, NULL);
18910+ }
18911+ au_set_dbend(d, a->btgt);
18912+
18913+ sb = d->d_sb;
18914+ i = a->src_inode;
18915+ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
18916+ return; /* success */
18917+
18918+ bend = au_ibend(i);
18919+ for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
18920+ h_i = au_h_iptr(i, bindex);
18921+ if (h_i) {
18922+ au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
18923+ /* ignore this error */
18924+ au_set_h_iptr(i, bindex, NULL, 0);
18925+ }
18926+ }
18927+ au_set_ibend(i, a->btgt);
1308ab2a 18928+}
dece6358 18929+
4a4d8108
AM
18930+/* ---------------------------------------------------------------------- */
18931+
18932+/* mainly for link(2) and rename(2) */
18933+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
1308ab2a 18934+{
4a4d8108
AM
18935+ aufs_bindex_t bdiropq, bwh;
18936+ struct dentry *parent;
18937+ struct au_branch *br;
18938+
18939+ parent = dentry->d_parent;
18940+ IMustLock(parent->d_inode); /* dir is locked */
18941+
18942+ bdiropq = au_dbdiropq(parent);
18943+ bwh = au_dbwh(dentry);
18944+ br = au_sbr(dentry->d_sb, btgt);
18945+ if (au_br_rdonly(br)
18946+ || (0 <= bdiropq && bdiropq < btgt)
18947+ || (0 <= bwh && bwh < btgt))
18948+ btgt = -1;
18949+
18950+ AuDbg("btgt %d\n", btgt);
18951+ return btgt;
1facf9fc 18952+}
18953+
4a4d8108
AM
18954+/* sets src_bstart, dst_bstart and btgt */
18955+static int au_ren_wbr(struct au_ren_args *a)
1facf9fc 18956+{
4a4d8108
AM
18957+ int err;
18958+ struct au_wr_dir_args wr_dir_args = {
18959+ /* .force_btgt = -1, */
18960+ .flags = AuWrDir_ADD_ENTRY
18961+ };
dece6358 18962+
4a4d8108
AM
18963+ a->src_bstart = au_dbstart(a->src_dentry);
18964+ a->dst_bstart = au_dbstart(a->dst_dentry);
18965+ if (au_ftest_ren(a->flags, ISDIR))
18966+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
18967+ wr_dir_args.force_btgt = a->src_bstart;
18968+ if (a->dst_inode && a->dst_bstart < a->src_bstart)
18969+ wr_dir_args.force_btgt = a->dst_bstart;
18970+ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
18971+ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
18972+ a->btgt = err;
dece6358 18973+
4a4d8108 18974+ return err;
1facf9fc 18975+}
18976+
4a4d8108 18977+static void au_ren_dt(struct au_ren_args *a)
1facf9fc 18978+{
4a4d8108
AM
18979+ a->h_path.dentry = a->src_h_parent;
18980+ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
18981+ if (!au_ftest_ren(a->flags, ISSAMEDIR)) {
18982+ a->h_path.dentry = a->dst_h_parent;
18983+ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
18984+ }
1facf9fc 18985+
4a4d8108
AM
18986+ au_fclr_ren(a->flags, DT_DSTDIR);
18987+ if (!au_ftest_ren(a->flags, ISDIR))
18988+ return;
dece6358 18989+
4a4d8108
AM
18990+ a->h_path.dentry = a->src_h_dentry;
18991+ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
18992+ if (a->dst_h_dentry->d_inode) {
18993+ au_fset_ren(a->flags, DT_DSTDIR);
18994+ a->h_path.dentry = a->dst_h_dentry;
18995+ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
18996+ }
1308ab2a 18997+}
dece6358 18998+
4a4d8108 18999+static void au_ren_rev_dt(int err, struct au_ren_args *a)
1308ab2a 19000+{
4a4d8108
AM
19001+ struct dentry *h_d;
19002+ struct mutex *h_mtx;
19003+
19004+ au_dtime_revert(a->src_dt + AuPARENT);
19005+ if (!au_ftest_ren(a->flags, ISSAMEDIR))
19006+ au_dtime_revert(a->dst_dt + AuPARENT);
19007+
19008+ if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) {
19009+ h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
19010+ h_mtx = &h_d->d_inode->i_mutex;
19011+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
19012+ au_dtime_revert(a->src_dt + AuCHILD);
19013+ mutex_unlock(h_mtx);
19014+
19015+ if (au_ftest_ren(a->flags, DT_DSTDIR)) {
19016+ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
19017+ h_mtx = &h_d->d_inode->i_mutex;
19018+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
19019+ au_dtime_revert(a->dst_dt + AuCHILD);
19020+ mutex_unlock(h_mtx);
1facf9fc 19021+ }
19022+ }
19023+}
19024+
4a4d8108
AM
19025+/* ---------------------------------------------------------------------- */
19026+
19027+int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
19028+ struct inode *_dst_dir, struct dentry *_dst_dentry)
1facf9fc 19029+{
e49829fe 19030+ int err, flags;
4a4d8108
AM
19031+ /* reduce stack space */
19032+ struct au_ren_args *a;
19033+
523b37e3 19034+ AuDbg("%pd, %pd\n", _src_dentry, _dst_dentry);
4a4d8108
AM
19035+ IMustLock(_src_dir);
19036+ IMustLock(_dst_dir);
19037+
19038+ err = -ENOMEM;
19039+ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
19040+ a = kzalloc(sizeof(*a), GFP_NOFS);
19041+ if (unlikely(!a))
19042+ goto out;
19043+
19044+ a->src_dir = _src_dir;
19045+ a->src_dentry = _src_dentry;
19046+ a->src_inode = a->src_dentry->d_inode;
19047+ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
19048+ a->dst_dir = _dst_dir;
19049+ a->dst_dentry = _dst_dentry;
19050+ a->dst_inode = a->dst_dentry->d_inode;
19051+ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
19052+ if (a->dst_inode) {
19053+ IMustLock(a->dst_inode);
19054+ au_igrab(a->dst_inode);
1facf9fc 19055+ }
1facf9fc 19056+
4a4d8108 19057+ err = -ENOTDIR;
027c5e7a 19058+ flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
4a4d8108
AM
19059+ if (S_ISDIR(a->src_inode->i_mode)) {
19060+ au_fset_ren(a->flags, ISDIR);
19061+ if (unlikely(a->dst_inode && !S_ISDIR(a->dst_inode->i_mode)))
19062+ goto out_free;
e49829fe
JR
19063+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
19064+ AuLock_DIR | flags);
4a4d8108 19065+ } else
e49829fe
JR
19066+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
19067+ flags);
19068+ if (unlikely(err))
19069+ goto out_free;
1facf9fc 19070+
027c5e7a
AM
19071+ err = au_d_hashed_positive(a->src_dentry);
19072+ if (unlikely(err))
19073+ goto out_unlock;
19074+ err = -ENOENT;
19075+ if (a->dst_inode) {
19076+ /*
19077+ * If it is a dir, VFS unhash dst_dentry before this
19078+ * function. It means we cannot rely upon d_unhashed().
19079+ */
19080+ if (unlikely(!a->dst_inode->i_nlink))
19081+ goto out_unlock;
19082+ if (!S_ISDIR(a->dst_inode->i_mode)) {
19083+ err = au_d_hashed_positive(a->dst_dentry);
19084+ if (unlikely(err))
19085+ goto out_unlock;
19086+ } else if (unlikely(IS_DEADDIR(a->dst_inode)))
19087+ goto out_unlock;
19088+ } else if (unlikely(d_unhashed(a->dst_dentry)))
19089+ goto out_unlock;
19090+
7eafdf33
AM
19091+ /*
19092+ * is it possible?
19093+ * yes, it happend (in linux-3.3-rcN) but I don't know why.
19094+ * there may exist a problem somewhere else.
19095+ */
19096+ err = -EINVAL;
19097+ if (unlikely(a->dst_parent->d_inode == a->src_dentry->d_inode))
19098+ goto out_unlock;
19099+
4a4d8108
AM
19100+ au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
19101+ di_write_lock_parent(a->dst_parent);
1facf9fc 19102+
4a4d8108
AM
19103+ /* which branch we process */
19104+ err = au_ren_wbr(a);
19105+ if (unlikely(err < 0))
027c5e7a 19106+ goto out_parent;
4a4d8108 19107+ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
86dc4139 19108+ a->h_path.mnt = au_br_mnt(a->br);
1facf9fc 19109+
4a4d8108
AM
19110+ /* are they available to be renamed */
19111+ err = au_ren_may_dir(a);
19112+ if (unlikely(err))
19113+ goto out_children;
1facf9fc 19114+
4a4d8108
AM
19115+ /* prepare the writable parent dir on the same branch */
19116+ if (a->dst_bstart == a->btgt) {
19117+ au_fset_ren(a->flags, WHDST);
19118+ } else {
19119+ err = au_cpup_dirs(a->dst_dentry, a->btgt);
19120+ if (unlikely(err))
19121+ goto out_children;
19122+ }
1facf9fc 19123+
4a4d8108
AM
19124+ if (a->src_dir != a->dst_dir) {
19125+ /*
19126+ * this temporary unlock is safe,
19127+ * because both dir->i_mutex are locked.
19128+ */
19129+ di_write_unlock(a->dst_parent);
19130+ di_write_lock_parent(a->src_parent);
19131+ err = au_wr_dir_need_wh(a->src_dentry,
19132+ au_ftest_ren(a->flags, ISDIR),
19133+ &a->btgt);
19134+ di_write_unlock(a->src_parent);
19135+ di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1);
19136+ au_fclr_ren(a->flags, ISSAMEDIR);
19137+ } else
19138+ err = au_wr_dir_need_wh(a->src_dentry,
19139+ au_ftest_ren(a->flags, ISDIR),
19140+ &a->btgt);
19141+ if (unlikely(err < 0))
19142+ goto out_children;
19143+ if (err)
19144+ au_fset_ren(a->flags, WHSRC);
1facf9fc 19145+
86dc4139
AM
19146+ /* cpup src */
19147+ if (a->src_bstart != a->btgt) {
86dc4139
AM
19148+ struct au_pin pin;
19149+
19150+ err = au_pin(&pin, a->src_dentry, a->btgt,
19151+ au_opt_udba(a->src_dentry->d_sb),
19152+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 19153+ if (!err) {
c2b27bf2
AM
19154+ struct au_cp_generic cpg = {
19155+ .dentry = a->src_dentry,
19156+ .bdst = a->btgt,
19157+ .bsrc = a->src_bstart,
19158+ .len = -1,
19159+ .pin = &pin,
19160+ .flags = AuCpup_DTIME | AuCpup_HOPEN
19161+ };
367653fa 19162+ AuDebugOn(au_dbstart(a->src_dentry) != a->src_bstart);
c2b27bf2 19163+ err = au_sio_cpup_simple(&cpg);
367653fa 19164+ au_unpin(&pin);
86dc4139 19165+ }
86dc4139
AM
19166+ if (unlikely(err))
19167+ goto out_children;
19168+ a->src_bstart = a->btgt;
19169+ a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt);
19170+ au_fset_ren(a->flags, WHSRC);
19171+ }
19172+
4a4d8108
AM
19173+ /* lock them all */
19174+ err = au_ren_lock(a);
19175+ if (unlikely(err))
86dc4139 19176+ /* leave the copied-up one */
4a4d8108 19177+ goto out_children;
1facf9fc 19178+
4a4d8108
AM
19179+ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE))
19180+ err = au_may_ren(a);
19181+ else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN))
19182+ err = -ENAMETOOLONG;
19183+ if (unlikely(err))
19184+ goto out_hdir;
1facf9fc 19185+
4a4d8108
AM
19186+ /* store timestamps to be revertible */
19187+ au_ren_dt(a);
1facf9fc 19188+
4a4d8108
AM
19189+ /* here we go */
19190+ err = do_rename(a);
19191+ if (unlikely(err))
19192+ goto out_dt;
19193+
19194+ /* update dir attributes */
19195+ au_ren_refresh_dir(a);
19196+
19197+ /* dput/iput all lower dentries */
19198+ au_ren_refresh(a);
19199+
19200+ goto out_hdir; /* success */
19201+
4f0767ce 19202+out_dt:
4a4d8108 19203+ au_ren_rev_dt(err, a);
4f0767ce 19204+out_hdir:
4a4d8108 19205+ au_ren_unlock(a);
4f0767ce 19206+out_children:
4a4d8108 19207+ au_nhash_wh_free(&a->whlist);
027c5e7a
AM
19208+ if (err && a->dst_inode && a->dst_bstart != a->btgt) {
19209+ AuDbg("bstart %d, btgt %d\n", a->dst_bstart, a->btgt);
19210+ au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
19211+ au_set_dbstart(a->dst_dentry, a->dst_bstart);
4a4d8108 19212+ }
027c5e7a 19213+out_parent:
4a4d8108
AM
19214+ if (!err)
19215+ d_move(a->src_dentry, a->dst_dentry);
027c5e7a
AM
19216+ else {
19217+ au_update_dbstart(a->dst_dentry);
19218+ if (!a->dst_inode)
19219+ d_drop(a->dst_dentry);
19220+ }
4a4d8108
AM
19221+ if (au_ftest_ren(a->flags, ISSAMEDIR))
19222+ di_write_unlock(a->dst_parent);
19223+ else
19224+ di_write_unlock2(a->src_parent, a->dst_parent);
027c5e7a 19225+out_unlock:
4a4d8108 19226+ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
4f0767ce 19227+out_free:
4a4d8108
AM
19228+ iput(a->dst_inode);
19229+ if (a->thargs)
19230+ au_whtmp_rmdir_free(a->thargs);
19231+ kfree(a);
4f0767ce 19232+out:
4a4d8108
AM
19233+ AuTraceErr(err);
19234+ return err;
1308ab2a 19235+}
7f207e10
AM
19236diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
19237--- /usr/share/empty/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
19238+++ linux/fs/aufs/Kconfig 2014-01-20 20:16:14.732796615 +0100
19239@@ -0,0 +1,179 @@
4a4d8108
AM
19240+config AUFS_FS
19241+ tristate "Aufs (Advanced multi layered unification filesystem) support"
4a4d8108
AM
19242+ help
19243+ Aufs is a stackable unification filesystem such as Unionfs,
19244+ which unifies several directories and provides a merged single
19245+ directory.
19246+ In the early days, aufs was entirely re-designed and
19247+ re-implemented Unionfs Version 1.x series. Introducing many
19248+ original ideas, approaches and improvements, it becomes totally
19249+ different from Unionfs while keeping the basic features.
1facf9fc 19250+
4a4d8108
AM
19251+if AUFS_FS
19252+choice
19253+ prompt "Maximum number of branches"
19254+ default AUFS_BRANCH_MAX_127
19255+ help
19256+ Specifies the maximum number of branches (or member directories)
19257+ in a single aufs. The larger value consumes more system
19258+ resources and has a minor impact to performance.
19259+config AUFS_BRANCH_MAX_127
19260+ bool "127"
19261+ help
19262+ Specifies the maximum number of branches (or member directories)
19263+ in a single aufs. The larger value consumes more system
19264+ resources and has a minor impact to performance.
19265+config AUFS_BRANCH_MAX_511
19266+ bool "511"
19267+ help
19268+ Specifies the maximum number of branches (or member directories)
19269+ in a single aufs. The larger value consumes more system
19270+ resources and has a minor impact to performance.
19271+config AUFS_BRANCH_MAX_1023
19272+ bool "1023"
19273+ help
19274+ Specifies the maximum number of branches (or member directories)
19275+ in a single aufs. The larger value consumes more system
19276+ resources and has a minor impact to performance.
19277+config AUFS_BRANCH_MAX_32767
19278+ bool "32767"
19279+ help
19280+ Specifies the maximum number of branches (or member directories)
19281+ in a single aufs. The larger value consumes more system
19282+ resources and has a minor impact to performance.
19283+endchoice
1facf9fc 19284+
e49829fe
JR
19285+config AUFS_SBILIST
19286+ bool
19287+ depends on AUFS_MAGIC_SYSRQ || PROC_FS
19288+ default y
19289+ help
19290+ Automatic configuration for internal use.
19291+ When aufs supports Magic SysRq or /proc, enabled automatically.
19292+
4a4d8108
AM
19293+config AUFS_HNOTIFY
19294+ bool "Detect direct branch access (bypassing aufs)"
19295+ help
19296+ If you want to modify files on branches directly, eg. bypassing aufs,
19297+ and want aufs to detect the changes of them fully, then enable this
19298+ option and use 'udba=notify' mount option.
7f207e10 19299+ Currently there is only one available configuration, "fsnotify".
4a4d8108
AM
19300+ It will have a negative impact to the performance.
19301+ See detail in aufs.5.
dece6358 19302+
4a4d8108
AM
19303+choice
19304+ prompt "method" if AUFS_HNOTIFY
19305+ default AUFS_HFSNOTIFY
19306+config AUFS_HFSNOTIFY
19307+ bool "fsnotify"
19308+ select FSNOTIFY
4a4d8108 19309+endchoice
1facf9fc 19310+
4a4d8108
AM
19311+config AUFS_EXPORT
19312+ bool "NFS-exportable aufs"
2cbb1c4b 19313+ depends on EXPORTFS
4a4d8108
AM
19314+ help
19315+ If you want to export your mounted aufs via NFS, then enable this
19316+ option. There are several requirements for this configuration.
19317+ See detail in aufs.5.
1facf9fc 19318+
4a4d8108
AM
19319+config AUFS_INO_T_64
19320+ bool
19321+ depends on AUFS_EXPORT
19322+ depends on 64BIT && !(ALPHA || S390)
19323+ default y
19324+ help
19325+ Automatic configuration for internal use.
19326+ /* typedef unsigned long/int __kernel_ino_t */
19327+ /* alpha and s390x are int */
1facf9fc 19328+
4a4d8108
AM
19329+config AUFS_RDU
19330+ bool "Readdir in userspace"
19331+ help
19332+ Aufs has two methods to provide a merged view for a directory,
19333+ by a user-space library and by kernel-space natively. The latter
19334+ is always enabled but sometimes large and slow.
19335+ If you enable this option, install the library in aufs2-util
19336+ package, and set some environment variables for your readdir(3),
19337+ then the work will be handled in user-space which generally
19338+ shows better performance in most cases.
19339+ See detail in aufs.5.
1facf9fc 19340+
4a4d8108
AM
19341+config AUFS_SP_IATTR
19342+ bool "Respect the attributes (mtime/ctime mainly) of special files"
19343+ help
19344+ When you write something to a special file, some attributes of it
19345+ (mtime/ctime mainly) may be updated. Generally such updates are
19346+ less important (actually some device drivers and NFS ignore
19347+ it). But some applications (such like test program) requires
19348+ such updates. If you need these updates, then enable this
19349+ configuration which introduces some overhead.
19350+ Currently this configuration handles FIFO only.
1facf9fc 19351+
4a4d8108
AM
19352+config AUFS_SHWH
19353+ bool "Show whiteouts"
19354+ help
19355+ If you want to make the whiteouts in aufs visible, then enable
19356+ this option and specify 'shwh' mount option. Although it may
19357+ sounds like philosophy or something, but in technically it
19358+ simply shows the name of whiteout with keeping its behaviour.
1facf9fc 19359+
4a4d8108
AM
19360+config AUFS_BR_RAMFS
19361+ bool "Ramfs (initramfs/rootfs) as an aufs branch"
19362+ help
19363+ If you want to use ramfs as an aufs branch fs, then enable this
19364+ option. Generally tmpfs is recommended.
19365+ Aufs prohibited them to be a branch fs by default, because
19366+ initramfs becomes unusable after switch_root or something
19367+ generally. If you sets initramfs as an aufs branch and boot your
19368+ system by switch_root, you will meet a problem easily since the
19369+ files in initramfs may be inaccessible.
19370+ Unless you are going to use ramfs as an aufs branch fs without
19371+ switch_root or something, leave it N.
1facf9fc 19372+
4a4d8108
AM
19373+config AUFS_BR_FUSE
19374+ bool "Fuse fs as an aufs branch"
19375+ depends on FUSE_FS
19376+ select AUFS_POLL
19377+ help
19378+ If you want to use fuse-based userspace filesystem as an aufs
19379+ branch fs, then enable this option.
19380+ It implements the internal poll(2) operation which is
19381+ implemented by fuse only (curretnly).
1facf9fc 19382+
4a4d8108
AM
19383+config AUFS_POLL
19384+ bool
19385+ help
19386+ Automatic configuration for internal use.
1facf9fc 19387+
4a4d8108
AM
19388+config AUFS_BR_HFSPLUS
19389+ bool "Hfsplus as an aufs branch"
19390+ depends on HFSPLUS_FS
19391+ default y
19392+ help
19393+ If you want to use hfsplus fs as an aufs branch fs, then enable
19394+ this option. This option introduces a small overhead at
19395+ copying-up a file on hfsplus.
1facf9fc 19396+
4a4d8108
AM
19397+config AUFS_BDEV_LOOP
19398+ bool
19399+ depends on BLK_DEV_LOOP
19400+ default y
19401+ help
19402+ Automatic configuration for internal use.
19403+ Convert =[ym] into =y.
1308ab2a 19404+
4a4d8108
AM
19405+config AUFS_DEBUG
19406+ bool "Debug aufs"
19407+ help
19408+ Enable this to compile aufs internal debug code.
19409+ It will have a negative impact to the performance.
19410+
19411+config AUFS_MAGIC_SYSRQ
19412+ bool
19413+ depends on AUFS_DEBUG && MAGIC_SYSRQ
19414+ default y
19415+ help
19416+ Automatic configuration for internal use.
19417+ When aufs supports Magic SysRq, enabled automatically.
19418+endif
7f207e10
AM
19419diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
19420--- /usr/share/empty/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
19421+++ linux/fs/aufs/loop.c 2014-01-20 20:16:14.739463504 +0100
19422@@ -0,0 +1,145 @@
1facf9fc 19423+/*
523b37e3 19424+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 19425+ *
19426+ * This program, aufs is free software; you can redistribute it and/or modify
19427+ * it under the terms of the GNU General Public License as published by
19428+ * the Free Software Foundation; either version 2 of the License, or
19429+ * (at your option) any later version.
dece6358
AM
19430+ *
19431+ * This program is distributed in the hope that it will be useful,
19432+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19433+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19434+ * GNU General Public License for more details.
19435+ *
19436+ * You should have received a copy of the GNU General Public License
523b37e3 19437+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 19438+ */
19439+
19440+/*
19441+ * support for loopback block device as a branch
19442+ */
19443+
1facf9fc 19444+#include "aufs.h"
19445+
392086de
AM
19446+/* added into drivers/block/loop.c */
19447+static struct file *(*backing_file_func)(struct super_block *sb);
19448+
1facf9fc 19449+/*
19450+ * test if two lower dentries have overlapping branches.
19451+ */
b752ccd1 19452+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
1facf9fc 19453+{
b752ccd1 19454+ struct super_block *h_sb;
392086de
AM
19455+ struct file *backing_file;
19456+
19457+ if (unlikely(!backing_file_func)) {
19458+ /* don't load "loop" module here */
19459+ backing_file_func = symbol_get(loop_backing_file);
19460+ if (unlikely(!backing_file_func))
19461+ /* "loop" module is not loaded */
19462+ return 0;
19463+ }
1facf9fc 19464+
b752ccd1 19465+ h_sb = h_adding->d_sb;
392086de
AM
19466+ backing_file = backing_file_func(h_sb);
19467+ if (!backing_file)
1facf9fc 19468+ return 0;
19469+
392086de 19470+ h_adding = backing_file->f_dentry;
b752ccd1
AM
19471+ /*
19472+ * h_adding can be local NFS.
19473+ * in this case aufs cannot detect the loop.
19474+ */
19475+ if (unlikely(h_adding->d_sb == sb))
1facf9fc 19476+ return 1;
b752ccd1 19477+ return !!au_test_subdir(h_adding, sb->s_root);
1facf9fc 19478+}
19479+
19480+/* true if a kernel thread named 'loop[0-9].*' accesses a file */
19481+int au_test_loopback_kthread(void)
19482+{
b752ccd1
AM
19483+ int ret;
19484+ struct task_struct *tsk = current;
a2a7ad62 19485+ char c, comm[sizeof(tsk->comm)];
b752ccd1
AM
19486+
19487+ ret = 0;
19488+ if (tsk->flags & PF_KTHREAD) {
a2a7ad62
AM
19489+ get_task_comm(comm, tsk);
19490+ c = comm[4];
b752ccd1 19491+ ret = ('0' <= c && c <= '9'
a2a7ad62 19492+ && !strncmp(comm, "loop", 4));
b752ccd1 19493+ }
1facf9fc 19494+
b752ccd1 19495+ return ret;
1facf9fc 19496+}
87a755f4
AM
19497+
19498+/* ---------------------------------------------------------------------- */
19499+
19500+#define au_warn_loopback_step 16
19501+static int au_warn_loopback_nelem = au_warn_loopback_step;
19502+static unsigned long *au_warn_loopback_array;
19503+
19504+void au_warn_loopback(struct super_block *h_sb)
19505+{
19506+ int i, new_nelem;
19507+ unsigned long *a, magic;
19508+ static DEFINE_SPINLOCK(spin);
19509+
19510+ magic = h_sb->s_magic;
19511+ spin_lock(&spin);
19512+ a = au_warn_loopback_array;
19513+ for (i = 0; i < au_warn_loopback_nelem && *a; i++)
19514+ if (a[i] == magic) {
19515+ spin_unlock(&spin);
19516+ return;
19517+ }
19518+
19519+ /* h_sb is new to us, print it */
19520+ if (i < au_warn_loopback_nelem) {
19521+ a[i] = magic;
19522+ goto pr;
19523+ }
19524+
19525+ /* expand the array */
19526+ new_nelem = au_warn_loopback_nelem + au_warn_loopback_step;
19527+ a = au_kzrealloc(au_warn_loopback_array,
19528+ au_warn_loopback_nelem * sizeof(unsigned long),
19529+ new_nelem * sizeof(unsigned long), GFP_ATOMIC);
19530+ if (a) {
19531+ au_warn_loopback_nelem = new_nelem;
19532+ au_warn_loopback_array = a;
19533+ a[i] = magic;
19534+ goto pr;
19535+ }
19536+
19537+ spin_unlock(&spin);
19538+ AuWarn1("realloc failed, ignored\n");
19539+ return;
19540+
19541+pr:
19542+ spin_unlock(&spin);
0c3ec466
AM
19543+ pr_warn("you may want to try another patch for loopback file "
19544+ "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic);
87a755f4
AM
19545+}
19546+
19547+int au_loopback_init(void)
19548+{
19549+ int err;
19550+ struct super_block *sb __maybe_unused;
19551+
19552+ AuDebugOn(sizeof(sb->s_magic) != sizeof(unsigned long));
19553+
19554+ err = 0;
19555+ au_warn_loopback_array = kcalloc(au_warn_loopback_step,
19556+ sizeof(unsigned long), GFP_NOFS);
19557+ if (unlikely(!au_warn_loopback_array))
19558+ err = -ENOMEM;
19559+
19560+ return err;
19561+}
19562+
19563+void au_loopback_fin(void)
19564+{
392086de 19565+ symbol_put(loop_backing_file);
87a755f4
AM
19566+ kfree(au_warn_loopback_array);
19567+}
7f207e10
AM
19568diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
19569--- /usr/share/empty/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
19570+++ linux/fs/aufs/loop.h 2014-01-20 20:16:14.739463504 +0100
19571@@ -0,0 +1,52 @@
1facf9fc 19572+/*
523b37e3 19573+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 19574+ *
19575+ * This program, aufs is free software; you can redistribute it and/or modify
19576+ * it under the terms of the GNU General Public License as published by
19577+ * the Free Software Foundation; either version 2 of the License, or
19578+ * (at your option) any later version.
dece6358
AM
19579+ *
19580+ * This program is distributed in the hope that it will be useful,
19581+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19582+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19583+ * GNU General Public License for more details.
19584+ *
19585+ * You should have received a copy of the GNU General Public License
523b37e3 19586+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 19587+ */
19588+
19589+/*
19590+ * support for loopback mount as a branch
19591+ */
19592+
19593+#ifndef __AUFS_LOOP_H__
19594+#define __AUFS_LOOP_H__
19595+
19596+#ifdef __KERNEL__
19597+
dece6358
AM
19598+struct dentry;
19599+struct super_block;
1facf9fc 19600+
19601+#ifdef CONFIG_AUFS_BDEV_LOOP
392086de
AM
19602+/* drivers/block/loop.c */
19603+struct file *loop_backing_file(struct super_block *sb);
19604+
1facf9fc 19605+/* loop.c */
b752ccd1 19606+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding);
1facf9fc 19607+int au_test_loopback_kthread(void);
87a755f4
AM
19608+void au_warn_loopback(struct super_block *h_sb);
19609+
19610+int au_loopback_init(void);
19611+void au_loopback_fin(void);
1facf9fc 19612+#else
4a4d8108 19613+AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
b752ccd1 19614+ struct dentry *h_adding)
4a4d8108 19615+AuStubInt0(au_test_loopback_kthread, void)
87a755f4
AM
19616+AuStubVoid(au_warn_loopback, struct super_block *h_sb)
19617+
19618+AuStubInt0(au_loopback_init, void)
19619+AuStubVoid(au_loopback_fin, void)
1facf9fc 19620+#endif /* BLK_DEV_LOOP */
19621+
19622+#endif /* __KERNEL__ */
19623+#endif /* __AUFS_LOOP_H__ */
7f207e10
AM
19624diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
19625--- /usr/share/empty/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100
86dc4139 19626+++ linux/fs/aufs/magic.mk 2013-07-06 13:20:47.750198454 +0200
4a4d8108 19627@@ -0,0 +1,54 @@
1facf9fc 19628+
19629+# defined in ${srctree}/fs/fuse/inode.c
19630+# tristate
19631+ifdef CONFIG_FUSE_FS
19632+ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
19633+endif
19634+
19635+# defined in ${srctree}/fs/ocfs2/ocfs2_fs.h
19636+# tristate
19637+ifdef CONFIG_OCFS2_FS
19638+ccflags-y += -DOCFS2_SUPER_MAGIC=0x7461636f
19639+endif
19640+
19641+# defined in ${srctree}/fs/ocfs2/dlm/userdlm.h
19642+# tristate
19643+ifdef CONFIG_OCFS2_FS_O2CB
19644+ccflags-y += -DDLMFS_MAGIC=0x76a9f425
19645+endif
19646+
1facf9fc 19647+# defined in ${srctree}/fs/cifs/cifsfs.c
19648+# tristate
19649+ifdef CONFIG_CIFS_FS
19650+ccflags-y += -DCIFS_MAGIC_NUMBER=0xFF534D42
19651+endif
19652+
19653+# defined in ${srctree}/fs/xfs/xfs_sb.h
19654+# tristate
19655+ifdef CONFIG_XFS_FS
19656+ccflags-y += -DXFS_SB_MAGIC=0x58465342
19657+endif
19658+
19659+# defined in ${srctree}/fs/configfs/mount.c
19660+# tristate
19661+ifdef CONFIG_CONFIGFS_FS
19662+ccflags-y += -DCONFIGFS_MAGIC=0x62656570
19663+endif
19664+
19665+# defined in ${srctree}/fs/9p/v9fs.h
19666+# tristate
19667+ifdef CONFIG_9P_FS
19668+ccflags-y += -DV9FS_MAGIC=0x01021997
19669+endif
19670+
19671+# defined in ${srctree}/fs/ubifs/ubifs.h
19672+# tristate
19673+ifdef CONFIG_UBIFS_FS
19674+ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
19675+endif
4a4d8108
AM
19676+
19677+# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h
19678+# tristate
19679+ifdef CONFIG_HFSPLUS_FS
19680+ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b
19681+endif
7f207e10
AM
19682diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
19683--- /usr/share/empty/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100
523b37e3 19684+++ linux/fs/aufs/Makefile 2014-01-20 20:16:14.732796615 +0100
2dfbb274 19685@@ -0,0 +1,42 @@
4a4d8108
AM
19686+
19687+include ${src}/magic.mk
19688+ifeq (${CONFIG_AUFS_FS},m)
19689+include ${src}/conf.mk
19690+endif
19691+-include ${src}/priv_def.mk
19692+
19693+# cf. include/linux/kernel.h
19694+# enable pr_debug
19695+ccflags-y += -DDEBUG
f6c5ef8b
AM
19696+# sparse requires the full pathname
19697+ifdef M
523b37e3 19698+ccflags-y += -include ${M}/../../include/uapi/linux/aufs_type.h
f6c5ef8b 19699+else
523b37e3 19700+ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h
f6c5ef8b 19701+endif
4a4d8108
AM
19702+
19703+obj-$(CONFIG_AUFS_FS) += aufs.o
19704+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
19705+ wkq.o vfsub.o dcsub.o \
e49829fe 19706+ cpup.o whout.o wbr_policy.o \
4a4d8108
AM
19707+ dinfo.o dentry.o \
19708+ dynop.o \
19709+ finfo.o file.o f_op.o \
19710+ dir.o vdir.o \
19711+ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
c2b27bf2 19712+ mvdown.o ioctl.o
4a4d8108
AM
19713+
19714+# all are boolean
e49829fe 19715+aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
4a4d8108
AM
19716+aufs-$(CONFIG_SYSFS) += sysfs.o
19717+aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
19718+aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
19719+aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
19720+aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
4a4d8108
AM
19721+aufs-$(CONFIG_AUFS_EXPORT) += export.o
19722+aufs-$(CONFIG_AUFS_POLL) += poll.o
19723+aufs-$(CONFIG_AUFS_RDU) += rdu.o
19724+aufs-$(CONFIG_AUFS_SP_IATTR) += f_op_sp.o
19725+aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
19726+aufs-$(CONFIG_AUFS_DEBUG) += debug.o
19727+aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
7f207e10
AM
19728diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
19729--- /usr/share/empty/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
19730+++ linux/fs/aufs/module.c 2014-01-20 20:16:14.739463504 +0100
19731@@ -0,0 +1,202 @@
1facf9fc 19732+/*
523b37e3 19733+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 19734+ *
19735+ * This program, aufs is free software; you can redistribute it and/or modify
19736+ * it under the terms of the GNU General Public License as published by
19737+ * the Free Software Foundation; either version 2 of the License, or
19738+ * (at your option) any later version.
dece6358
AM
19739+ *
19740+ * This program is distributed in the hope that it will be useful,
19741+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19742+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19743+ * GNU General Public License for more details.
19744+ *
19745+ * You should have received a copy of the GNU General Public License
523b37e3 19746+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 19747+ */
19748+
19749+/*
19750+ * module global variables and operations
19751+ */
19752+
19753+#include <linux/module.h>
19754+#include <linux/seq_file.h>
19755+#include "aufs.h"
19756+
19757+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp)
19758+{
19759+ if (new_sz <= nused)
19760+ return p;
19761+
19762+ p = krealloc(p, new_sz, gfp);
19763+ if (p)
19764+ memset(p + nused, 0, new_sz - nused);
19765+ return p;
19766+}
19767+
19768+/* ---------------------------------------------------------------------- */
19769+
19770+/*
19771+ * aufs caches
19772+ */
19773+struct kmem_cache *au_cachep[AuCache_Last];
19774+static int __init au_cache_init(void)
19775+{
4a4d8108 19776+ au_cachep[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
1facf9fc 19777+ if (au_cachep[AuCache_DINFO])
027c5e7a 19778+ /* SLAB_DESTROY_BY_RCU */
4a4d8108
AM
19779+ au_cachep[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
19780+ au_icntnr_init_once);
1facf9fc 19781+ if (au_cachep[AuCache_ICNTNR])
4a4d8108
AM
19782+ au_cachep[AuCache_FINFO] = AuCacheCtor(au_finfo,
19783+ au_fi_init_once);
1facf9fc 19784+ if (au_cachep[AuCache_FINFO])
19785+ au_cachep[AuCache_VDIR] = AuCache(au_vdir);
19786+ if (au_cachep[AuCache_VDIR])
19787+ au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
19788+ if (au_cachep[AuCache_DEHSTR])
19789+ return 0;
19790+
19791+ return -ENOMEM;
19792+}
19793+
19794+static void au_cache_fin(void)
19795+{
19796+ int i;
4a4d8108 19797+
537831f9
AM
19798+ /*
19799+ * Make sure all delayed rcu free inodes are flushed before we
19800+ * destroy cache.
19801+ */
19802+ rcu_barrier();
19803+
7eafdf33
AM
19804+ /* excluding AuCache_HNOTIFY */
19805+ BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
19806+ for (i = 0; i < AuCache_HNOTIFY; i++)
1facf9fc 19807+ if (au_cachep[i]) {
19808+ kmem_cache_destroy(au_cachep[i]);
19809+ au_cachep[i] = NULL;
19810+ }
19811+}
19812+
19813+/* ---------------------------------------------------------------------- */
19814+
19815+int au_dir_roflags;
19816+
e49829fe 19817+#ifdef CONFIG_AUFS_SBILIST
1e00d052
AM
19818+/*
19819+ * iterate_supers_type() doesn't protect us from
19820+ * remounting (branch management)
19821+ */
e49829fe
JR
19822+struct au_splhead au_sbilist;
19823+#endif
19824+
9dbd164d
AM
19825+struct lock_class_key au_lc_key[AuLcKey_Last];
19826+
1facf9fc 19827+/*
19828+ * functions for module interface.
19829+ */
19830+MODULE_LICENSE("GPL");
19831+/* MODULE_LICENSE("GPL v2"); */
dece6358 19832+MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
1facf9fc 19833+MODULE_DESCRIPTION(AUFS_NAME
19834+ " -- Advanced multi layered unification filesystem");
19835+MODULE_VERSION(AUFS_VERSION);
c06a8ce3 19836+MODULE_ALIAS_FS(AUFS_NAME);
1facf9fc 19837+
1facf9fc 19838+/* this module parameter has no meaning when SYSFS is disabled */
19839+int sysaufs_brs = 1;
19840+MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
19841+module_param_named(brs, sysaufs_brs, int, S_IRUGO);
19842+
19843+/* ---------------------------------------------------------------------- */
19844+
19845+static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
19846+
19847+int au_seq_path(struct seq_file *seq, struct path *path)
19848+{
19849+ return seq_path(seq, path, au_esc_chars);
19850+}
19851+
19852+/* ---------------------------------------------------------------------- */
19853+
19854+static int __init aufs_init(void)
19855+{
19856+ int err, i;
19857+ char *p;
19858+
19859+ p = au_esc_chars;
19860+ for (i = 1; i <= ' '; i++)
19861+ *p++ = i;
19862+ *p++ = '\\';
19863+ *p++ = '\x7f';
19864+ *p = 0;
19865+
19866+ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
19867+
e49829fe 19868+ au_sbilist_init();
1facf9fc 19869+ sysaufs_brs_init();
19870+ au_debug_init();
4a4d8108 19871+ au_dy_init();
1facf9fc 19872+ err = sysaufs_init();
19873+ if (unlikely(err))
19874+ goto out;
e49829fe 19875+ err = au_procfs_init();
4f0767ce 19876+ if (unlikely(err))
953406b4 19877+ goto out_sysaufs;
e49829fe
JR
19878+ err = au_wkq_init();
19879+ if (unlikely(err))
19880+ goto out_procfs;
87a755f4 19881+ err = au_loopback_init();
1facf9fc 19882+ if (unlikely(err))
19883+ goto out_wkq;
87a755f4
AM
19884+ err = au_hnotify_init();
19885+ if (unlikely(err))
19886+ goto out_loopback;
1facf9fc 19887+ err = au_sysrq_init();
19888+ if (unlikely(err))
19889+ goto out_hin;
19890+ err = au_cache_init();
19891+ if (unlikely(err))
19892+ goto out_sysrq;
19893+ err = register_filesystem(&aufs_fs_type);
19894+ if (unlikely(err))
19895+ goto out_cache;
4a4d8108
AM
19896+ /* since we define pr_fmt, call printk directly */
19897+ printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
1facf9fc 19898+ goto out; /* success */
19899+
4f0767ce 19900+out_cache:
1facf9fc 19901+ au_cache_fin();
4f0767ce 19902+out_sysrq:
1facf9fc 19903+ au_sysrq_fin();
4f0767ce 19904+out_hin:
4a4d8108 19905+ au_hnotify_fin();
87a755f4
AM
19906+out_loopback:
19907+ au_loopback_fin();
4f0767ce 19908+out_wkq:
1facf9fc 19909+ au_wkq_fin();
e49829fe
JR
19910+out_procfs:
19911+ au_procfs_fin();
4f0767ce 19912+out_sysaufs:
1facf9fc 19913+ sysaufs_fin();
4a4d8108 19914+ au_dy_fin();
4f0767ce 19915+out:
1facf9fc 19916+ return err;
19917+}
19918+
19919+static void __exit aufs_exit(void)
19920+{
19921+ unregister_filesystem(&aufs_fs_type);
19922+ au_cache_fin();
19923+ au_sysrq_fin();
4a4d8108 19924+ au_hnotify_fin();
87a755f4 19925+ au_loopback_fin();
1facf9fc 19926+ au_wkq_fin();
e49829fe 19927+ au_procfs_fin();
1facf9fc 19928+ sysaufs_fin();
4a4d8108 19929+ au_dy_fin();
1facf9fc 19930+}
19931+
19932+module_init(aufs_init);
19933+module_exit(aufs_exit);
7f207e10
AM
19934diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
19935--- /usr/share/empty/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
19936+++ linux/fs/aufs/module.h 2014-01-20 20:16:14.742796949 +0100
19937@@ -0,0 +1,104 @@
1facf9fc 19938+/*
523b37e3 19939+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 19940+ *
19941+ * This program, aufs is free software; you can redistribute it and/or modify
19942+ * it under the terms of the GNU General Public License as published by
19943+ * the Free Software Foundation; either version 2 of the License, or
19944+ * (at your option) any later version.
dece6358
AM
19945+ *
19946+ * This program is distributed in the hope that it will be useful,
19947+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19948+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19949+ * GNU General Public License for more details.
19950+ *
19951+ * You should have received a copy of the GNU General Public License
523b37e3 19952+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 19953+ */
19954+
19955+/*
19956+ * module initialization and module-global
19957+ */
19958+
19959+#ifndef __AUFS_MODULE_H__
19960+#define __AUFS_MODULE_H__
19961+
19962+#ifdef __KERNEL__
19963+
19964+#include <linux/slab.h>
19965+
dece6358
AM
19966+struct path;
19967+struct seq_file;
19968+
1facf9fc 19969+/* module parameters */
1facf9fc 19970+extern int sysaufs_brs;
19971+
19972+/* ---------------------------------------------------------------------- */
19973+
19974+extern int au_dir_roflags;
19975+
9dbd164d
AM
19976+enum {
19977+ AuLcNonDir_FIINFO,
19978+ AuLcNonDir_DIINFO,
19979+ AuLcNonDir_IIINFO,
19980+
19981+ AuLcDir_FIINFO,
19982+ AuLcDir_DIINFO,
19983+ AuLcDir_IIINFO,
19984+
19985+ AuLcSymlink_DIINFO,
19986+ AuLcSymlink_IIINFO,
19987+
19988+ AuLcKey_Last
19989+};
19990+extern struct lock_class_key au_lc_key[AuLcKey_Last];
19991+
1facf9fc 19992+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp);
19993+int au_seq_path(struct seq_file *seq, struct path *path);
19994+
e49829fe
JR
19995+#ifdef CONFIG_PROC_FS
19996+/* procfs.c */
19997+int __init au_procfs_init(void);
19998+void au_procfs_fin(void);
19999+#else
20000+AuStubInt0(au_procfs_init, void);
20001+AuStubVoid(au_procfs_fin, void);
20002+#endif
20003+
4f0767ce
JR
20004+/* ---------------------------------------------------------------------- */
20005+
20006+/* kmem cache */
1facf9fc 20007+enum {
20008+ AuCache_DINFO,
20009+ AuCache_ICNTNR,
20010+ AuCache_FINFO,
20011+ AuCache_VDIR,
20012+ AuCache_DEHSTR,
7eafdf33 20013+ AuCache_HNOTIFY, /* must be last */
1facf9fc 20014+ AuCache_Last
20015+};
20016+
4a4d8108
AM
20017+#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
20018+#define AuCache(type) KMEM_CACHE(type, AuCacheFlags)
20019+#define AuCacheCtor(type, ctor) \
20020+ kmem_cache_create(#type, sizeof(struct type), \
20021+ __alignof__(struct type), AuCacheFlags, ctor)
1facf9fc 20022+
20023+extern struct kmem_cache *au_cachep[];
20024+
20025+#define AuCacheFuncs(name, index) \
4a4d8108 20026+static inline struct au_##name *au_cache_alloc_##name(void) \
1facf9fc 20027+{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \
4a4d8108 20028+static inline void au_cache_free_##name(struct au_##name *p) \
1facf9fc 20029+{ kmem_cache_free(au_cachep[AuCache_##index], p); }
20030+
20031+AuCacheFuncs(dinfo, DINFO);
20032+AuCacheFuncs(icntnr, ICNTNR);
20033+AuCacheFuncs(finfo, FINFO);
20034+AuCacheFuncs(vdir, VDIR);
4a4d8108
AM
20035+AuCacheFuncs(vdir_dehstr, DEHSTR);
20036+#ifdef CONFIG_AUFS_HNOTIFY
20037+AuCacheFuncs(hnotify, HNOTIFY);
20038+#endif
1facf9fc 20039+
4a4d8108
AM
20040+#endif /* __KERNEL__ */
20041+#endif /* __AUFS_MODULE_H__ */
c2b27bf2
AM
20042diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
20043--- /usr/share/empty/fs/aufs/mvdown.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
20044+++ linux/fs/aufs/mvdown.c 2014-01-20 20:16:14.742796949 +0100
20045@@ -0,0 +1,627 @@
c2b27bf2 20046+/*
523b37e3 20047+ * Copyright (C) 2011-2014 Junjiro R. Okajima
c2b27bf2
AM
20048+ *
20049+ * This program, aufs is free software; you can redistribute it and/or modify
20050+ * it under the terms of the GNU General Public License as published by
20051+ * the Free Software Foundation; either version 2 of the License, or
20052+ * (at your option) any later version.
20053+ *
20054+ * This program is distributed in the hope that it will be useful,
20055+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20056+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20057+ * GNU General Public License for more details.
20058+ *
20059+ * You should have received a copy of the GNU General Public License
523b37e3
AM
20060+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20061+ */
20062+
20063+/*
20064+ * move-down, opposite of copy-up
c2b27bf2
AM
20065+ */
20066+
20067+#include "aufs.h"
20068+
c2b27bf2
AM
20069+struct au_mvd_args {
20070+ struct {
c2b27bf2
AM
20071+ struct super_block *h_sb;
20072+ struct dentry *h_parent;
20073+ struct au_hinode *hdir;
392086de 20074+ struct inode *h_dir, *h_inode;
c2b27bf2
AM
20075+ } info[AUFS_MVDOWN_NARRAY];
20076+
20077+ struct aufs_mvdown mvdown;
20078+ struct dentry *dentry, *parent;
20079+ struct inode *inode, *dir;
20080+ struct super_block *sb;
20081+ aufs_bindex_t bopq, bwh, bfound;
20082+ unsigned char rename_lock;
20083+ struct au_pin pin;
20084+};
20085+
392086de
AM
20086+#define mvd_errno mvdown.au_errno
20087+#define mvd_bsrc mvdown.a[AUFS_MVDOWN_UPPER].bindex
20088+#define mvd_src_brid mvdown.a[AUFS_MVDOWN_UPPER].brid
20089+#define mvd_bdst mvdown.a[AUFS_MVDOWN_LOWER].bindex
20090+#define mvd_dst_brid mvdown.a[AUFS_MVDOWN_LOWER].brid
c2b27bf2 20091+
392086de
AM
20092+#define mvd_h_src_sb info[AUFS_MVDOWN_UPPER].h_sb
20093+#define mvd_h_src_parent info[AUFS_MVDOWN_UPPER].h_parent
20094+#define mvd_hdir_src info[AUFS_MVDOWN_UPPER].hdir
20095+#define mvd_h_src_dir info[AUFS_MVDOWN_UPPER].h_dir
20096+#define mvd_h_src_inode info[AUFS_MVDOWN_UPPER].h_inode
20097+
20098+#define mvd_h_dst_sb info[AUFS_MVDOWN_LOWER].h_sb
20099+#define mvd_h_dst_parent info[AUFS_MVDOWN_LOWER].h_parent
20100+#define mvd_hdir_dst info[AUFS_MVDOWN_LOWER].hdir
20101+#define mvd_h_dst_dir info[AUFS_MVDOWN_LOWER].h_dir
20102+#define mvd_h_dst_inode info[AUFS_MVDOWN_LOWER].h_inode
c2b27bf2
AM
20103+
20104+#define AU_MVD_PR(flag, ...) do { \
20105+ if (flag) \
20106+ pr_err(__VA_ARGS__); \
20107+ } while (0)
20108+
20109+/* make the parent dir on bdst */
392086de 20110+static int au_do_mkdir(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20111+{
20112+ int err;
20113+
20114+ err = 0;
20115+ a->mvd_hdir_src = au_hi(a->dir, a->mvd_bsrc);
20116+ a->mvd_hdir_dst = au_hi(a->dir, a->mvd_bdst);
20117+ a->mvd_h_src_parent = au_h_dptr(a->parent, a->mvd_bsrc);
20118+ a->mvd_h_dst_parent = NULL;
20119+ if (au_dbend(a->parent) >= a->mvd_bdst)
20120+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
20121+ if (!a->mvd_h_dst_parent) {
20122+ err = au_cpdown_dirs(a->dentry, a->mvd_bdst);
20123+ if (unlikely(err)) {
392086de 20124+ AU_MVD_PR(dmsg, "cpdown_dirs failed\n");
c2b27bf2
AM
20125+ goto out;
20126+ }
20127+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
20128+ }
20129+
20130+out:
20131+ AuTraceErr(err);
20132+ return err;
20133+}
20134+
20135+/* lock them all */
392086de 20136+static int au_do_lock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20137+{
20138+ int err;
20139+ struct dentry *h_trap;
20140+
20141+ a->mvd_h_src_sb = au_sbr_sb(a->sb, a->mvd_bsrc);
20142+ a->mvd_h_dst_sb = au_sbr_sb(a->sb, a->mvd_bdst);
20143+ if (a->mvd_h_src_sb != a->mvd_h_dst_sb) {
20144+ a->rename_lock = 0;
392086de
AM
20145+ err = au_pin(&a->pin, a->dentry, a->mvd_bdst,
20146+ au_opt_udba(a->sb),
c2b27bf2
AM
20147+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
20148+ if (!err) {
20149+ a->mvd_h_src_dir = a->mvd_h_src_parent->d_inode;
20150+ mutex_lock_nested(&a->mvd_h_src_dir->i_mutex,
20151+ AuLsc_I_PARENT3);
20152+ } else
392086de 20153+ AU_MVD_PR(dmsg, "pin failed\n");
c2b27bf2
AM
20154+ goto out;
20155+ }
20156+
20157+ err = 0;
20158+ a->rename_lock = 1;
20159+ h_trap = vfsub_lock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
20160+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
20161+ if (h_trap) {
20162+ err = (h_trap != a->mvd_h_src_parent);
20163+ if (err)
20164+ err = (h_trap != a->mvd_h_dst_parent);
20165+ }
20166+ BUG_ON(err); /* it should never happen */
20167+
20168+out:
20169+ AuTraceErr(err);
20170+ return err;
20171+}
20172+
392086de 20173+static void au_do_unlock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20174+{
20175+ if (!a->rename_lock) {
20176+ mutex_unlock(&a->mvd_h_src_dir->i_mutex);
20177+ au_unpin(&a->pin);
20178+ } else
20179+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
20180+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
20181+}
20182+
20183+/* copy-down the file */
392086de 20184+static int au_do_cpdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20185+{
20186+ int err;
20187+ struct au_cp_generic cpg = {
20188+ .dentry = a->dentry,
20189+ .bdst = a->mvd_bdst,
20190+ .bsrc = a->mvd_bsrc,
20191+ .len = -1,
20192+ .pin = &a->pin,
20193+ .flags = AuCpup_DTIME | AuCpup_HOPEN
20194+ };
20195+
20196+ AuDbg("b%d, b%d\n", cpg.bsrc, cpg.bdst);
392086de
AM
20197+ if (a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
20198+ au_fset_cpup(cpg.flags, OVERWRITE);
20199+ if (a->mvdown.flags & AUFS_MVDOWN_ROLOWER)
20200+ au_fset_cpup(cpg.flags, RWDST);
c2b27bf2
AM
20201+ err = au_sio_cpdown_simple(&cpg);
20202+ if (unlikely(err))
392086de 20203+ AU_MVD_PR(dmsg, "cpdown failed\n");
c2b27bf2
AM
20204+
20205+ AuTraceErr(err);
20206+ return err;
20207+}
20208+
20209+/*
20210+ * unlink the whiteout on bdst if exist which may be created by UDBA while we
20211+ * were sleeping
20212+ */
392086de 20213+static int au_do_unlink_wh(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20214+{
20215+ int err;
20216+ struct path h_path;
20217+ struct au_branch *br;
523b37e3 20218+ struct inode *delegated;
c2b27bf2
AM
20219+
20220+ br = au_sbr(a->sb, a->mvd_bdst);
20221+ h_path.dentry = au_wh_lkup(a->mvd_h_dst_parent, &a->dentry->d_name, br);
20222+ err = PTR_ERR(h_path.dentry);
20223+ if (IS_ERR(h_path.dentry)) {
392086de 20224+ AU_MVD_PR(dmsg, "wh_lkup failed\n");
c2b27bf2
AM
20225+ goto out;
20226+ }
20227+
20228+ err = 0;
20229+ if (h_path.dentry->d_inode) {
20230+ h_path.mnt = au_br_mnt(br);
523b37e3 20231+ delegated = NULL;
c2b27bf2 20232+ err = vfsub_unlink(a->mvd_h_dst_parent->d_inode, &h_path,
523b37e3
AM
20233+ &delegated, /*force*/0);
20234+ if (unlikely(err == -EWOULDBLOCK)) {
20235+ pr_warn("cannot retry for NFSv4 delegation"
20236+ " for an internal unlink\n");
20237+ iput(delegated);
20238+ }
c2b27bf2 20239+ if (unlikely(err))
392086de 20240+ AU_MVD_PR(dmsg, "wh_unlink failed\n");
c2b27bf2
AM
20241+ }
20242+ dput(h_path.dentry);
20243+
20244+out:
20245+ AuTraceErr(err);
20246+ return err;
20247+}
20248+
20249+/*
20250+ * unlink the topmost h_dentry
20251+ * Note: the target file MAY be modified by UDBA between this mutex_unlock() and
20252+ * mutex_lock() in vfs_unlink(). in this case, such changes may be lost.
20253+ */
392086de 20254+static int au_do_unlink(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20255+{
20256+ int err;
20257+ struct path h_path;
523b37e3 20258+ struct inode *delegated;
c2b27bf2
AM
20259+
20260+ h_path.mnt = au_sbr_mnt(a->sb, a->mvd_bsrc);
20261+ h_path.dentry = au_h_dptr(a->dentry, a->mvd_bsrc);
523b37e3
AM
20262+ delegated = NULL;
20263+ err = vfsub_unlink(a->mvd_h_src_dir, &h_path, &delegated, /*force*/0);
20264+ if (unlikely(err == -EWOULDBLOCK)) {
20265+ pr_warn("cannot retry for NFSv4 delegation"
20266+ " for an internal unlink\n");
20267+ iput(delegated);
20268+ }
c2b27bf2 20269+ if (unlikely(err))
392086de 20270+ AU_MVD_PR(dmsg, "unlink failed\n");
c2b27bf2
AM
20271+
20272+ AuTraceErr(err);
20273+ return err;
20274+}
20275+
20276+/*
20277+ * copy-down the file and unlink the bsrc file.
20278+ * - unlink the bdst whout if exist
20279+ * - copy-down the file (with whtmp name and rename)
20280+ * - unlink the bsrc file
20281+ */
392086de 20282+static int au_do_mvdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20283+{
20284+ int err;
20285+
392086de 20286+ err = au_do_mkdir(dmsg, a);
c2b27bf2 20287+ if (!err)
392086de 20288+ err = au_do_lock(dmsg, a);
c2b27bf2
AM
20289+ if (unlikely(err))
20290+ goto out;
20291+
20292+ /*
20293+ * do not revert the activities we made on bdst since they should be
20294+ * harmless in aufs.
20295+ */
20296+
392086de 20297+ err = au_do_cpdown(dmsg, a);
c2b27bf2 20298+ if (!err)
392086de
AM
20299+ err = au_do_unlink_wh(dmsg, a);
20300+ if (!err && !(a->mvdown.flags & AUFS_MVDOWN_KUPPER))
20301+ err = au_do_unlink(dmsg, a);
c2b27bf2
AM
20302+ if (unlikely(err))
20303+ goto out_unlock;
20304+
20305+ /* maintain internal array */
392086de
AM
20306+ if (!(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) {
20307+ au_set_h_dptr(a->dentry, a->mvd_bsrc, NULL);
20308+ au_set_dbstart(a->dentry, a->mvd_bdst);
20309+ au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0);
20310+ au_set_ibstart(a->inode, a->mvd_bdst);
20311+ }
c2b27bf2
AM
20312+ if (au_dbend(a->dentry) < a->mvd_bdst)
20313+ au_set_dbend(a->dentry, a->mvd_bdst);
c2b27bf2
AM
20314+ if (au_ibend(a->inode) < a->mvd_bdst)
20315+ au_set_ibend(a->inode, a->mvd_bdst);
20316+
20317+out_unlock:
392086de 20318+ au_do_unlock(dmsg, a);
c2b27bf2
AM
20319+out:
20320+ AuTraceErr(err);
20321+ return err;
20322+}
20323+
20324+/* ---------------------------------------------------------------------- */
20325+
392086de 20326+static int find_lower_writable(struct au_mvd_args *a)
c2b27bf2 20327+{
392086de
AM
20328+ struct super_block *sb;
20329+ aufs_bindex_t bindex, bend;
c2b27bf2
AM
20330+ struct au_branch *br;
20331+
392086de
AM
20332+ sb = a->sb;
20333+ bindex = a->mvd_bsrc;
c2b27bf2 20334+ bend = au_sbend(sb);
392086de
AM
20335+ if (!(a->mvdown.flags & AUFS_MVDOWN_ROLOWER)) {
20336+ for (bindex++; bindex <= bend; bindex++) {
20337+ br = au_sbr(sb, bindex);
20338+ if (!au_br_rdonly(br))
20339+ return bindex;
20340+ }
20341+ } else {
20342+ for (bindex++; bindex <= bend; bindex++) {
20343+ br = au_sbr(sb, bindex);
20344+ if (!(au_br_sb(br)->s_flags & MS_RDONLY)) {
20345+ if (au_br_rdonly(br))
20346+ a->mvdown.flags
20347+ |= AUFS_MVDOWN_ROLOWER_R;
20348+ return bindex;
20349+ }
20350+ }
c2b27bf2
AM
20351+ }
20352+
20353+ return -1;
20354+}
20355+
20356+/* make sure the file is idle */
392086de 20357+static int au_mvd_args_busy(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20358+{
20359+ int err, plinked;
c2b27bf2
AM
20360+
20361+ err = 0;
c2b27bf2
AM
20362+ plinked = !!au_opt_test(au_mntflags(a->sb), PLINK);
20363+ if (au_dbstart(a->dentry) == a->mvd_bsrc
392086de 20364+ && d_count(a->dentry) == 1
c2b27bf2 20365+ && atomic_read(&a->inode->i_count) == 1
392086de 20366+ /* && a->mvd_h_src_inode->i_nlink == 1 */
c2b27bf2
AM
20367+ && (!plinked || !au_plink_test(a->inode))
20368+ && a->inode->i_nlink == 1)
20369+ goto out;
20370+
20371+ err = -EBUSY;
392086de 20372+ AU_MVD_PR(dmsg,
c2b27bf2 20373+ "b%d, d{b%d, c%u?}, i{c%d?, l%u}, hi{l%u}, p{%d, %d}\n",
392086de 20374+ a->mvd_bsrc, au_dbstart(a->dentry), d_count(a->dentry),
c2b27bf2 20375+ atomic_read(&a->inode->i_count), a->inode->i_nlink,
392086de 20376+ a->mvd_h_src_inode->i_nlink,
c2b27bf2
AM
20377+ plinked, plinked ? au_plink_test(a->inode) : 0);
20378+
20379+out:
20380+ AuTraceErr(err);
20381+ return err;
20382+}
20383+
20384+/* make sure the parent dir is fine */
392086de 20385+static int au_mvd_args_parent(const unsigned char dmsg,
c2b27bf2
AM
20386+ struct au_mvd_args *a)
20387+{
20388+ int err;
20389+ aufs_bindex_t bindex;
20390+
20391+ err = 0;
20392+ if (unlikely(au_alive_dir(a->parent))) {
20393+ err = -ENOENT;
392086de 20394+ AU_MVD_PR(dmsg, "parent dir is dead\n");
c2b27bf2
AM
20395+ goto out;
20396+ }
20397+
20398+ a->bopq = au_dbdiropq(a->parent);
20399+ bindex = au_wbr_nonopq(a->dentry, a->mvd_bdst);
20400+ AuDbg("b%d\n", bindex);
20401+ if (unlikely((bindex >= 0 && bindex < a->mvd_bdst)
20402+ || (a->bopq != -1 && a->bopq < a->mvd_bdst))) {
20403+ err = -EINVAL;
392086de
AM
20404+ a->mvd_errno = EAU_MVDOWN_OPAQUE;
20405+ AU_MVD_PR(dmsg, "ancestor is opaque b%d, b%d\n",
c2b27bf2
AM
20406+ a->bopq, a->mvd_bdst);
20407+ }
20408+
20409+out:
20410+ AuTraceErr(err);
20411+ return err;
20412+}
20413+
392086de 20414+static int au_mvd_args_intermediate(const unsigned char dmsg,
c2b27bf2
AM
20415+ struct au_mvd_args *a)
20416+{
20417+ int err;
20418+ struct au_dinfo *dinfo, *tmp;
20419+
20420+ /* lookup the next lower positive entry */
20421+ err = -ENOMEM;
20422+ tmp = au_di_alloc(a->sb, AuLsc_DI_TMP);
20423+ if (unlikely(!tmp))
20424+ goto out;
20425+
20426+ a->bfound = -1;
20427+ a->bwh = -1;
20428+ dinfo = au_di(a->dentry);
20429+ au_di_cp(tmp, dinfo);
20430+ au_di_swap(tmp, dinfo);
20431+
20432+ /* returns the number of positive dentries */
20433+ err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1, /*type*/0);
20434+ if (!err)
20435+ a->bwh = au_dbwh(a->dentry);
20436+ else if (err > 0)
20437+ a->bfound = au_dbstart(a->dentry);
20438+
20439+ au_di_swap(tmp, dinfo);
20440+ au_rw_write_unlock(&tmp->di_rwsem);
20441+ au_di_free(tmp);
20442+ if (unlikely(err < 0))
392086de 20443+ AU_MVD_PR(dmsg, "failed look-up lower\n");
c2b27bf2
AM
20444+
20445+ /*
20446+ * here, we have these cases.
20447+ * bfound == -1
20448+ * no positive dentry under bsrc. there are more sub-cases.
20449+ * bwh < 0
20450+ * there no whiteout, we can safely move-down.
20451+ * bwh <= bsrc
20452+ * impossible
20453+ * bsrc < bwh && bwh < bdst
20454+ * there is a whiteout on RO branch. cannot proceed.
20455+ * bwh == bdst
20456+ * there is a whiteout on the RW target branch. it should
20457+ * be removed.
20458+ * bdst < bwh
20459+ * there is a whiteout somewhere unrelated branch.
20460+ * -1 < bfound && bfound <= bsrc
20461+ * impossible.
20462+ * bfound < bdst
20463+ * found, but it is on RO branch between bsrc and bdst. cannot
20464+ * proceed.
20465+ * bfound == bdst
20466+ * found, replace it if AUFS_MVDOWN_FORCE is set. otherwise return
20467+ * error.
20468+ * bdst < bfound
20469+ * found, after we create the file on bdst, it will be hidden.
20470+ */
20471+
20472+ AuDebugOn(a->bfound == -1
20473+ && a->bwh != -1
20474+ && a->bwh <= a->mvd_bsrc);
20475+ AuDebugOn(-1 < a->bfound
20476+ && a->bfound <= a->mvd_bsrc);
20477+
20478+ err = -EINVAL;
20479+ if (a->bfound == -1
20480+ && a->mvd_bsrc < a->bwh
20481+ && a->bwh != -1
20482+ && a->bwh < a->mvd_bdst) {
392086de
AM
20483+ a->mvd_errno = EAU_MVDOWN_WHITEOUT;
20484+ AU_MVD_PR(dmsg, "bsrc %d, bdst %d, bfound %d, bwh %d\n",
c2b27bf2
AM
20485+ a->mvd_bsrc, a->mvd_bdst, a->bfound, a->bwh);
20486+ goto out;
20487+ } else if (a->bfound != -1 && a->bfound < a->mvd_bdst) {
392086de
AM
20488+ a->mvd_errno = EAU_MVDOWN_UPPER;
20489+ AU_MVD_PR(dmsg, "bdst %d, bfound %d\n",
c2b27bf2
AM
20490+ a->mvd_bdst, a->bfound);
20491+ goto out;
20492+ }
20493+
20494+ err = 0; /* success */
20495+
20496+out:
20497+ AuTraceErr(err);
20498+ return err;
20499+}
20500+
392086de 20501+static int au_mvd_args_exist(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20502+{
20503+ int err;
20504+
392086de
AM
20505+ err = 0;
20506+ if (!(a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
20507+ && a->bfound == a->mvd_bdst)
20508+ err = -EEXIST;
c2b27bf2
AM
20509+ AuTraceErr(err);
20510+ return err;
20511+}
20512+
392086de 20513+static int au_mvd_args(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20514+{
20515+ int err;
20516+ struct au_branch *br;
20517+
20518+ err = -EISDIR;
20519+ if (unlikely(S_ISDIR(a->inode->i_mode)))
20520+ goto out;
20521+
20522+ err = -EINVAL;
392086de
AM
20523+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_UPPER))
20524+ a->mvd_bsrc = au_ibstart(a->inode);
20525+ else {
20526+ a->mvd_bsrc = au_br_index(a->sb, a->mvd_src_brid);
20527+ if (unlikely(a->mvd_bsrc < 0
20528+ || (a->mvd_bsrc < au_dbstart(a->dentry)
20529+ || au_dbend(a->dentry) < a->mvd_bsrc
20530+ || !au_h_dptr(a->dentry, a->mvd_bsrc))
20531+ || (a->mvd_bsrc < au_ibstart(a->inode)
20532+ || au_ibend(a->inode) < a->mvd_bsrc
20533+ || !au_h_iptr(a->inode, a->mvd_bsrc)))) {
20534+ a->mvd_errno = EAU_MVDOWN_NOUPPER;
20535+ AU_MVD_PR(dmsg, "no upper\n");
20536+ goto out;
20537+ }
20538+ }
c2b27bf2 20539+ if (unlikely(a->mvd_bsrc == au_sbend(a->sb))) {
392086de
AM
20540+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
20541+ AU_MVD_PR(dmsg, "on the bottom\n");
c2b27bf2
AM
20542+ goto out;
20543+ }
392086de 20544+ a->mvd_h_src_inode = au_h_iptr(a->inode, a->mvd_bsrc);
c2b27bf2
AM
20545+ br = au_sbr(a->sb, a->mvd_bsrc);
20546+ err = au_br_rdonly(br);
392086de
AM
20547+ if (!(a->mvdown.flags & AUFS_MVDOWN_ROUPPER)) {
20548+ if (unlikely(err))
20549+ goto out;
20550+ } else if (!(vfsub_native_ro(a->mvd_h_src_inode)
20551+ || IS_APPEND(a->mvd_h_src_inode))) {
20552+ if (err)
20553+ a->mvdown.flags |= AUFS_MVDOWN_ROUPPER_R;
20554+ /* go on */
20555+ } else
c2b27bf2
AM
20556+ goto out;
20557+
20558+ err = -EINVAL;
392086de
AM
20559+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_LOWER)) {
20560+ a->mvd_bdst = find_lower_writable(a);
20561+ if (unlikely(a->mvd_bdst < 0)) {
20562+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
20563+ AU_MVD_PR(dmsg, "no writable lower branch\n");
20564+ goto out;
20565+ }
20566+ } else {
20567+ a->mvd_bdst = au_br_index(a->sb, a->mvd_dst_brid);
20568+ if (unlikely(a->mvd_bdst < 0
20569+ || au_sbend(a->sb) < a->mvd_bdst)) {
20570+ a->mvd_errno = EAU_MVDOWN_NOLOWERBR;
20571+ AU_MVD_PR(dmsg, "no lower brid\n");
20572+ goto out;
20573+ }
c2b27bf2
AM
20574+ }
20575+
392086de 20576+ err = au_mvd_args_busy(dmsg, a);
c2b27bf2 20577+ if (!err)
392086de 20578+ err = au_mvd_args_parent(dmsg, a);
c2b27bf2 20579+ if (!err)
392086de 20580+ err = au_mvd_args_intermediate(dmsg, a);
c2b27bf2 20581+ if (!err)
392086de 20582+ err = au_mvd_args_exist(dmsg, a);
c2b27bf2
AM
20583+ if (!err)
20584+ AuDbg("b%d, b%d\n", a->mvd_bsrc, a->mvd_bdst);
20585+
20586+out:
20587+ AuTraceErr(err);
20588+ return err;
20589+}
20590+
20591+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg)
20592+{
392086de
AM
20593+ int err, e;
20594+ unsigned char dmsg;
20595+ struct au_mvd_args *args;
c2b27bf2
AM
20596+
20597+ err = -EPERM;
20598+ if (unlikely(!capable(CAP_SYS_ADMIN)))
20599+ goto out;
20600+
392086de
AM
20601+ WARN_ONCE(1, "move-down is still testing...\n");
20602+
20603+ err = -ENOMEM;
20604+ args = kmalloc(sizeof(*args), GFP_NOFS);
20605+ if (unlikely(!args))
20606+ goto out;
20607+
20608+ err = copy_from_user(&args->mvdown, uarg, sizeof(args->mvdown));
20609+ if (!err)
20610+ err = !access_ok(VERIFY_WRITE, uarg, sizeof(*uarg));
c2b27bf2
AM
20611+ if (unlikely(err)) {
20612+ err = -EFAULT;
392086de
AM
20613+ AuTraceErr(err);
20614+ goto out_free;
c2b27bf2 20615+ }
392086de
AM
20616+ AuDbg("flags 0x%x\n", args->mvdown.flags);
20617+ args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R);
20618+ args->mvdown.au_errno = 0;
20619+ args->dentry = dentry;
20620+ args->inode = dentry->d_inode;
20621+ args->sb = dentry->d_sb;
c2b27bf2 20622+
392086de
AM
20623+ err = -ENOENT;
20624+ dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG);
20625+ args->parent = dget_parent(dentry);
20626+ args->dir = args->parent->d_inode;
20627+ mutex_lock_nested(&args->dir->i_mutex, I_MUTEX_PARENT);
20628+ dput(args->parent);
20629+ if (unlikely(args->parent != dentry->d_parent)) {
20630+ AU_MVD_PR(dmsg, "parent dir is moved\n");
c2b27bf2
AM
20631+ goto out_dir;
20632+ }
20633+
392086de 20634+ mutex_lock_nested(&args->inode->i_mutex, I_MUTEX_CHILD);
c2b27bf2
AM
20635+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH);
20636+ if (unlikely(err))
20637+ goto out_inode;
20638+
392086de
AM
20639+ di_write_lock_parent(args->parent);
20640+ err = au_mvd_args(dmsg, args);
c2b27bf2
AM
20641+ if (unlikely(err))
20642+ goto out_parent;
20643+
20644+ AuDbgDentry(dentry);
392086de
AM
20645+ AuDbgInode(args->inode);
20646+ err = au_do_mvdown(dmsg, args);
c2b27bf2
AM
20647+ if (unlikely(err))
20648+ goto out_parent;
20649+ AuDbgDentry(dentry);
392086de 20650+ AuDbgInode(args->inode);
c2b27bf2 20651+
392086de
AM
20652+ au_cpup_attr_timesizes(args->dir);
20653+ au_cpup_attr_timesizes(args->inode);
20654+ au_cpup_igen(args->inode, au_h_iptr(args->inode, args->mvd_bdst));
c2b27bf2
AM
20655+ /* au_digen_dec(dentry); */
20656+
20657+out_parent:
392086de 20658+ di_write_unlock(args->parent);
c2b27bf2
AM
20659+ aufs_read_unlock(dentry, AuLock_DW);
20660+out_inode:
392086de 20661+ mutex_unlock(&args->inode->i_mutex);
c2b27bf2 20662+out_dir:
392086de
AM
20663+ mutex_unlock(&args->dir->i_mutex);
20664+out_free:
20665+ e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown));
20666+ if (unlikely(e))
20667+ err = -EFAULT;
20668+ kfree(args);
c2b27bf2
AM
20669+out:
20670+ AuTraceErr(err);
20671+ return err;
20672+}
20673diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
20674--- /usr/share/empty/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100
f6b6e03d 20675+++ linux/fs/aufs/opts.c 2014-01-27 23:16:52.715087263 +0100
523b37e3 20676@@ -0,0 +1,1701 @@
1facf9fc 20677+/*
523b37e3 20678+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 20679+ *
20680+ * This program, aufs is free software; you can redistribute it and/or modify
20681+ * it under the terms of the GNU General Public License as published by
20682+ * the Free Software Foundation; either version 2 of the License, or
20683+ * (at your option) any later version.
dece6358
AM
20684+ *
20685+ * This program is distributed in the hope that it will be useful,
20686+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20687+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20688+ * GNU General Public License for more details.
20689+ *
20690+ * You should have received a copy of the GNU General Public License
523b37e3 20691+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 20692+ */
20693+
20694+/*
20695+ * mount options/flags
20696+ */
20697+
dece6358 20698+#include <linux/namei.h>
1facf9fc 20699+#include <linux/types.h> /* a distribution requires */
20700+#include <linux/parser.h>
20701+#include "aufs.h"
20702+
20703+/* ---------------------------------------------------------------------- */
20704+
20705+enum {
20706+ Opt_br,
20707+ Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend,
20708+ Opt_idel, Opt_imod, Opt_ireorder,
20709+ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, Opt_rendir,
dece6358 20710+ Opt_rdblk_def, Opt_rdhash_def,
1facf9fc 20711+ Opt_xino, Opt_zxino, Opt_noxino,
20712+ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
20713+ Opt_trunc_xino_path, Opt_itrunc_xino,
20714+ Opt_trunc_xib, Opt_notrunc_xib,
dece6358 20715+ Opt_shwh, Opt_noshwh,
1facf9fc 20716+ Opt_plink, Opt_noplink, Opt_list_plink,
20717+ Opt_udba,
4a4d8108 20718+ Opt_dio, Opt_nodio,
1facf9fc 20719+ /* Opt_lock, Opt_unlock, */
20720+ Opt_cmd, Opt_cmd_args,
20721+ Opt_diropq_a, Opt_diropq_w,
20722+ Opt_warn_perm, Opt_nowarn_perm,
20723+ Opt_wbr_copyup, Opt_wbr_create,
20724+ Opt_refrof, Opt_norefrof,
20725+ Opt_verbose, Opt_noverbose,
20726+ Opt_sum, Opt_nosum, Opt_wsum,
20727+ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
20728+};
20729+
20730+static match_table_t options = {
20731+ {Opt_br, "br=%s"},
20732+ {Opt_br, "br:%s"},
20733+
20734+ {Opt_add, "add=%d:%s"},
20735+ {Opt_add, "add:%d:%s"},
20736+ {Opt_add, "ins=%d:%s"},
20737+ {Opt_add, "ins:%d:%s"},
20738+ {Opt_append, "append=%s"},
20739+ {Opt_append, "append:%s"},
20740+ {Opt_prepend, "prepend=%s"},
20741+ {Opt_prepend, "prepend:%s"},
20742+
20743+ {Opt_del, "del=%s"},
20744+ {Opt_del, "del:%s"},
20745+ /* {Opt_idel, "idel:%d"}, */
20746+ {Opt_mod, "mod=%s"},
20747+ {Opt_mod, "mod:%s"},
20748+ /* {Opt_imod, "imod:%d:%s"}, */
20749+
20750+ {Opt_dirwh, "dirwh=%d"},
20751+
20752+ {Opt_xino, "xino=%s"},
20753+ {Opt_noxino, "noxino"},
20754+ {Opt_trunc_xino, "trunc_xino"},
20755+ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
20756+ {Opt_notrunc_xino, "notrunc_xino"},
20757+ {Opt_trunc_xino_path, "trunc_xino=%s"},
20758+ {Opt_itrunc_xino, "itrunc_xino=%d"},
20759+ /* {Opt_zxino, "zxino=%s"}, */
20760+ {Opt_trunc_xib, "trunc_xib"},
20761+ {Opt_notrunc_xib, "notrunc_xib"},
20762+
e49829fe 20763+#ifdef CONFIG_PROC_FS
1facf9fc 20764+ {Opt_plink, "plink"},
e49829fe
JR
20765+#else
20766+ {Opt_ignore_silent, "plink"},
20767+#endif
20768+
1facf9fc 20769+ {Opt_noplink, "noplink"},
e49829fe 20770+
1facf9fc 20771+#ifdef CONFIG_AUFS_DEBUG
20772+ {Opt_list_plink, "list_plink"},
20773+#endif
20774+
20775+ {Opt_udba, "udba=%s"},
20776+
4a4d8108
AM
20777+ {Opt_dio, "dio"},
20778+ {Opt_nodio, "nodio"},
20779+
1facf9fc 20780+ {Opt_diropq_a, "diropq=always"},
20781+ {Opt_diropq_a, "diropq=a"},
20782+ {Opt_diropq_w, "diropq=whiteouted"},
20783+ {Opt_diropq_w, "diropq=w"},
20784+
20785+ {Opt_warn_perm, "warn_perm"},
20786+ {Opt_nowarn_perm, "nowarn_perm"},
20787+
20788+ /* keep them temporary */
20789+ {Opt_ignore_silent, "coo=%s"},
20790+ {Opt_ignore_silent, "nodlgt"},
20791+ {Opt_ignore_silent, "nodirperm1"},
1facf9fc 20792+ {Opt_ignore_silent, "clean_plink"},
20793+
dece6358
AM
20794+#ifdef CONFIG_AUFS_SHWH
20795+ {Opt_shwh, "shwh"},
20796+#endif
20797+ {Opt_noshwh, "noshwh"},
20798+
1facf9fc 20799+ {Opt_rendir, "rendir=%d"},
20800+
20801+ {Opt_refrof, "refrof"},
20802+ {Opt_norefrof, "norefrof"},
20803+
20804+ {Opt_verbose, "verbose"},
20805+ {Opt_verbose, "v"},
20806+ {Opt_noverbose, "noverbose"},
20807+ {Opt_noverbose, "quiet"},
20808+ {Opt_noverbose, "q"},
20809+ {Opt_noverbose, "silent"},
20810+
20811+ {Opt_sum, "sum"},
20812+ {Opt_nosum, "nosum"},
20813+ {Opt_wsum, "wsum"},
20814+
20815+ {Opt_rdcache, "rdcache=%d"},
20816+ {Opt_rdblk, "rdblk=%d"},
dece6358 20817+ {Opt_rdblk_def, "rdblk=def"},
1facf9fc 20818+ {Opt_rdhash, "rdhash=%d"},
dece6358 20819+ {Opt_rdhash_def, "rdhash=def"},
1facf9fc 20820+
20821+ {Opt_wbr_create, "create=%s"},
20822+ {Opt_wbr_create, "create_policy=%s"},
20823+ {Opt_wbr_copyup, "cpup=%s"},
20824+ {Opt_wbr_copyup, "copyup=%s"},
20825+ {Opt_wbr_copyup, "copyup_policy=%s"},
20826+
20827+ /* internal use for the scripts */
20828+ {Opt_ignore_silent, "si=%s"},
20829+
20830+ {Opt_br, "dirs=%s"},
20831+ {Opt_ignore, "debug=%d"},
20832+ {Opt_ignore, "delete=whiteout"},
20833+ {Opt_ignore, "delete=all"},
20834+ {Opt_ignore, "imap=%s"},
20835+
1308ab2a 20836+ /* temporary workaround, due to old mount(8)? */
20837+ {Opt_ignore_silent, "relatime"},
20838+
1facf9fc 20839+ {Opt_err, NULL}
20840+};
20841+
20842+/* ---------------------------------------------------------------------- */
20843+
20844+static const char *au_parser_pattern(int val, struct match_token *token)
20845+{
20846+ while (token->pattern) {
20847+ if (token->token == val)
20848+ return token->pattern;
20849+ token++;
20850+ }
20851+ BUG();
20852+ return "??";
20853+}
20854+
20855+/* ---------------------------------------------------------------------- */
20856+
1e00d052 20857+static match_table_t brperm = {
1facf9fc 20858+ {AuBrPerm_RO, AUFS_BRPERM_RO},
20859+ {AuBrPerm_RR, AUFS_BRPERM_RR},
20860+ {AuBrPerm_RW, AUFS_BRPERM_RW},
1e00d052
AM
20861+ {0, NULL}
20862+};
1facf9fc 20863+
86dc4139
AM
20864+static match_table_t brattr = {
20865+ {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN},
1e00d052 20866+ {AuBrRAttr_WH, AUFS_BRRATTR_WH},
1e00d052
AM
20867+ {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
20868+ {0, NULL}
1facf9fc 20869+};
20870+
86dc4139
AM
20871+#define AuBrStr_LONGEST AUFS_BRPERM_RW \
20872+ "+" AUFS_BRATTR_UNPIN \
20873+ "+" AUFS_BRWATTR_NLWH
1e00d052
AM
20874+
20875+static int br_attr_val(char *str, match_table_t table, substring_t args[])
20876+{
20877+ int attr, v;
20878+ char *p;
20879+
20880+ attr = 0;
20881+ do {
20882+ p = strchr(str, '+');
20883+ if (p)
20884+ *p = 0;
20885+ v = match_token(str, table, args);
20886+ if (v)
20887+ attr |= v;
20888+ else {
20889+ if (p)
20890+ *p = '+';
0c3ec466 20891+ pr_warn("ignored branch attribute %s\n", str);
1e00d052
AM
20892+ break;
20893+ }
20894+ if (p)
20895+ str = p + 1;
20896+ } while (p);
20897+
20898+ return attr;
20899+}
20900+
4a4d8108 20901+static int noinline_for_stack br_perm_val(char *perm)
1facf9fc 20902+{
20903+ int val;
86dc4139 20904+ char *p, *q;
1facf9fc 20905+ substring_t args[MAX_OPT_ARGS];
20906+
1e00d052
AM
20907+ p = strchr(perm, '+');
20908+ if (p)
20909+ *p = 0;
20910+ val = match_token(perm, brperm, args);
20911+ if (!val) {
20912+ if (p)
20913+ *p = '+';
0c3ec466 20914+ pr_warn("ignored branch permission %s\n", perm);
1e00d052
AM
20915+ val = AuBrPerm_RO;
20916+ goto out;
20917+ }
20918+ if (!p)
20919+ goto out;
20920+
86dc4139
AM
20921+ p++;
20922+ while (1) {
20923+ q = strchr(p, '+');
20924+ if (q)
20925+ *q = 0;
20926+ val |= br_attr_val(p, brattr, args);
20927+ if (q) {
20928+ *q = '+';
20929+ p = q + 1;
20930+ } else
20931+ break;
20932+ }
20933+ switch (val & AuBrPerm_Mask) {
1e00d052
AM
20934+ case AuBrPerm_RO:
20935+ case AuBrPerm_RR:
86dc4139
AM
20936+ if (unlikely(val & AuBrWAttr_NoLinkWH)) {
20937+ pr_warn("ignored branch attribute %s\n",
20938+ AUFS_BRWATTR_NLWH);
20939+ val &= ~AuBrWAttr_NoLinkWH;
20940+ }
1e00d052
AM
20941+ break;
20942+ case AuBrPerm_RW:
86dc4139
AM
20943+ if (unlikely(val & AuBrRAttr_WH)) {
20944+ pr_warn("ignored branch attribute %s\n",
20945+ AUFS_BRRATTR_WH);
20946+ val &= ~AuBrRAttr_WH;
20947+ }
1e00d052
AM
20948+ break;
20949+ }
20950+
20951+out:
1facf9fc 20952+ return val;
20953+}
20954+
1e00d052
AM
20955+/* Caller should free the return value */
20956+char *au_optstr_br_perm(int brperm)
1facf9fc 20957+{
1e00d052
AM
20958+ char *p, a[sizeof(AuBrStr_LONGEST)];
20959+ int sz;
20960+
20961+#define SetPerm(str) do { \
20962+ sz = sizeof(str); \
20963+ memcpy(a, str, sz); \
20964+ p = a + sz - 1; \
20965+ } while (0)
20966+
20967+#define AppendAttr(flag, str) do { \
20968+ if (brperm & flag) { \
20969+ sz = sizeof(str); \
20970+ *p++ = '+'; \
20971+ memcpy(p, str, sz); \
20972+ p += sz - 1; \
20973+ } \
20974+ } while (0)
20975+
20976+ switch (brperm & AuBrPerm_Mask) {
20977+ case AuBrPerm_RO:
20978+ SetPerm(AUFS_BRPERM_RO);
20979+ break;
20980+ case AuBrPerm_RR:
20981+ SetPerm(AUFS_BRPERM_RR);
20982+ break;
20983+ case AuBrPerm_RW:
20984+ SetPerm(AUFS_BRPERM_RW);
20985+ break;
20986+ default:
20987+ AuDebugOn(1);
20988+ }
20989+
86dc4139 20990+ AppendAttr(AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN);
1e00d052
AM
20991+ AppendAttr(AuBrRAttr_WH, AUFS_BRRATTR_WH);
20992+ AppendAttr(AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH);
20993+
20994+ AuDebugOn(strlen(a) >= sizeof(a));
20995+ return kstrdup(a, GFP_NOFS);
20996+#undef SetPerm
20997+#undef AppendAttr
1facf9fc 20998+}
20999+
21000+/* ---------------------------------------------------------------------- */
21001+
21002+static match_table_t udbalevel = {
21003+ {AuOpt_UDBA_REVAL, "reval"},
21004+ {AuOpt_UDBA_NONE, "none"},
4a4d8108
AM
21005+#ifdef CONFIG_AUFS_HNOTIFY
21006+ {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
21007+#ifdef CONFIG_AUFS_HFSNOTIFY
21008+ {AuOpt_UDBA_HNOTIFY, "fsnotify"},
4a4d8108 21009+#endif
1facf9fc 21010+#endif
21011+ {-1, NULL}
21012+};
21013+
4a4d8108 21014+static int noinline_for_stack udba_val(char *str)
1facf9fc 21015+{
21016+ substring_t args[MAX_OPT_ARGS];
21017+
7f207e10 21018+ return match_token(str, udbalevel, args);
1facf9fc 21019+}
21020+
21021+const char *au_optstr_udba(int udba)
21022+{
21023+ return au_parser_pattern(udba, (void *)udbalevel);
21024+}
21025+
21026+/* ---------------------------------------------------------------------- */
21027+
21028+static match_table_t au_wbr_create_policy = {
21029+ {AuWbrCreate_TDP, "tdp"},
21030+ {AuWbrCreate_TDP, "top-down-parent"},
21031+ {AuWbrCreate_RR, "rr"},
21032+ {AuWbrCreate_RR, "round-robin"},
21033+ {AuWbrCreate_MFS, "mfs"},
21034+ {AuWbrCreate_MFS, "most-free-space"},
21035+ {AuWbrCreate_MFSV, "mfs:%d"},
21036+ {AuWbrCreate_MFSV, "most-free-space:%d"},
21037+
21038+ {AuWbrCreate_MFSRR, "mfsrr:%d"},
21039+ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
21040+ {AuWbrCreate_PMFS, "pmfs"},
21041+ {AuWbrCreate_PMFSV, "pmfs:%d"},
392086de
AM
21042+ {AuWbrCreate_PMFSRR, "pmfsrr:%d"},
21043+ {AuWbrCreate_PMFSRRV, "pmfsrr:%d:%d"},
1facf9fc 21044+
21045+ {-1, NULL}
21046+};
21047+
dece6358
AM
21048+/*
21049+ * cf. linux/lib/parser.c and cmdline.c
21050+ * gave up calling memparse() since it uses simple_strtoull() instead of
9dbd164d 21051+ * kstrto...().
dece6358 21052+ */
4a4d8108
AM
21053+static int noinline_for_stack
21054+au_match_ull(substring_t *s, unsigned long long *result)
1facf9fc 21055+{
21056+ int err;
21057+ unsigned int len;
21058+ char a[32];
21059+
21060+ err = -ERANGE;
21061+ len = s->to - s->from;
21062+ if (len + 1 <= sizeof(a)) {
21063+ memcpy(a, s->from, len);
21064+ a[len] = '\0';
9dbd164d 21065+ err = kstrtoull(a, 0, result);
1facf9fc 21066+ }
21067+ return err;
21068+}
21069+
21070+static int au_wbr_mfs_wmark(substring_t *arg, char *str,
21071+ struct au_opt_wbr_create *create)
21072+{
21073+ int err;
21074+ unsigned long long ull;
21075+
21076+ err = 0;
21077+ if (!au_match_ull(arg, &ull))
21078+ create->mfsrr_watermark = ull;
21079+ else {
4a4d8108 21080+ pr_err("bad integer in %s\n", str);
1facf9fc 21081+ err = -EINVAL;
21082+ }
21083+
21084+ return err;
21085+}
21086+
21087+static int au_wbr_mfs_sec(substring_t *arg, char *str,
21088+ struct au_opt_wbr_create *create)
21089+{
21090+ int n, err;
21091+
21092+ err = 0;
027c5e7a 21093+ if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
1facf9fc 21094+ create->mfs_second = n;
21095+ else {
4a4d8108 21096+ pr_err("bad integer in %s\n", str);
1facf9fc 21097+ err = -EINVAL;
21098+ }
21099+
21100+ return err;
21101+}
21102+
4a4d8108
AM
21103+static int noinline_for_stack
21104+au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
1facf9fc 21105+{
21106+ int err, e;
21107+ substring_t args[MAX_OPT_ARGS];
21108+
21109+ err = match_token(str, au_wbr_create_policy, args);
21110+ create->wbr_create = err;
21111+ switch (err) {
21112+ case AuWbrCreate_MFSRRV:
392086de 21113+ case AuWbrCreate_PMFSRRV:
1facf9fc 21114+ e = au_wbr_mfs_wmark(&args[0], str, create);
21115+ if (!e)
21116+ e = au_wbr_mfs_sec(&args[1], str, create);
21117+ if (unlikely(e))
21118+ err = e;
21119+ break;
21120+ case AuWbrCreate_MFSRR:
392086de 21121+ case AuWbrCreate_PMFSRR:
1facf9fc 21122+ e = au_wbr_mfs_wmark(&args[0], str, create);
21123+ if (unlikely(e)) {
21124+ err = e;
21125+ break;
21126+ }
21127+ /*FALLTHROUGH*/
21128+ case AuWbrCreate_MFS:
21129+ case AuWbrCreate_PMFS:
027c5e7a 21130+ create->mfs_second = AUFS_MFS_DEF_SEC;
1facf9fc 21131+ break;
21132+ case AuWbrCreate_MFSV:
21133+ case AuWbrCreate_PMFSV:
21134+ e = au_wbr_mfs_sec(&args[0], str, create);
21135+ if (unlikely(e))
21136+ err = e;
21137+ break;
21138+ }
21139+
21140+ return err;
21141+}
21142+
21143+const char *au_optstr_wbr_create(int wbr_create)
21144+{
21145+ return au_parser_pattern(wbr_create, (void *)au_wbr_create_policy);
21146+}
21147+
21148+static match_table_t au_wbr_copyup_policy = {
21149+ {AuWbrCopyup_TDP, "tdp"},
21150+ {AuWbrCopyup_TDP, "top-down-parent"},
21151+ {AuWbrCopyup_BUP, "bup"},
21152+ {AuWbrCopyup_BUP, "bottom-up-parent"},
21153+ {AuWbrCopyup_BU, "bu"},
21154+ {AuWbrCopyup_BU, "bottom-up"},
21155+ {-1, NULL}
21156+};
21157+
4a4d8108 21158+static int noinline_for_stack au_wbr_copyup_val(char *str)
1facf9fc 21159+{
21160+ substring_t args[MAX_OPT_ARGS];
21161+
21162+ return match_token(str, au_wbr_copyup_policy, args);
21163+}
21164+
21165+const char *au_optstr_wbr_copyup(int wbr_copyup)
21166+{
21167+ return au_parser_pattern(wbr_copyup, (void *)au_wbr_copyup_policy);
21168+}
21169+
21170+/* ---------------------------------------------------------------------- */
21171+
21172+static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
21173+
21174+static void dump_opts(struct au_opts *opts)
21175+{
21176+#ifdef CONFIG_AUFS_DEBUG
21177+ /* reduce stack space */
21178+ union {
21179+ struct au_opt_add *add;
21180+ struct au_opt_del *del;
21181+ struct au_opt_mod *mod;
21182+ struct au_opt_xino *xino;
21183+ struct au_opt_xino_itrunc *xino_itrunc;
21184+ struct au_opt_wbr_create *create;
21185+ } u;
21186+ struct au_opt *opt;
21187+
21188+ opt = opts->opt;
21189+ while (opt->type != Opt_tail) {
21190+ switch (opt->type) {
21191+ case Opt_add:
21192+ u.add = &opt->add;
21193+ AuDbg("add {b%d, %s, 0x%x, %p}\n",
21194+ u.add->bindex, u.add->pathname, u.add->perm,
21195+ u.add->path.dentry);
21196+ break;
21197+ case Opt_del:
21198+ case Opt_idel:
21199+ u.del = &opt->del;
21200+ AuDbg("del {%s, %p}\n",
21201+ u.del->pathname, u.del->h_path.dentry);
21202+ break;
21203+ case Opt_mod:
21204+ case Opt_imod:
21205+ u.mod = &opt->mod;
21206+ AuDbg("mod {%s, 0x%x, %p}\n",
21207+ u.mod->path, u.mod->perm, u.mod->h_root);
21208+ break;
21209+ case Opt_append:
21210+ u.add = &opt->add;
21211+ AuDbg("append {b%d, %s, 0x%x, %p}\n",
21212+ u.add->bindex, u.add->pathname, u.add->perm,
21213+ u.add->path.dentry);
21214+ break;
21215+ case Opt_prepend:
21216+ u.add = &opt->add;
21217+ AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
21218+ u.add->bindex, u.add->pathname, u.add->perm,
21219+ u.add->path.dentry);
21220+ break;
21221+ case Opt_dirwh:
21222+ AuDbg("dirwh %d\n", opt->dirwh);
21223+ break;
21224+ case Opt_rdcache:
21225+ AuDbg("rdcache %d\n", opt->rdcache);
21226+ break;
21227+ case Opt_rdblk:
21228+ AuDbg("rdblk %u\n", opt->rdblk);
21229+ break;
dece6358
AM
21230+ case Opt_rdblk_def:
21231+ AuDbg("rdblk_def\n");
21232+ break;
1facf9fc 21233+ case Opt_rdhash:
21234+ AuDbg("rdhash %u\n", opt->rdhash);
21235+ break;
dece6358
AM
21236+ case Opt_rdhash_def:
21237+ AuDbg("rdhash_def\n");
21238+ break;
1facf9fc 21239+ case Opt_xino:
21240+ u.xino = &opt->xino;
523b37e3 21241+ AuDbg("xino {%s %pD}\n", u.xino->path, u.xino->file);
1facf9fc 21242+ break;
21243+ case Opt_trunc_xino:
21244+ AuLabel(trunc_xino);
21245+ break;
21246+ case Opt_notrunc_xino:
21247+ AuLabel(notrunc_xino);
21248+ break;
21249+ case Opt_trunc_xino_path:
21250+ case Opt_itrunc_xino:
21251+ u.xino_itrunc = &opt->xino_itrunc;
21252+ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
21253+ break;
21254+
21255+ case Opt_noxino:
21256+ AuLabel(noxino);
21257+ break;
21258+ case Opt_trunc_xib:
21259+ AuLabel(trunc_xib);
21260+ break;
21261+ case Opt_notrunc_xib:
21262+ AuLabel(notrunc_xib);
21263+ break;
dece6358
AM
21264+ case Opt_shwh:
21265+ AuLabel(shwh);
21266+ break;
21267+ case Opt_noshwh:
21268+ AuLabel(noshwh);
21269+ break;
1facf9fc 21270+ case Opt_plink:
21271+ AuLabel(plink);
21272+ break;
21273+ case Opt_noplink:
21274+ AuLabel(noplink);
21275+ break;
21276+ case Opt_list_plink:
21277+ AuLabel(list_plink);
21278+ break;
21279+ case Opt_udba:
21280+ AuDbg("udba %d, %s\n",
21281+ opt->udba, au_optstr_udba(opt->udba));
21282+ break;
4a4d8108
AM
21283+ case Opt_dio:
21284+ AuLabel(dio);
21285+ break;
21286+ case Opt_nodio:
21287+ AuLabel(nodio);
21288+ break;
1facf9fc 21289+ case Opt_diropq_a:
21290+ AuLabel(diropq_a);
21291+ break;
21292+ case Opt_diropq_w:
21293+ AuLabel(diropq_w);
21294+ break;
21295+ case Opt_warn_perm:
21296+ AuLabel(warn_perm);
21297+ break;
21298+ case Opt_nowarn_perm:
21299+ AuLabel(nowarn_perm);
21300+ break;
21301+ case Opt_refrof:
21302+ AuLabel(refrof);
21303+ break;
21304+ case Opt_norefrof:
21305+ AuLabel(norefrof);
21306+ break;
21307+ case Opt_verbose:
21308+ AuLabel(verbose);
21309+ break;
21310+ case Opt_noverbose:
21311+ AuLabel(noverbose);
21312+ break;
21313+ case Opt_sum:
21314+ AuLabel(sum);
21315+ break;
21316+ case Opt_nosum:
21317+ AuLabel(nosum);
21318+ break;
21319+ case Opt_wsum:
21320+ AuLabel(wsum);
21321+ break;
21322+ case Opt_wbr_create:
21323+ u.create = &opt->wbr_create;
21324+ AuDbg("create %d, %s\n", u.create->wbr_create,
21325+ au_optstr_wbr_create(u.create->wbr_create));
21326+ switch (u.create->wbr_create) {
21327+ case AuWbrCreate_MFSV:
21328+ case AuWbrCreate_PMFSV:
21329+ AuDbg("%d sec\n", u.create->mfs_second);
21330+ break;
21331+ case AuWbrCreate_MFSRR:
21332+ AuDbg("%llu watermark\n",
21333+ u.create->mfsrr_watermark);
21334+ break;
21335+ case AuWbrCreate_MFSRRV:
392086de 21336+ case AuWbrCreate_PMFSRRV:
1facf9fc 21337+ AuDbg("%llu watermark, %d sec\n",
21338+ u.create->mfsrr_watermark,
21339+ u.create->mfs_second);
21340+ break;
21341+ }
21342+ break;
21343+ case Opt_wbr_copyup:
21344+ AuDbg("copyup %d, %s\n", opt->wbr_copyup,
21345+ au_optstr_wbr_copyup(opt->wbr_copyup));
21346+ break;
21347+ default:
21348+ BUG();
21349+ }
21350+ opt++;
21351+ }
21352+#endif
21353+}
21354+
21355+void au_opts_free(struct au_opts *opts)
21356+{
21357+ struct au_opt *opt;
21358+
21359+ opt = opts->opt;
21360+ while (opt->type != Opt_tail) {
21361+ switch (opt->type) {
21362+ case Opt_add:
21363+ case Opt_append:
21364+ case Opt_prepend:
21365+ path_put(&opt->add.path);
21366+ break;
21367+ case Opt_del:
21368+ case Opt_idel:
21369+ path_put(&opt->del.h_path);
21370+ break;
21371+ case Opt_mod:
21372+ case Opt_imod:
21373+ dput(opt->mod.h_root);
21374+ break;
21375+ case Opt_xino:
21376+ fput(opt->xino.file);
21377+ break;
21378+ }
21379+ opt++;
21380+ }
21381+}
21382+
21383+static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
21384+ aufs_bindex_t bindex)
21385+{
21386+ int err;
21387+ struct au_opt_add *add = &opt->add;
21388+ char *p;
21389+
21390+ add->bindex = bindex;
1e00d052 21391+ add->perm = AuBrPerm_RO;
1facf9fc 21392+ add->pathname = opt_str;
21393+ p = strchr(opt_str, '=');
21394+ if (p) {
21395+ *p++ = 0;
21396+ if (*p)
21397+ add->perm = br_perm_val(p);
21398+ }
21399+
21400+ err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
21401+ if (!err) {
21402+ if (!p) {
21403+ add->perm = AuBrPerm_RO;
21404+ if (au_test_fs_rr(add->path.dentry->d_sb))
21405+ add->perm = AuBrPerm_RR;
21406+ else if (!bindex && !(sb_flags & MS_RDONLY))
21407+ add->perm = AuBrPerm_RW;
21408+ }
21409+ opt->type = Opt_add;
21410+ goto out;
21411+ }
4a4d8108 21412+ pr_err("lookup failed %s (%d)\n", add->pathname, err);
1facf9fc 21413+ err = -EINVAL;
21414+
4f0767ce 21415+out:
1facf9fc 21416+ return err;
21417+}
21418+
21419+static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
21420+{
21421+ int err;
21422+
21423+ del->pathname = args[0].from;
21424+ AuDbg("del path %s\n", del->pathname);
21425+
21426+ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
21427+ if (unlikely(err))
4a4d8108 21428+ pr_err("lookup failed %s (%d)\n", del->pathname, err);
1facf9fc 21429+
21430+ return err;
21431+}
21432+
21433+#if 0 /* reserved for future use */
21434+static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
21435+ struct au_opt_del *del, substring_t args[])
21436+{
21437+ int err;
21438+ struct dentry *root;
21439+
21440+ err = -EINVAL;
21441+ root = sb->s_root;
21442+ aufs_read_lock(root, AuLock_FLUSH);
21443+ if (bindex < 0 || au_sbend(sb) < bindex) {
4a4d8108 21444+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 21445+ goto out;
21446+ }
21447+
21448+ err = 0;
21449+ del->h_path.dentry = dget(au_h_dptr(root, bindex));
21450+ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
21451+
4f0767ce 21452+out:
1facf9fc 21453+ aufs_read_unlock(root, !AuLock_IR);
21454+ return err;
21455+}
21456+#endif
21457+
4a4d8108
AM
21458+static int noinline_for_stack
21459+au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
1facf9fc 21460+{
21461+ int err;
21462+ struct path path;
21463+ char *p;
21464+
21465+ err = -EINVAL;
21466+ mod->path = args[0].from;
21467+ p = strchr(mod->path, '=');
21468+ if (unlikely(!p)) {
4a4d8108 21469+ pr_err("no permssion %s\n", args[0].from);
1facf9fc 21470+ goto out;
21471+ }
21472+
21473+ *p++ = 0;
21474+ err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
21475+ if (unlikely(err)) {
4a4d8108 21476+ pr_err("lookup failed %s (%d)\n", mod->path, err);
1facf9fc 21477+ goto out;
21478+ }
21479+
21480+ mod->perm = br_perm_val(p);
21481+ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
21482+ mod->h_root = dget(path.dentry);
21483+ path_put(&path);
21484+
4f0767ce 21485+out:
1facf9fc 21486+ return err;
21487+}
21488+
21489+#if 0 /* reserved for future use */
21490+static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
21491+ struct au_opt_mod *mod, substring_t args[])
21492+{
21493+ int err;
21494+ struct dentry *root;
21495+
21496+ err = -EINVAL;
21497+ root = sb->s_root;
21498+ aufs_read_lock(root, AuLock_FLUSH);
21499+ if (bindex < 0 || au_sbend(sb) < bindex) {
4a4d8108 21500+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 21501+ goto out;
21502+ }
21503+
21504+ err = 0;
21505+ mod->perm = br_perm_val(args[1].from);
21506+ AuDbg("mod path %s, perm 0x%x, %s\n",
21507+ mod->path, mod->perm, args[1].from);
21508+ mod->h_root = dget(au_h_dptr(root, bindex));
21509+
4f0767ce 21510+out:
1facf9fc 21511+ aufs_read_unlock(root, !AuLock_IR);
21512+ return err;
21513+}
21514+#endif
21515+
21516+static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
21517+ substring_t args[])
21518+{
21519+ int err;
21520+ struct file *file;
21521+
21522+ file = au_xino_create(sb, args[0].from, /*silent*/0);
21523+ err = PTR_ERR(file);
21524+ if (IS_ERR(file))
21525+ goto out;
21526+
21527+ err = -EINVAL;
21528+ if (unlikely(file->f_dentry->d_sb == sb)) {
21529+ fput(file);
4a4d8108 21530+ pr_err("%s must be outside\n", args[0].from);
1facf9fc 21531+ goto out;
21532+ }
21533+
21534+ err = 0;
21535+ xino->file = file;
21536+ xino->path = args[0].from;
21537+
4f0767ce 21538+out:
1facf9fc 21539+ return err;
21540+}
21541+
4a4d8108
AM
21542+static int noinline_for_stack
21543+au_opts_parse_xino_itrunc_path(struct super_block *sb,
21544+ struct au_opt_xino_itrunc *xino_itrunc,
21545+ substring_t args[])
1facf9fc 21546+{
21547+ int err;
21548+ aufs_bindex_t bend, bindex;
21549+ struct path path;
21550+ struct dentry *root;
21551+
21552+ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
21553+ if (unlikely(err)) {
4a4d8108 21554+ pr_err("lookup failed %s (%d)\n", args[0].from, err);
1facf9fc 21555+ goto out;
21556+ }
21557+
21558+ xino_itrunc->bindex = -1;
21559+ root = sb->s_root;
21560+ aufs_read_lock(root, AuLock_FLUSH);
21561+ bend = au_sbend(sb);
21562+ for (bindex = 0; bindex <= bend; bindex++) {
21563+ if (au_h_dptr(root, bindex) == path.dentry) {
21564+ xino_itrunc->bindex = bindex;
21565+ break;
21566+ }
21567+ }
21568+ aufs_read_unlock(root, !AuLock_IR);
21569+ path_put(&path);
21570+
21571+ if (unlikely(xino_itrunc->bindex < 0)) {
4a4d8108 21572+ pr_err("no such branch %s\n", args[0].from);
1facf9fc 21573+ err = -EINVAL;
21574+ }
21575+
4f0767ce 21576+out:
1facf9fc 21577+ return err;
21578+}
21579+
21580+/* called without aufs lock */
21581+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
21582+{
21583+ int err, n, token;
21584+ aufs_bindex_t bindex;
21585+ unsigned char skipped;
21586+ struct dentry *root;
21587+ struct au_opt *opt, *opt_tail;
21588+ char *opt_str;
21589+ /* reduce the stack space */
21590+ union {
21591+ struct au_opt_xino_itrunc *xino_itrunc;
21592+ struct au_opt_wbr_create *create;
21593+ } u;
21594+ struct {
21595+ substring_t args[MAX_OPT_ARGS];
21596+ } *a;
21597+
21598+ err = -ENOMEM;
21599+ a = kmalloc(sizeof(*a), GFP_NOFS);
21600+ if (unlikely(!a))
21601+ goto out;
21602+
21603+ root = sb->s_root;
21604+ err = 0;
21605+ bindex = 0;
21606+ opt = opts->opt;
21607+ opt_tail = opt + opts->max_opt - 1;
21608+ opt->type = Opt_tail;
21609+ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
21610+ err = -EINVAL;
21611+ skipped = 0;
21612+ token = match_token(opt_str, options, a->args);
21613+ switch (token) {
21614+ case Opt_br:
21615+ err = 0;
21616+ while (!err && (opt_str = strsep(&a->args[0].from, ":"))
21617+ && *opt_str) {
21618+ err = opt_add(opt, opt_str, opts->sb_flags,
21619+ bindex++);
21620+ if (unlikely(!err && ++opt > opt_tail)) {
21621+ err = -E2BIG;
21622+ break;
21623+ }
21624+ opt->type = Opt_tail;
21625+ skipped = 1;
21626+ }
21627+ break;
21628+ case Opt_add:
21629+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 21630+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 21631+ break;
21632+ }
21633+ bindex = n;
21634+ err = opt_add(opt, a->args[1].from, opts->sb_flags,
21635+ bindex);
21636+ if (!err)
21637+ opt->type = token;
21638+ break;
21639+ case Opt_append:
21640+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
21641+ /*dummy bindex*/1);
21642+ if (!err)
21643+ opt->type = token;
21644+ break;
21645+ case Opt_prepend:
21646+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
21647+ /*bindex*/0);
21648+ if (!err)
21649+ opt->type = token;
21650+ break;
21651+ case Opt_del:
21652+ err = au_opts_parse_del(&opt->del, a->args);
21653+ if (!err)
21654+ opt->type = token;
21655+ break;
21656+#if 0 /* reserved for future use */
21657+ case Opt_idel:
21658+ del->pathname = "(indexed)";
21659+ if (unlikely(match_int(&args[0], &n))) {
4a4d8108 21660+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 21661+ break;
21662+ }
21663+ err = au_opts_parse_idel(sb, n, &opt->del, a->args);
21664+ if (!err)
21665+ opt->type = token;
21666+ break;
21667+#endif
21668+ case Opt_mod:
21669+ err = au_opts_parse_mod(&opt->mod, a->args);
21670+ if (!err)
21671+ opt->type = token;
21672+ break;
21673+#ifdef IMOD /* reserved for future use */
21674+ case Opt_imod:
21675+ u.mod->path = "(indexed)";
21676+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 21677+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 21678+ break;
21679+ }
21680+ err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
21681+ if (!err)
21682+ opt->type = token;
21683+ break;
21684+#endif
21685+ case Opt_xino:
21686+ err = au_opts_parse_xino(sb, &opt->xino, a->args);
21687+ if (!err)
21688+ opt->type = token;
21689+ break;
21690+
21691+ case Opt_trunc_xino_path:
21692+ err = au_opts_parse_xino_itrunc_path
21693+ (sb, &opt->xino_itrunc, a->args);
21694+ if (!err)
21695+ opt->type = token;
21696+ break;
21697+
21698+ case Opt_itrunc_xino:
21699+ u.xino_itrunc = &opt->xino_itrunc;
21700+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 21701+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 21702+ break;
21703+ }
21704+ u.xino_itrunc->bindex = n;
21705+ aufs_read_lock(root, AuLock_FLUSH);
21706+ if (n < 0 || au_sbend(sb) < n) {
4a4d8108 21707+ pr_err("out of bounds, %d\n", n);
1facf9fc 21708+ aufs_read_unlock(root, !AuLock_IR);
21709+ break;
21710+ }
21711+ aufs_read_unlock(root, !AuLock_IR);
21712+ err = 0;
21713+ opt->type = token;
21714+ break;
21715+
21716+ case Opt_dirwh:
21717+ if (unlikely(match_int(&a->args[0], &opt->dirwh)))
21718+ break;
21719+ err = 0;
21720+ opt->type = token;
21721+ break;
21722+
21723+ case Opt_rdcache:
027c5e7a
AM
21724+ if (unlikely(match_int(&a->args[0], &n))) {
21725+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 21726+ break;
027c5e7a
AM
21727+ }
21728+ if (unlikely(n > AUFS_RDCACHE_MAX)) {
21729+ pr_err("rdcache must be smaller than %d\n",
21730+ AUFS_RDCACHE_MAX);
21731+ break;
21732+ }
21733+ opt->rdcache = n;
1facf9fc 21734+ err = 0;
21735+ opt->type = token;
21736+ break;
21737+ case Opt_rdblk:
21738+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 21739+ || n < 0
1facf9fc 21740+ || n > KMALLOC_MAX_SIZE)) {
4a4d8108 21741+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 21742+ break;
21743+ }
1308ab2a 21744+ if (unlikely(n && n < NAME_MAX)) {
4a4d8108
AM
21745+ pr_err("rdblk must be larger than %d\n",
21746+ NAME_MAX);
1facf9fc 21747+ break;
21748+ }
21749+ opt->rdblk = n;
21750+ err = 0;
21751+ opt->type = token;
21752+ break;
21753+ case Opt_rdhash:
21754+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 21755+ || n < 0
1facf9fc 21756+ || n * sizeof(struct hlist_head)
21757+ > KMALLOC_MAX_SIZE)) {
4a4d8108 21758+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 21759+ break;
21760+ }
21761+ opt->rdhash = n;
21762+ err = 0;
21763+ opt->type = token;
21764+ break;
21765+
21766+ case Opt_trunc_xino:
21767+ case Opt_notrunc_xino:
21768+ case Opt_noxino:
21769+ case Opt_trunc_xib:
21770+ case Opt_notrunc_xib:
dece6358
AM
21771+ case Opt_shwh:
21772+ case Opt_noshwh:
1facf9fc 21773+ case Opt_plink:
21774+ case Opt_noplink:
21775+ case Opt_list_plink:
4a4d8108
AM
21776+ case Opt_dio:
21777+ case Opt_nodio:
1facf9fc 21778+ case Opt_diropq_a:
21779+ case Opt_diropq_w:
21780+ case Opt_warn_perm:
21781+ case Opt_nowarn_perm:
21782+ case Opt_refrof:
21783+ case Opt_norefrof:
21784+ case Opt_verbose:
21785+ case Opt_noverbose:
21786+ case Opt_sum:
21787+ case Opt_nosum:
21788+ case Opt_wsum:
dece6358
AM
21789+ case Opt_rdblk_def:
21790+ case Opt_rdhash_def:
1facf9fc 21791+ err = 0;
21792+ opt->type = token;
21793+ break;
21794+
21795+ case Opt_udba:
21796+ opt->udba = udba_val(a->args[0].from);
21797+ if (opt->udba >= 0) {
21798+ err = 0;
21799+ opt->type = token;
21800+ } else
4a4d8108 21801+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 21802+ break;
21803+
21804+ case Opt_wbr_create:
21805+ u.create = &opt->wbr_create;
21806+ u.create->wbr_create
21807+ = au_wbr_create_val(a->args[0].from, u.create);
21808+ if (u.create->wbr_create >= 0) {
21809+ err = 0;
21810+ opt->type = token;
21811+ } else
4a4d8108 21812+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 21813+ break;
21814+ case Opt_wbr_copyup:
21815+ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
21816+ if (opt->wbr_copyup >= 0) {
21817+ err = 0;
21818+ opt->type = token;
21819+ } else
4a4d8108 21820+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 21821+ break;
21822+
21823+ case Opt_ignore:
0c3ec466 21824+ pr_warn("ignored %s\n", opt_str);
1facf9fc 21825+ /*FALLTHROUGH*/
21826+ case Opt_ignore_silent:
21827+ skipped = 1;
21828+ err = 0;
21829+ break;
21830+ case Opt_err:
4a4d8108 21831+ pr_err("unknown option %s\n", opt_str);
1facf9fc 21832+ break;
21833+ }
21834+
21835+ if (!err && !skipped) {
21836+ if (unlikely(++opt > opt_tail)) {
21837+ err = -E2BIG;
21838+ opt--;
21839+ opt->type = Opt_tail;
21840+ break;
21841+ }
21842+ opt->type = Opt_tail;
21843+ }
21844+ }
21845+
21846+ kfree(a);
21847+ dump_opts(opts);
21848+ if (unlikely(err))
21849+ au_opts_free(opts);
21850+
4f0767ce 21851+out:
1facf9fc 21852+ return err;
21853+}
21854+
21855+static int au_opt_wbr_create(struct super_block *sb,
21856+ struct au_opt_wbr_create *create)
21857+{
21858+ int err;
21859+ struct au_sbinfo *sbinfo;
21860+
dece6358
AM
21861+ SiMustWriteLock(sb);
21862+
1facf9fc 21863+ err = 1; /* handled */
21864+ sbinfo = au_sbi(sb);
21865+ if (sbinfo->si_wbr_create_ops->fin) {
21866+ err = sbinfo->si_wbr_create_ops->fin(sb);
21867+ if (!err)
21868+ err = 1;
21869+ }
21870+
21871+ sbinfo->si_wbr_create = create->wbr_create;
21872+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
21873+ switch (create->wbr_create) {
21874+ case AuWbrCreate_MFSRRV:
21875+ case AuWbrCreate_MFSRR:
392086de
AM
21876+ case AuWbrCreate_PMFSRR:
21877+ case AuWbrCreate_PMFSRRV:
1facf9fc 21878+ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
21879+ /*FALLTHROUGH*/
21880+ case AuWbrCreate_MFS:
21881+ case AuWbrCreate_MFSV:
21882+ case AuWbrCreate_PMFS:
21883+ case AuWbrCreate_PMFSV:
e49829fe
JR
21884+ sbinfo->si_wbr_mfs.mfs_expire
21885+ = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
1facf9fc 21886+ break;
21887+ }
21888+
21889+ if (sbinfo->si_wbr_create_ops->init)
21890+ sbinfo->si_wbr_create_ops->init(sb); /* ignore */
21891+
21892+ return err;
21893+}
21894+
21895+/*
21896+ * returns,
21897+ * plus: processed without an error
21898+ * zero: unprocessed
21899+ */
21900+static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
21901+ struct au_opts *opts)
21902+{
21903+ int err;
21904+ struct au_sbinfo *sbinfo;
21905+
dece6358
AM
21906+ SiMustWriteLock(sb);
21907+
1facf9fc 21908+ err = 1; /* handled */
21909+ sbinfo = au_sbi(sb);
21910+ switch (opt->type) {
21911+ case Opt_udba:
21912+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
21913+ sbinfo->si_mntflags |= opt->udba;
21914+ opts->given_udba |= opt->udba;
21915+ break;
21916+
21917+ case Opt_plink:
21918+ au_opt_set(sbinfo->si_mntflags, PLINK);
21919+ break;
21920+ case Opt_noplink:
21921+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
e49829fe 21922+ au_plink_put(sb, /*verbose*/1);
1facf9fc 21923+ au_opt_clr(sbinfo->si_mntflags, PLINK);
21924+ break;
21925+ case Opt_list_plink:
21926+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
21927+ au_plink_list(sb);
21928+ break;
21929+
4a4d8108
AM
21930+ case Opt_dio:
21931+ au_opt_set(sbinfo->si_mntflags, DIO);
21932+ au_fset_opts(opts->flags, REFRESH_DYAOP);
21933+ break;
21934+ case Opt_nodio:
21935+ au_opt_clr(sbinfo->si_mntflags, DIO);
21936+ au_fset_opts(opts->flags, REFRESH_DYAOP);
21937+ break;
21938+
1facf9fc 21939+ case Opt_diropq_a:
21940+ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
21941+ break;
21942+ case Opt_diropq_w:
21943+ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
21944+ break;
21945+
21946+ case Opt_warn_perm:
21947+ au_opt_set(sbinfo->si_mntflags, WARN_PERM);
21948+ break;
21949+ case Opt_nowarn_perm:
21950+ au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
21951+ break;
21952+
21953+ case Opt_refrof:
21954+ au_opt_set(sbinfo->si_mntflags, REFROF);
21955+ break;
21956+ case Opt_norefrof:
21957+ au_opt_clr(sbinfo->si_mntflags, REFROF);
21958+ break;
21959+
21960+ case Opt_verbose:
21961+ au_opt_set(sbinfo->si_mntflags, VERBOSE);
21962+ break;
21963+ case Opt_noverbose:
21964+ au_opt_clr(sbinfo->si_mntflags, VERBOSE);
21965+ break;
21966+
21967+ case Opt_sum:
21968+ au_opt_set(sbinfo->si_mntflags, SUM);
21969+ break;
21970+ case Opt_wsum:
21971+ au_opt_clr(sbinfo->si_mntflags, SUM);
21972+ au_opt_set(sbinfo->si_mntflags, SUM_W);
21973+ case Opt_nosum:
21974+ au_opt_clr(sbinfo->si_mntflags, SUM);
21975+ au_opt_clr(sbinfo->si_mntflags, SUM_W);
21976+ break;
21977+
21978+ case Opt_wbr_create:
21979+ err = au_opt_wbr_create(sb, &opt->wbr_create);
21980+ break;
21981+ case Opt_wbr_copyup:
21982+ sbinfo->si_wbr_copyup = opt->wbr_copyup;
21983+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
21984+ break;
21985+
21986+ case Opt_dirwh:
21987+ sbinfo->si_dirwh = opt->dirwh;
21988+ break;
21989+
21990+ case Opt_rdcache:
e49829fe
JR
21991+ sbinfo->si_rdcache
21992+ = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
1facf9fc 21993+ break;
21994+ case Opt_rdblk:
21995+ sbinfo->si_rdblk = opt->rdblk;
21996+ break;
dece6358
AM
21997+ case Opt_rdblk_def:
21998+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
21999+ break;
1facf9fc 22000+ case Opt_rdhash:
22001+ sbinfo->si_rdhash = opt->rdhash;
22002+ break;
dece6358
AM
22003+ case Opt_rdhash_def:
22004+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
22005+ break;
22006+
22007+ case Opt_shwh:
22008+ au_opt_set(sbinfo->si_mntflags, SHWH);
22009+ break;
22010+ case Opt_noshwh:
22011+ au_opt_clr(sbinfo->si_mntflags, SHWH);
22012+ break;
1facf9fc 22013+
22014+ case Opt_trunc_xino:
22015+ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
22016+ break;
22017+ case Opt_notrunc_xino:
22018+ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
22019+ break;
22020+
22021+ case Opt_trunc_xino_path:
22022+ case Opt_itrunc_xino:
22023+ err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
22024+ if (!err)
22025+ err = 1;
22026+ break;
22027+
22028+ case Opt_trunc_xib:
22029+ au_fset_opts(opts->flags, TRUNC_XIB);
22030+ break;
22031+ case Opt_notrunc_xib:
22032+ au_fclr_opts(opts->flags, TRUNC_XIB);
22033+ break;
22034+
22035+ default:
22036+ err = 0;
22037+ break;
22038+ }
22039+
22040+ return err;
22041+}
22042+
22043+/*
22044+ * returns tri-state.
22045+ * plus: processed without an error
22046+ * zero: unprocessed
22047+ * minus: error
22048+ */
22049+static int au_opt_br(struct super_block *sb, struct au_opt *opt,
22050+ struct au_opts *opts)
22051+{
22052+ int err, do_refresh;
22053+
22054+ err = 0;
22055+ switch (opt->type) {
22056+ case Opt_append:
22057+ opt->add.bindex = au_sbend(sb) + 1;
22058+ if (opt->add.bindex < 0)
22059+ opt->add.bindex = 0;
22060+ goto add;
22061+ case Opt_prepend:
22062+ opt->add.bindex = 0;
f6b6e03d 22063+ add: /* indented label */
1facf9fc 22064+ case Opt_add:
22065+ err = au_br_add(sb, &opt->add,
22066+ au_ftest_opts(opts->flags, REMOUNT));
22067+ if (!err) {
22068+ err = 1;
027c5e7a 22069+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 22070+ }
22071+ break;
22072+
22073+ case Opt_del:
22074+ case Opt_idel:
22075+ err = au_br_del(sb, &opt->del,
22076+ au_ftest_opts(opts->flags, REMOUNT));
22077+ if (!err) {
22078+ err = 1;
22079+ au_fset_opts(opts->flags, TRUNC_XIB);
027c5e7a 22080+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 22081+ }
22082+ break;
22083+
22084+ case Opt_mod:
22085+ case Opt_imod:
22086+ err = au_br_mod(sb, &opt->mod,
22087+ au_ftest_opts(opts->flags, REMOUNT),
22088+ &do_refresh);
22089+ if (!err) {
22090+ err = 1;
027c5e7a
AM
22091+ if (do_refresh)
22092+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 22093+ }
22094+ break;
22095+ }
22096+
22097+ return err;
22098+}
22099+
22100+static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
22101+ struct au_opt_xino **opt_xino,
22102+ struct au_opts *opts)
22103+{
22104+ int err;
22105+ aufs_bindex_t bend, bindex;
22106+ struct dentry *root, *parent, *h_root;
22107+
22108+ err = 0;
22109+ switch (opt->type) {
22110+ case Opt_xino:
22111+ err = au_xino_set(sb, &opt->xino,
22112+ !!au_ftest_opts(opts->flags, REMOUNT));
22113+ if (unlikely(err))
22114+ break;
22115+
22116+ *opt_xino = &opt->xino;
22117+ au_xino_brid_set(sb, -1);
22118+
22119+ /* safe d_parent access */
22120+ parent = opt->xino.file->f_dentry->d_parent;
22121+ root = sb->s_root;
22122+ bend = au_sbend(sb);
22123+ for (bindex = 0; bindex <= bend; bindex++) {
22124+ h_root = au_h_dptr(root, bindex);
22125+ if (h_root == parent) {
22126+ au_xino_brid_set(sb, au_sbr_id(sb, bindex));
22127+ break;
22128+ }
22129+ }
22130+ break;
22131+
22132+ case Opt_noxino:
22133+ au_xino_clr(sb);
22134+ au_xino_brid_set(sb, -1);
22135+ *opt_xino = (void *)-1;
22136+ break;
22137+ }
22138+
22139+ return err;
22140+}
22141+
22142+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
22143+ unsigned int pending)
22144+{
22145+ int err;
22146+ aufs_bindex_t bindex, bend;
22147+ unsigned char do_plink, skip, do_free;
22148+ struct au_branch *br;
22149+ struct au_wbr *wbr;
22150+ struct dentry *root;
22151+ struct inode *dir, *h_dir;
22152+ struct au_sbinfo *sbinfo;
22153+ struct au_hinode *hdir;
22154+
dece6358
AM
22155+ SiMustAnyLock(sb);
22156+
1facf9fc 22157+ sbinfo = au_sbi(sb);
22158+ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
22159+
dece6358
AM
22160+ if (!(sb_flags & MS_RDONLY)) {
22161+ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
0c3ec466 22162+ pr_warn("first branch should be rw\n");
dece6358 22163+ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
0c3ec466 22164+ pr_warn("shwh should be used with ro\n");
dece6358 22165+ }
1facf9fc 22166+
4a4d8108 22167+ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
1facf9fc 22168+ && !au_opt_test(sbinfo->si_mntflags, XINO))
0c3ec466 22169+ pr_warn("udba=*notify requires xino\n");
1facf9fc 22170+
22171+ err = 0;
22172+ root = sb->s_root;
4a4d8108 22173+ dir = root->d_inode;
1facf9fc 22174+ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
22175+ bend = au_sbend(sb);
22176+ for (bindex = 0; !err && bindex <= bend; bindex++) {
22177+ skip = 0;
22178+ h_dir = au_h_iptr(dir, bindex);
22179+ br = au_sbr(sb, bindex);
22180+ do_free = 0;
22181+
22182+ wbr = br->br_wbr;
22183+ if (wbr)
22184+ wbr_wh_read_lock(wbr);
22185+
1e00d052 22186+ if (!au_br_writable(br->br_perm)) {
1facf9fc 22187+ do_free = !!wbr;
22188+ skip = (!wbr
22189+ || (!wbr->wbr_whbase
22190+ && !wbr->wbr_plink
22191+ && !wbr->wbr_orph));
1e00d052 22192+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 22193+ /* skip = (!br->br_whbase && !br->br_orph); */
22194+ skip = (!wbr || !wbr->wbr_whbase);
22195+ if (skip && wbr) {
22196+ if (do_plink)
22197+ skip = !!wbr->wbr_plink;
22198+ else
22199+ skip = !wbr->wbr_plink;
22200+ }
1e00d052 22201+ } else {
1facf9fc 22202+ /* skip = (br->br_whbase && br->br_ohph); */
22203+ skip = (wbr && wbr->wbr_whbase);
22204+ if (skip) {
22205+ if (do_plink)
22206+ skip = !!wbr->wbr_plink;
22207+ else
22208+ skip = !wbr->wbr_plink;
22209+ }
1facf9fc 22210+ }
22211+ if (wbr)
22212+ wbr_wh_read_unlock(wbr);
22213+
22214+ if (skip)
22215+ continue;
22216+
22217+ hdir = au_hi(dir, bindex);
4a4d8108 22218+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 22219+ if (wbr)
22220+ wbr_wh_write_lock(wbr);
86dc4139 22221+ err = au_wh_init(br, sb);
1facf9fc 22222+ if (wbr)
22223+ wbr_wh_write_unlock(wbr);
4a4d8108 22224+ au_hn_imtx_unlock(hdir);
1facf9fc 22225+
22226+ if (!err && do_free) {
22227+ kfree(wbr);
22228+ br->br_wbr = NULL;
22229+ }
22230+ }
22231+
22232+ return err;
22233+}
22234+
22235+int au_opts_mount(struct super_block *sb, struct au_opts *opts)
22236+{
22237+ int err;
22238+ unsigned int tmp;
027c5e7a 22239+ aufs_bindex_t bindex, bend;
1facf9fc 22240+ struct au_opt *opt;
22241+ struct au_opt_xino *opt_xino, xino;
22242+ struct au_sbinfo *sbinfo;
027c5e7a 22243+ struct au_branch *br;
1facf9fc 22244+
dece6358
AM
22245+ SiMustWriteLock(sb);
22246+
1facf9fc 22247+ err = 0;
22248+ opt_xino = NULL;
22249+ opt = opts->opt;
22250+ while (err >= 0 && opt->type != Opt_tail)
22251+ err = au_opt_simple(sb, opt++, opts);
22252+ if (err > 0)
22253+ err = 0;
22254+ else if (unlikely(err < 0))
22255+ goto out;
22256+
22257+ /* disable xino and udba temporary */
22258+ sbinfo = au_sbi(sb);
22259+ tmp = sbinfo->si_mntflags;
22260+ au_opt_clr(sbinfo->si_mntflags, XINO);
22261+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
22262+
22263+ opt = opts->opt;
22264+ while (err >= 0 && opt->type != Opt_tail)
22265+ err = au_opt_br(sb, opt++, opts);
22266+ if (err > 0)
22267+ err = 0;
22268+ else if (unlikely(err < 0))
22269+ goto out;
22270+
22271+ bend = au_sbend(sb);
22272+ if (unlikely(bend < 0)) {
22273+ err = -EINVAL;
4a4d8108 22274+ pr_err("no branches\n");
1facf9fc 22275+ goto out;
22276+ }
22277+
22278+ if (au_opt_test(tmp, XINO))
22279+ au_opt_set(sbinfo->si_mntflags, XINO);
22280+ opt = opts->opt;
22281+ while (!err && opt->type != Opt_tail)
22282+ err = au_opt_xino(sb, opt++, &opt_xino, opts);
22283+ if (unlikely(err))
22284+ goto out;
22285+
22286+ err = au_opts_verify(sb, sb->s_flags, tmp);
22287+ if (unlikely(err))
22288+ goto out;
22289+
22290+ /* restore xino */
22291+ if (au_opt_test(tmp, XINO) && !opt_xino) {
22292+ xino.file = au_xino_def(sb);
22293+ err = PTR_ERR(xino.file);
22294+ if (IS_ERR(xino.file))
22295+ goto out;
22296+
22297+ err = au_xino_set(sb, &xino, /*remount*/0);
22298+ fput(xino.file);
22299+ if (unlikely(err))
22300+ goto out;
22301+ }
22302+
22303+ /* restore udba */
027c5e7a 22304+ tmp &= AuOptMask_UDBA;
1facf9fc 22305+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
027c5e7a
AM
22306+ sbinfo->si_mntflags |= tmp;
22307+ bend = au_sbend(sb);
22308+ for (bindex = 0; bindex <= bend; bindex++) {
22309+ br = au_sbr(sb, bindex);
22310+ err = au_hnotify_reset_br(tmp, br, br->br_perm);
22311+ if (unlikely(err))
22312+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
22313+ bindex, err);
22314+ /* go on even if err */
22315+ }
4a4d8108 22316+ if (au_opt_test(tmp, UDBA_HNOTIFY)) {
1facf9fc 22317+ struct inode *dir = sb->s_root->d_inode;
4a4d8108 22318+ au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
1facf9fc 22319+ }
22320+
4f0767ce 22321+out:
1facf9fc 22322+ return err;
22323+}
22324+
22325+int au_opts_remount(struct super_block *sb, struct au_opts *opts)
22326+{
22327+ int err, rerr;
22328+ struct inode *dir;
22329+ struct au_opt_xino *opt_xino;
22330+ struct au_opt *opt;
22331+ struct au_sbinfo *sbinfo;
22332+
dece6358
AM
22333+ SiMustWriteLock(sb);
22334+
1facf9fc 22335+ dir = sb->s_root->d_inode;
22336+ sbinfo = au_sbi(sb);
22337+ err = 0;
22338+ opt_xino = NULL;
22339+ opt = opts->opt;
22340+ while (err >= 0 && opt->type != Opt_tail) {
22341+ err = au_opt_simple(sb, opt, opts);
22342+ if (!err)
22343+ err = au_opt_br(sb, opt, opts);
22344+ if (!err)
22345+ err = au_opt_xino(sb, opt, &opt_xino, opts);
22346+ opt++;
22347+ }
22348+ if (err > 0)
22349+ err = 0;
22350+ AuTraceErr(err);
22351+ /* go on even err */
22352+
22353+ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
22354+ if (unlikely(rerr && !err))
22355+ err = rerr;
22356+
22357+ if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
22358+ rerr = au_xib_trunc(sb);
22359+ if (unlikely(rerr && !err))
22360+ err = rerr;
22361+ }
22362+
22363+ /* will be handled by the caller */
027c5e7a 22364+ if (!au_ftest_opts(opts->flags, REFRESH)
1facf9fc 22365+ && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO)))
027c5e7a 22366+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 22367+
22368+ AuDbg("status 0x%x\n", opts->flags);
22369+ return err;
22370+}
22371+
22372+/* ---------------------------------------------------------------------- */
22373+
22374+unsigned int au_opt_udba(struct super_block *sb)
22375+{
22376+ return au_mntflags(sb) & AuOptMask_UDBA;
22377+}
7f207e10
AM
22378diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
22379--- /usr/share/empty/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
22380+++ linux/fs/aufs/opts.h 2014-01-20 20:16:14.742796949 +0100
22381@@ -0,0 +1,210 @@
1facf9fc 22382+/*
523b37e3 22383+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 22384+ *
22385+ * This program, aufs is free software; you can redistribute it and/or modify
22386+ * it under the terms of the GNU General Public License as published by
22387+ * the Free Software Foundation; either version 2 of the License, or
22388+ * (at your option) any later version.
dece6358
AM
22389+ *
22390+ * This program is distributed in the hope that it will be useful,
22391+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22392+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22393+ * GNU General Public License for more details.
22394+ *
22395+ * You should have received a copy of the GNU General Public License
523b37e3 22396+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 22397+ */
22398+
22399+/*
22400+ * mount options/flags
22401+ */
22402+
22403+#ifndef __AUFS_OPTS_H__
22404+#define __AUFS_OPTS_H__
22405+
22406+#ifdef __KERNEL__
22407+
dece6358 22408+#include <linux/path.h>
1facf9fc 22409+
dece6358
AM
22410+struct file;
22411+struct super_block;
22412+
1facf9fc 22413+/* ---------------------------------------------------------------------- */
22414+
22415+/* mount flags */
22416+#define AuOpt_XINO 1 /* external inode number bitmap
22417+ and translation table */
22418+#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */
22419+#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */
22420+#define AuOpt_UDBA_REVAL (1 << 3)
4a4d8108 22421+#define AuOpt_UDBA_HNOTIFY (1 << 4)
dece6358
AM
22422+#define AuOpt_SHWH (1 << 5) /* show whiteout */
22423+#define AuOpt_PLINK (1 << 6) /* pseudo-link */
22424+#define AuOpt_DIRPERM1 (1 << 7) /* unimplemented */
22425+#define AuOpt_REFROF (1 << 8) /* unimplemented */
22426+#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */
22427+#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
22428+#define AuOpt_SUM_W (1 << 11) /* unimplemented */
22429+#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */
22430+#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */
4a4d8108 22431+#define AuOpt_DIO (1 << 14) /* direct io */
1facf9fc 22432+
4a4d8108
AM
22433+#ifndef CONFIG_AUFS_HNOTIFY
22434+#undef AuOpt_UDBA_HNOTIFY
22435+#define AuOpt_UDBA_HNOTIFY 0
1facf9fc 22436+#endif
dece6358
AM
22437+#ifndef CONFIG_AUFS_SHWH
22438+#undef AuOpt_SHWH
22439+#define AuOpt_SHWH 0
22440+#endif
1facf9fc 22441+
22442+#define AuOpt_Def (AuOpt_XINO \
22443+ | AuOpt_UDBA_REVAL \
22444+ | AuOpt_PLINK \
22445+ /* | AuOpt_DIRPERM1 */ \
22446+ | AuOpt_WARN_PERM)
22447+#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
22448+ | AuOpt_UDBA_REVAL \
4a4d8108 22449+ | AuOpt_UDBA_HNOTIFY)
1facf9fc 22450+
22451+#define au_opt_test(flags, name) (flags & AuOpt_##name)
22452+#define au_opt_set(flags, name) do { \
22453+ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
22454+ ((flags) |= AuOpt_##name); \
22455+} while (0)
22456+#define au_opt_set_udba(flags, name) do { \
22457+ (flags) &= ~AuOptMask_UDBA; \
22458+ ((flags) |= AuOpt_##name); \
22459+} while (0)
7f207e10
AM
22460+#define au_opt_clr(flags, name) do { \
22461+ ((flags) &= ~AuOpt_##name); \
22462+} while (0)
1facf9fc 22463+
e49829fe
JR
22464+static inline unsigned int au_opts_plink(unsigned int mntflags)
22465+{
22466+#ifdef CONFIG_PROC_FS
22467+ return mntflags;
22468+#else
22469+ return mntflags & ~AuOpt_PLINK;
22470+#endif
22471+}
22472+
1facf9fc 22473+/* ---------------------------------------------------------------------- */
22474+
22475+/* policies to select one among multiple writable branches */
22476+enum {
22477+ AuWbrCreate_TDP, /* top down parent */
22478+ AuWbrCreate_RR, /* round robin */
22479+ AuWbrCreate_MFS, /* most free space */
22480+ AuWbrCreate_MFSV, /* mfs with seconds */
22481+ AuWbrCreate_MFSRR, /* mfs then rr */
22482+ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */
22483+ AuWbrCreate_PMFS, /* parent and mfs */
22484+ AuWbrCreate_PMFSV, /* parent and mfs with seconds */
392086de
AM
22485+ AuWbrCreate_PMFSRR, /* parent, mfs and round-robin */
22486+ AuWbrCreate_PMFSRRV, /* plus seconds */
1facf9fc 22487+
22488+ AuWbrCreate_Def = AuWbrCreate_TDP
22489+};
22490+
22491+enum {
22492+ AuWbrCopyup_TDP, /* top down parent */
22493+ AuWbrCopyup_BUP, /* bottom up parent */
22494+ AuWbrCopyup_BU, /* bottom up */
22495+
22496+ AuWbrCopyup_Def = AuWbrCopyup_TDP
22497+};
22498+
22499+/* ---------------------------------------------------------------------- */
22500+
22501+struct au_opt_add {
22502+ aufs_bindex_t bindex;
22503+ char *pathname;
22504+ int perm;
22505+ struct path path;
22506+};
22507+
22508+struct au_opt_del {
22509+ char *pathname;
22510+ struct path h_path;
22511+};
22512+
22513+struct au_opt_mod {
22514+ char *path;
22515+ int perm;
22516+ struct dentry *h_root;
22517+};
22518+
22519+struct au_opt_xino {
22520+ char *path;
22521+ struct file *file;
22522+};
22523+
22524+struct au_opt_xino_itrunc {
22525+ aufs_bindex_t bindex;
22526+};
22527+
22528+struct au_opt_wbr_create {
22529+ int wbr_create;
22530+ int mfs_second;
22531+ unsigned long long mfsrr_watermark;
22532+};
22533+
22534+struct au_opt {
22535+ int type;
22536+ union {
22537+ struct au_opt_xino xino;
22538+ struct au_opt_xino_itrunc xino_itrunc;
22539+ struct au_opt_add add;
22540+ struct au_opt_del del;
22541+ struct au_opt_mod mod;
22542+ int dirwh;
22543+ int rdcache;
22544+ unsigned int rdblk;
22545+ unsigned int rdhash;
22546+ int udba;
22547+ struct au_opt_wbr_create wbr_create;
22548+ int wbr_copyup;
22549+ };
22550+};
22551+
22552+/* opts flags */
22553+#define AuOpts_REMOUNT 1
027c5e7a
AM
22554+#define AuOpts_REFRESH (1 << 1)
22555+#define AuOpts_TRUNC_XIB (1 << 2)
22556+#define AuOpts_REFRESH_DYAOP (1 << 3)
1facf9fc 22557+#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
7f207e10
AM
22558+#define au_fset_opts(flags, name) \
22559+ do { (flags) |= AuOpts_##name; } while (0)
22560+#define au_fclr_opts(flags, name) \
22561+ do { (flags) &= ~AuOpts_##name; } while (0)
1facf9fc 22562+
22563+struct au_opts {
22564+ struct au_opt *opt;
22565+ int max_opt;
22566+
22567+ unsigned int given_udba;
22568+ unsigned int flags;
22569+ unsigned long sb_flags;
22570+};
22571+
22572+/* ---------------------------------------------------------------------- */
22573+
1e00d052 22574+char *au_optstr_br_perm(int brperm);
1facf9fc 22575+const char *au_optstr_udba(int udba);
22576+const char *au_optstr_wbr_copyup(int wbr_copyup);
22577+const char *au_optstr_wbr_create(int wbr_create);
22578+
22579+void au_opts_free(struct au_opts *opts);
22580+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
22581+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
22582+ unsigned int pending);
22583+int au_opts_mount(struct super_block *sb, struct au_opts *opts);
22584+int au_opts_remount(struct super_block *sb, struct au_opts *opts);
22585+
22586+unsigned int au_opt_udba(struct super_block *sb);
22587+
22588+/* ---------------------------------------------------------------------- */
22589+
22590+#endif /* __KERNEL__ */
22591+#endif /* __AUFS_OPTS_H__ */
7f207e10
AM
22592diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
22593--- /usr/share/empty/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
22594+++ linux/fs/aufs/plink.c 2014-01-20 20:16:14.742796949 +0100
22595@@ -0,0 +1,532 @@
1facf9fc 22596+/*
523b37e3 22597+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 22598+ *
22599+ * This program, aufs is free software; you can redistribute it and/or modify
22600+ * it under the terms of the GNU General Public License as published by
22601+ * the Free Software Foundation; either version 2 of the License, or
22602+ * (at your option) any later version.
dece6358
AM
22603+ *
22604+ * This program is distributed in the hope that it will be useful,
22605+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22606+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22607+ * GNU General Public License for more details.
22608+ *
22609+ * You should have received a copy of the GNU General Public License
523b37e3 22610+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 22611+ */
22612+
22613+/*
22614+ * pseudo-link
22615+ */
22616+
22617+#include "aufs.h"
22618+
22619+/*
e49829fe 22620+ * the pseudo-link maintenance mode.
1facf9fc 22621+ * during a user process maintains the pseudo-links,
22622+ * prohibit adding a new plink and branch manipulation.
e49829fe
JR
22623+ *
22624+ * Flags
22625+ * NOPLM:
22626+ * For entry functions which will handle plink, and i_mutex is already held
22627+ * in VFS.
22628+ * They cannot wait and should return an error at once.
22629+ * Callers has to check the error.
22630+ * NOPLMW:
22631+ * For entry functions which will handle plink, but i_mutex is not held
22632+ * in VFS.
22633+ * They can wait the plink maintenance mode to finish.
22634+ *
22635+ * They behave like F_SETLK and F_SETLKW.
22636+ * If the caller never handle plink, then both flags are unnecessary.
1facf9fc 22637+ */
e49829fe
JR
22638+
22639+int au_plink_maint(struct super_block *sb, int flags)
1facf9fc 22640+{
e49829fe
JR
22641+ int err;
22642+ pid_t pid, ppid;
22643+ struct au_sbinfo *sbi;
dece6358
AM
22644+
22645+ SiMustAnyLock(sb);
22646+
e49829fe
JR
22647+ err = 0;
22648+ if (!au_opt_test(au_mntflags(sb), PLINK))
22649+ goto out;
22650+
22651+ sbi = au_sbi(sb);
22652+ pid = sbi->si_plink_maint_pid;
22653+ if (!pid || pid == current->pid)
22654+ goto out;
22655+
22656+ /* todo: it highly depends upon /sbin/mount.aufs */
22657+ rcu_read_lock();
22658+ ppid = task_pid_vnr(rcu_dereference(current->real_parent));
22659+ rcu_read_unlock();
22660+ if (pid == ppid)
22661+ goto out;
22662+
22663+ if (au_ftest_lock(flags, NOPLMW)) {
027c5e7a
AM
22664+ /* if there is no i_mutex lock in VFS, we don't need to wait */
22665+ /* AuDebugOn(!lockdep_depth(current)); */
e49829fe
JR
22666+ while (sbi->si_plink_maint_pid) {
22667+ si_read_unlock(sb);
22668+ /* gave up wake_up_bit() */
22669+ wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
22670+
22671+ if (au_ftest_lock(flags, FLUSH))
22672+ au_nwt_flush(&sbi->si_nowait);
22673+ si_noflush_read_lock(sb);
22674+ }
22675+ } else if (au_ftest_lock(flags, NOPLM)) {
22676+ AuDbg("ppid %d, pid %d\n", ppid, pid);
22677+ err = -EAGAIN;
22678+ }
22679+
22680+out:
22681+ return err;
4a4d8108
AM
22682+}
22683+
e49829fe 22684+void au_plink_maint_leave(struct au_sbinfo *sbinfo)
4a4d8108 22685+{
4a4d8108 22686+ spin_lock(&sbinfo->si_plink_maint_lock);
027c5e7a 22687+ sbinfo->si_plink_maint_pid = 0;
4a4d8108 22688+ spin_unlock(&sbinfo->si_plink_maint_lock);
027c5e7a 22689+ wake_up_all(&sbinfo->si_plink_wq);
4a4d8108
AM
22690+}
22691+
e49829fe 22692+int au_plink_maint_enter(struct super_block *sb)
4a4d8108
AM
22693+{
22694+ int err;
4a4d8108
AM
22695+ struct au_sbinfo *sbinfo;
22696+
22697+ err = 0;
4a4d8108
AM
22698+ sbinfo = au_sbi(sb);
22699+ /* make sure i am the only one in this fs */
e49829fe
JR
22700+ si_write_lock(sb, AuLock_FLUSH);
22701+ if (au_opt_test(au_mntflags(sb), PLINK)) {
22702+ spin_lock(&sbinfo->si_plink_maint_lock);
22703+ if (!sbinfo->si_plink_maint_pid)
22704+ sbinfo->si_plink_maint_pid = current->pid;
22705+ else
22706+ err = -EBUSY;
22707+ spin_unlock(&sbinfo->si_plink_maint_lock);
22708+ }
4a4d8108
AM
22709+ si_write_unlock(sb);
22710+
22711+ return err;
1facf9fc 22712+}
22713+
22714+/* ---------------------------------------------------------------------- */
22715+
1facf9fc 22716+#ifdef CONFIG_AUFS_DEBUG
22717+void au_plink_list(struct super_block *sb)
22718+{
86dc4139 22719+ int i;
1facf9fc 22720+ struct au_sbinfo *sbinfo;
86dc4139 22721+ struct hlist_head *plink_hlist;
1facf9fc 22722+ struct pseudo_link *plink;
22723+
dece6358
AM
22724+ SiMustAnyLock(sb);
22725+
1facf9fc 22726+ sbinfo = au_sbi(sb);
22727+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 22728+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 22729+
86dc4139
AM
22730+ for (i = 0; i < AuPlink_NHASH; i++) {
22731+ plink_hlist = &sbinfo->si_plink[i].head;
22732+ rcu_read_lock();
22733+ hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
22734+ AuDbg("%lu\n", plink->inode->i_ino);
22735+ rcu_read_unlock();
22736+ }
1facf9fc 22737+}
22738+#endif
22739+
22740+/* is the inode pseudo-linked? */
22741+int au_plink_test(struct inode *inode)
22742+{
86dc4139 22743+ int found, i;
1facf9fc 22744+ struct au_sbinfo *sbinfo;
86dc4139 22745+ struct hlist_head *plink_hlist;
1facf9fc 22746+ struct pseudo_link *plink;
22747+
22748+ sbinfo = au_sbi(inode->i_sb);
dece6358 22749+ AuRwMustAnyLock(&sbinfo->si_rwsem);
1facf9fc 22750+ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
e49829fe 22751+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
1facf9fc 22752+
22753+ found = 0;
86dc4139
AM
22754+ i = au_plink_hash(inode->i_ino);
22755+ plink_hlist = &sbinfo->si_plink[i].head;
4a4d8108 22756+ rcu_read_lock();
86dc4139 22757+ hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
1facf9fc 22758+ if (plink->inode == inode) {
22759+ found = 1;
22760+ break;
22761+ }
4a4d8108 22762+ rcu_read_unlock();
1facf9fc 22763+ return found;
22764+}
22765+
22766+/* ---------------------------------------------------------------------- */
22767+
22768+/*
22769+ * generate a name for plink.
22770+ * the file will be stored under AUFS_WH_PLINKDIR.
22771+ */
22772+/* 20 is max digits length of ulong 64 */
22773+#define PLINK_NAME_LEN ((20 + 1) * 2)
22774+
22775+static int plink_name(char *name, int len, struct inode *inode,
22776+ aufs_bindex_t bindex)
22777+{
22778+ int rlen;
22779+ struct inode *h_inode;
22780+
22781+ h_inode = au_h_iptr(inode, bindex);
22782+ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
22783+ return rlen;
22784+}
22785+
7f207e10
AM
22786+struct au_do_plink_lkup_args {
22787+ struct dentry **errp;
22788+ struct qstr *tgtname;
22789+ struct dentry *h_parent;
22790+ struct au_branch *br;
22791+};
22792+
22793+static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
22794+ struct dentry *h_parent,
22795+ struct au_branch *br)
22796+{
22797+ struct dentry *h_dentry;
22798+ struct mutex *h_mtx;
22799+
22800+ h_mtx = &h_parent->d_inode->i_mutex;
22801+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
b4510431 22802+ h_dentry = vfsub_lkup_one(tgtname, h_parent);
7f207e10
AM
22803+ mutex_unlock(h_mtx);
22804+ return h_dentry;
22805+}
22806+
22807+static void au_call_do_plink_lkup(void *args)
22808+{
22809+ struct au_do_plink_lkup_args *a = args;
22810+ *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
22811+}
22812+
1facf9fc 22813+/* lookup the plink-ed @inode under the branch at @bindex */
22814+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
22815+{
22816+ struct dentry *h_dentry, *h_parent;
22817+ struct au_branch *br;
22818+ struct inode *h_dir;
7f207e10 22819+ int wkq_err;
1facf9fc 22820+ char a[PLINK_NAME_LEN];
0c3ec466 22821+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 22822+
e49829fe
JR
22823+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
22824+
1facf9fc 22825+ br = au_sbr(inode->i_sb, bindex);
22826+ h_parent = br->br_wbr->wbr_plink;
22827+ h_dir = h_parent->d_inode;
22828+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
22829+
2dfbb274 22830+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
7f207e10
AM
22831+ struct au_do_plink_lkup_args args = {
22832+ .errp = &h_dentry,
22833+ .tgtname = &tgtname,
22834+ .h_parent = h_parent,
22835+ .br = br
22836+ };
22837+
22838+ wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
22839+ if (unlikely(wkq_err))
22840+ h_dentry = ERR_PTR(wkq_err);
22841+ } else
22842+ h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
22843+
1facf9fc 22844+ return h_dentry;
22845+}
22846+
22847+/* create a pseudo-link */
22848+static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
22849+ struct dentry *h_dentry, struct au_branch *br)
22850+{
22851+ int err;
22852+ struct path h_path = {
86dc4139 22853+ .mnt = au_br_mnt(br)
1facf9fc 22854+ };
523b37e3 22855+ struct inode *h_dir, *delegated;
1facf9fc 22856+
22857+ h_dir = h_parent->d_inode;
7f207e10 22858+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
4f0767ce 22859+again:
b4510431 22860+ h_path.dentry = vfsub_lkup_one(tgt, h_parent);
1facf9fc 22861+ err = PTR_ERR(h_path.dentry);
22862+ if (IS_ERR(h_path.dentry))
22863+ goto out;
22864+
22865+ err = 0;
22866+ /* wh.plink dir is not monitored */
7f207e10 22867+ /* todo: is it really safe? */
1facf9fc 22868+ if (h_path.dentry->d_inode
22869+ && h_path.dentry->d_inode != h_dentry->d_inode) {
523b37e3
AM
22870+ delegated = NULL;
22871+ err = vfsub_unlink(h_dir, &h_path, &delegated, /*force*/0);
22872+ if (unlikely(err == -EWOULDBLOCK)) {
22873+ pr_warn("cannot retry for NFSv4 delegation"
22874+ " for an internal unlink\n");
22875+ iput(delegated);
22876+ }
1facf9fc 22877+ dput(h_path.dentry);
22878+ h_path.dentry = NULL;
22879+ if (!err)
22880+ goto again;
22881+ }
523b37e3
AM
22882+ if (!err && !h_path.dentry->d_inode) {
22883+ delegated = NULL;
22884+ err = vfsub_link(h_dentry, h_dir, &h_path, &delegated);
22885+ if (unlikely(err == -EWOULDBLOCK)) {
22886+ pr_warn("cannot retry for NFSv4 delegation"
22887+ " for an internal link\n");
22888+ iput(delegated);
22889+ }
22890+ }
1facf9fc 22891+ dput(h_path.dentry);
22892+
4f0767ce 22893+out:
7f207e10 22894+ mutex_unlock(&h_dir->i_mutex);
1facf9fc 22895+ return err;
22896+}
22897+
22898+struct do_whplink_args {
22899+ int *errp;
22900+ struct qstr *tgt;
22901+ struct dentry *h_parent;
22902+ struct dentry *h_dentry;
22903+ struct au_branch *br;
22904+};
22905+
22906+static void call_do_whplink(void *args)
22907+{
22908+ struct do_whplink_args *a = args;
22909+ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
22910+}
22911+
22912+static int whplink(struct dentry *h_dentry, struct inode *inode,
22913+ aufs_bindex_t bindex, struct au_branch *br)
22914+{
22915+ int err, wkq_err;
22916+ struct au_wbr *wbr;
22917+ struct dentry *h_parent;
22918+ struct inode *h_dir;
22919+ char a[PLINK_NAME_LEN];
0c3ec466 22920+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 22921+
22922+ wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
22923+ h_parent = wbr->wbr_plink;
22924+ h_dir = h_parent->d_inode;
22925+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
22926+
22927+ /* always superio. */
2dfbb274 22928+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
1facf9fc 22929+ struct do_whplink_args args = {
22930+ .errp = &err,
22931+ .tgt = &tgtname,
22932+ .h_parent = h_parent,
22933+ .h_dentry = h_dentry,
22934+ .br = br
22935+ };
22936+ wkq_err = au_wkq_wait(call_do_whplink, &args);
22937+ if (unlikely(wkq_err))
22938+ err = wkq_err;
22939+ } else
22940+ err = do_whplink(&tgtname, h_parent, h_dentry, br);
1facf9fc 22941+
22942+ return err;
22943+}
22944+
22945+/* free a single plink */
22946+static void do_put_plink(struct pseudo_link *plink, int do_del)
22947+{
1facf9fc 22948+ if (do_del)
86dc4139 22949+ hlist_del(&plink->hlist);
4a4d8108
AM
22950+ iput(plink->inode);
22951+ kfree(plink);
22952+}
22953+
22954+static void do_put_plink_rcu(struct rcu_head *rcu)
22955+{
22956+ struct pseudo_link *plink;
22957+
22958+ plink = container_of(rcu, struct pseudo_link, rcu);
22959+ iput(plink->inode);
1facf9fc 22960+ kfree(plink);
22961+}
22962+
22963+/*
22964+ * create a new pseudo-link for @h_dentry on @bindex.
22965+ * the linked inode is held in aufs @inode.
22966+ */
22967+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
22968+ struct dentry *h_dentry)
22969+{
22970+ struct super_block *sb;
22971+ struct au_sbinfo *sbinfo;
86dc4139 22972+ struct hlist_head *plink_hlist;
4a4d8108 22973+ struct pseudo_link *plink, *tmp;
86dc4139
AM
22974+ struct au_sphlhead *sphl;
22975+ int found, err, cnt, i;
1facf9fc 22976+
22977+ sb = inode->i_sb;
22978+ sbinfo = au_sbi(sb);
22979+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 22980+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 22981+
86dc4139 22982+ found = au_plink_test(inode);
4a4d8108 22983+ if (found)
1facf9fc 22984+ return;
4a4d8108 22985+
86dc4139
AM
22986+ i = au_plink_hash(inode->i_ino);
22987+ sphl = sbinfo->si_plink + i;
22988+ plink_hlist = &sphl->head;
4a4d8108
AM
22989+ tmp = kmalloc(sizeof(*plink), GFP_NOFS);
22990+ if (tmp)
22991+ tmp->inode = au_igrab(inode);
22992+ else {
22993+ err = -ENOMEM;
22994+ goto out;
1facf9fc 22995+ }
22996+
86dc4139
AM
22997+ spin_lock(&sphl->spin);
22998+ hlist_for_each_entry(plink, plink_hlist, hlist) {
4a4d8108
AM
22999+ if (plink->inode == inode) {
23000+ found = 1;
23001+ break;
23002+ }
1facf9fc 23003+ }
4a4d8108 23004+ if (!found)
86dc4139
AM
23005+ hlist_add_head_rcu(&tmp->hlist, plink_hlist);
23006+ spin_unlock(&sphl->spin);
4a4d8108 23007+ if (!found) {
86dc4139
AM
23008+ cnt = au_sphl_count(sphl);
23009+#define msg "unexpectedly unblanced or too many pseudo-links"
23010+ if (cnt > AUFS_PLINK_WARN)
23011+ AuWarn1(msg ", %d\n", cnt);
23012+#undef msg
1facf9fc 23013+ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
4a4d8108
AM
23014+ } else {
23015+ do_put_plink(tmp, 0);
23016+ return;
1facf9fc 23017+ }
23018+
4a4d8108 23019+out:
1facf9fc 23020+ if (unlikely(err)) {
0c3ec466 23021+ pr_warn("err %d, damaged pseudo link.\n", err);
4a4d8108 23022+ if (tmp) {
86dc4139 23023+ au_sphl_del_rcu(&tmp->hlist, sphl);
4a4d8108
AM
23024+ call_rcu(&tmp->rcu, do_put_plink_rcu);
23025+ }
1facf9fc 23026+ }
23027+}
23028+
23029+/* free all plinks */
e49829fe 23030+void au_plink_put(struct super_block *sb, int verbose)
1facf9fc 23031+{
86dc4139 23032+ int i, warned;
1facf9fc 23033+ struct au_sbinfo *sbinfo;
86dc4139
AM
23034+ struct hlist_head *plink_hlist;
23035+ struct hlist_node *tmp;
23036+ struct pseudo_link *plink;
1facf9fc 23037+
dece6358
AM
23038+ SiMustWriteLock(sb);
23039+
1facf9fc 23040+ sbinfo = au_sbi(sb);
23041+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 23042+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 23043+
1facf9fc 23044+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
23045+ warned = 0;
23046+ for (i = 0; i < AuPlink_NHASH; i++) {
23047+ plink_hlist = &sbinfo->si_plink[i].head;
23048+ if (!warned && verbose && !hlist_empty(plink_hlist)) {
23049+ pr_warn("pseudo-link is not flushed");
23050+ warned = 1;
23051+ }
23052+ hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist)
23053+ do_put_plink(plink, 0);
23054+ INIT_HLIST_HEAD(plink_hlist);
23055+ }
1facf9fc 23056+}
23057+
e49829fe
JR
23058+void au_plink_clean(struct super_block *sb, int verbose)
23059+{
23060+ struct dentry *root;
23061+
23062+ root = sb->s_root;
23063+ aufs_write_lock(root);
23064+ if (au_opt_test(au_mntflags(sb), PLINK))
23065+ au_plink_put(sb, verbose);
23066+ aufs_write_unlock(root);
23067+}
23068+
86dc4139
AM
23069+static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id)
23070+{
23071+ int do_put;
23072+ aufs_bindex_t bstart, bend, bindex;
23073+
23074+ do_put = 0;
23075+ bstart = au_ibstart(inode);
23076+ bend = au_ibend(inode);
23077+ if (bstart >= 0) {
23078+ for (bindex = bstart; bindex <= bend; bindex++) {
23079+ if (!au_h_iptr(inode, bindex)
23080+ || au_ii_br_id(inode, bindex) != br_id)
23081+ continue;
23082+ au_set_h_iptr(inode, bindex, NULL, 0);
23083+ do_put = 1;
23084+ break;
23085+ }
23086+ if (do_put)
23087+ for (bindex = bstart; bindex <= bend; bindex++)
23088+ if (au_h_iptr(inode, bindex)) {
23089+ do_put = 0;
23090+ break;
23091+ }
23092+ } else
23093+ do_put = 1;
23094+
23095+ return do_put;
23096+}
23097+
1facf9fc 23098+/* free the plinks on a branch specified by @br_id */
23099+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
23100+{
23101+ struct au_sbinfo *sbinfo;
86dc4139
AM
23102+ struct hlist_head *plink_hlist;
23103+ struct hlist_node *tmp;
23104+ struct pseudo_link *plink;
1facf9fc 23105+ struct inode *inode;
86dc4139 23106+ int i, do_put;
1facf9fc 23107+
dece6358
AM
23108+ SiMustWriteLock(sb);
23109+
1facf9fc 23110+ sbinfo = au_sbi(sb);
23111+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 23112+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 23113+
1facf9fc 23114+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
23115+ for (i = 0; i < AuPlink_NHASH; i++) {
23116+ plink_hlist = &sbinfo->si_plink[i].head;
23117+ hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist) {
23118+ inode = au_igrab(plink->inode);
23119+ ii_write_lock_child(inode);
23120+ do_put = au_plink_do_half_refresh(inode, br_id);
dece6358
AM
23121+ if (do_put)
23122+ do_put_plink(plink, 1);
86dc4139
AM
23123+ ii_write_unlock(inode);
23124+ iput(inode);
dece6358 23125+ }
dece6358
AM
23126+ }
23127+}
7f207e10
AM
23128diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
23129--- /usr/share/empty/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
23130+++ linux/fs/aufs/poll.c 2014-01-20 20:16:14.742796949 +0100
23131@@ -0,0 +1,55 @@
dece6358 23132+/*
523b37e3 23133+ * Copyright (C) 2005-2014 Junjiro R. Okajima
dece6358
AM
23134+ *
23135+ * This program, aufs is free software; you can redistribute it and/or modify
23136+ * it under the terms of the GNU General Public License as published by
23137+ * the Free Software Foundation; either version 2 of the License, or
23138+ * (at your option) any later version.
23139+ *
23140+ * This program is distributed in the hope that it will be useful,
23141+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23142+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23143+ * GNU General Public License for more details.
23144+ *
23145+ * You should have received a copy of the GNU General Public License
523b37e3 23146+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358
AM
23147+ */
23148+
1308ab2a 23149+/*
23150+ * poll operation
23151+ * There is only one filesystem which implements ->poll operation, currently.
23152+ */
23153+
23154+#include "aufs.h"
23155+
23156+unsigned int aufs_poll(struct file *file, poll_table *wait)
23157+{
23158+ unsigned int mask;
23159+ int err;
23160+ struct file *h_file;
23161+ struct dentry *dentry;
23162+ struct super_block *sb;
23163+
23164+ /* We should pretend an error happened. */
23165+ mask = POLLERR /* | POLLIN | POLLOUT */;
23166+ dentry = file->f_dentry;
23167+ sb = dentry->d_sb;
e49829fe 23168+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
1308ab2a 23169+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
23170+ if (unlikely(err))
23171+ goto out;
23172+
23173+ /* it is not an error if h_file has no operation */
23174+ mask = DEFAULT_POLLMASK;
4a4d8108 23175+ h_file = au_hf_top(file);
523b37e3 23176+ if (h_file->f_op->poll)
1308ab2a 23177+ mask = h_file->f_op->poll(h_file, wait);
23178+
23179+ di_read_unlock(dentry, AuLock_IR);
23180+ fi_read_unlock(file);
23181+
4f0767ce 23182+out:
1308ab2a 23183+ si_read_unlock(sb);
23184+ AuTraceErr((int)mask);
23185+ return mask;
23186+}
7f207e10
AM
23187diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
23188--- /usr/share/empty/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
23189+++ linux/fs/aufs/procfs.c 2014-01-20 20:16:14.742796949 +0100
23190@@ -0,0 +1,169 @@
e49829fe 23191+/*
523b37e3 23192+ * Copyright (C) 2010-2014 Junjiro R. Okajima
e49829fe
JR
23193+ *
23194+ * This program, aufs is free software; you can redistribute it and/or modify
23195+ * it under the terms of the GNU General Public License as published by
23196+ * the Free Software Foundation; either version 2 of the License, or
23197+ * (at your option) any later version.
23198+ *
23199+ * This program is distributed in the hope that it will be useful,
23200+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23201+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23202+ * GNU General Public License for more details.
23203+ *
23204+ * You should have received a copy of the GNU General Public License
523b37e3 23205+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
23206+ */
23207+
23208+/*
23209+ * procfs interfaces
23210+ */
23211+
23212+#include <linux/proc_fs.h>
23213+#include "aufs.h"
23214+
23215+static int au_procfs_plm_release(struct inode *inode, struct file *file)
23216+{
23217+ struct au_sbinfo *sbinfo;
23218+
23219+ sbinfo = file->private_data;
23220+ if (sbinfo) {
23221+ au_plink_maint_leave(sbinfo);
23222+ kobject_put(&sbinfo->si_kobj);
23223+ }
23224+
23225+ return 0;
23226+}
23227+
23228+static void au_procfs_plm_write_clean(struct file *file)
23229+{
23230+ struct au_sbinfo *sbinfo;
23231+
23232+ sbinfo = file->private_data;
23233+ if (sbinfo)
23234+ au_plink_clean(sbinfo->si_sb, /*verbose*/0);
23235+}
23236+
23237+static int au_procfs_plm_write_si(struct file *file, unsigned long id)
23238+{
23239+ int err;
23240+ struct super_block *sb;
23241+ struct au_sbinfo *sbinfo;
23242+
23243+ err = -EBUSY;
23244+ if (unlikely(file->private_data))
23245+ goto out;
23246+
23247+ sb = NULL;
53392da6 23248+ /* don't use au_sbilist_lock() here */
e49829fe
JR
23249+ spin_lock(&au_sbilist.spin);
23250+ list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
23251+ if (id == sysaufs_si_id(sbinfo)) {
23252+ kobject_get(&sbinfo->si_kobj);
23253+ sb = sbinfo->si_sb;
23254+ break;
23255+ }
23256+ spin_unlock(&au_sbilist.spin);
23257+
23258+ err = -EINVAL;
23259+ if (unlikely(!sb))
23260+ goto out;
23261+
23262+ err = au_plink_maint_enter(sb);
23263+ if (!err)
23264+ /* keep kobject_get() */
23265+ file->private_data = sbinfo;
23266+ else
23267+ kobject_put(&sbinfo->si_kobj);
23268+out:
23269+ return err;
23270+}
23271+
23272+/*
23273+ * Accept a valid "si=xxxx" only.
23274+ * Once it is accepted successfully, accept "clean" too.
23275+ */
23276+static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf,
23277+ size_t count, loff_t *ppos)
23278+{
23279+ ssize_t err;
23280+ unsigned long id;
23281+ /* last newline is allowed */
23282+ char buf[3 + sizeof(unsigned long) * 2 + 1];
23283+
23284+ err = -EACCES;
23285+ if (unlikely(!capable(CAP_SYS_ADMIN)))
23286+ goto out;
23287+
23288+ err = -EINVAL;
23289+ if (unlikely(count > sizeof(buf)))
23290+ goto out;
23291+
23292+ err = copy_from_user(buf, ubuf, count);
23293+ if (unlikely(err)) {
23294+ err = -EFAULT;
23295+ goto out;
23296+ }
23297+ buf[count] = 0;
23298+
23299+ err = -EINVAL;
23300+ if (!strcmp("clean", buf)) {
23301+ au_procfs_plm_write_clean(file);
23302+ goto out_success;
23303+ } else if (unlikely(strncmp("si=", buf, 3)))
23304+ goto out;
23305+
9dbd164d 23306+ err = kstrtoul(buf + 3, 16, &id);
e49829fe
JR
23307+ if (unlikely(err))
23308+ goto out;
23309+
23310+ err = au_procfs_plm_write_si(file, id);
23311+ if (unlikely(err))
23312+ goto out;
23313+
23314+out_success:
23315+ err = count; /* success */
23316+out:
23317+ return err;
23318+}
23319+
23320+static const struct file_operations au_procfs_plm_fop = {
23321+ .write = au_procfs_plm_write,
23322+ .release = au_procfs_plm_release,
23323+ .owner = THIS_MODULE
23324+};
23325+
23326+/* ---------------------------------------------------------------------- */
23327+
23328+static struct proc_dir_entry *au_procfs_dir;
23329+
23330+void au_procfs_fin(void)
23331+{
23332+ remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir);
23333+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
23334+}
23335+
23336+int __init au_procfs_init(void)
23337+{
23338+ int err;
23339+ struct proc_dir_entry *entry;
23340+
23341+ err = -ENOMEM;
23342+ au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL);
23343+ if (unlikely(!au_procfs_dir))
23344+ goto out;
23345+
23346+ entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | S_IWUSR,
23347+ au_procfs_dir, &au_procfs_plm_fop);
23348+ if (unlikely(!entry))
23349+ goto out_dir;
23350+
23351+ err = 0;
23352+ goto out; /* success */
23353+
23354+
23355+out_dir:
23356+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
23357+out:
23358+ return err;
23359+}
7f207e10
AM
23360diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
23361--- /usr/share/empty/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
23362+++ linux/fs/aufs/rdu.c 2014-01-20 20:16:14.742796949 +0100
23363@@ -0,0 +1,388 @@
1308ab2a 23364+/*
523b37e3 23365+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1308ab2a 23366+ *
23367+ * This program, aufs is free software; you can redistribute it and/or modify
23368+ * it under the terms of the GNU General Public License as published by
23369+ * the Free Software Foundation; either version 2 of the License, or
23370+ * (at your option) any later version.
23371+ *
23372+ * This program is distributed in the hope that it will be useful,
23373+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23374+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23375+ * GNU General Public License for more details.
23376+ *
23377+ * You should have received a copy of the GNU General Public License
523b37e3 23378+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1308ab2a 23379+ */
23380+
23381+/*
23382+ * readdir in userspace.
23383+ */
23384+
b752ccd1 23385+#include <linux/compat.h>
4a4d8108 23386+#include <linux/fs_stack.h>
1308ab2a 23387+#include <linux/security.h>
1308ab2a 23388+#include "aufs.h"
23389+
23390+/* bits for struct aufs_rdu.flags */
23391+#define AuRdu_CALLED 1
23392+#define AuRdu_CONT (1 << 1)
23393+#define AuRdu_FULL (1 << 2)
23394+#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name)
7f207e10
AM
23395+#define au_fset_rdu(flags, name) \
23396+ do { (flags) |= AuRdu_##name; } while (0)
23397+#define au_fclr_rdu(flags, name) \
23398+ do { (flags) &= ~AuRdu_##name; } while (0)
1308ab2a 23399+
23400+struct au_rdu_arg {
392086de 23401+ struct dir_context ctx;
1308ab2a 23402+ struct aufs_rdu *rdu;
23403+ union au_rdu_ent_ul ent;
23404+ unsigned long end;
23405+
23406+ struct super_block *sb;
23407+ int err;
23408+};
23409+
392086de 23410+static int au_rdu_fill(struct dir_context *ctx, const char *name, int nlen,
1308ab2a 23411+ loff_t offset, u64 h_ino, unsigned int d_type)
23412+{
23413+ int err, len;
392086de 23414+ struct au_rdu_arg *arg = container_of(ctx, struct au_rdu_arg, ctx);
1308ab2a 23415+ struct aufs_rdu *rdu = arg->rdu;
23416+ struct au_rdu_ent ent;
23417+
23418+ err = 0;
23419+ arg->err = 0;
23420+ au_fset_rdu(rdu->cookie.flags, CALLED);
23421+ len = au_rdu_len(nlen);
23422+ if (arg->ent.ul + len < arg->end) {
23423+ ent.ino = h_ino;
23424+ ent.bindex = rdu->cookie.bindex;
23425+ ent.type = d_type;
23426+ ent.nlen = nlen;
4a4d8108
AM
23427+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
23428+ ent.type = DT_UNKNOWN;
1308ab2a 23429+
9dbd164d 23430+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 23431+ err = -EFAULT;
23432+ if (copy_to_user(arg->ent.e, &ent, sizeof(ent)))
23433+ goto out;
23434+ if (copy_to_user(arg->ent.e->name, name, nlen))
23435+ goto out;
23436+ /* the terminating NULL */
23437+ if (__put_user(0, arg->ent.e->name + nlen))
23438+ goto out;
23439+ err = 0;
23440+ /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */
23441+ arg->ent.ul += len;
23442+ rdu->rent++;
23443+ } else {
23444+ err = -EFAULT;
23445+ au_fset_rdu(rdu->cookie.flags, FULL);
23446+ rdu->full = 1;
23447+ rdu->tail = arg->ent;
23448+ }
23449+
4f0767ce 23450+out:
1308ab2a 23451+ /* AuTraceErr(err); */
23452+ return err;
23453+}
23454+
23455+static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg)
23456+{
23457+ int err;
23458+ loff_t offset;
23459+ struct au_rdu_cookie *cookie = &arg->rdu->cookie;
23460+
92d182d2 23461+ /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */
1308ab2a 23462+ offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET);
23463+ err = offset;
23464+ if (unlikely(offset != cookie->h_pos))
23465+ goto out;
23466+
23467+ err = 0;
23468+ do {
23469+ arg->err = 0;
23470+ au_fclr_rdu(cookie->flags, CALLED);
23471+ /* smp_mb(); */
392086de 23472+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1308ab2a 23473+ if (err >= 0)
23474+ err = arg->err;
23475+ } while (!err
23476+ && au_ftest_rdu(cookie->flags, CALLED)
23477+ && !au_ftest_rdu(cookie->flags, FULL));
23478+ cookie->h_pos = h_file->f_pos;
23479+
4f0767ce 23480+out:
1308ab2a 23481+ AuTraceErr(err);
23482+ return err;
23483+}
23484+
23485+static int au_rdu(struct file *file, struct aufs_rdu *rdu)
23486+{
23487+ int err;
23488+ aufs_bindex_t bend;
392086de
AM
23489+ struct au_rdu_arg arg = {
23490+ .ctx = {
23491+ .actor = au_diractor(au_rdu_fill)
23492+ }
23493+ };
1308ab2a 23494+ struct dentry *dentry;
23495+ struct inode *inode;
23496+ struct file *h_file;
23497+ struct au_rdu_cookie *cookie = &rdu->cookie;
23498+
23499+ err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz);
23500+ if (unlikely(err)) {
23501+ err = -EFAULT;
23502+ AuTraceErr(err);
23503+ goto out;
23504+ }
23505+ rdu->rent = 0;
23506+ rdu->tail = rdu->ent;
23507+ rdu->full = 0;
23508+ arg.rdu = rdu;
23509+ arg.ent = rdu->ent;
23510+ arg.end = arg.ent.ul;
23511+ arg.end += rdu->sz;
23512+
23513+ err = -ENOTDIR;
523b37e3 23514+ if (unlikely(!file->f_op->iterate))
1308ab2a 23515+ goto out;
23516+
23517+ err = security_file_permission(file, MAY_READ);
23518+ AuTraceErr(err);
23519+ if (unlikely(err))
23520+ goto out;
23521+
23522+ dentry = file->f_dentry;
23523+ inode = dentry->d_inode;
23524+#if 1
23525+ mutex_lock(&inode->i_mutex);
23526+#else
23527+ err = mutex_lock_killable(&inode->i_mutex);
23528+ AuTraceErr(err);
23529+ if (unlikely(err))
23530+ goto out;
23531+#endif
1308ab2a 23532+
23533+ arg.sb = inode->i_sb;
e49829fe
JR
23534+ err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM);
23535+ if (unlikely(err))
23536+ goto out_mtx;
027c5e7a
AM
23537+ err = au_alive_dir(dentry);
23538+ if (unlikely(err))
23539+ goto out_si;
e49829fe 23540+ /* todo: reval? */
1308ab2a 23541+ fi_read_lock(file);
23542+
23543+ err = -EAGAIN;
23544+ if (unlikely(au_ftest_rdu(cookie->flags, CONT)
23545+ && cookie->generation != au_figen(file)))
23546+ goto out_unlock;
23547+
23548+ err = 0;
23549+ if (!rdu->blk) {
23550+ rdu->blk = au_sbi(arg.sb)->si_rdblk;
23551+ if (!rdu->blk)
23552+ rdu->blk = au_dir_size(file, /*dentry*/NULL);
23553+ }
23554+ bend = au_fbstart(file);
23555+ if (cookie->bindex < bend)
23556+ cookie->bindex = bend;
4a4d8108 23557+ bend = au_fbend_dir(file);
1308ab2a 23558+ /* AuDbg("b%d, b%d\n", cookie->bindex, bend); */
23559+ for (; !err && cookie->bindex <= bend;
23560+ cookie->bindex++, cookie->h_pos = 0) {
4a4d8108 23561+ h_file = au_hf_dir(file, cookie->bindex);
1308ab2a 23562+ if (!h_file)
23563+ continue;
23564+
23565+ au_fclr_rdu(cookie->flags, FULL);
23566+ err = au_rdu_do(h_file, &arg);
23567+ AuTraceErr(err);
23568+ if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err))
23569+ break;
23570+ }
23571+ AuDbg("rent %llu\n", rdu->rent);
23572+
23573+ if (!err && !au_ftest_rdu(cookie->flags, CONT)) {
23574+ rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH);
23575+ au_fset_rdu(cookie->flags, CONT);
23576+ cookie->generation = au_figen(file);
23577+ }
23578+
23579+ ii_read_lock_child(inode);
23580+ fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibstart(inode)));
23581+ ii_read_unlock(inode);
23582+
4f0767ce 23583+out_unlock:
1308ab2a 23584+ fi_read_unlock(file);
027c5e7a 23585+out_si:
1308ab2a 23586+ si_read_unlock(arg.sb);
4f0767ce 23587+out_mtx:
1308ab2a 23588+ mutex_unlock(&inode->i_mutex);
4f0767ce 23589+out:
1308ab2a 23590+ AuTraceErr(err);
23591+ return err;
23592+}
23593+
23594+static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu)
23595+{
23596+ int err;
23597+ ino_t ino;
23598+ unsigned long long nent;
23599+ union au_rdu_ent_ul *u;
23600+ struct au_rdu_ent ent;
23601+ struct super_block *sb;
23602+
23603+ err = 0;
23604+ nent = rdu->nent;
23605+ u = &rdu->ent;
23606+ sb = file->f_dentry->d_sb;
23607+ si_read_lock(sb, AuLock_FLUSH);
23608+ while (nent-- > 0) {
9dbd164d 23609+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 23610+ err = copy_from_user(&ent, u->e, sizeof(ent));
4a4d8108
AM
23611+ if (!err)
23612+ err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino));
1308ab2a 23613+ if (unlikely(err)) {
23614+ err = -EFAULT;
23615+ AuTraceErr(err);
23616+ break;
23617+ }
23618+
23619+ /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */
23620+ if (!ent.wh)
23621+ err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino);
23622+ else
23623+ err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type,
23624+ &ino);
23625+ if (unlikely(err)) {
23626+ AuTraceErr(err);
23627+ break;
23628+ }
23629+
23630+ err = __put_user(ino, &u->e->ino);
23631+ if (unlikely(err)) {
23632+ err = -EFAULT;
23633+ AuTraceErr(err);
23634+ break;
23635+ }
23636+ u->ul += au_rdu_len(ent.nlen);
23637+ }
23638+ si_read_unlock(sb);
23639+
23640+ return err;
23641+}
23642+
23643+/* ---------------------------------------------------------------------- */
23644+
23645+static int au_rdu_verify(struct aufs_rdu *rdu)
23646+{
b752ccd1 23647+ AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | "
1308ab2a 23648+ "%llu, b%d, 0x%x, g%u}\n",
b752ccd1 23649+ rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ],
1308ab2a 23650+ rdu->blk,
23651+ rdu->rent, rdu->shwh, rdu->full,
23652+ rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags,
23653+ rdu->cookie.generation);
dece6358 23654+
b752ccd1 23655+ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu))
1308ab2a 23656+ return 0;
dece6358 23657+
b752ccd1
AM
23658+ AuDbg("%u:%u\n",
23659+ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu));
1308ab2a 23660+ return -EINVAL;
23661+}
23662+
23663+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
dece6358 23664+{
1308ab2a 23665+ long err, e;
23666+ struct aufs_rdu rdu;
23667+ void __user *p = (void __user *)arg;
dece6358 23668+
1308ab2a 23669+ err = copy_from_user(&rdu, p, sizeof(rdu));
23670+ if (unlikely(err)) {
23671+ err = -EFAULT;
23672+ AuTraceErr(err);
23673+ goto out;
23674+ }
23675+ err = au_rdu_verify(&rdu);
dece6358
AM
23676+ if (unlikely(err))
23677+ goto out;
23678+
1308ab2a 23679+ switch (cmd) {
23680+ case AUFS_CTL_RDU:
23681+ err = au_rdu(file, &rdu);
23682+ if (unlikely(err))
23683+ break;
dece6358 23684+
1308ab2a 23685+ e = copy_to_user(p, &rdu, sizeof(rdu));
23686+ if (unlikely(e)) {
23687+ err = -EFAULT;
23688+ AuTraceErr(err);
23689+ }
23690+ break;
23691+ case AUFS_CTL_RDU_INO:
23692+ err = au_rdu_ino(file, &rdu);
23693+ break;
23694+
23695+ default:
4a4d8108 23696+ /* err = -ENOTTY; */
1308ab2a 23697+ err = -EINVAL;
23698+ }
dece6358 23699+
4f0767ce 23700+out:
1308ab2a 23701+ AuTraceErr(err);
23702+ return err;
1facf9fc 23703+}
b752ccd1
AM
23704+
23705+#ifdef CONFIG_COMPAT
23706+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
23707+{
23708+ long err, e;
23709+ struct aufs_rdu rdu;
23710+ void __user *p = compat_ptr(arg);
23711+
23712+ /* todo: get_user()? */
23713+ err = copy_from_user(&rdu, p, sizeof(rdu));
23714+ if (unlikely(err)) {
23715+ err = -EFAULT;
23716+ AuTraceErr(err);
23717+ goto out;
23718+ }
23719+ rdu.ent.e = compat_ptr(rdu.ent.ul);
23720+ err = au_rdu_verify(&rdu);
23721+ if (unlikely(err))
23722+ goto out;
23723+
23724+ switch (cmd) {
23725+ case AUFS_CTL_RDU:
23726+ err = au_rdu(file, &rdu);
23727+ if (unlikely(err))
23728+ break;
23729+
23730+ rdu.ent.ul = ptr_to_compat(rdu.ent.e);
23731+ rdu.tail.ul = ptr_to_compat(rdu.tail.e);
23732+ e = copy_to_user(p, &rdu, sizeof(rdu));
23733+ if (unlikely(e)) {
23734+ err = -EFAULT;
23735+ AuTraceErr(err);
23736+ }
23737+ break;
23738+ case AUFS_CTL_RDU_INO:
23739+ err = au_rdu_ino(file, &rdu);
23740+ break;
23741+
23742+ default:
23743+ /* err = -ENOTTY; */
23744+ err = -EINVAL;
23745+ }
23746+
4f0767ce 23747+out:
b752ccd1
AM
23748+ AuTraceErr(err);
23749+ return err;
23750+}
23751+#endif
7f207e10
AM
23752diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h
23753--- /usr/share/empty/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
23754+++ linux/fs/aufs/rwsem.h 2014-01-20 20:16:14.742796949 +0100
23755@@ -0,0 +1,187 @@
1facf9fc 23756+/*
523b37e3 23757+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 23758+ *
23759+ * This program, aufs is free software; you can redistribute it and/or modify
23760+ * it under the terms of the GNU General Public License as published by
23761+ * the Free Software Foundation; either version 2 of the License, or
23762+ * (at your option) any later version.
dece6358
AM
23763+ *
23764+ * This program is distributed in the hope that it will be useful,
23765+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23766+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23767+ * GNU General Public License for more details.
23768+ *
23769+ * You should have received a copy of the GNU General Public License
523b37e3 23770+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 23771+ */
23772+
23773+/*
23774+ * simple read-write semaphore wrappers
23775+ */
23776+
23777+#ifndef __AUFS_RWSEM_H__
23778+#define __AUFS_RWSEM_H__
23779+
23780+#ifdef __KERNEL__
23781+
4a4d8108 23782+#include "debug.h"
dece6358
AM
23783+
23784+struct au_rwsem {
23785+ struct rw_semaphore rwsem;
23786+#ifdef CONFIG_AUFS_DEBUG
23787+ /* just for debugging, not almighty counter */
23788+ atomic_t rcnt, wcnt;
23789+#endif
23790+};
23791+
23792+#ifdef CONFIG_AUFS_DEBUG
23793+#define AuDbgCntInit(rw) do { \
23794+ atomic_set(&(rw)->rcnt, 0); \
23795+ atomic_set(&(rw)->wcnt, 0); \
23796+ smp_mb(); /* atomic set */ \
23797+} while (0)
23798+
e49829fe 23799+#define AuDbgRcntInc(rw) atomic_inc(&(rw)->rcnt)
dece6358 23800+#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0)
e49829fe 23801+#define AuDbgWcntInc(rw) atomic_inc(&(rw)->wcnt)
dece6358
AM
23802+#define AuDbgWcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->wcnt) < 0)
23803+#else
23804+#define AuDbgCntInit(rw) do {} while (0)
23805+#define AuDbgRcntInc(rw) do {} while (0)
23806+#define AuDbgRcntDec(rw) do {} while (0)
23807+#define AuDbgWcntInc(rw) do {} while (0)
23808+#define AuDbgWcntDec(rw) do {} while (0)
23809+#endif /* CONFIG_AUFS_DEBUG */
23810+
23811+/* to debug easier, do not make them inlined functions */
23812+#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->rwsem.wait_list))
23813+/* rwsem_is_locked() is unusable */
23814+#define AuRwMustReadLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0)
23815+#define AuRwMustWriteLock(rw) AuDebugOn(atomic_read(&(rw)->wcnt) <= 0)
23816+#define AuRwMustAnyLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0 \
23817+ && atomic_read(&(rw)->wcnt) <= 0)
23818+#define AuRwDestroy(rw) AuDebugOn(atomic_read(&(rw)->rcnt) \
23819+ || atomic_read(&(rw)->wcnt))
23820+
e49829fe
JR
23821+#define au_rw_class(rw, key) lockdep_set_class(&(rw)->rwsem, key)
23822+
dece6358
AM
23823+static inline void au_rw_init(struct au_rwsem *rw)
23824+{
23825+ AuDbgCntInit(rw);
23826+ init_rwsem(&rw->rwsem);
23827+}
23828+
23829+static inline void au_rw_init_wlock(struct au_rwsem *rw)
23830+{
23831+ au_rw_init(rw);
23832+ down_write(&rw->rwsem);
23833+ AuDbgWcntInc(rw);
23834+}
23835+
23836+static inline void au_rw_init_wlock_nested(struct au_rwsem *rw,
23837+ unsigned int lsc)
23838+{
23839+ au_rw_init(rw);
23840+ down_write_nested(&rw->rwsem, lsc);
23841+ AuDbgWcntInc(rw);
23842+}
23843+
23844+static inline void au_rw_read_lock(struct au_rwsem *rw)
23845+{
23846+ down_read(&rw->rwsem);
23847+ AuDbgRcntInc(rw);
23848+}
23849+
23850+static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc)
23851+{
23852+ down_read_nested(&rw->rwsem, lsc);
23853+ AuDbgRcntInc(rw);
23854+}
23855+
23856+static inline void au_rw_read_unlock(struct au_rwsem *rw)
23857+{
23858+ AuRwMustReadLock(rw);
23859+ AuDbgRcntDec(rw);
23860+ up_read(&rw->rwsem);
23861+}
23862+
23863+static inline void au_rw_dgrade_lock(struct au_rwsem *rw)
23864+{
23865+ AuRwMustWriteLock(rw);
23866+ AuDbgRcntInc(rw);
23867+ AuDbgWcntDec(rw);
23868+ downgrade_write(&rw->rwsem);
23869+}
23870+
23871+static inline void au_rw_write_lock(struct au_rwsem *rw)
23872+{
23873+ down_write(&rw->rwsem);
23874+ AuDbgWcntInc(rw);
23875+}
23876+
23877+static inline void au_rw_write_lock_nested(struct au_rwsem *rw,
23878+ unsigned int lsc)
23879+{
23880+ down_write_nested(&rw->rwsem, lsc);
23881+ AuDbgWcntInc(rw);
23882+}
1facf9fc 23883+
dece6358
AM
23884+static inline void au_rw_write_unlock(struct au_rwsem *rw)
23885+{
23886+ AuRwMustWriteLock(rw);
23887+ AuDbgWcntDec(rw);
23888+ up_write(&rw->rwsem);
23889+}
23890+
23891+/* why is not _nested version defined */
23892+static inline int au_rw_read_trylock(struct au_rwsem *rw)
23893+{
23894+ int ret = down_read_trylock(&rw->rwsem);
23895+ if (ret)
23896+ AuDbgRcntInc(rw);
23897+ return ret;
23898+}
23899+
23900+static inline int au_rw_write_trylock(struct au_rwsem *rw)
23901+{
23902+ int ret = down_write_trylock(&rw->rwsem);
23903+ if (ret)
23904+ AuDbgWcntInc(rw);
23905+ return ret;
23906+}
23907+
23908+#undef AuDbgCntInit
23909+#undef AuDbgRcntInc
23910+#undef AuDbgRcntDec
23911+#undef AuDbgWcntInc
23912+#undef AuDbgWcntDec
1facf9fc 23913+
23914+#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
23915+static inline void prefix##_read_lock(param) \
dece6358 23916+{ au_rw_read_lock(rwsem); } \
1facf9fc 23917+static inline void prefix##_write_lock(param) \
dece6358 23918+{ au_rw_write_lock(rwsem); } \
1facf9fc 23919+static inline int prefix##_read_trylock(param) \
dece6358 23920+{ return au_rw_read_trylock(rwsem); } \
1facf9fc 23921+static inline int prefix##_write_trylock(param) \
dece6358 23922+{ return au_rw_write_trylock(rwsem); }
1facf9fc 23923+/* why is not _nested version defined */
23924+/* static inline void prefix##_read_trylock_nested(param, lsc)
dece6358 23925+{ au_rw_read_trylock_nested(rwsem, lsc)); }
1facf9fc 23926+static inline void prefix##_write_trylock_nestd(param, lsc)
dece6358 23927+{ au_rw_write_trylock_nested(rwsem, lsc); } */
1facf9fc 23928+
23929+#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
23930+static inline void prefix##_read_unlock(param) \
dece6358 23931+{ au_rw_read_unlock(rwsem); } \
1facf9fc 23932+static inline void prefix##_write_unlock(param) \
dece6358 23933+{ au_rw_write_unlock(rwsem); } \
1facf9fc 23934+static inline void prefix##_downgrade_lock(param) \
dece6358 23935+{ au_rw_dgrade_lock(rwsem); }
1facf9fc 23936+
23937+#define AuSimpleRwsemFuncs(prefix, param, rwsem) \
23938+ AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
23939+ AuSimpleUnlockRwsemFuncs(prefix, param, rwsem)
23940+
23941+#endif /* __KERNEL__ */
23942+#endif /* __AUFS_RWSEM_H__ */
7f207e10
AM
23943diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
23944--- /usr/share/empty/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
23945+++ linux/fs/aufs/sbinfo.c 2014-01-20 20:16:14.742796949 +0100
23946@@ -0,0 +1,351 @@
1facf9fc 23947+/*
523b37e3 23948+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 23949+ *
23950+ * This program, aufs is free software; you can redistribute it and/or modify
23951+ * it under the terms of the GNU General Public License as published by
23952+ * the Free Software Foundation; either version 2 of the License, or
23953+ * (at your option) any later version.
dece6358
AM
23954+ *
23955+ * This program is distributed in the hope that it will be useful,
23956+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23957+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23958+ * GNU General Public License for more details.
23959+ *
23960+ * You should have received a copy of the GNU General Public License
523b37e3 23961+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 23962+ */
23963+
23964+/*
23965+ * superblock private data
23966+ */
23967+
23968+#include "aufs.h"
23969+
23970+/*
23971+ * they are necessary regardless sysfs is disabled.
23972+ */
23973+void au_si_free(struct kobject *kobj)
23974+{
86dc4139 23975+ int i;
1facf9fc 23976+ struct au_sbinfo *sbinfo;
b752ccd1 23977+ char *locked __maybe_unused; /* debug only */
1facf9fc 23978+
23979+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
86dc4139
AM
23980+ for (i = 0; i < AuPlink_NHASH; i++)
23981+ AuDebugOn(!hlist_empty(&sbinfo->si_plink[i].head));
e49829fe 23982+ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
1facf9fc 23983+
e49829fe 23984+ au_rw_write_lock(&sbinfo->si_rwsem);
1facf9fc 23985+ au_br_free(sbinfo);
e49829fe 23986+ au_rw_write_unlock(&sbinfo->si_rwsem);
b752ccd1
AM
23987+
23988+ AuDebugOn(radix_tree_gang_lookup
23989+ (&sbinfo->au_si_pid.tree, (void **)&locked,
23990+ /*first_index*/PID_MAX_DEFAULT - 1,
23991+ /*max_items*/sizeof(locked)/sizeof(*locked)));
23992+
1facf9fc 23993+ kfree(sbinfo->si_branch);
b752ccd1 23994+ kfree(sbinfo->au_si_pid.bitmap);
1facf9fc 23995+ mutex_destroy(&sbinfo->si_xib_mtx);
dece6358 23996+ AuRwDestroy(&sbinfo->si_rwsem);
1facf9fc 23997+
23998+ kfree(sbinfo);
23999+}
24000+
24001+int au_si_alloc(struct super_block *sb)
24002+{
86dc4139 24003+ int err, i;
1facf9fc 24004+ struct au_sbinfo *sbinfo;
e49829fe 24005+ static struct lock_class_key aufs_si;
1facf9fc 24006+
24007+ err = -ENOMEM;
4a4d8108 24008+ sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS);
1facf9fc 24009+ if (unlikely(!sbinfo))
24010+ goto out;
24011+
b752ccd1
AM
24012+ BUILD_BUG_ON(sizeof(unsigned long) !=
24013+ sizeof(*sbinfo->au_si_pid.bitmap));
24014+ sbinfo->au_si_pid.bitmap = kcalloc(BITS_TO_LONGS(PID_MAX_DEFAULT),
24015+ sizeof(*sbinfo->au_si_pid.bitmap),
24016+ GFP_NOFS);
24017+ if (unlikely(!sbinfo->au_si_pid.bitmap))
24018+ goto out_sbinfo;
24019+
1facf9fc 24020+ /* will be reallocated separately */
24021+ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
24022+ if (unlikely(!sbinfo->si_branch))
b752ccd1 24023+ goto out_pidmap;
1facf9fc 24024+
1facf9fc 24025+ err = sysaufs_si_init(sbinfo);
24026+ if (unlikely(err))
24027+ goto out_br;
24028+
24029+ au_nwt_init(&sbinfo->si_nowait);
dece6358 24030+ au_rw_init_wlock(&sbinfo->si_rwsem);
e49829fe 24031+ au_rw_class(&sbinfo->si_rwsem, &aufs_si);
b752ccd1
AM
24032+ spin_lock_init(&sbinfo->au_si_pid.tree_lock);
24033+ INIT_RADIX_TREE(&sbinfo->au_si_pid.tree, GFP_ATOMIC | __GFP_NOFAIL);
24034+
7f207e10 24035+ atomic_long_set(&sbinfo->si_ninodes, 0);
7f207e10
AM
24036+ atomic_long_set(&sbinfo->si_nfiles, 0);
24037+
1facf9fc 24038+ sbinfo->si_bend = -1;
392086de 24039+ sbinfo->si_last_br_id = AUFS_BRANCH_MAX / 2;
1facf9fc 24040+
24041+ sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
24042+ sbinfo->si_wbr_create = AuWbrCreate_Def;
4a4d8108
AM
24043+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup;
24044+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create;
1facf9fc 24045+
e49829fe 24046+ sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
1facf9fc 24047+
392086de
AM
24048+ sbinfo->si_xino_jiffy = jiffies;
24049+ sbinfo->si_xino_expire
24050+ = msecs_to_jiffies(AUFS_XINO_DEF_SEC * MSEC_PER_SEC);
1facf9fc 24051+ mutex_init(&sbinfo->si_xib_mtx);
1facf9fc 24052+ sbinfo->si_xino_brid = -1;
24053+ /* leave si_xib_last_pindex and si_xib_next_bit */
24054+
e49829fe 24055+ sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
1facf9fc 24056+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
24057+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
24058+ sbinfo->si_dirwh = AUFS_DIRWH_DEF;
24059+
86dc4139
AM
24060+ for (i = 0; i < AuPlink_NHASH; i++)
24061+ au_sphl_init(sbinfo->si_plink + i);
1facf9fc 24062+ init_waitqueue_head(&sbinfo->si_plink_wq);
4a4d8108 24063+ spin_lock_init(&sbinfo->si_plink_maint_lock);
1facf9fc 24064+
523b37e3
AM
24065+ au_sphl_init(&sbinfo->si_files);
24066+
1facf9fc 24067+ /* leave other members for sysaufs and si_mnt. */
24068+ sbinfo->si_sb = sb;
24069+ sb->s_fs_info = sbinfo;
b752ccd1 24070+ si_pid_set(sb);
1facf9fc 24071+ au_debug_sbinfo_init(sbinfo);
24072+ return 0; /* success */
24073+
4f0767ce 24074+out_br:
1facf9fc 24075+ kfree(sbinfo->si_branch);
4f0767ce 24076+out_pidmap:
b752ccd1 24077+ kfree(sbinfo->au_si_pid.bitmap);
4f0767ce 24078+out_sbinfo:
1facf9fc 24079+ kfree(sbinfo);
4f0767ce 24080+out:
1facf9fc 24081+ return err;
24082+}
24083+
24084+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr)
24085+{
24086+ int err, sz;
24087+ struct au_branch **brp;
24088+
dece6358
AM
24089+ AuRwMustWriteLock(&sbinfo->si_rwsem);
24090+
1facf9fc 24091+ err = -ENOMEM;
24092+ sz = sizeof(*brp) * (sbinfo->si_bend + 1);
24093+ if (unlikely(!sz))
24094+ sz = sizeof(*brp);
24095+ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS);
24096+ if (brp) {
24097+ sbinfo->si_branch = brp;
24098+ err = 0;
24099+ }
24100+
24101+ return err;
24102+}
24103+
24104+/* ---------------------------------------------------------------------- */
24105+
24106+unsigned int au_sigen_inc(struct super_block *sb)
24107+{
24108+ unsigned int gen;
24109+
dece6358
AM
24110+ SiMustWriteLock(sb);
24111+
1facf9fc 24112+ gen = ++au_sbi(sb)->si_generation;
24113+ au_update_digen(sb->s_root);
537831f9 24114+ au_update_iigen(sb->s_root->d_inode, /*half*/0);
1facf9fc 24115+ sb->s_root->d_inode->i_version++;
24116+ return gen;
24117+}
24118+
24119+aufs_bindex_t au_new_br_id(struct super_block *sb)
24120+{
24121+ aufs_bindex_t br_id;
24122+ int i;
24123+ struct au_sbinfo *sbinfo;
24124+
dece6358
AM
24125+ SiMustWriteLock(sb);
24126+
1facf9fc 24127+ sbinfo = au_sbi(sb);
24128+ for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
24129+ br_id = ++sbinfo->si_last_br_id;
7f207e10 24130+ AuDebugOn(br_id < 0);
1facf9fc 24131+ if (br_id && au_br_index(sb, br_id) < 0)
24132+ return br_id;
24133+ }
24134+
24135+ return -1;
24136+}
24137+
24138+/* ---------------------------------------------------------------------- */
24139+
e49829fe
JR
24140+/* it is ok that new 'nwt' tasks are appended while we are sleeping */
24141+int si_read_lock(struct super_block *sb, int flags)
24142+{
24143+ int err;
24144+
24145+ err = 0;
24146+ if (au_ftest_lock(flags, FLUSH))
24147+ au_nwt_flush(&au_sbi(sb)->si_nowait);
24148+
24149+ si_noflush_read_lock(sb);
24150+ err = au_plink_maint(sb, flags);
24151+ if (unlikely(err))
24152+ si_read_unlock(sb);
24153+
24154+ return err;
24155+}
24156+
24157+int si_write_lock(struct super_block *sb, int flags)
24158+{
24159+ int err;
24160+
24161+ if (au_ftest_lock(flags, FLUSH))
24162+ au_nwt_flush(&au_sbi(sb)->si_nowait);
24163+
24164+ si_noflush_write_lock(sb);
24165+ err = au_plink_maint(sb, flags);
24166+ if (unlikely(err))
24167+ si_write_unlock(sb);
24168+
24169+ return err;
24170+}
24171+
1facf9fc 24172+/* dentry and super_block lock. call at entry point */
e49829fe 24173+int aufs_read_lock(struct dentry *dentry, int flags)
1facf9fc 24174+{
e49829fe 24175+ int err;
027c5e7a 24176+ struct super_block *sb;
e49829fe 24177+
027c5e7a
AM
24178+ sb = dentry->d_sb;
24179+ err = si_read_lock(sb, flags);
24180+ if (unlikely(err))
24181+ goto out;
24182+
24183+ if (au_ftest_lock(flags, DW))
24184+ di_write_lock_child(dentry);
24185+ else
24186+ di_read_lock_child(dentry, flags);
24187+
24188+ if (au_ftest_lock(flags, GEN)) {
24189+ err = au_digen_test(dentry, au_sigen(sb));
24190+ AuDebugOn(!err && au_dbrange_test(dentry));
24191+ if (unlikely(err))
24192+ aufs_read_unlock(dentry, flags);
e49829fe
JR
24193+ }
24194+
027c5e7a 24195+out:
e49829fe 24196+ return err;
1facf9fc 24197+}
24198+
24199+void aufs_read_unlock(struct dentry *dentry, int flags)
24200+{
24201+ if (au_ftest_lock(flags, DW))
24202+ di_write_unlock(dentry);
24203+ else
24204+ di_read_unlock(dentry, flags);
24205+ si_read_unlock(dentry->d_sb);
24206+}
24207+
24208+void aufs_write_lock(struct dentry *dentry)
24209+{
e49829fe 24210+ si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW);
1facf9fc 24211+ di_write_lock_child(dentry);
24212+}
24213+
24214+void aufs_write_unlock(struct dentry *dentry)
24215+{
24216+ di_write_unlock(dentry);
24217+ si_write_unlock(dentry->d_sb);
24218+}
24219+
e49829fe 24220+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
1facf9fc 24221+{
e49829fe 24222+ int err;
027c5e7a
AM
24223+ unsigned int sigen;
24224+ struct super_block *sb;
e49829fe 24225+
027c5e7a
AM
24226+ sb = d1->d_sb;
24227+ err = si_read_lock(sb, flags);
24228+ if (unlikely(err))
24229+ goto out;
24230+
24231+ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR));
24232+
24233+ if (au_ftest_lock(flags, GEN)) {
24234+ sigen = au_sigen(sb);
24235+ err = au_digen_test(d1, sigen);
24236+ AuDebugOn(!err && au_dbrange_test(d1));
24237+ if (!err) {
24238+ err = au_digen_test(d2, sigen);
24239+ AuDebugOn(!err && au_dbrange_test(d2));
24240+ }
24241+ if (unlikely(err))
24242+ aufs_read_and_write_unlock2(d1, d2);
24243+ }
24244+
24245+out:
e49829fe 24246+ return err;
1facf9fc 24247+}
24248+
24249+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
24250+{
24251+ di_write_unlock2(d1, d2);
24252+ si_read_unlock(d1->d_sb);
24253+}
b752ccd1
AM
24254+
24255+/* ---------------------------------------------------------------------- */
24256+
24257+int si_pid_test_slow(struct super_block *sb)
24258+{
24259+ void *p;
24260+
24261+ rcu_read_lock();
24262+ p = radix_tree_lookup(&au_sbi(sb)->au_si_pid.tree, current->pid);
24263+ rcu_read_unlock();
24264+
027c5e7a 24265+ return (long)!!p;
b752ccd1
AM
24266+}
24267+
24268+void si_pid_set_slow(struct super_block *sb)
24269+{
24270+ int err;
24271+ struct au_sbinfo *sbinfo;
24272+
24273+ AuDebugOn(si_pid_test_slow(sb));
24274+
24275+ sbinfo = au_sbi(sb);
24276+ err = radix_tree_preload(GFP_NOFS | __GFP_NOFAIL);
24277+ AuDebugOn(err);
24278+ spin_lock(&sbinfo->au_si_pid.tree_lock);
24279+ err = radix_tree_insert(&sbinfo->au_si_pid.tree, current->pid,
027c5e7a 24280+ /*any valid ptr*/sb);
b752ccd1
AM
24281+ spin_unlock(&sbinfo->au_si_pid.tree_lock);
24282+ AuDebugOn(err);
24283+ radix_tree_preload_end();
24284+}
24285+
24286+void si_pid_clr_slow(struct super_block *sb)
24287+{
24288+ void *p;
24289+ struct au_sbinfo *sbinfo;
24290+
24291+ AuDebugOn(!si_pid_test_slow(sb));
24292+
24293+ sbinfo = au_sbi(sb);
24294+ spin_lock(&sbinfo->au_si_pid.tree_lock);
24295+ p = radix_tree_delete(&sbinfo->au_si_pid.tree, current->pid);
24296+ spin_unlock(&sbinfo->au_si_pid.tree_lock);
b752ccd1 24297+}
7f207e10
AM
24298diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h
24299--- /usr/share/empty/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
24300+++ linux/fs/aufs/spl.h 2014-01-20 20:16:14.742796949 +0100
24301@@ -0,0 +1,111 @@
1facf9fc 24302+/*
523b37e3 24303+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 24304+ *
24305+ * This program, aufs is free software; you can redistribute it and/or modify
24306+ * it under the terms of the GNU General Public License as published by
24307+ * the Free Software Foundation; either version 2 of the License, or
24308+ * (at your option) any later version.
dece6358
AM
24309+ *
24310+ * This program is distributed in the hope that it will be useful,
24311+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24312+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24313+ * GNU General Public License for more details.
24314+ *
24315+ * You should have received a copy of the GNU General Public License
523b37e3 24316+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24317+ */
24318+
24319+/*
24320+ * simple list protected by a spinlock
24321+ */
24322+
24323+#ifndef __AUFS_SPL_H__
24324+#define __AUFS_SPL_H__
24325+
24326+#ifdef __KERNEL__
24327+
1facf9fc 24328+struct au_splhead {
24329+ spinlock_t spin;
24330+ struct list_head head;
24331+};
24332+
24333+static inline void au_spl_init(struct au_splhead *spl)
24334+{
24335+ spin_lock_init(&spl->spin);
24336+ INIT_LIST_HEAD(&spl->head);
24337+}
24338+
24339+static inline void au_spl_add(struct list_head *list, struct au_splhead *spl)
24340+{
24341+ spin_lock(&spl->spin);
24342+ list_add(list, &spl->head);
24343+ spin_unlock(&spl->spin);
24344+}
24345+
24346+static inline void au_spl_del(struct list_head *list, struct au_splhead *spl)
24347+{
24348+ spin_lock(&spl->spin);
24349+ list_del(list);
24350+ spin_unlock(&spl->spin);
24351+}
24352+
4a4d8108
AM
24353+static inline void au_spl_del_rcu(struct list_head *list,
24354+ struct au_splhead *spl)
24355+{
24356+ spin_lock(&spl->spin);
24357+ list_del_rcu(list);
24358+ spin_unlock(&spl->spin);
24359+}
24360+
86dc4139
AM
24361+/* ---------------------------------------------------------------------- */
24362+
24363+struct au_sphlhead {
24364+ spinlock_t spin;
24365+ struct hlist_head head;
24366+};
24367+
24368+static inline void au_sphl_init(struct au_sphlhead *sphl)
24369+{
24370+ spin_lock_init(&sphl->spin);
24371+ INIT_HLIST_HEAD(&sphl->head);
24372+}
24373+
24374+static inline void au_sphl_add(struct hlist_node *hlist,
24375+ struct au_sphlhead *sphl)
24376+{
24377+ spin_lock(&sphl->spin);
24378+ hlist_add_head(hlist, &sphl->head);
24379+ spin_unlock(&sphl->spin);
24380+}
24381+
24382+static inline void au_sphl_del(struct hlist_node *hlist,
24383+ struct au_sphlhead *sphl)
24384+{
24385+ spin_lock(&sphl->spin);
24386+ hlist_del(hlist);
24387+ spin_unlock(&sphl->spin);
24388+}
24389+
24390+static inline void au_sphl_del_rcu(struct hlist_node *hlist,
24391+ struct au_sphlhead *sphl)
24392+{
24393+ spin_lock(&sphl->spin);
24394+ hlist_del_rcu(hlist);
24395+ spin_unlock(&sphl->spin);
24396+}
24397+
24398+static inline unsigned long au_sphl_count(struct au_sphlhead *sphl)
24399+{
24400+ unsigned long cnt;
24401+ struct hlist_node *pos;
24402+
24403+ cnt = 0;
24404+ spin_lock(&sphl->spin);
24405+ hlist_for_each(pos, &sphl->head)
24406+ cnt++;
24407+ spin_unlock(&sphl->spin);
24408+ return cnt;
24409+}
24410+
1facf9fc 24411+#endif /* __KERNEL__ */
24412+#endif /* __AUFS_SPL_H__ */
7f207e10
AM
24413diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
24414--- /usr/share/empty/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
24415+++ linux/fs/aufs/super.c 2014-01-20 20:16:14.742796949 +0100
24416@@ -0,0 +1,1001 @@
1facf9fc 24417+/*
523b37e3 24418+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 24419+ *
24420+ * This program, aufs is free software; you can redistribute it and/or modify
24421+ * it under the terms of the GNU General Public License as published by
24422+ * the Free Software Foundation; either version 2 of the License, or
24423+ * (at your option) any later version.
dece6358
AM
24424+ *
24425+ * This program is distributed in the hope that it will be useful,
24426+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24427+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24428+ * GNU General Public License for more details.
24429+ *
24430+ * You should have received a copy of the GNU General Public License
523b37e3 24431+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24432+ */
24433+
24434+/*
24435+ * mount and super_block operations
24436+ */
24437+
f6c5ef8b 24438+#include <linux/mm.h>
dece6358 24439+#include <linux/module.h>
1facf9fc 24440+#include <linux/seq_file.h>
24441+#include <linux/statfs.h>
7f207e10
AM
24442+#include <linux/vmalloc.h>
24443+#include <linux/writeback.h>
1facf9fc 24444+#include "aufs.h"
24445+
24446+/*
24447+ * super_operations
24448+ */
24449+static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
24450+{
24451+ struct au_icntnr *c;
24452+
24453+ c = au_cache_alloc_icntnr();
24454+ if (c) {
027c5e7a 24455+ au_icntnr_init(c);
1facf9fc 24456+ c->vfs_inode.i_version = 1; /* sigen(sb); */
24457+ c->iinfo.ii_hinode = NULL;
24458+ return &c->vfs_inode;
24459+ }
24460+ return NULL;
24461+}
24462+
027c5e7a
AM
24463+static void aufs_destroy_inode_cb(struct rcu_head *head)
24464+{
24465+ struct inode *inode = container_of(head, struct inode, i_rcu);
24466+
b4510431 24467+ INIT_HLIST_HEAD(&inode->i_dentry);
027c5e7a
AM
24468+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
24469+}
24470+
1facf9fc 24471+static void aufs_destroy_inode(struct inode *inode)
24472+{
24473+ au_iinfo_fin(inode);
027c5e7a 24474+ call_rcu(&inode->i_rcu, aufs_destroy_inode_cb);
1facf9fc 24475+}
24476+
24477+struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
24478+{
24479+ struct inode *inode;
24480+ int err;
24481+
24482+ inode = iget_locked(sb, ino);
24483+ if (unlikely(!inode)) {
24484+ inode = ERR_PTR(-ENOMEM);
24485+ goto out;
24486+ }
24487+ if (!(inode->i_state & I_NEW))
24488+ goto out;
24489+
24490+ err = au_xigen_new(inode);
24491+ if (!err)
24492+ err = au_iinfo_init(inode);
24493+ if (!err)
24494+ inode->i_version++;
24495+ else {
24496+ iget_failed(inode);
24497+ inode = ERR_PTR(err);
24498+ }
24499+
4f0767ce 24500+out:
1facf9fc 24501+ /* never return NULL */
24502+ AuDebugOn(!inode);
24503+ AuTraceErrPtr(inode);
24504+ return inode;
24505+}
24506+
24507+/* lock free root dinfo */
24508+static int au_show_brs(struct seq_file *seq, struct super_block *sb)
24509+{
24510+ int err;
24511+ aufs_bindex_t bindex, bend;
24512+ struct path path;
4a4d8108 24513+ struct au_hdentry *hdp;
1facf9fc 24514+ struct au_branch *br;
1e00d052 24515+ char *perm;
1facf9fc 24516+
24517+ err = 0;
24518+ bend = au_sbend(sb);
4a4d8108 24519+ hdp = au_di(sb->s_root)->di_hdentry;
1facf9fc 24520+ for (bindex = 0; !err && bindex <= bend; bindex++) {
24521+ br = au_sbr(sb, bindex);
86dc4139 24522+ path.mnt = au_br_mnt(br);
4a4d8108 24523+ path.dentry = hdp[bindex].hd_dentry;
1facf9fc 24524+ err = au_seq_path(seq, &path);
1e00d052
AM
24525+ if (err > 0) {
24526+ perm = au_optstr_br_perm(br->br_perm);
24527+ if (perm) {
24528+ err = seq_printf(seq, "=%s", perm);
24529+ kfree(perm);
24530+ if (err == -1)
24531+ err = -E2BIG;
24532+ } else
24533+ err = -ENOMEM;
24534+ }
1facf9fc 24535+ if (!err && bindex != bend)
24536+ err = seq_putc(seq, ':');
24537+ }
24538+
24539+ return err;
24540+}
24541+
24542+static void au_show_wbr_create(struct seq_file *m, int v,
24543+ struct au_sbinfo *sbinfo)
24544+{
24545+ const char *pat;
24546+
dece6358
AM
24547+ AuRwMustAnyLock(&sbinfo->si_rwsem);
24548+
c2b27bf2 24549+ seq_puts(m, ",create=");
1facf9fc 24550+ pat = au_optstr_wbr_create(v);
24551+ switch (v) {
24552+ case AuWbrCreate_TDP:
24553+ case AuWbrCreate_RR:
24554+ case AuWbrCreate_MFS:
24555+ case AuWbrCreate_PMFS:
c2b27bf2 24556+ seq_puts(m, pat);
1facf9fc 24557+ break;
24558+ case AuWbrCreate_MFSV:
24559+ seq_printf(m, /*pat*/"mfs:%lu",
e49829fe
JR
24560+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
24561+ / MSEC_PER_SEC);
1facf9fc 24562+ break;
24563+ case AuWbrCreate_PMFSV:
24564+ seq_printf(m, /*pat*/"pmfs:%lu",
e49829fe
JR
24565+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
24566+ / MSEC_PER_SEC);
1facf9fc 24567+ break;
24568+ case AuWbrCreate_MFSRR:
24569+ seq_printf(m, /*pat*/"mfsrr:%llu",
24570+ sbinfo->si_wbr_mfs.mfsrr_watermark);
24571+ break;
24572+ case AuWbrCreate_MFSRRV:
24573+ seq_printf(m, /*pat*/"mfsrr:%llu:%lu",
24574+ sbinfo->si_wbr_mfs.mfsrr_watermark,
e49829fe
JR
24575+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
24576+ / MSEC_PER_SEC);
1facf9fc 24577+ break;
392086de
AM
24578+ case AuWbrCreate_PMFSRR:
24579+ seq_printf(m, /*pat*/"pmfsrr:%llu",
24580+ sbinfo->si_wbr_mfs.mfsrr_watermark);
24581+ break;
24582+ case AuWbrCreate_PMFSRRV:
24583+ seq_printf(m, /*pat*/"pmfsrr:%llu:%lu",
24584+ sbinfo->si_wbr_mfs.mfsrr_watermark,
24585+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
24586+ / MSEC_PER_SEC);
24587+ break;
1facf9fc 24588+ }
24589+}
24590+
7eafdf33 24591+static int au_show_xino(struct seq_file *seq, struct super_block *sb)
1facf9fc 24592+{
24593+#ifdef CONFIG_SYSFS
24594+ return 0;
24595+#else
24596+ int err;
24597+ const int len = sizeof(AUFS_XINO_FNAME) - 1;
24598+ aufs_bindex_t bindex, brid;
1facf9fc 24599+ struct qstr *name;
24600+ struct file *f;
24601+ struct dentry *d, *h_root;
4a4d8108 24602+ struct au_hdentry *hdp;
1facf9fc 24603+
dece6358
AM
24604+ AuRwMustAnyLock(&sbinfo->si_rwsem);
24605+
1facf9fc 24606+ err = 0;
1facf9fc 24607+ f = au_sbi(sb)->si_xib;
24608+ if (!f)
24609+ goto out;
24610+
24611+ /* stop printing the default xino path on the first writable branch */
24612+ h_root = NULL;
24613+ brid = au_xino_brid(sb);
24614+ if (brid >= 0) {
24615+ bindex = au_br_index(sb, brid);
4a4d8108
AM
24616+ hdp = au_di(sb->s_root)->di_hdentry;
24617+ h_root = hdp[0 + bindex].hd_dentry;
1facf9fc 24618+ }
24619+ d = f->f_dentry;
24620+ name = &d->d_name;
24621+ /* safe ->d_parent because the file is unlinked */
24622+ if (d->d_parent == h_root
24623+ && name->len == len
24624+ && !memcmp(name->name, AUFS_XINO_FNAME, len))
24625+ goto out;
24626+
24627+ seq_puts(seq, ",xino=");
24628+ err = au_xino_path(seq, f);
24629+
4f0767ce 24630+out:
1facf9fc 24631+ return err;
24632+#endif
24633+}
24634+
24635+/* seq_file will re-call me in case of too long string */
7eafdf33 24636+static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
1facf9fc 24637+{
027c5e7a 24638+ int err;
1facf9fc 24639+ unsigned int mnt_flags, v;
24640+ struct super_block *sb;
24641+ struct au_sbinfo *sbinfo;
24642+
24643+#define AuBool(name, str) do { \
24644+ v = au_opt_test(mnt_flags, name); \
24645+ if (v != au_opt_test(AuOpt_Def, name)) \
24646+ seq_printf(m, ",%s" #str, v ? "" : "no"); \
24647+} while (0)
24648+
24649+#define AuStr(name, str) do { \
24650+ v = mnt_flags & AuOptMask_##name; \
24651+ if (v != (AuOpt_Def & AuOptMask_##name)) \
24652+ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
24653+} while (0)
24654+
24655+#define AuUInt(name, str, val) do { \
24656+ if (val != AUFS_##name##_DEF) \
24657+ seq_printf(m, "," #str "=%u", val); \
24658+} while (0)
24659+
24660+ /* lock free root dinfo */
7eafdf33 24661+ sb = dentry->d_sb;
1facf9fc 24662+ si_noflush_read_lock(sb);
24663+ sbinfo = au_sbi(sb);
24664+ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
24665+
24666+ mnt_flags = au_mntflags(sb);
24667+ if (au_opt_test(mnt_flags, XINO)) {
7eafdf33 24668+ err = au_show_xino(m, sb);
1facf9fc 24669+ if (unlikely(err))
24670+ goto out;
24671+ } else
24672+ seq_puts(m, ",noxino");
24673+
24674+ AuBool(TRUNC_XINO, trunc_xino);
24675+ AuStr(UDBA, udba);
dece6358 24676+ AuBool(SHWH, shwh);
1facf9fc 24677+ AuBool(PLINK, plink);
4a4d8108 24678+ AuBool(DIO, dio);
1facf9fc 24679+ /* AuBool(DIRPERM1, dirperm1); */
24680+ /* AuBool(REFROF, refrof); */
24681+
24682+ v = sbinfo->si_wbr_create;
24683+ if (v != AuWbrCreate_Def)
24684+ au_show_wbr_create(m, v, sbinfo);
24685+
24686+ v = sbinfo->si_wbr_copyup;
24687+ if (v != AuWbrCopyup_Def)
24688+ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
24689+
24690+ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
24691+ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
24692+ seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
24693+
24694+ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
24695+
027c5e7a
AM
24696+ v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC;
24697+ AuUInt(RDCACHE, rdcache, v);
1facf9fc 24698+
24699+ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
24700+ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
24701+
24702+ AuBool(SUM, sum);
24703+ /* AuBool(SUM_W, wsum); */
24704+ AuBool(WARN_PERM, warn_perm);
24705+ AuBool(VERBOSE, verbose);
24706+
4f0767ce 24707+out:
1facf9fc 24708+ /* be sure to print "br:" last */
24709+ if (!sysaufs_brs) {
24710+ seq_puts(m, ",br:");
24711+ au_show_brs(m, sb);
24712+ }
24713+ si_read_unlock(sb);
24714+ return 0;
24715+
1facf9fc 24716+#undef AuBool
24717+#undef AuStr
4a4d8108 24718+#undef AuUInt
1facf9fc 24719+}
24720+
24721+/* ---------------------------------------------------------------------- */
24722+
24723+/* sum mode which returns the summation for statfs(2) */
24724+
24725+static u64 au_add_till_max(u64 a, u64 b)
24726+{
24727+ u64 old;
24728+
24729+ old = a;
24730+ a += b;
92d182d2
AM
24731+ if (old <= a)
24732+ return a;
24733+ return ULLONG_MAX;
24734+}
24735+
24736+static u64 au_mul_till_max(u64 a, long mul)
24737+{
24738+ u64 old;
24739+
24740+ old = a;
24741+ a *= mul;
24742+ if (old <= a)
1facf9fc 24743+ return a;
24744+ return ULLONG_MAX;
24745+}
24746+
24747+static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
24748+{
24749+ int err;
92d182d2 24750+ long bsize, factor;
1facf9fc 24751+ u64 blocks, bfree, bavail, files, ffree;
24752+ aufs_bindex_t bend, bindex, i;
24753+ unsigned char shared;
7f207e10 24754+ struct path h_path;
1facf9fc 24755+ struct super_block *h_sb;
24756+
92d182d2
AM
24757+ err = 0;
24758+ bsize = LONG_MAX;
24759+ files = 0;
24760+ ffree = 0;
1facf9fc 24761+ blocks = 0;
24762+ bfree = 0;
24763+ bavail = 0;
1facf9fc 24764+ bend = au_sbend(sb);
92d182d2 24765+ for (bindex = 0; bindex <= bend; bindex++) {
7f207e10
AM
24766+ h_path.mnt = au_sbr_mnt(sb, bindex);
24767+ h_sb = h_path.mnt->mnt_sb;
1facf9fc 24768+ shared = 0;
92d182d2 24769+ for (i = 0; !shared && i < bindex; i++)
1facf9fc 24770+ shared = (au_sbr_sb(sb, i) == h_sb);
24771+ if (shared)
24772+ continue;
24773+
24774+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
24775+ h_path.dentry = h_path.mnt->mnt_root;
24776+ err = vfs_statfs(&h_path, buf);
1facf9fc 24777+ if (unlikely(err))
24778+ goto out;
24779+
92d182d2
AM
24780+ if (bsize > buf->f_bsize) {
24781+ /*
24782+ * we will reduce bsize, so we have to expand blocks
24783+ * etc. to match them again
24784+ */
24785+ factor = (bsize / buf->f_bsize);
24786+ blocks = au_mul_till_max(blocks, factor);
24787+ bfree = au_mul_till_max(bfree, factor);
24788+ bavail = au_mul_till_max(bavail, factor);
24789+ bsize = buf->f_bsize;
24790+ }
24791+
24792+ factor = (buf->f_bsize / bsize);
24793+ blocks = au_add_till_max(blocks,
24794+ au_mul_till_max(buf->f_blocks, factor));
24795+ bfree = au_add_till_max(bfree,
24796+ au_mul_till_max(buf->f_bfree, factor));
24797+ bavail = au_add_till_max(bavail,
24798+ au_mul_till_max(buf->f_bavail, factor));
1facf9fc 24799+ files = au_add_till_max(files, buf->f_files);
24800+ ffree = au_add_till_max(ffree, buf->f_ffree);
24801+ }
24802+
92d182d2 24803+ buf->f_bsize = bsize;
1facf9fc 24804+ buf->f_blocks = blocks;
24805+ buf->f_bfree = bfree;
24806+ buf->f_bavail = bavail;
24807+ buf->f_files = files;
24808+ buf->f_ffree = ffree;
92d182d2 24809+ buf->f_frsize = 0;
1facf9fc 24810+
4f0767ce 24811+out:
1facf9fc 24812+ return err;
24813+}
24814+
24815+static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
24816+{
24817+ int err;
7f207e10 24818+ struct path h_path;
1facf9fc 24819+ struct super_block *sb;
24820+
24821+ /* lock free root dinfo */
24822+ sb = dentry->d_sb;
24823+ si_noflush_read_lock(sb);
7f207e10 24824+ if (!au_opt_test(au_mntflags(sb), SUM)) {
1facf9fc 24825+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
24826+ h_path.mnt = au_sbr_mnt(sb, 0);
24827+ h_path.dentry = h_path.mnt->mnt_root;
24828+ err = vfs_statfs(&h_path, buf);
24829+ } else
1facf9fc 24830+ err = au_statfs_sum(sb, buf);
24831+ si_read_unlock(sb);
24832+
24833+ if (!err) {
24834+ buf->f_type = AUFS_SUPER_MAGIC;
4a4d8108 24835+ buf->f_namelen = AUFS_MAX_NAMELEN;
1facf9fc 24836+ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
24837+ }
24838+ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
24839+
24840+ return err;
24841+}
24842+
24843+/* ---------------------------------------------------------------------- */
24844+
537831f9
AM
24845+static int aufs_sync_fs(struct super_block *sb, int wait)
24846+{
24847+ int err, e;
24848+ aufs_bindex_t bend, bindex;
24849+ struct au_branch *br;
24850+ struct super_block *h_sb;
24851+
24852+ err = 0;
24853+ si_noflush_read_lock(sb);
24854+ bend = au_sbend(sb);
24855+ for (bindex = 0; bindex <= bend; bindex++) {
24856+ br = au_sbr(sb, bindex);
24857+ if (!au_br_writable(br->br_perm))
24858+ continue;
24859+
24860+ h_sb = au_sbr_sb(sb, bindex);
24861+ if (h_sb->s_op->sync_fs) {
24862+ e = h_sb->s_op->sync_fs(h_sb, wait);
24863+ if (unlikely(e && !err))
24864+ err = e;
24865+ /* go on even if an error happens */
24866+ }
24867+ }
24868+ si_read_unlock(sb);
24869+
24870+ return err;
24871+}
24872+
24873+/* ---------------------------------------------------------------------- */
24874+
1facf9fc 24875+/* final actions when unmounting a file system */
24876+static void aufs_put_super(struct super_block *sb)
24877+{
24878+ struct au_sbinfo *sbinfo;
24879+
24880+ sbinfo = au_sbi(sb);
24881+ if (!sbinfo)
24882+ return;
24883+
1facf9fc 24884+ dbgaufs_si_fin(sbinfo);
24885+ kobject_put(&sbinfo->si_kobj);
24886+}
24887+
24888+/* ---------------------------------------------------------------------- */
24889+
7f207e10
AM
24890+void au_array_free(void *array)
24891+{
24892+ if (array) {
24893+ if (!is_vmalloc_addr(array))
24894+ kfree(array);
24895+ else
24896+ vfree(array);
24897+ }
24898+}
24899+
24900+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg)
24901+{
24902+ void *array;
24903+ unsigned long long n;
24904+
24905+ array = NULL;
24906+ n = 0;
24907+ if (!*hint)
24908+ goto out;
24909+
24910+ if (*hint > ULLONG_MAX / sizeof(array)) {
24911+ array = ERR_PTR(-EMFILE);
24912+ pr_err("hint %llu\n", *hint);
24913+ goto out;
24914+ }
24915+
24916+ array = kmalloc(sizeof(array) * *hint, GFP_NOFS);
24917+ if (unlikely(!array))
24918+ array = vmalloc(sizeof(array) * *hint);
24919+ if (unlikely(!array)) {
24920+ array = ERR_PTR(-ENOMEM);
24921+ goto out;
24922+ }
24923+
24924+ n = cb(array, *hint, arg);
24925+ AuDebugOn(n > *hint);
24926+
24927+out:
24928+ *hint = n;
24929+ return array;
24930+}
24931+
24932+static unsigned long long au_iarray_cb(void *a,
24933+ unsigned long long max __maybe_unused,
24934+ void *arg)
24935+{
24936+ unsigned long long n;
24937+ struct inode **p, *inode;
24938+ struct list_head *head;
24939+
24940+ n = 0;
24941+ p = a;
24942+ head = arg;
2cbb1c4b 24943+ spin_lock(&inode_sb_list_lock);
7f207e10
AM
24944+ list_for_each_entry(inode, head, i_sb_list) {
24945+ if (!is_bad_inode(inode)
24946+ && au_ii(inode)->ii_bstart >= 0) {
2cbb1c4b
JR
24947+ spin_lock(&inode->i_lock);
24948+ if (atomic_read(&inode->i_count)) {
24949+ au_igrab(inode);
24950+ *p++ = inode;
24951+ n++;
24952+ AuDebugOn(n > max);
24953+ }
24954+ spin_unlock(&inode->i_lock);
7f207e10
AM
24955+ }
24956+ }
2cbb1c4b 24957+ spin_unlock(&inode_sb_list_lock);
7f207e10
AM
24958+
24959+ return n;
24960+}
24961+
24962+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max)
24963+{
24964+ *max = atomic_long_read(&au_sbi(sb)->si_ninodes);
24965+ return au_array_alloc(max, au_iarray_cb, &sb->s_inodes);
24966+}
24967+
24968+void au_iarray_free(struct inode **a, unsigned long long max)
24969+{
24970+ unsigned long long ull;
24971+
24972+ for (ull = 0; ull < max; ull++)
24973+ iput(a[ull]);
24974+ au_array_free(a);
24975+}
24976+
24977+/* ---------------------------------------------------------------------- */
24978+
1facf9fc 24979+/*
24980+ * refresh dentry and inode at remount time.
24981+ */
027c5e7a
AM
24982+/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */
24983+static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags,
24984+ struct dentry *parent)
1facf9fc 24985+{
24986+ int err;
1facf9fc 24987+
24988+ di_write_lock_child(dentry);
1facf9fc 24989+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
24990+ err = au_refresh_dentry(dentry, parent);
24991+ if (!err && dir_flags)
24992+ au_hn_reset(dentry->d_inode, dir_flags);
1facf9fc 24993+ di_read_unlock(parent, AuLock_IR);
1facf9fc 24994+ di_write_unlock(dentry);
24995+
24996+ return err;
24997+}
24998+
027c5e7a
AM
24999+static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
25000+ struct au_sbinfo *sbinfo,
25001+ const unsigned int dir_flags)
1facf9fc 25002+{
027c5e7a
AM
25003+ int err;
25004+ struct dentry *parent;
25005+ struct inode *inode;
25006+
25007+ err = 0;
25008+ parent = dget_parent(dentry);
25009+ if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
25010+ inode = dentry->d_inode;
25011+ if (inode) {
25012+ if (!S_ISDIR(inode->i_mode))
25013+ err = au_do_refresh(dentry, /*dir_flags*/0,
25014+ parent);
25015+ else {
25016+ err = au_do_refresh(dentry, dir_flags, parent);
25017+ if (unlikely(err))
25018+ au_fset_si(sbinfo, FAILED_REFRESH_DIR);
25019+ }
25020+ } else
25021+ err = au_do_refresh(dentry, /*dir_flags*/0, parent);
25022+ AuDbgDentry(dentry);
25023+ }
25024+ dput(parent);
25025+
25026+ AuTraceErr(err);
25027+ return err;
1facf9fc 25028+}
25029+
027c5e7a 25030+static int au_refresh_d(struct super_block *sb)
1facf9fc 25031+{
25032+ int err, i, j, ndentry, e;
027c5e7a 25033+ unsigned int sigen;
1facf9fc 25034+ struct au_dcsub_pages dpages;
25035+ struct au_dpage *dpage;
027c5e7a
AM
25036+ struct dentry **dentries, *d;
25037+ struct au_sbinfo *sbinfo;
25038+ struct dentry *root = sb->s_root;
25039+ const unsigned int dir_flags = au_hi_flags(root->d_inode, /*isdir*/1);
1facf9fc 25040+
027c5e7a
AM
25041+ err = au_dpages_init(&dpages, GFP_NOFS);
25042+ if (unlikely(err))
1facf9fc 25043+ goto out;
027c5e7a
AM
25044+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
25045+ if (unlikely(err))
1facf9fc 25046+ goto out_dpages;
1facf9fc 25047+
027c5e7a
AM
25048+ sigen = au_sigen(sb);
25049+ sbinfo = au_sbi(sb);
25050+ for (i = 0; i < dpages.ndpage; i++) {
1facf9fc 25051+ dpage = dpages.dpages + i;
25052+ dentries = dpage->dentries;
25053+ ndentry = dpage->ndentry;
027c5e7a 25054+ for (j = 0; j < ndentry; j++) {
1facf9fc 25055+ d = dentries[j];
027c5e7a
AM
25056+ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags);
25057+ if (unlikely(e && !err))
25058+ err = e;
25059+ /* go on even err */
1facf9fc 25060+ }
25061+ }
25062+
4f0767ce 25063+out_dpages:
1facf9fc 25064+ au_dpages_free(&dpages);
4f0767ce 25065+out:
1facf9fc 25066+ return err;
25067+}
25068+
027c5e7a 25069+static int au_refresh_i(struct super_block *sb)
1facf9fc 25070+{
027c5e7a
AM
25071+ int err, e;
25072+ unsigned int sigen;
25073+ unsigned long long max, ull;
25074+ struct inode *inode, **array;
1facf9fc 25075+
027c5e7a
AM
25076+ array = au_iarray_alloc(sb, &max);
25077+ err = PTR_ERR(array);
25078+ if (IS_ERR(array))
25079+ goto out;
1facf9fc 25080+
25081+ err = 0;
027c5e7a
AM
25082+ sigen = au_sigen(sb);
25083+ for (ull = 0; ull < max; ull++) {
25084+ inode = array[ull];
537831f9 25085+ if (au_iigen(inode, NULL) != sigen) {
1facf9fc 25086+ ii_write_lock_child(inode);
027c5e7a 25087+ e = au_refresh_hinode_self(inode);
1facf9fc 25088+ ii_write_unlock(inode);
25089+ if (unlikely(e)) {
027c5e7a 25090+ pr_err("error %d, i%lu\n", e, inode->i_ino);
1facf9fc 25091+ if (!err)
25092+ err = e;
25093+ /* go on even if err */
25094+ }
25095+ }
1facf9fc 25096+ }
25097+
027c5e7a 25098+ au_iarray_free(array, max);
1facf9fc 25099+
4f0767ce 25100+out:
1facf9fc 25101+ return err;
25102+}
25103+
027c5e7a 25104+static void au_remount_refresh(struct super_block *sb)
1facf9fc 25105+{
027c5e7a
AM
25106+ int err, e;
25107+ unsigned int udba;
25108+ aufs_bindex_t bindex, bend;
1facf9fc 25109+ struct dentry *root;
25110+ struct inode *inode;
027c5e7a 25111+ struct au_branch *br;
1facf9fc 25112+
25113+ au_sigen_inc(sb);
027c5e7a 25114+ au_fclr_si(au_sbi(sb), FAILED_REFRESH_DIR);
1facf9fc 25115+
25116+ root = sb->s_root;
25117+ DiMustNoWaiters(root);
25118+ inode = root->d_inode;
25119+ IiMustNoWaiters(inode);
1facf9fc 25120+
027c5e7a
AM
25121+ udba = au_opt_udba(sb);
25122+ bend = au_sbend(sb);
25123+ for (bindex = 0; bindex <= bend; bindex++) {
25124+ br = au_sbr(sb, bindex);
25125+ err = au_hnotify_reset_br(udba, br, br->br_perm);
1facf9fc 25126+ if (unlikely(err))
027c5e7a
AM
25127+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
25128+ bindex, err);
25129+ /* go on even if err */
1facf9fc 25130+ }
027c5e7a 25131+ au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
1facf9fc 25132+
027c5e7a
AM
25133+ di_write_unlock(root);
25134+ err = au_refresh_d(sb);
25135+ e = au_refresh_i(sb);
25136+ if (unlikely(e && !err))
25137+ err = e;
1facf9fc 25138+ /* aufs_write_lock() calls ..._child() */
25139+ di_write_lock_child(root);
027c5e7a
AM
25140+
25141+ au_cpup_attr_all(inode, /*force*/1);
25142+
25143+ if (unlikely(err))
25144+ AuIOErr("refresh failed, ignored, %d\n", err);
1facf9fc 25145+}
25146+
25147+/* stop extra interpretation of errno in mount(8), and strange error messages */
25148+static int cvt_err(int err)
25149+{
25150+ AuTraceErr(err);
25151+
25152+ switch (err) {
25153+ case -ENOENT:
25154+ case -ENOTDIR:
25155+ case -EEXIST:
25156+ case -EIO:
25157+ err = -EINVAL;
25158+ }
25159+ return err;
25160+}
25161+
25162+static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
25163+{
4a4d8108
AM
25164+ int err, do_dx;
25165+ unsigned int mntflags;
1facf9fc 25166+ struct au_opts opts;
25167+ struct dentry *root;
25168+ struct inode *inode;
25169+ struct au_sbinfo *sbinfo;
25170+
25171+ err = 0;
25172+ root = sb->s_root;
25173+ if (!data || !*data) {
e49829fe
JR
25174+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
25175+ if (!err) {
25176+ di_write_lock_child(root);
25177+ err = au_opts_verify(sb, *flags, /*pending*/0);
25178+ aufs_write_unlock(root);
25179+ }
1facf9fc 25180+ goto out;
25181+ }
25182+
25183+ err = -ENOMEM;
25184+ memset(&opts, 0, sizeof(opts));
25185+ opts.opt = (void *)__get_free_page(GFP_NOFS);
25186+ if (unlikely(!opts.opt))
25187+ goto out;
25188+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
25189+ opts.flags = AuOpts_REMOUNT;
25190+ opts.sb_flags = *flags;
25191+
25192+ /* parse it before aufs lock */
25193+ err = au_opts_parse(sb, data, &opts);
25194+ if (unlikely(err))
25195+ goto out_opts;
25196+
25197+ sbinfo = au_sbi(sb);
25198+ inode = root->d_inode;
25199+ mutex_lock(&inode->i_mutex);
e49829fe
JR
25200+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
25201+ if (unlikely(err))
25202+ goto out_mtx;
25203+ di_write_lock_child(root);
1facf9fc 25204+
25205+ /* au_opts_remount() may return an error */
25206+ err = au_opts_remount(sb, &opts);
25207+ au_opts_free(&opts);
25208+
027c5e7a
AM
25209+ if (au_ftest_opts(opts.flags, REFRESH))
25210+ au_remount_refresh(sb);
1facf9fc 25211+
4a4d8108
AM
25212+ if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
25213+ mntflags = au_mntflags(sb);
25214+ do_dx = !!au_opt_test(mntflags, DIO);
25215+ au_dy_arefresh(do_dx);
25216+ }
25217+
1facf9fc 25218+ aufs_write_unlock(root);
953406b4 25219+
e49829fe
JR
25220+out_mtx:
25221+ mutex_unlock(&inode->i_mutex);
4f0767ce 25222+out_opts:
1facf9fc 25223+ free_page((unsigned long)opts.opt);
4f0767ce 25224+out:
1facf9fc 25225+ err = cvt_err(err);
25226+ AuTraceErr(err);
25227+ return err;
25228+}
25229+
4a4d8108 25230+static const struct super_operations aufs_sop = {
1facf9fc 25231+ .alloc_inode = aufs_alloc_inode,
25232+ .destroy_inode = aufs_destroy_inode,
b752ccd1 25233+ /* always deleting, no clearing */
1facf9fc 25234+ .drop_inode = generic_delete_inode,
25235+ .show_options = aufs_show_options,
25236+ .statfs = aufs_statfs,
25237+ .put_super = aufs_put_super,
537831f9 25238+ .sync_fs = aufs_sync_fs,
1facf9fc 25239+ .remount_fs = aufs_remount_fs
25240+};
25241+
25242+/* ---------------------------------------------------------------------- */
25243+
25244+static int alloc_root(struct super_block *sb)
25245+{
25246+ int err;
25247+ struct inode *inode;
25248+ struct dentry *root;
25249+
25250+ err = -ENOMEM;
25251+ inode = au_iget_locked(sb, AUFS_ROOT_INO);
25252+ err = PTR_ERR(inode);
25253+ if (IS_ERR(inode))
25254+ goto out;
25255+
25256+ inode->i_op = &aufs_dir_iop;
25257+ inode->i_fop = &aufs_dir_fop;
25258+ inode->i_mode = S_IFDIR;
9dbd164d 25259+ set_nlink(inode, 2);
1facf9fc 25260+ unlock_new_inode(inode);
25261+
92d182d2 25262+ root = d_make_root(inode);
1facf9fc 25263+ if (unlikely(!root))
92d182d2 25264+ goto out;
1facf9fc 25265+ err = PTR_ERR(root);
25266+ if (IS_ERR(root))
92d182d2 25267+ goto out;
1facf9fc 25268+
4a4d8108 25269+ err = au_di_init(root);
1facf9fc 25270+ if (!err) {
25271+ sb->s_root = root;
25272+ return 0; /* success */
25273+ }
25274+ dput(root);
1facf9fc 25275+
4f0767ce 25276+out:
1facf9fc 25277+ return err;
1facf9fc 25278+}
25279+
25280+static int aufs_fill_super(struct super_block *sb, void *raw_data,
25281+ int silent __maybe_unused)
25282+{
25283+ int err;
25284+ struct au_opts opts;
25285+ struct dentry *root;
25286+ struct inode *inode;
25287+ char *arg = raw_data;
25288+
25289+ if (unlikely(!arg || !*arg)) {
25290+ err = -EINVAL;
4a4d8108 25291+ pr_err("no arg\n");
1facf9fc 25292+ goto out;
25293+ }
25294+
25295+ err = -ENOMEM;
25296+ memset(&opts, 0, sizeof(opts));
25297+ opts.opt = (void *)__get_free_page(GFP_NOFS);
25298+ if (unlikely(!opts.opt))
25299+ goto out;
25300+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
25301+ opts.sb_flags = sb->s_flags;
25302+
25303+ err = au_si_alloc(sb);
25304+ if (unlikely(err))
25305+ goto out_opts;
25306+
25307+ /* all timestamps always follow the ones on the branch */
25308+ sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
25309+ sb->s_op = &aufs_sop;
027c5e7a 25310+ sb->s_d_op = &aufs_dop;
1facf9fc 25311+ sb->s_magic = AUFS_SUPER_MAGIC;
25312+ sb->s_maxbytes = 0;
25313+ au_export_init(sb);
25314+
25315+ err = alloc_root(sb);
25316+ if (unlikely(err)) {
25317+ si_write_unlock(sb);
25318+ goto out_info;
25319+ }
25320+ root = sb->s_root;
25321+ inode = root->d_inode;
25322+
25323+ /*
25324+ * actually we can parse options regardless aufs lock here.
25325+ * but at remount time, parsing must be done before aufs lock.
25326+ * so we follow the same rule.
25327+ */
25328+ ii_write_lock_parent(inode);
25329+ aufs_write_unlock(root);
25330+ err = au_opts_parse(sb, arg, &opts);
25331+ if (unlikely(err))
25332+ goto out_root;
25333+
25334+ /* lock vfs_inode first, then aufs. */
25335+ mutex_lock(&inode->i_mutex);
1facf9fc 25336+ aufs_write_lock(root);
25337+ err = au_opts_mount(sb, &opts);
25338+ au_opts_free(&opts);
1facf9fc 25339+ aufs_write_unlock(root);
25340+ mutex_unlock(&inode->i_mutex);
4a4d8108
AM
25341+ if (!err)
25342+ goto out_opts; /* success */
1facf9fc 25343+
4f0767ce 25344+out_root:
1facf9fc 25345+ dput(root);
25346+ sb->s_root = NULL;
4f0767ce 25347+out_info:
2cbb1c4b 25348+ dbgaufs_si_fin(au_sbi(sb));
1facf9fc 25349+ kobject_put(&au_sbi(sb)->si_kobj);
25350+ sb->s_fs_info = NULL;
4f0767ce 25351+out_opts:
1facf9fc 25352+ free_page((unsigned long)opts.opt);
4f0767ce 25353+out:
1facf9fc 25354+ AuTraceErr(err);
25355+ err = cvt_err(err);
25356+ AuTraceErr(err);
25357+ return err;
25358+}
25359+
25360+/* ---------------------------------------------------------------------- */
25361+
027c5e7a
AM
25362+static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags,
25363+ const char *dev_name __maybe_unused,
25364+ void *raw_data)
1facf9fc 25365+{
027c5e7a 25366+ struct dentry *root;
1facf9fc 25367+ struct super_block *sb;
25368+
25369+ /* all timestamps always follow the ones on the branch */
25370+ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
027c5e7a
AM
25371+ root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super);
25372+ if (IS_ERR(root))
25373+ goto out;
25374+
25375+ sb = root->d_sb;
25376+ si_write_lock(sb, !AuLock_FLUSH);
25377+ sysaufs_brs_add(sb, 0);
25378+ si_write_unlock(sb);
25379+ au_sbilist_add(sb);
25380+
25381+out:
25382+ return root;
1facf9fc 25383+}
25384+
e49829fe
JR
25385+static void aufs_kill_sb(struct super_block *sb)
25386+{
25387+ struct au_sbinfo *sbinfo;
25388+
25389+ sbinfo = au_sbi(sb);
25390+ if (sbinfo) {
25391+ au_sbilist_del(sb);
25392+ aufs_write_lock(sb->s_root);
25393+ if (sbinfo->si_wbr_create_ops->fin)
25394+ sbinfo->si_wbr_create_ops->fin(sb);
25395+ if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
25396+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
027c5e7a 25397+ au_remount_refresh(sb);
e49829fe
JR
25398+ }
25399+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
25400+ au_plink_put(sb, /*verbose*/1);
25401+ au_xino_clr(sb);
1e00d052 25402+ sbinfo->si_sb = NULL;
e49829fe 25403+ aufs_write_unlock(sb->s_root);
e49829fe
JR
25404+ au_nwt_flush(&sbinfo->si_nowait);
25405+ }
25406+ generic_shutdown_super(sb);
25407+}
25408+
1facf9fc 25409+struct file_system_type aufs_fs_type = {
25410+ .name = AUFS_FSTYPE,
c06a8ce3
AM
25411+ /* a race between rename and others */
25412+ .fs_flags = FS_RENAME_DOES_D_MOVE,
027c5e7a 25413+ .mount = aufs_mount,
e49829fe 25414+ .kill_sb = aufs_kill_sb,
1facf9fc 25415+ /* no need to __module_get() and module_put(). */
25416+ .owner = THIS_MODULE,
25417+};
7f207e10
AM
25418diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
25419--- /usr/share/empty/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
25420+++ linux/fs/aufs/super.h 2014-01-20 20:16:14.742796949 +0100
25421@@ -0,0 +1,571 @@
1facf9fc 25422+/*
523b37e3 25423+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 25424+ *
25425+ * This program, aufs is free software; you can redistribute it and/or modify
25426+ * it under the terms of the GNU General Public License as published by
25427+ * the Free Software Foundation; either version 2 of the License, or
25428+ * (at your option) any later version.
dece6358
AM
25429+ *
25430+ * This program is distributed in the hope that it will be useful,
25431+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25432+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25433+ * GNU General Public License for more details.
25434+ *
25435+ * You should have received a copy of the GNU General Public License
523b37e3 25436+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 25437+ */
25438+
25439+/*
25440+ * super_block operations
25441+ */
25442+
25443+#ifndef __AUFS_SUPER_H__
25444+#define __AUFS_SUPER_H__
25445+
25446+#ifdef __KERNEL__
25447+
25448+#include <linux/fs.h>
1facf9fc 25449+#include "rwsem.h"
25450+#include "spl.h"
25451+#include "wkq.h"
25452+
25453+typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *);
25454+typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t,
25455+ loff_t *);
25456+
25457+/* policies to select one among multiple writable branches */
25458+struct au_wbr_copyup_operations {
25459+ int (*copyup)(struct dentry *dentry);
25460+};
25461+
392086de
AM
25462+#define AuWbr_DIR 1 /* target is a dir */
25463+#define AuWbr_PARENT (1 << 1) /* always require a parent */
25464+
25465+#define au_ftest_wbr(flags, name) ((flags) & AuWbr_##name)
25466+#define au_fset_wbr(flags, name) { (flags) |= AuWbr_##name; }
25467+#define au_fclr_wbr(flags, name) { (flags) &= ~AuWbr_##name; }
25468+
1facf9fc 25469+struct au_wbr_create_operations {
392086de 25470+ int (*create)(struct dentry *dentry, unsigned int flags);
1facf9fc 25471+ int (*init)(struct super_block *sb);
25472+ int (*fin)(struct super_block *sb);
25473+};
25474+
25475+struct au_wbr_mfs {
25476+ struct mutex mfs_lock; /* protect this structure */
25477+ unsigned long mfs_jiffy;
25478+ unsigned long mfs_expire;
25479+ aufs_bindex_t mfs_bindex;
25480+
25481+ unsigned long long mfsrr_bytes;
25482+ unsigned long long mfsrr_watermark;
25483+};
25484+
86dc4139
AM
25485+struct pseudo_link {
25486+ union {
25487+ struct hlist_node hlist;
25488+ struct rcu_head rcu;
25489+ };
25490+ struct inode *inode;
25491+};
25492+
25493+#define AuPlink_NHASH 100
25494+static inline int au_plink_hash(ino_t ino)
25495+{
25496+ return ino % AuPlink_NHASH;
25497+}
25498+
1facf9fc 25499+struct au_branch;
25500+struct au_sbinfo {
25501+ /* nowait tasks in the system-wide workqueue */
25502+ struct au_nowait_tasks si_nowait;
25503+
b752ccd1
AM
25504+ /*
25505+ * tried sb->s_umount, but failed due to the dependecy between i_mutex.
25506+ * rwsem for au_sbinfo is necessary.
25507+ */
dece6358 25508+ struct au_rwsem si_rwsem;
1facf9fc 25509+
b752ccd1
AM
25510+ /* prevent recursive locking in deleting inode */
25511+ struct {
25512+ unsigned long *bitmap;
25513+ spinlock_t tree_lock;
25514+ struct radix_tree_root tree;
25515+ } au_si_pid;
25516+
7f207e10 25517+ /*
523b37e3
AM
25518+ * dirty approach to protect sb->sb_inodes and ->s_files (gone) from
25519+ * remount.
7f207e10
AM
25520+ */
25521+ atomic_long_t si_ninodes, si_nfiles;
25522+
1facf9fc 25523+ /* branch management */
25524+ unsigned int si_generation;
25525+
25526+ /* see above flags */
25527+ unsigned char au_si_status;
25528+
25529+ aufs_bindex_t si_bend;
7f207e10
AM
25530+
25531+ /* dirty trick to keep br_id plus */
25532+ unsigned int si_last_br_id :
25533+ sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1;
1facf9fc 25534+ struct au_branch **si_branch;
25535+
25536+ /* policy to select a writable branch */
25537+ unsigned char si_wbr_copyup;
25538+ unsigned char si_wbr_create;
25539+ struct au_wbr_copyup_operations *si_wbr_copyup_ops;
25540+ struct au_wbr_create_operations *si_wbr_create_ops;
25541+
25542+ /* round robin */
25543+ atomic_t si_wbr_rr_next;
25544+
25545+ /* most free space */
25546+ struct au_wbr_mfs si_wbr_mfs;
25547+
25548+ /* mount flags */
25549+ /* include/asm-ia64/siginfo.h defines a macro named si_flags */
25550+ unsigned int si_mntflags;
25551+
25552+ /* external inode number (bitmap and translation table) */
25553+ au_readf_t si_xread;
25554+ au_writef_t si_xwrite;
25555+ struct file *si_xib;
25556+ struct mutex si_xib_mtx; /* protect xib members */
25557+ unsigned long *si_xib_buf;
25558+ unsigned long si_xib_last_pindex;
25559+ int si_xib_next_bit;
25560+ aufs_bindex_t si_xino_brid;
392086de
AM
25561+ unsigned long si_xino_jiffy;
25562+ unsigned long si_xino_expire;
1facf9fc 25563+ /* reserved for future use */
25564+ /* unsigned long long si_xib_limit; */ /* Max xib file size */
25565+
25566+#ifdef CONFIG_AUFS_EXPORT
25567+ /* i_generation */
25568+ struct file *si_xigen;
25569+ atomic_t si_xigen_next;
25570+#endif
25571+
25572+ /* vdir parameters */
e49829fe 25573+ unsigned long si_rdcache; /* max cache time in jiffies */
1facf9fc 25574+ unsigned int si_rdblk; /* deblk size */
25575+ unsigned int si_rdhash; /* hash size */
25576+
25577+ /*
25578+ * If the number of whiteouts are larger than si_dirwh, leave all of
25579+ * them after au_whtmp_ren to reduce the cost of rmdir(2).
25580+ * future fsck.aufs or kernel thread will remove them later.
25581+ * Otherwise, remove all whiteouts and the dir in rmdir(2).
25582+ */
25583+ unsigned int si_dirwh;
25584+
25585+ /*
25586+ * rename(2) a directory with all children.
25587+ */
25588+ /* reserved for future use */
25589+ /* int si_rendir; */
25590+
25591+ /* pseudo_link list */
86dc4139 25592+ struct au_sphlhead si_plink[AuPlink_NHASH];
1facf9fc 25593+ wait_queue_head_t si_plink_wq;
4a4d8108 25594+ spinlock_t si_plink_maint_lock;
e49829fe 25595+ pid_t si_plink_maint_pid;
1facf9fc 25596+
523b37e3
AM
25597+ /* file list */
25598+ struct au_sphlhead si_files;
25599+
1facf9fc 25600+ /*
25601+ * sysfs and lifetime management.
25602+ * this is not a small structure and it may be a waste of memory in case
25603+ * of sysfs is disabled, particulary when many aufs-es are mounted.
25604+ * but using sysfs is majority.
25605+ */
25606+ struct kobject si_kobj;
25607+#ifdef CONFIG_DEBUG_FS
86dc4139
AM
25608+ struct dentry *si_dbgaufs;
25609+ struct dentry *si_dbgaufs_plink;
25610+ struct dentry *si_dbgaufs_xib;
1facf9fc 25611+#ifdef CONFIG_AUFS_EXPORT
25612+ struct dentry *si_dbgaufs_xigen;
25613+#endif
25614+#endif
25615+
e49829fe
JR
25616+#ifdef CONFIG_AUFS_SBILIST
25617+ struct list_head si_list;
25618+#endif
25619+
1facf9fc 25620+ /* dirty, necessary for unmounting, sysfs and sysrq */
25621+ struct super_block *si_sb;
25622+};
25623+
dece6358
AM
25624+/* sbinfo status flags */
25625+/*
25626+ * set true when refresh_dirs() failed at remount time.
25627+ * then try refreshing dirs at access time again.
25628+ * if it is false, refreshing dirs at access time is unnecesary
25629+ */
027c5e7a 25630+#define AuSi_FAILED_REFRESH_DIR 1
dece6358
AM
25631+static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
25632+ unsigned int flag)
25633+{
25634+ AuRwMustAnyLock(&sbi->si_rwsem);
25635+ return sbi->au_si_status & flag;
25636+}
25637+#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name)
25638+#define au_fset_si(sbinfo, name) do { \
25639+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
25640+ (sbinfo)->au_si_status |= AuSi_##name; \
25641+} while (0)
25642+#define au_fclr_si(sbinfo, name) do { \
25643+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
25644+ (sbinfo)->au_si_status &= ~AuSi_##name; \
25645+} while (0)
25646+
1facf9fc 25647+/* ---------------------------------------------------------------------- */
25648+
25649+/* policy to select one among writable branches */
4a4d8108
AM
25650+#define AuWbrCopyup(sbinfo, ...) \
25651+ ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__))
25652+#define AuWbrCreate(sbinfo, ...) \
25653+ ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__))
1facf9fc 25654+
25655+/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
25656+#define AuLock_DW 1 /* write-lock dentry */
25657+#define AuLock_IR (1 << 1) /* read-lock inode */
25658+#define AuLock_IW (1 << 2) /* write-lock inode */
25659+#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
25660+#define AuLock_DIR (1 << 4) /* target is a dir */
e49829fe
JR
25661+#define AuLock_NOPLM (1 << 5) /* return err in plm mode */
25662+#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */
027c5e7a 25663+#define AuLock_GEN (1 << 7) /* test digen/iigen */
1facf9fc 25664+#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
7f207e10
AM
25665+#define au_fset_lock(flags, name) \
25666+ do { (flags) |= AuLock_##name; } while (0)
25667+#define au_fclr_lock(flags, name) \
25668+ do { (flags) &= ~AuLock_##name; } while (0)
1facf9fc 25669+
25670+/* ---------------------------------------------------------------------- */
25671+
25672+/* super.c */
25673+extern struct file_system_type aufs_fs_type;
25674+struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
7f207e10
AM
25675+typedef unsigned long long (*au_arraycb_t)(void *array, unsigned long long max,
25676+ void *arg);
25677+void au_array_free(void *array);
25678+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg);
25679+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
25680+void au_iarray_free(struct inode **a, unsigned long long max);
1facf9fc 25681+
25682+/* sbinfo.c */
25683+void au_si_free(struct kobject *kobj);
25684+int au_si_alloc(struct super_block *sb);
25685+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr);
25686+
25687+unsigned int au_sigen_inc(struct super_block *sb);
25688+aufs_bindex_t au_new_br_id(struct super_block *sb);
25689+
e49829fe
JR
25690+int si_read_lock(struct super_block *sb, int flags);
25691+int si_write_lock(struct super_block *sb, int flags);
25692+int aufs_read_lock(struct dentry *dentry, int flags);
1facf9fc 25693+void aufs_read_unlock(struct dentry *dentry, int flags);
25694+void aufs_write_lock(struct dentry *dentry);
25695+void aufs_write_unlock(struct dentry *dentry);
e49829fe 25696+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
1facf9fc 25697+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
25698+
b752ccd1
AM
25699+int si_pid_test_slow(struct super_block *sb);
25700+void si_pid_set_slow(struct super_block *sb);
25701+void si_pid_clr_slow(struct super_block *sb);
25702+
1facf9fc 25703+/* wbr_policy.c */
25704+extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
25705+extern struct au_wbr_create_operations au_wbr_create_ops[];
25706+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
c2b27bf2
AM
25707+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex);
25708+
25709+/* mvdown.c */
25710+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *arg);
1facf9fc 25711+
25712+/* ---------------------------------------------------------------------- */
25713+
25714+static inline struct au_sbinfo *au_sbi(struct super_block *sb)
25715+{
25716+ return sb->s_fs_info;
25717+}
25718+
25719+/* ---------------------------------------------------------------------- */
25720+
25721+#ifdef CONFIG_AUFS_EXPORT
a2a7ad62 25722+int au_test_nfsd(void);
1facf9fc 25723+void au_export_init(struct super_block *sb);
b752ccd1 25724+void au_xigen_inc(struct inode *inode);
1facf9fc 25725+int au_xigen_new(struct inode *inode);
25726+int au_xigen_set(struct super_block *sb, struct file *base);
25727+void au_xigen_clr(struct super_block *sb);
25728+
25729+static inline int au_busy_or_stale(void)
25730+{
b752ccd1 25731+ if (!au_test_nfsd())
1facf9fc 25732+ return -EBUSY;
25733+ return -ESTALE;
25734+}
25735+#else
b752ccd1 25736+AuStubInt0(au_test_nfsd, void)
a2a7ad62 25737+AuStubVoid(au_export_init, struct super_block *sb)
b752ccd1 25738+AuStubVoid(au_xigen_inc, struct inode *inode)
4a4d8108
AM
25739+AuStubInt0(au_xigen_new, struct inode *inode)
25740+AuStubInt0(au_xigen_set, struct super_block *sb, struct file *base)
25741+AuStubVoid(au_xigen_clr, struct super_block *sb)
1facf9fc 25742+static inline int au_busy_or_stale(void)
25743+{
25744+ return -EBUSY;
25745+}
25746+#endif /* CONFIG_AUFS_EXPORT */
25747+
25748+/* ---------------------------------------------------------------------- */
25749+
e49829fe
JR
25750+#ifdef CONFIG_AUFS_SBILIST
25751+/* module.c */
25752+extern struct au_splhead au_sbilist;
25753+
25754+static inline void au_sbilist_init(void)
25755+{
25756+ au_spl_init(&au_sbilist);
25757+}
25758+
25759+static inline void au_sbilist_add(struct super_block *sb)
25760+{
25761+ au_spl_add(&au_sbi(sb)->si_list, &au_sbilist);
25762+}
25763+
25764+static inline void au_sbilist_del(struct super_block *sb)
25765+{
25766+ au_spl_del(&au_sbi(sb)->si_list, &au_sbilist);
25767+}
53392da6
AM
25768+
25769+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
25770+static inline void au_sbilist_lock(void)
25771+{
25772+ spin_lock(&au_sbilist.spin);
25773+}
25774+
25775+static inline void au_sbilist_unlock(void)
25776+{
25777+ spin_unlock(&au_sbilist.spin);
25778+}
25779+#define AuGFP_SBILIST GFP_ATOMIC
25780+#else
25781+AuStubVoid(au_sbilist_lock, void)
25782+AuStubVoid(au_sbilist_unlock, void)
25783+#define AuGFP_SBILIST GFP_NOFS
25784+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
e49829fe
JR
25785+#else
25786+AuStubVoid(au_sbilist_init, void)
25787+AuStubVoid(au_sbilist_add, struct super_block*)
25788+AuStubVoid(au_sbilist_del, struct super_block*)
53392da6
AM
25789+AuStubVoid(au_sbilist_lock, void)
25790+AuStubVoid(au_sbilist_unlock, void)
25791+#define AuGFP_SBILIST GFP_NOFS
e49829fe
JR
25792+#endif
25793+
25794+/* ---------------------------------------------------------------------- */
25795+
1facf9fc 25796+static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
25797+{
dece6358
AM
25798+ /*
25799+ * This function is a dynamic '__init' fucntion actually,
25800+ * so the tiny check for si_rwsem is unnecessary.
25801+ */
25802+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
1facf9fc 25803+#ifdef CONFIG_DEBUG_FS
25804+ sbinfo->si_dbgaufs = NULL;
86dc4139 25805+ sbinfo->si_dbgaufs_plink = NULL;
1facf9fc 25806+ sbinfo->si_dbgaufs_xib = NULL;
25807+#ifdef CONFIG_AUFS_EXPORT
25808+ sbinfo->si_dbgaufs_xigen = NULL;
25809+#endif
25810+#endif
25811+}
25812+
25813+/* ---------------------------------------------------------------------- */
25814+
b752ccd1
AM
25815+static inline pid_t si_pid_bit(void)
25816+{
25817+ /* the origin of pid is 1, but the bitmap's is 0 */
25818+ return current->pid - 1;
25819+}
25820+
25821+static inline int si_pid_test(struct super_block *sb)
25822+{
25823+ pid_t bit = si_pid_bit();
25824+ if (bit < PID_MAX_DEFAULT)
25825+ return test_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
25826+ else
25827+ return si_pid_test_slow(sb);
25828+}
25829+
25830+static inline void si_pid_set(struct super_block *sb)
25831+{
25832+ pid_t bit = si_pid_bit();
25833+ if (bit < PID_MAX_DEFAULT) {
25834+ AuDebugOn(test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
25835+ set_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
25836+ /* smp_mb(); */
25837+ } else
25838+ si_pid_set_slow(sb);
25839+}
25840+
25841+static inline void si_pid_clr(struct super_block *sb)
25842+{
25843+ pid_t bit = si_pid_bit();
25844+ if (bit < PID_MAX_DEFAULT) {
25845+ AuDebugOn(!test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
25846+ clear_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
25847+ /* smp_mb(); */
25848+ } else
25849+ si_pid_clr_slow(sb);
25850+}
25851+
25852+/* ---------------------------------------------------------------------- */
25853+
1facf9fc 25854+/* lock superblock. mainly for entry point functions */
25855+/*
b752ccd1
AM
25856+ * __si_read_lock, __si_write_lock,
25857+ * __si_read_unlock, __si_write_unlock, __si_downgrade_lock
1facf9fc 25858+ */
b752ccd1 25859+AuSimpleRwsemFuncs(__si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
1facf9fc 25860+
dece6358
AM
25861+#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
25862+#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
25863+#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
25864+
b752ccd1
AM
25865+static inline void si_noflush_read_lock(struct super_block *sb)
25866+{
25867+ __si_read_lock(sb);
25868+ si_pid_set(sb);
25869+}
25870+
25871+static inline int si_noflush_read_trylock(struct super_block *sb)
25872+{
25873+ int locked = __si_read_trylock(sb);
25874+ if (locked)
25875+ si_pid_set(sb);
25876+ return locked;
25877+}
25878+
25879+static inline void si_noflush_write_lock(struct super_block *sb)
25880+{
25881+ __si_write_lock(sb);
25882+ si_pid_set(sb);
25883+}
25884+
25885+static inline int si_noflush_write_trylock(struct super_block *sb)
25886+{
25887+ int locked = __si_write_trylock(sb);
25888+ if (locked)
25889+ si_pid_set(sb);
25890+ return locked;
25891+}
25892+
e49829fe 25893+#if 0 /* unused */
1facf9fc 25894+static inline int si_read_trylock(struct super_block *sb, int flags)
25895+{
25896+ if (au_ftest_lock(flags, FLUSH))
25897+ au_nwt_flush(&au_sbi(sb)->si_nowait);
25898+ return si_noflush_read_trylock(sb);
25899+}
e49829fe 25900+#endif
1facf9fc 25901+
b752ccd1
AM
25902+static inline void si_read_unlock(struct super_block *sb)
25903+{
25904+ si_pid_clr(sb);
25905+ __si_read_unlock(sb);
25906+}
25907+
b752ccd1 25908+#if 0 /* unused */
1facf9fc 25909+static inline int si_write_trylock(struct super_block *sb, int flags)
25910+{
25911+ if (au_ftest_lock(flags, FLUSH))
25912+ au_nwt_flush(&au_sbi(sb)->si_nowait);
25913+ return si_noflush_write_trylock(sb);
25914+}
b752ccd1
AM
25915+#endif
25916+
25917+static inline void si_write_unlock(struct super_block *sb)
25918+{
25919+ si_pid_clr(sb);
25920+ __si_write_unlock(sb);
25921+}
25922+
25923+#if 0 /* unused */
25924+static inline void si_downgrade_lock(struct super_block *sb)
25925+{
25926+ __si_downgrade_lock(sb);
25927+}
25928+#endif
1facf9fc 25929+
25930+/* ---------------------------------------------------------------------- */
25931+
25932+static inline aufs_bindex_t au_sbend(struct super_block *sb)
25933+{
dece6358 25934+ SiMustAnyLock(sb);
1facf9fc 25935+ return au_sbi(sb)->si_bend;
25936+}
25937+
25938+static inline unsigned int au_mntflags(struct super_block *sb)
25939+{
dece6358 25940+ SiMustAnyLock(sb);
1facf9fc 25941+ return au_sbi(sb)->si_mntflags;
25942+}
25943+
25944+static inline unsigned int au_sigen(struct super_block *sb)
25945+{
dece6358 25946+ SiMustAnyLock(sb);
1facf9fc 25947+ return au_sbi(sb)->si_generation;
25948+}
25949+
7f207e10
AM
25950+static inline void au_ninodes_inc(struct super_block *sb)
25951+{
25952+ atomic_long_inc(&au_sbi(sb)->si_ninodes);
25953+}
25954+
25955+static inline void au_ninodes_dec(struct super_block *sb)
25956+{
25957+ AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_ninodes));
25958+ atomic_long_dec(&au_sbi(sb)->si_ninodes);
25959+}
25960+
25961+static inline void au_nfiles_inc(struct super_block *sb)
25962+{
25963+ atomic_long_inc(&au_sbi(sb)->si_nfiles);
25964+}
25965+
25966+static inline void au_nfiles_dec(struct super_block *sb)
25967+{
25968+ AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_nfiles));
25969+ atomic_long_dec(&au_sbi(sb)->si_nfiles);
25970+}
25971+
1facf9fc 25972+static inline struct au_branch *au_sbr(struct super_block *sb,
25973+ aufs_bindex_t bindex)
25974+{
dece6358 25975+ SiMustAnyLock(sb);
1facf9fc 25976+ return au_sbi(sb)->si_branch[0 + bindex];
25977+}
25978+
25979+static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid)
25980+{
dece6358 25981+ SiMustWriteLock(sb);
1facf9fc 25982+ au_sbi(sb)->si_xino_brid = brid;
25983+}
25984+
25985+static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
25986+{
dece6358 25987+ SiMustAnyLock(sb);
1facf9fc 25988+ return au_sbi(sb)->si_xino_brid;
25989+}
25990+
25991+#endif /* __KERNEL__ */
25992+#endif /* __AUFS_SUPER_H__ */
7f207e10
AM
25993diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c
25994--- /usr/share/empty/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
25995+++ linux/fs/aufs/sysaufs.c 2014-01-20 20:16:14.749463838 +0100
25996@@ -0,0 +1,104 @@
1facf9fc 25997+/*
523b37e3 25998+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 25999+ *
26000+ * This program, aufs is free software; you can redistribute it and/or modify
26001+ * it under the terms of the GNU General Public License as published by
26002+ * the Free Software Foundation; either version 2 of the License, or
26003+ * (at your option) any later version.
dece6358
AM
26004+ *
26005+ * This program is distributed in the hope that it will be useful,
26006+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26007+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26008+ * GNU General Public License for more details.
26009+ *
26010+ * You should have received a copy of the GNU General Public License
523b37e3 26011+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26012+ */
26013+
26014+/*
26015+ * sysfs interface and lifetime management
26016+ * they are necessary regardless sysfs is disabled.
26017+ */
26018+
1facf9fc 26019+#include <linux/random.h>
1facf9fc 26020+#include "aufs.h"
26021+
26022+unsigned long sysaufs_si_mask;
e49829fe 26023+struct kset *sysaufs_kset;
1facf9fc 26024+
26025+#define AuSiAttr(_name) { \
26026+ .attr = { .name = __stringify(_name), .mode = 0444 }, \
26027+ .show = sysaufs_si_##_name, \
26028+}
26029+
26030+static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
26031+struct attribute *sysaufs_si_attrs[] = {
26032+ &sysaufs_si_attr_xi_path.attr,
26033+ NULL,
26034+};
26035+
4a4d8108 26036+static const struct sysfs_ops au_sbi_ops = {
1facf9fc 26037+ .show = sysaufs_si_show
26038+};
26039+
26040+static struct kobj_type au_sbi_ktype = {
26041+ .release = au_si_free,
26042+ .sysfs_ops = &au_sbi_ops,
26043+ .default_attrs = sysaufs_si_attrs
26044+};
26045+
26046+/* ---------------------------------------------------------------------- */
26047+
26048+int sysaufs_si_init(struct au_sbinfo *sbinfo)
26049+{
26050+ int err;
26051+
e49829fe 26052+ sbinfo->si_kobj.kset = sysaufs_kset;
1facf9fc 26053+ /* cf. sysaufs_name() */
26054+ err = kobject_init_and_add
e49829fe 26055+ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL,
1facf9fc 26056+ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
26057+
26058+ dbgaufs_si_null(sbinfo);
26059+ if (!err) {
26060+ err = dbgaufs_si_init(sbinfo);
26061+ if (unlikely(err))
26062+ kobject_put(&sbinfo->si_kobj);
26063+ }
26064+ return err;
26065+}
26066+
26067+void sysaufs_fin(void)
26068+{
26069+ dbgaufs_fin();
e49829fe
JR
26070+ sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group);
26071+ kset_unregister(sysaufs_kset);
1facf9fc 26072+}
26073+
26074+int __init sysaufs_init(void)
26075+{
26076+ int err;
26077+
26078+ do {
26079+ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
26080+ } while (!sysaufs_si_mask);
26081+
4a4d8108 26082+ err = -EINVAL;
e49829fe
JR
26083+ sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
26084+ if (unlikely(!sysaufs_kset))
4a4d8108 26085+ goto out;
e49829fe
JR
26086+ err = PTR_ERR(sysaufs_kset);
26087+ if (IS_ERR(sysaufs_kset))
1facf9fc 26088+ goto out;
e49829fe 26089+ err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group);
1facf9fc 26090+ if (unlikely(err)) {
e49829fe 26091+ kset_unregister(sysaufs_kset);
1facf9fc 26092+ goto out;
26093+ }
26094+
26095+ err = dbgaufs_init();
26096+ if (unlikely(err))
26097+ sysaufs_fin();
4f0767ce 26098+out:
1facf9fc 26099+ return err;
26100+}
7f207e10
AM
26101diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h
26102--- /usr/share/empty/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
26103+++ linux/fs/aufs/sysaufs.h 2014-01-20 20:16:14.749463838 +0100
26104@@ -0,0 +1,103 @@
1facf9fc 26105+/*
523b37e3 26106+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 26107+ *
26108+ * This program, aufs is free software; you can redistribute it and/or modify
26109+ * it under the terms of the GNU General Public License as published by
26110+ * the Free Software Foundation; either version 2 of the License, or
26111+ * (at your option) any later version.
dece6358
AM
26112+ *
26113+ * This program is distributed in the hope that it will be useful,
26114+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26115+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26116+ * GNU General Public License for more details.
26117+ *
26118+ * You should have received a copy of the GNU General Public License
523b37e3 26119+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26120+ */
26121+
26122+/*
26123+ * sysfs interface and mount lifetime management
26124+ */
26125+
26126+#ifndef __SYSAUFS_H__
26127+#define __SYSAUFS_H__
26128+
26129+#ifdef __KERNEL__
26130+
1facf9fc 26131+#include <linux/sysfs.h>
1facf9fc 26132+#include "module.h"
26133+
dece6358
AM
26134+struct super_block;
26135+struct au_sbinfo;
26136+
1facf9fc 26137+struct sysaufs_si_attr {
26138+ struct attribute attr;
26139+ int (*show)(struct seq_file *seq, struct super_block *sb);
26140+};
26141+
26142+/* ---------------------------------------------------------------------- */
26143+
26144+/* sysaufs.c */
26145+extern unsigned long sysaufs_si_mask;
e49829fe 26146+extern struct kset *sysaufs_kset;
1facf9fc 26147+extern struct attribute *sysaufs_si_attrs[];
26148+int sysaufs_si_init(struct au_sbinfo *sbinfo);
26149+int __init sysaufs_init(void);
26150+void sysaufs_fin(void);
26151+
26152+/* ---------------------------------------------------------------------- */
26153+
26154+/* some people doesn't like to show a pointer in kernel */
26155+static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
26156+{
26157+ return sysaufs_si_mask ^ (unsigned long)sbinfo;
26158+}
26159+
26160+#define SysaufsSiNamePrefix "si_"
26161+#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16)
26162+static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
26163+{
26164+ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
26165+ sysaufs_si_id(sbinfo));
26166+}
26167+
26168+struct au_branch;
26169+#ifdef CONFIG_SYSFS
26170+/* sysfs.c */
26171+extern struct attribute_group *sysaufs_attr_group;
26172+
26173+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
26174+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
26175+ char *buf);
26176+
26177+void sysaufs_br_init(struct au_branch *br);
26178+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
26179+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
26180+
26181+#define sysaufs_brs_init() do {} while (0)
26182+
26183+#else
26184+#define sysaufs_attr_group NULL
26185+
4a4d8108 26186+AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb)
1facf9fc 26187+
26188+static inline
26189+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
26190+ char *buf)
26191+{
26192+ return 0;
26193+}
26194+
4a4d8108
AM
26195+AuStubVoid(sysaufs_br_init, struct au_branch *br)
26196+AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
26197+AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
1facf9fc 26198+
26199+static inline void sysaufs_brs_init(void)
26200+{
26201+ sysaufs_brs = 0;
26202+}
26203+
26204+#endif /* CONFIG_SYSFS */
26205+
26206+#endif /* __KERNEL__ */
26207+#endif /* __SYSAUFS_H__ */
7f207e10
AM
26208diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
26209--- /usr/share/empty/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
26210+++ linux/fs/aufs/sysfs.c 2014-01-20 20:16:14.749463838 +0100
26211@@ -0,0 +1,296 @@
1facf9fc 26212+/*
523b37e3 26213+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 26214+ *
26215+ * This program, aufs is free software; you can redistribute it and/or modify
26216+ * it under the terms of the GNU General Public License as published by
26217+ * the Free Software Foundation; either version 2 of the License, or
26218+ * (at your option) any later version.
dece6358
AM
26219+ *
26220+ * This program is distributed in the hope that it will be useful,
26221+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26222+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26223+ * GNU General Public License for more details.
26224+ *
26225+ * You should have received a copy of the GNU General Public License
523b37e3 26226+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26227+ */
26228+
26229+/*
26230+ * sysfs interface
26231+ */
26232+
1facf9fc 26233+#include <linux/seq_file.h>
1facf9fc 26234+#include "aufs.h"
26235+
4a4d8108
AM
26236+#ifdef CONFIG_AUFS_FS_MODULE
26237+/* this entry violates the "one line per file" policy of sysfs */
26238+static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr,
26239+ char *buf)
26240+{
26241+ ssize_t err;
26242+ static char *conf =
26243+/* this file is generated at compiling */
26244+#include "conf.str"
26245+ ;
26246+
26247+ err = snprintf(buf, PAGE_SIZE, conf);
26248+ if (unlikely(err >= PAGE_SIZE))
26249+ err = -EFBIG;
26250+ return err;
26251+}
26252+
26253+static struct kobj_attribute au_config_attr = __ATTR_RO(config);
26254+#endif
26255+
1facf9fc 26256+static struct attribute *au_attr[] = {
4a4d8108
AM
26257+#ifdef CONFIG_AUFS_FS_MODULE
26258+ &au_config_attr.attr,
26259+#endif
1facf9fc 26260+ NULL, /* need to NULL terminate the list of attributes */
26261+};
26262+
26263+static struct attribute_group sysaufs_attr_group_body = {
26264+ .attrs = au_attr
26265+};
26266+
26267+struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
26268+
26269+/* ---------------------------------------------------------------------- */
26270+
26271+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
26272+{
26273+ int err;
26274+
dece6358
AM
26275+ SiMustAnyLock(sb);
26276+
1facf9fc 26277+ err = 0;
26278+ if (au_opt_test(au_mntflags(sb), XINO)) {
26279+ err = au_xino_path(seq, au_sbi(sb)->si_xib);
26280+ seq_putc(seq, '\n');
26281+ }
26282+ return err;
26283+}
26284+
26285+/*
26286+ * the lifetime of branch is independent from the entry under sysfs.
26287+ * sysfs handles the lifetime of the entry, and never call ->show() after it is
26288+ * unlinked.
26289+ */
26290+static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
392086de 26291+ aufs_bindex_t bindex, int idx)
1facf9fc 26292+{
1e00d052 26293+ int err;
1facf9fc 26294+ struct path path;
26295+ struct dentry *root;
26296+ struct au_branch *br;
1e00d052 26297+ char *perm;
1facf9fc 26298+
26299+ AuDbg("b%d\n", bindex);
26300+
1e00d052 26301+ err = 0;
1facf9fc 26302+ root = sb->s_root;
26303+ di_read_lock_parent(root, !AuLock_IR);
26304+ br = au_sbr(sb, bindex);
392086de
AM
26305+
26306+ switch (idx) {
26307+ case AuBrSysfs_BR:
26308+ path.mnt = au_br_mnt(br);
26309+ path.dentry = au_h_dptr(root, bindex);
26310+ au_seq_path(seq, &path);
26311+ di_read_unlock(root, !AuLock_IR);
26312+ perm = au_optstr_br_perm(br->br_perm);
26313+ if (perm) {
26314+ err = seq_printf(seq, "=%s\n", perm);
26315+ kfree(perm);
26316+ if (err == -1)
26317+ err = -E2BIG;
26318+ } else
26319+ err = -ENOMEM;
26320+ break;
26321+ case AuBrSysfs_BRID:
26322+ err = seq_printf(seq, "%d\n", br->br_id);
26323+ di_read_unlock(root, !AuLock_IR);
1e00d052
AM
26324+ if (err == -1)
26325+ err = -E2BIG;
392086de
AM
26326+ break;
26327+ }
26328+
1e00d052 26329+ return err;
1facf9fc 26330+}
26331+
26332+/* ---------------------------------------------------------------------- */
26333+
26334+static struct seq_file *au_seq(char *p, ssize_t len)
26335+{
26336+ struct seq_file *seq;
26337+
26338+ seq = kzalloc(sizeof(*seq), GFP_NOFS);
26339+ if (seq) {
26340+ /* mutex_init(&seq.lock); */
26341+ seq->buf = p;
26342+ seq->size = len;
26343+ return seq; /* success */
26344+ }
26345+
26346+ seq = ERR_PTR(-ENOMEM);
26347+ return seq;
26348+}
26349+
392086de
AM
26350+#define SysaufsBr_PREFIX "br"
26351+#define SysaufsBrid_PREFIX "brid"
1facf9fc 26352+
26353+/* todo: file size may exceed PAGE_SIZE */
26354+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
1308ab2a 26355+ char *buf)
1facf9fc 26356+{
26357+ ssize_t err;
392086de 26358+ int idx;
1facf9fc 26359+ long l;
26360+ aufs_bindex_t bend;
26361+ struct au_sbinfo *sbinfo;
26362+ struct super_block *sb;
26363+ struct seq_file *seq;
26364+ char *name;
26365+ struct attribute **cattr;
26366+
26367+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
26368+ sb = sbinfo->si_sb;
1308ab2a 26369+
26370+ /*
26371+ * prevent a race condition between sysfs and aufs.
26372+ * for instance, sysfs_file_read() calls sysfs_get_active_two() which
26373+ * prohibits maintaining the sysfs entries.
26374+ * hew we acquire read lock after sysfs_get_active_two().
26375+ * on the other hand, the remount process may maintain the sysfs/aufs
26376+ * entries after acquiring write lock.
26377+ * it can cause a deadlock.
26378+ * simply we gave up processing read here.
26379+ */
26380+ err = -EBUSY;
26381+ if (unlikely(!si_noflush_read_trylock(sb)))
26382+ goto out;
1facf9fc 26383+
26384+ seq = au_seq(buf, PAGE_SIZE);
26385+ err = PTR_ERR(seq);
26386+ if (IS_ERR(seq))
1308ab2a 26387+ goto out_unlock;
1facf9fc 26388+
26389+ name = (void *)attr->name;
26390+ cattr = sysaufs_si_attrs;
26391+ while (*cattr) {
26392+ if (!strcmp(name, (*cattr)->name)) {
26393+ err = container_of(*cattr, struct sysaufs_si_attr, attr)
26394+ ->show(seq, sb);
26395+ goto out_seq;
26396+ }
26397+ cattr++;
26398+ }
26399+
392086de
AM
26400+ if (!strncmp(name, SysaufsBrid_PREFIX,
26401+ sizeof(SysaufsBrid_PREFIX) - 1)) {
26402+ idx = AuBrSysfs_BRID;
26403+ name += sizeof(SysaufsBrid_PREFIX) - 1;
26404+ } else if (!strncmp(name, SysaufsBr_PREFIX,
26405+ sizeof(SysaufsBr_PREFIX) - 1)) {
26406+ idx = AuBrSysfs_BR;
1facf9fc 26407+ name += sizeof(SysaufsBr_PREFIX) - 1;
392086de
AM
26408+ } else
26409+ BUG();
26410+
26411+ err = kstrtol(name, 10, &l);
26412+ if (!err) {
26413+ bend = au_sbend(sb);
26414+ if (l <= bend)
26415+ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l, idx);
26416+ else
26417+ err = -ENOENT;
1facf9fc 26418+ }
1facf9fc 26419+
4f0767ce 26420+out_seq:
1facf9fc 26421+ if (!err) {
26422+ err = seq->count;
26423+ /* sysfs limit */
26424+ if (unlikely(err == PAGE_SIZE))
26425+ err = -EFBIG;
26426+ }
26427+ kfree(seq);
4f0767ce 26428+out_unlock:
1facf9fc 26429+ si_read_unlock(sb);
4f0767ce 26430+out:
1facf9fc 26431+ return err;
26432+}
26433+
26434+/* ---------------------------------------------------------------------- */
26435+
26436+void sysaufs_br_init(struct au_branch *br)
26437+{
392086de
AM
26438+ int i;
26439+ struct au_brsysfs *br_sysfs;
26440+ struct attribute *attr;
4a4d8108 26441+
392086de
AM
26442+ br_sysfs = br->br_sysfs;
26443+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
26444+ attr = &br_sysfs->attr;
26445+ sysfs_attr_init(attr);
26446+ attr->name = br_sysfs->name;
26447+ attr->mode = S_IRUGO;
26448+ br_sysfs++;
26449+ }
1facf9fc 26450+}
26451+
26452+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
26453+{
26454+ struct au_branch *br;
26455+ struct kobject *kobj;
392086de
AM
26456+ struct au_brsysfs *br_sysfs;
26457+ int i;
1facf9fc 26458+ aufs_bindex_t bend;
26459+
26460+ dbgaufs_brs_del(sb, bindex);
26461+
26462+ if (!sysaufs_brs)
26463+ return;
26464+
26465+ kobj = &au_sbi(sb)->si_kobj;
26466+ bend = au_sbend(sb);
26467+ for (; bindex <= bend; bindex++) {
26468+ br = au_sbr(sb, bindex);
392086de
AM
26469+ br_sysfs = br->br_sysfs;
26470+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
26471+ sysfs_remove_file(kobj, &br_sysfs->attr);
26472+ br_sysfs++;
26473+ }
1facf9fc 26474+ }
26475+}
26476+
26477+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
26478+{
392086de 26479+ int err, i;
1facf9fc 26480+ aufs_bindex_t bend;
26481+ struct kobject *kobj;
26482+ struct au_branch *br;
392086de 26483+ struct au_brsysfs *br_sysfs;
1facf9fc 26484+
26485+ dbgaufs_brs_add(sb, bindex);
26486+
26487+ if (!sysaufs_brs)
26488+ return;
26489+
26490+ kobj = &au_sbi(sb)->si_kobj;
26491+ bend = au_sbend(sb);
26492+ for (; bindex <= bend; bindex++) {
26493+ br = au_sbr(sb, bindex);
392086de
AM
26494+ br_sysfs = br->br_sysfs;
26495+ snprintf(br_sysfs[AuBrSysfs_BR].name, sizeof(br_sysfs->name),
26496+ SysaufsBr_PREFIX "%d", bindex);
26497+ snprintf(br_sysfs[AuBrSysfs_BRID].name, sizeof(br_sysfs->name),
26498+ SysaufsBrid_PREFIX "%d", bindex);
26499+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
26500+ err = sysfs_create_file(kobj, &br_sysfs->attr);
26501+ if (unlikely(err))
26502+ pr_warn("failed %s under sysfs(%d)\n",
26503+ br_sysfs->name, err);
26504+ br_sysfs++;
26505+ }
1facf9fc 26506+ }
26507+}
7f207e10
AM
26508diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
26509--- /usr/share/empty/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
26510+++ linux/fs/aufs/sysrq.c 2014-01-20 20:16:14.749463838 +0100
26511@@ -0,0 +1,154 @@
1facf9fc 26512+/*
523b37e3 26513+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 26514+ *
26515+ * This program, aufs is free software; you can redistribute it and/or modify
26516+ * it under the terms of the GNU General Public License as published by
26517+ * the Free Software Foundation; either version 2 of the License, or
26518+ * (at your option) any later version.
dece6358
AM
26519+ *
26520+ * This program is distributed in the hope that it will be useful,
26521+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26522+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26523+ * GNU General Public License for more details.
26524+ *
26525+ * You should have received a copy of the GNU General Public License
523b37e3 26526+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26527+ */
26528+
26529+/*
26530+ * magic sysrq hanlder
26531+ */
26532+
1facf9fc 26533+/* #include <linux/sysrq.h> */
027c5e7a 26534+#include <linux/writeback.h>
1facf9fc 26535+#include "aufs.h"
26536+
26537+/* ---------------------------------------------------------------------- */
26538+
26539+static void sysrq_sb(struct super_block *sb)
26540+{
26541+ char *plevel;
26542+ struct au_sbinfo *sbinfo;
26543+ struct file *file;
523b37e3
AM
26544+ struct au_sphlhead *files;
26545+ struct au_finfo *finfo;
1facf9fc 26546+
26547+ plevel = au_plevel;
26548+ au_plevel = KERN_WARNING;
1facf9fc 26549+
4a4d8108 26550+ /* since we define pr_fmt, call printk directly */
c06a8ce3
AM
26551+#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str)
26552+
26553+ sbinfo = au_sbi(sb);
4a4d8108 26554+ printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo));
c06a8ce3 26555+ pr("superblock\n");
1facf9fc 26556+ au_dpri_sb(sb);
027c5e7a
AM
26557+
26558+#if 0
c06a8ce3 26559+ pr("root dentry\n");
1facf9fc 26560+ au_dpri_dentry(sb->s_root);
c06a8ce3 26561+ pr("root inode\n");
1facf9fc 26562+ au_dpri_inode(sb->s_root->d_inode);
027c5e7a
AM
26563+#endif
26564+
1facf9fc 26565+#if 0
027c5e7a
AM
26566+ do {
26567+ int err, i, j, ndentry;
26568+ struct au_dcsub_pages dpages;
26569+ struct au_dpage *dpage;
26570+
26571+ err = au_dpages_init(&dpages, GFP_ATOMIC);
26572+ if (unlikely(err))
26573+ break;
26574+ err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL);
26575+ if (!err)
26576+ for (i = 0; i < dpages.ndpage; i++) {
26577+ dpage = dpages.dpages + i;
26578+ ndentry = dpage->ndentry;
26579+ for (j = 0; j < ndentry; j++)
26580+ au_dpri_dentry(dpage->dentries[j]);
26581+ }
26582+ au_dpages_free(&dpages);
26583+ } while (0);
26584+#endif
26585+
26586+#if 1
26587+ {
26588+ struct inode *i;
c06a8ce3 26589+ pr("isolated inode\n");
2cbb1c4b
JR
26590+ spin_lock(&inode_sb_list_lock);
26591+ list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
26592+ spin_lock(&i->i_lock);
b4510431 26593+ if (1 || hlist_empty(&i->i_dentry))
027c5e7a 26594+ au_dpri_inode(i);
2cbb1c4b
JR
26595+ spin_unlock(&i->i_lock);
26596+ }
26597+ spin_unlock(&inode_sb_list_lock);
027c5e7a 26598+ }
1facf9fc 26599+#endif
c06a8ce3 26600+ pr("files\n");
523b37e3
AM
26601+ files = &au_sbi(sb)->si_files;
26602+ spin_lock(&files->spin);
26603+ hlist_for_each_entry(finfo, &files->head, fi_hlist) {
4a4d8108 26604+ umode_t mode;
523b37e3 26605+ file = finfo->fi_file;
c06a8ce3 26606+ mode = file_inode(file)->i_mode;
4a4d8108 26607+ if (!special_file(mode) || au_special_file(mode))
1facf9fc 26608+ au_dpri_file(file);
523b37e3
AM
26609+ }
26610+ spin_unlock(&files->spin);
c06a8ce3 26611+ pr("done\n");
1facf9fc 26612+
c06a8ce3 26613+#undef pr
1facf9fc 26614+ au_plevel = plevel;
1facf9fc 26615+}
26616+
26617+/* ---------------------------------------------------------------------- */
26618+
26619+/* module parameter */
26620+static char *aufs_sysrq_key = "a";
26621+module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO);
26622+MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
26623+
0c5527e5 26624+static void au_sysrq(int key __maybe_unused)
1facf9fc 26625+{
1facf9fc 26626+ struct au_sbinfo *sbinfo;
26627+
027c5e7a 26628+ lockdep_off();
53392da6 26629+ au_sbilist_lock();
e49829fe 26630+ list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
1facf9fc 26631+ sysrq_sb(sbinfo->si_sb);
53392da6 26632+ au_sbilist_unlock();
027c5e7a 26633+ lockdep_on();
1facf9fc 26634+}
26635+
26636+static struct sysrq_key_op au_sysrq_op = {
26637+ .handler = au_sysrq,
26638+ .help_msg = "Aufs",
26639+ .action_msg = "Aufs",
26640+ .enable_mask = SYSRQ_ENABLE_DUMP
26641+};
26642+
26643+/* ---------------------------------------------------------------------- */
26644+
26645+int __init au_sysrq_init(void)
26646+{
26647+ int err;
26648+ char key;
26649+
26650+ err = -1;
26651+ key = *aufs_sysrq_key;
26652+ if ('a' <= key && key <= 'z')
26653+ err = register_sysrq_key(key, &au_sysrq_op);
26654+ if (unlikely(err))
4a4d8108 26655+ pr_err("err %d, sysrq=%c\n", err, key);
1facf9fc 26656+ return err;
26657+}
26658+
26659+void au_sysrq_fin(void)
26660+{
26661+ int err;
26662+ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
26663+ if (unlikely(err))
4a4d8108 26664+ pr_err("err %d (ignored)\n", err);
1facf9fc 26665+}
7f207e10
AM
26666diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
26667--- /usr/share/empty/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
26668+++ linux/fs/aufs/vdir.c 2014-01-20 20:16:14.749463838 +0100
26669@@ -0,0 +1,887 @@
1facf9fc 26670+/*
523b37e3 26671+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 26672+ *
26673+ * This program, aufs is free software; you can redistribute it and/or modify
26674+ * it under the terms of the GNU General Public License as published by
26675+ * the Free Software Foundation; either version 2 of the License, or
26676+ * (at your option) any later version.
dece6358
AM
26677+ *
26678+ * This program is distributed in the hope that it will be useful,
26679+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26680+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26681+ * GNU General Public License for more details.
26682+ *
26683+ * You should have received a copy of the GNU General Public License
523b37e3 26684+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26685+ */
26686+
26687+/*
26688+ * virtual or vertical directory
26689+ */
26690+
26691+#include "aufs.h"
26692+
dece6358 26693+static unsigned int calc_size(int nlen)
1facf9fc 26694+{
dece6358 26695+ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
1facf9fc 26696+}
26697+
26698+static int set_deblk_end(union au_vdir_deblk_p *p,
26699+ union au_vdir_deblk_p *deblk_end)
26700+{
26701+ if (calc_size(0) <= deblk_end->deblk - p->deblk) {
26702+ p->de->de_str.len = 0;
26703+ /* smp_mb(); */
26704+ return 0;
26705+ }
26706+ return -1; /* error */
26707+}
26708+
26709+/* returns true or false */
26710+static int is_deblk_end(union au_vdir_deblk_p *p,
26711+ union au_vdir_deblk_p *deblk_end)
26712+{
26713+ if (calc_size(0) <= deblk_end->deblk - p->deblk)
26714+ return !p->de->de_str.len;
26715+ return 1;
26716+}
26717+
26718+static unsigned char *last_deblk(struct au_vdir *vdir)
26719+{
26720+ return vdir->vd_deblk[vdir->vd_nblk - 1];
26721+}
26722+
26723+/* ---------------------------------------------------------------------- */
26724+
1308ab2a 26725+/* estimate the apropriate size for name hash table */
26726+unsigned int au_rdhash_est(loff_t sz)
26727+{
26728+ unsigned int n;
26729+
26730+ n = UINT_MAX;
26731+ sz >>= 10;
26732+ if (sz < n)
26733+ n = sz;
26734+ if (sz < AUFS_RDHASH_DEF)
26735+ n = AUFS_RDHASH_DEF;
4a4d8108 26736+ /* pr_info("n %u\n", n); */
1308ab2a 26737+ return n;
26738+}
26739+
1facf9fc 26740+/*
26741+ * the allocated memory has to be freed by
dece6358 26742+ * au_nhash_wh_free() or au_nhash_de_free().
1facf9fc 26743+ */
dece6358 26744+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
1facf9fc 26745+{
1facf9fc 26746+ struct hlist_head *head;
dece6358 26747+ unsigned int u;
1facf9fc 26748+
dece6358
AM
26749+ head = kmalloc(sizeof(*nhash->nh_head) * num_hash, gfp);
26750+ if (head) {
26751+ nhash->nh_num = num_hash;
26752+ nhash->nh_head = head;
26753+ for (u = 0; u < num_hash; u++)
1facf9fc 26754+ INIT_HLIST_HEAD(head++);
dece6358 26755+ return 0; /* success */
1facf9fc 26756+ }
1facf9fc 26757+
dece6358 26758+ return -ENOMEM;
1facf9fc 26759+}
26760+
dece6358
AM
26761+static void nhash_count(struct hlist_head *head)
26762+{
26763+#if 0
26764+ unsigned long n;
26765+ struct hlist_node *pos;
26766+
26767+ n = 0;
26768+ hlist_for_each(pos, head)
26769+ n++;
4a4d8108 26770+ pr_info("%lu\n", n);
dece6358
AM
26771+#endif
26772+}
26773+
26774+static void au_nhash_wh_do_free(struct hlist_head *head)
1facf9fc 26775+{
c06a8ce3
AM
26776+ struct au_vdir_wh *pos;
26777+ struct hlist_node *node;
1facf9fc 26778+
c06a8ce3
AM
26779+ hlist_for_each_entry_safe(pos, node, head, wh_hash)
26780+ kfree(pos);
1facf9fc 26781+}
26782+
dece6358 26783+static void au_nhash_de_do_free(struct hlist_head *head)
1facf9fc 26784+{
c06a8ce3
AM
26785+ struct au_vdir_dehstr *pos;
26786+ struct hlist_node *node;
1facf9fc 26787+
c06a8ce3
AM
26788+ hlist_for_each_entry_safe(pos, node, head, hash)
26789+ au_cache_free_vdir_dehstr(pos);
1facf9fc 26790+}
26791+
dece6358
AM
26792+static void au_nhash_do_free(struct au_nhash *nhash,
26793+ void (*free)(struct hlist_head *head))
1facf9fc 26794+{
1308ab2a 26795+ unsigned int n;
1facf9fc 26796+ struct hlist_head *head;
1facf9fc 26797+
dece6358 26798+ n = nhash->nh_num;
1308ab2a 26799+ if (!n)
26800+ return;
26801+
dece6358 26802+ head = nhash->nh_head;
1308ab2a 26803+ while (n-- > 0) {
dece6358
AM
26804+ nhash_count(head);
26805+ free(head++);
1facf9fc 26806+ }
dece6358 26807+ kfree(nhash->nh_head);
1facf9fc 26808+}
26809+
dece6358 26810+void au_nhash_wh_free(struct au_nhash *whlist)
1facf9fc 26811+{
dece6358
AM
26812+ au_nhash_do_free(whlist, au_nhash_wh_do_free);
26813+}
1facf9fc 26814+
dece6358
AM
26815+static void au_nhash_de_free(struct au_nhash *delist)
26816+{
26817+ au_nhash_do_free(delist, au_nhash_de_do_free);
1facf9fc 26818+}
26819+
26820+/* ---------------------------------------------------------------------- */
26821+
26822+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
26823+ int limit)
26824+{
26825+ int num;
26826+ unsigned int u, n;
26827+ struct hlist_head *head;
c06a8ce3 26828+ struct au_vdir_wh *pos;
1facf9fc 26829+
26830+ num = 0;
26831+ n = whlist->nh_num;
26832+ head = whlist->nh_head;
1308ab2a 26833+ for (u = 0; u < n; u++, head++)
c06a8ce3
AM
26834+ hlist_for_each_entry(pos, head, wh_hash)
26835+ if (pos->wh_bindex == btgt && ++num > limit)
1facf9fc 26836+ return 1;
1facf9fc 26837+ return 0;
26838+}
26839+
26840+static struct hlist_head *au_name_hash(struct au_nhash *nhash,
dece6358 26841+ unsigned char *name,
1facf9fc 26842+ unsigned int len)
26843+{
dece6358
AM
26844+ unsigned int v;
26845+ /* const unsigned int magic_bit = 12; */
26846+
1308ab2a 26847+ AuDebugOn(!nhash->nh_num || !nhash->nh_head);
26848+
dece6358
AM
26849+ v = 0;
26850+ while (len--)
26851+ v += *name++;
26852+ /* v = hash_long(v, magic_bit); */
26853+ v %= nhash->nh_num;
26854+ return nhash->nh_head + v;
26855+}
26856+
26857+static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
26858+ int nlen)
26859+{
26860+ return str->len == nlen && !memcmp(str->name, name, nlen);
1facf9fc 26861+}
26862+
26863+/* returns found or not */
dece6358 26864+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
1facf9fc 26865+{
26866+ struct hlist_head *head;
c06a8ce3 26867+ struct au_vdir_wh *pos;
1facf9fc 26868+ struct au_vdir_destr *str;
26869+
dece6358 26870+ head = au_name_hash(whlist, name, nlen);
c06a8ce3
AM
26871+ hlist_for_each_entry(pos, head, wh_hash) {
26872+ str = &pos->wh_str;
1facf9fc 26873+ AuDbg("%.*s\n", str->len, str->name);
dece6358
AM
26874+ if (au_nhash_test_name(str, name, nlen))
26875+ return 1;
26876+ }
26877+ return 0;
26878+}
26879+
26880+/* returns found(true) or not */
26881+static int test_known(struct au_nhash *delist, char *name, int nlen)
26882+{
26883+ struct hlist_head *head;
c06a8ce3 26884+ struct au_vdir_dehstr *pos;
dece6358
AM
26885+ struct au_vdir_destr *str;
26886+
26887+ head = au_name_hash(delist, name, nlen);
c06a8ce3
AM
26888+ hlist_for_each_entry(pos, head, hash) {
26889+ str = pos->str;
dece6358
AM
26890+ AuDbg("%.*s\n", str->len, str->name);
26891+ if (au_nhash_test_name(str, name, nlen))
1facf9fc 26892+ return 1;
26893+ }
26894+ return 0;
26895+}
26896+
dece6358
AM
26897+static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
26898+ unsigned char d_type)
26899+{
26900+#ifdef CONFIG_AUFS_SHWH
26901+ wh->wh_ino = ino;
26902+ wh->wh_type = d_type;
26903+#endif
26904+}
26905+
26906+/* ---------------------------------------------------------------------- */
26907+
26908+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
26909+ unsigned int d_type, aufs_bindex_t bindex,
26910+ unsigned char shwh)
1facf9fc 26911+{
26912+ int err;
26913+ struct au_vdir_destr *str;
26914+ struct au_vdir_wh *wh;
26915+
dece6358 26916+ AuDbg("%.*s\n", nlen, name);
1308ab2a 26917+ AuDebugOn(!whlist->nh_num || !whlist->nh_head);
26918+
1facf9fc 26919+ err = -ENOMEM;
dece6358 26920+ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
1facf9fc 26921+ if (unlikely(!wh))
26922+ goto out;
26923+
26924+ err = 0;
26925+ wh->wh_bindex = bindex;
dece6358
AM
26926+ if (shwh)
26927+ au_shwh_init_wh(wh, ino, d_type);
1facf9fc 26928+ str = &wh->wh_str;
dece6358
AM
26929+ str->len = nlen;
26930+ memcpy(str->name, name, nlen);
26931+ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
1facf9fc 26932+ /* smp_mb(); */
26933+
4f0767ce 26934+out:
1facf9fc 26935+ return err;
26936+}
26937+
1facf9fc 26938+static int append_deblk(struct au_vdir *vdir)
26939+{
26940+ int err;
dece6358 26941+ unsigned long ul;
1facf9fc 26942+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
26943+ union au_vdir_deblk_p p, deblk_end;
26944+ unsigned char **o;
26945+
26946+ err = -ENOMEM;
dece6358
AM
26947+ o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
26948+ GFP_NOFS);
1facf9fc 26949+ if (unlikely(!o))
26950+ goto out;
26951+
26952+ vdir->vd_deblk = o;
26953+ p.deblk = kmalloc(deblk_sz, GFP_NOFS);
26954+ if (p.deblk) {
26955+ ul = vdir->vd_nblk++;
26956+ vdir->vd_deblk[ul] = p.deblk;
26957+ vdir->vd_last.ul = ul;
26958+ vdir->vd_last.p.deblk = p.deblk;
26959+ deblk_end.deblk = p.deblk + deblk_sz;
26960+ err = set_deblk_end(&p, &deblk_end);
26961+ }
26962+
4f0767ce 26963+out:
1facf9fc 26964+ return err;
26965+}
26966+
dece6358
AM
26967+static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
26968+ unsigned int d_type, struct au_nhash *delist)
26969+{
26970+ int err;
26971+ unsigned int sz;
26972+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
26973+ union au_vdir_deblk_p p, *room, deblk_end;
26974+ struct au_vdir_dehstr *dehstr;
26975+
26976+ p.deblk = last_deblk(vdir);
26977+ deblk_end.deblk = p.deblk + deblk_sz;
26978+ room = &vdir->vd_last.p;
26979+ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
26980+ || !is_deblk_end(room, &deblk_end));
26981+
26982+ sz = calc_size(nlen);
26983+ if (unlikely(sz > deblk_end.deblk - room->deblk)) {
26984+ err = append_deblk(vdir);
26985+ if (unlikely(err))
26986+ goto out;
26987+
26988+ p.deblk = last_deblk(vdir);
26989+ deblk_end.deblk = p.deblk + deblk_sz;
26990+ /* smp_mb(); */
26991+ AuDebugOn(room->deblk != p.deblk);
26992+ }
26993+
26994+ err = -ENOMEM;
4a4d8108 26995+ dehstr = au_cache_alloc_vdir_dehstr();
dece6358
AM
26996+ if (unlikely(!dehstr))
26997+ goto out;
26998+
26999+ dehstr->str = &room->de->de_str;
27000+ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
27001+ room->de->de_ino = ino;
27002+ room->de->de_type = d_type;
27003+ room->de->de_str.len = nlen;
27004+ memcpy(room->de->de_str.name, name, nlen);
27005+
27006+ err = 0;
27007+ room->deblk += sz;
27008+ if (unlikely(set_deblk_end(room, &deblk_end)))
27009+ err = append_deblk(vdir);
27010+ /* smp_mb(); */
27011+
4f0767ce 27012+out:
dece6358
AM
27013+ return err;
27014+}
27015+
27016+/* ---------------------------------------------------------------------- */
27017+
27018+void au_vdir_free(struct au_vdir *vdir)
27019+{
27020+ unsigned char **deblk;
27021+
27022+ deblk = vdir->vd_deblk;
27023+ while (vdir->vd_nblk--)
27024+ kfree(*deblk++);
27025+ kfree(vdir->vd_deblk);
27026+ au_cache_free_vdir(vdir);
27027+}
27028+
1308ab2a 27029+static struct au_vdir *alloc_vdir(struct file *file)
1facf9fc 27030+{
27031+ struct au_vdir *vdir;
1308ab2a 27032+ struct super_block *sb;
1facf9fc 27033+ int err;
27034+
1308ab2a 27035+ sb = file->f_dentry->d_sb;
dece6358
AM
27036+ SiMustAnyLock(sb);
27037+
1facf9fc 27038+ err = -ENOMEM;
27039+ vdir = au_cache_alloc_vdir();
27040+ if (unlikely(!vdir))
27041+ goto out;
27042+
27043+ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
27044+ if (unlikely(!vdir->vd_deblk))
27045+ goto out_free;
27046+
27047+ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
1308ab2a 27048+ if (!vdir->vd_deblk_sz) {
27049+ /* estimate the apropriate size for deblk */
27050+ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
4a4d8108 27051+ /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
1308ab2a 27052+ }
1facf9fc 27053+ vdir->vd_nblk = 0;
27054+ vdir->vd_version = 0;
27055+ vdir->vd_jiffy = 0;
27056+ err = append_deblk(vdir);
27057+ if (!err)
27058+ return vdir; /* success */
27059+
27060+ kfree(vdir->vd_deblk);
27061+
4f0767ce 27062+out_free:
1facf9fc 27063+ au_cache_free_vdir(vdir);
4f0767ce 27064+out:
1facf9fc 27065+ vdir = ERR_PTR(err);
27066+ return vdir;
27067+}
27068+
27069+static int reinit_vdir(struct au_vdir *vdir)
27070+{
27071+ int err;
27072+ union au_vdir_deblk_p p, deblk_end;
27073+
27074+ while (vdir->vd_nblk > 1) {
27075+ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
27076+ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
27077+ vdir->vd_nblk--;
27078+ }
27079+ p.deblk = vdir->vd_deblk[0];
27080+ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
27081+ err = set_deblk_end(&p, &deblk_end);
27082+ /* keep vd_dblk_sz */
27083+ vdir->vd_last.ul = 0;
27084+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
27085+ vdir->vd_version = 0;
27086+ vdir->vd_jiffy = 0;
27087+ /* smp_mb(); */
27088+ return err;
27089+}
27090+
27091+/* ---------------------------------------------------------------------- */
27092+
1facf9fc 27093+#define AuFillVdir_CALLED 1
27094+#define AuFillVdir_WHABLE (1 << 1)
dece6358 27095+#define AuFillVdir_SHWH (1 << 2)
1facf9fc 27096+#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
7f207e10
AM
27097+#define au_fset_fillvdir(flags, name) \
27098+ do { (flags) |= AuFillVdir_##name; } while (0)
27099+#define au_fclr_fillvdir(flags, name) \
27100+ do { (flags) &= ~AuFillVdir_##name; } while (0)
1facf9fc 27101+
dece6358
AM
27102+#ifndef CONFIG_AUFS_SHWH
27103+#undef AuFillVdir_SHWH
27104+#define AuFillVdir_SHWH 0
27105+#endif
27106+
1facf9fc 27107+struct fillvdir_arg {
392086de 27108+ struct dir_context ctx;
1facf9fc 27109+ struct file *file;
27110+ struct au_vdir *vdir;
dece6358
AM
27111+ struct au_nhash delist;
27112+ struct au_nhash whlist;
1facf9fc 27113+ aufs_bindex_t bindex;
27114+ unsigned int flags;
27115+ int err;
27116+};
27117+
392086de 27118+static int fillvdir(struct dir_context *ctx, const char *__name, int nlen,
1facf9fc 27119+ loff_t offset __maybe_unused, u64 h_ino,
27120+ unsigned int d_type)
27121+{
392086de 27122+ struct fillvdir_arg *arg = container_of(ctx, struct fillvdir_arg, ctx);
1facf9fc 27123+ char *name = (void *)__name;
27124+ struct super_block *sb;
1facf9fc 27125+ ino_t ino;
dece6358 27126+ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
1facf9fc 27127+
1facf9fc 27128+ arg->err = 0;
dece6358 27129+ sb = arg->file->f_dentry->d_sb;
1facf9fc 27130+ au_fset_fillvdir(arg->flags, CALLED);
27131+ /* smp_mb(); */
dece6358 27132+ if (nlen <= AUFS_WH_PFX_LEN
1facf9fc 27133+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
dece6358
AM
27134+ if (test_known(&arg->delist, name, nlen)
27135+ || au_nhash_test_known_wh(&arg->whlist, name, nlen))
27136+ goto out; /* already exists or whiteouted */
1facf9fc 27137+
27138+ sb = arg->file->f_dentry->d_sb;
dece6358 27139+ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
4a4d8108
AM
27140+ if (!arg->err) {
27141+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
27142+ d_type = DT_UNKNOWN;
dece6358
AM
27143+ arg->err = append_de(arg->vdir, name, nlen, ino,
27144+ d_type, &arg->delist);
4a4d8108 27145+ }
1facf9fc 27146+ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
27147+ name += AUFS_WH_PFX_LEN;
dece6358
AM
27148+ nlen -= AUFS_WH_PFX_LEN;
27149+ if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
27150+ goto out; /* already whiteouted */
1facf9fc 27151+
dece6358
AM
27152+ if (shwh)
27153+ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
27154+ &ino);
4a4d8108
AM
27155+ if (!arg->err) {
27156+ if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
27157+ d_type = DT_UNKNOWN;
1facf9fc 27158+ arg->err = au_nhash_append_wh
dece6358
AM
27159+ (&arg->whlist, name, nlen, ino, d_type,
27160+ arg->bindex, shwh);
4a4d8108 27161+ }
1facf9fc 27162+ }
27163+
4f0767ce 27164+out:
1facf9fc 27165+ if (!arg->err)
27166+ arg->vdir->vd_jiffy = jiffies;
27167+ /* smp_mb(); */
27168+ AuTraceErr(arg->err);
27169+ return arg->err;
27170+}
27171+
dece6358
AM
27172+static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
27173+ struct au_nhash *whlist, struct au_nhash *delist)
27174+{
27175+#ifdef CONFIG_AUFS_SHWH
27176+ int err;
27177+ unsigned int nh, u;
27178+ struct hlist_head *head;
c06a8ce3
AM
27179+ struct au_vdir_wh *pos;
27180+ struct hlist_node *n;
dece6358
AM
27181+ char *p, *o;
27182+ struct au_vdir_destr *destr;
27183+
27184+ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
27185+
27186+ err = -ENOMEM;
537831f9 27187+ o = p = (void *)__get_free_page(GFP_NOFS);
dece6358
AM
27188+ if (unlikely(!p))
27189+ goto out;
27190+
27191+ err = 0;
27192+ nh = whlist->nh_num;
27193+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
27194+ p += AUFS_WH_PFX_LEN;
27195+ for (u = 0; u < nh; u++) {
27196+ head = whlist->nh_head + u;
c06a8ce3
AM
27197+ hlist_for_each_entry_safe(pos, n, head, wh_hash) {
27198+ destr = &pos->wh_str;
dece6358
AM
27199+ memcpy(p, destr->name, destr->len);
27200+ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
c06a8ce3 27201+ pos->wh_ino, pos->wh_type, delist);
dece6358
AM
27202+ if (unlikely(err))
27203+ break;
27204+ }
27205+ }
27206+
537831f9 27207+ free_page((unsigned long)o);
dece6358 27208+
4f0767ce 27209+out:
dece6358
AM
27210+ AuTraceErr(err);
27211+ return err;
27212+#else
27213+ return 0;
27214+#endif
27215+}
27216+
1facf9fc 27217+static int au_do_read_vdir(struct fillvdir_arg *arg)
27218+{
27219+ int err;
dece6358 27220+ unsigned int rdhash;
1facf9fc 27221+ loff_t offset;
dece6358
AM
27222+ aufs_bindex_t bend, bindex, bstart;
27223+ unsigned char shwh;
1facf9fc 27224+ struct file *hf, *file;
27225+ struct super_block *sb;
27226+
1facf9fc 27227+ file = arg->file;
27228+ sb = file->f_dentry->d_sb;
dece6358
AM
27229+ SiMustAnyLock(sb);
27230+
27231+ rdhash = au_sbi(sb)->si_rdhash;
1308ab2a 27232+ if (!rdhash)
27233+ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
dece6358
AM
27234+ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
27235+ if (unlikely(err))
1facf9fc 27236+ goto out;
dece6358
AM
27237+ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
27238+ if (unlikely(err))
1facf9fc 27239+ goto out_delist;
27240+
27241+ err = 0;
27242+ arg->flags = 0;
dece6358
AM
27243+ shwh = 0;
27244+ if (au_opt_test(au_mntflags(sb), SHWH)) {
27245+ shwh = 1;
27246+ au_fset_fillvdir(arg->flags, SHWH);
27247+ }
27248+ bstart = au_fbstart(file);
4a4d8108 27249+ bend = au_fbend_dir(file);
dece6358 27250+ for (bindex = bstart; !err && bindex <= bend; bindex++) {
4a4d8108 27251+ hf = au_hf_dir(file, bindex);
1facf9fc 27252+ if (!hf)
27253+ continue;
27254+
27255+ offset = vfsub_llseek(hf, 0, SEEK_SET);
27256+ err = offset;
27257+ if (unlikely(offset))
27258+ break;
27259+
27260+ arg->bindex = bindex;
27261+ au_fclr_fillvdir(arg->flags, WHABLE);
dece6358
AM
27262+ if (shwh
27263+ || (bindex != bend
27264+ && au_br_whable(au_sbr_perm(sb, bindex))))
1facf9fc 27265+ au_fset_fillvdir(arg->flags, WHABLE);
27266+ do {
27267+ arg->err = 0;
27268+ au_fclr_fillvdir(arg->flags, CALLED);
27269+ /* smp_mb(); */
392086de 27270+ err = vfsub_iterate_dir(hf, &arg->ctx);
1facf9fc 27271+ if (err >= 0)
27272+ err = arg->err;
27273+ } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
392086de
AM
27274+
27275+ /*
27276+ * dir_relax() may be good for concurrency, but aufs should not
27277+ * use it since it will cause a lockdep problem.
27278+ */
1facf9fc 27279+ }
dece6358
AM
27280+
27281+ if (!err && shwh)
27282+ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
27283+
27284+ au_nhash_wh_free(&arg->whlist);
1facf9fc 27285+
4f0767ce 27286+out_delist:
dece6358 27287+ au_nhash_de_free(&arg->delist);
4f0767ce 27288+out:
1facf9fc 27289+ return err;
27290+}
27291+
27292+static int read_vdir(struct file *file, int may_read)
27293+{
27294+ int err;
27295+ unsigned long expire;
27296+ unsigned char do_read;
392086de
AM
27297+ struct fillvdir_arg arg = {
27298+ .ctx = {
27299+ .actor = au_diractor(fillvdir)
27300+ }
27301+ };
1facf9fc 27302+ struct inode *inode;
27303+ struct au_vdir *vdir, *allocated;
27304+
27305+ err = 0;
c06a8ce3 27306+ inode = file_inode(file);
1facf9fc 27307+ IMustLock(inode);
dece6358
AM
27308+ SiMustAnyLock(inode->i_sb);
27309+
1facf9fc 27310+ allocated = NULL;
27311+ do_read = 0;
27312+ expire = au_sbi(inode->i_sb)->si_rdcache;
27313+ vdir = au_ivdir(inode);
27314+ if (!vdir) {
27315+ do_read = 1;
1308ab2a 27316+ vdir = alloc_vdir(file);
1facf9fc 27317+ err = PTR_ERR(vdir);
27318+ if (IS_ERR(vdir))
27319+ goto out;
27320+ err = 0;
27321+ allocated = vdir;
27322+ } else if (may_read
27323+ && (inode->i_version != vdir->vd_version
27324+ || time_after(jiffies, vdir->vd_jiffy + expire))) {
27325+ do_read = 1;
27326+ err = reinit_vdir(vdir);
27327+ if (unlikely(err))
27328+ goto out;
27329+ }
27330+
27331+ if (!do_read)
27332+ return 0; /* success */
27333+
27334+ arg.file = file;
27335+ arg.vdir = vdir;
27336+ err = au_do_read_vdir(&arg);
27337+ if (!err) {
392086de 27338+ /* file->f_pos = 0; */ /* todo: ctx->pos? */
1facf9fc 27339+ vdir->vd_version = inode->i_version;
27340+ vdir->vd_last.ul = 0;
27341+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
27342+ if (allocated)
27343+ au_set_ivdir(inode, allocated);
27344+ } else if (allocated)
27345+ au_vdir_free(allocated);
27346+
4f0767ce 27347+out:
1facf9fc 27348+ return err;
27349+}
27350+
27351+static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
27352+{
27353+ int err, rerr;
27354+ unsigned long ul, n;
27355+ const unsigned int deblk_sz = src->vd_deblk_sz;
27356+
27357+ AuDebugOn(tgt->vd_nblk != 1);
27358+
27359+ err = -ENOMEM;
27360+ if (tgt->vd_nblk < src->vd_nblk) {
27361+ unsigned char **p;
27362+
dece6358
AM
27363+ p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
27364+ GFP_NOFS);
1facf9fc 27365+ if (unlikely(!p))
27366+ goto out;
27367+ tgt->vd_deblk = p;
27368+ }
27369+
1308ab2a 27370+ if (tgt->vd_deblk_sz != deblk_sz) {
27371+ unsigned char *p;
27372+
27373+ tgt->vd_deblk_sz = deblk_sz;
27374+ p = krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS);
27375+ if (unlikely(!p))
27376+ goto out;
27377+ tgt->vd_deblk[0] = p;
27378+ }
1facf9fc 27379+ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
1facf9fc 27380+ tgt->vd_version = src->vd_version;
27381+ tgt->vd_jiffy = src->vd_jiffy;
27382+
27383+ n = src->vd_nblk;
27384+ for (ul = 1; ul < n; ul++) {
dece6358
AM
27385+ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
27386+ GFP_NOFS);
27387+ if (unlikely(!tgt->vd_deblk[ul]))
1facf9fc 27388+ goto out;
1308ab2a 27389+ tgt->vd_nblk++;
1facf9fc 27390+ }
1308ab2a 27391+ tgt->vd_nblk = n;
27392+ tgt->vd_last.ul = tgt->vd_last.ul;
27393+ tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul];
27394+ tgt->vd_last.p.deblk += src->vd_last.p.deblk
27395+ - src->vd_deblk[src->vd_last.ul];
1facf9fc 27396+ /* smp_mb(); */
27397+ return 0; /* success */
27398+
4f0767ce 27399+out:
1facf9fc 27400+ rerr = reinit_vdir(tgt);
27401+ BUG_ON(rerr);
27402+ return err;
27403+}
27404+
27405+int au_vdir_init(struct file *file)
27406+{
27407+ int err;
27408+ struct inode *inode;
27409+ struct au_vdir *vdir_cache, *allocated;
27410+
392086de 27411+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 27412+ err = read_vdir(file, !file->f_pos);
27413+ if (unlikely(err))
27414+ goto out;
27415+
27416+ allocated = NULL;
27417+ vdir_cache = au_fvdir_cache(file);
27418+ if (!vdir_cache) {
1308ab2a 27419+ vdir_cache = alloc_vdir(file);
1facf9fc 27420+ err = PTR_ERR(vdir_cache);
27421+ if (IS_ERR(vdir_cache))
27422+ goto out;
27423+ allocated = vdir_cache;
27424+ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
392086de 27425+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 27426+ err = reinit_vdir(vdir_cache);
27427+ if (unlikely(err))
27428+ goto out;
27429+ } else
27430+ return 0; /* success */
27431+
c06a8ce3 27432+ inode = file_inode(file);
1facf9fc 27433+ err = copy_vdir(vdir_cache, au_ivdir(inode));
27434+ if (!err) {
27435+ file->f_version = inode->i_version;
27436+ if (allocated)
27437+ au_set_fvdir_cache(file, allocated);
27438+ } else if (allocated)
27439+ au_vdir_free(allocated);
27440+
4f0767ce 27441+out:
1facf9fc 27442+ return err;
27443+}
27444+
27445+static loff_t calc_offset(struct au_vdir *vdir)
27446+{
27447+ loff_t offset;
27448+ union au_vdir_deblk_p p;
27449+
27450+ p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
27451+ offset = vdir->vd_last.p.deblk - p.deblk;
27452+ offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
27453+ return offset;
27454+}
27455+
27456+/* returns true or false */
392086de 27457+static int seek_vdir(struct file *file, struct dir_context *ctx)
1facf9fc 27458+{
27459+ int valid;
27460+ unsigned int deblk_sz;
27461+ unsigned long ul, n;
27462+ loff_t offset;
27463+ union au_vdir_deblk_p p, deblk_end;
27464+ struct au_vdir *vdir_cache;
27465+
27466+ valid = 1;
27467+ vdir_cache = au_fvdir_cache(file);
27468+ offset = calc_offset(vdir_cache);
27469+ AuDbg("offset %lld\n", offset);
392086de 27470+ if (ctx->pos == offset)
1facf9fc 27471+ goto out;
27472+
27473+ vdir_cache->vd_last.ul = 0;
27474+ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
392086de 27475+ if (!ctx->pos)
1facf9fc 27476+ goto out;
27477+
27478+ valid = 0;
27479+ deblk_sz = vdir_cache->vd_deblk_sz;
392086de 27480+ ul = div64_u64(ctx->pos, deblk_sz);
1facf9fc 27481+ AuDbg("ul %lu\n", ul);
27482+ if (ul >= vdir_cache->vd_nblk)
27483+ goto out;
27484+
27485+ n = vdir_cache->vd_nblk;
27486+ for (; ul < n; ul++) {
27487+ p.deblk = vdir_cache->vd_deblk[ul];
27488+ deblk_end.deblk = p.deblk + deblk_sz;
27489+ offset = ul;
27490+ offset *= deblk_sz;
392086de 27491+ while (!is_deblk_end(&p, &deblk_end) && offset < ctx->pos) {
1facf9fc 27492+ unsigned int l;
27493+
27494+ l = calc_size(p.de->de_str.len);
27495+ offset += l;
27496+ p.deblk += l;
27497+ }
27498+ if (!is_deblk_end(&p, &deblk_end)) {
27499+ valid = 1;
27500+ vdir_cache->vd_last.ul = ul;
27501+ vdir_cache->vd_last.p = p;
27502+ break;
27503+ }
27504+ }
27505+
4f0767ce 27506+out:
1facf9fc 27507+ /* smp_mb(); */
27508+ AuTraceErr(!valid);
27509+ return valid;
27510+}
27511+
392086de 27512+int au_vdir_fill_de(struct file *file, struct dir_context *ctx)
1facf9fc 27513+{
1facf9fc 27514+ unsigned int l, deblk_sz;
27515+ union au_vdir_deblk_p deblk_end;
27516+ struct au_vdir *vdir_cache;
27517+ struct au_vdir_de *de;
27518+
27519+ vdir_cache = au_fvdir_cache(file);
392086de 27520+ if (!seek_vdir(file, ctx))
1facf9fc 27521+ return 0;
27522+
27523+ deblk_sz = vdir_cache->vd_deblk_sz;
27524+ while (1) {
27525+ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
27526+ deblk_end.deblk += deblk_sz;
27527+ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
27528+ de = vdir_cache->vd_last.p.de;
27529+ AuDbg("%.*s, off%lld, i%lu, dt%d\n",
392086de 27530+ de->de_str.len, de->de_str.name, ctx->pos,
1facf9fc 27531+ (unsigned long)de->de_ino, de->de_type);
392086de
AM
27532+ if (unlikely(!dir_emit(ctx, de->de_str.name,
27533+ de->de_str.len, de->de_ino,
27534+ de->de_type))) {
1facf9fc 27535+ /* todo: ignore the error caused by udba? */
27536+ /* return err; */
27537+ return 0;
27538+ }
27539+
27540+ l = calc_size(de->de_str.len);
27541+ vdir_cache->vd_last.p.deblk += l;
392086de 27542+ ctx->pos += l;
1facf9fc 27543+ }
27544+ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
27545+ vdir_cache->vd_last.ul++;
27546+ vdir_cache->vd_last.p.deblk
27547+ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
392086de 27548+ ctx->pos = deblk_sz * vdir_cache->vd_last.ul;
1facf9fc 27549+ continue;
27550+ }
27551+ break;
27552+ }
27553+
27554+ /* smp_mb(); */
27555+ return 0;
27556+}
7f207e10
AM
27557diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
27558--- /usr/share/empty/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
27559+++ linux/fs/aufs/vfsub.c 2014-01-20 20:16:14.749463838 +0100
27560@@ -0,0 +1,782 @@
1facf9fc 27561+/*
523b37e3 27562+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 27563+ *
27564+ * This program, aufs is free software; you can redistribute it and/or modify
27565+ * it under the terms of the GNU General Public License as published by
27566+ * the Free Software Foundation; either version 2 of the License, or
27567+ * (at your option) any later version.
dece6358
AM
27568+ *
27569+ * This program is distributed in the hope that it will be useful,
27570+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27571+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27572+ * GNU General Public License for more details.
27573+ *
27574+ * You should have received a copy of the GNU General Public License
523b37e3 27575+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27576+ */
27577+
27578+/*
27579+ * sub-routines for VFS
27580+ */
27581+
1308ab2a 27582+#include <linux/ima.h>
dece6358
AM
27583+#include <linux/namei.h>
27584+#include <linux/security.h>
27585+#include <linux/splice.h>
1facf9fc 27586+#include "aufs.h"
27587+
27588+int vfsub_update_h_iattr(struct path *h_path, int *did)
27589+{
27590+ int err;
27591+ struct kstat st;
27592+ struct super_block *h_sb;
27593+
27594+ /* for remote fs, leave work for its getattr or d_revalidate */
27595+ /* for bad i_attr fs, handle them in aufs_getattr() */
27596+ /* still some fs may acquire i_mutex. we need to skip them */
27597+ err = 0;
27598+ if (!did)
27599+ did = &err;
27600+ h_sb = h_path->dentry->d_sb;
27601+ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
27602+ if (*did)
c06a8ce3 27603+ err = vfs_getattr(h_path, &st);
1facf9fc 27604+
27605+ return err;
27606+}
27607+
27608+/* ---------------------------------------------------------------------- */
27609+
4a4d8108 27610+struct file *vfsub_dentry_open(struct path *path, int flags)
1308ab2a 27611+{
27612+ struct file *file;
27613+
b4510431 27614+ file = dentry_open(path, flags /* | __FMODE_NONOTIFY */,
7f207e10 27615+ current_cred());
2cbb1c4b
JR
27616+ if (!IS_ERR_OR_NULL(file)
27617+ && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
27618+ i_readcount_inc(path->dentry->d_inode);
4a4d8108 27619+
1308ab2a 27620+ return file;
27621+}
27622+
1facf9fc 27623+struct file *vfsub_filp_open(const char *path, int oflags, int mode)
27624+{
27625+ struct file *file;
27626+
2cbb1c4b 27627+ lockdep_off();
7f207e10 27628+ file = filp_open(path,
2cbb1c4b 27629+ oflags /* | __FMODE_NONOTIFY */,
7f207e10 27630+ mode);
2cbb1c4b 27631+ lockdep_on();
1facf9fc 27632+ if (IS_ERR(file))
27633+ goto out;
27634+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
27635+
4f0767ce 27636+out:
1facf9fc 27637+ return file;
27638+}
27639+
27640+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
27641+{
27642+ int err;
27643+
1facf9fc 27644+ err = kern_path(name, flags, path);
1facf9fc 27645+ if (!err && path->dentry->d_inode)
27646+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
27647+ return err;
27648+}
27649+
27650+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
27651+ int len)
27652+{
27653+ struct path path = {
27654+ .mnt = NULL
27655+ };
27656+
1308ab2a 27657+ /* VFS checks it too, but by WARN_ON_ONCE() */
1facf9fc 27658+ IMustLock(parent->d_inode);
27659+
27660+ path.dentry = lookup_one_len(name, parent, len);
27661+ if (IS_ERR(path.dentry))
27662+ goto out;
27663+ if (path.dentry->d_inode)
27664+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
27665+
4f0767ce 27666+out:
4a4d8108 27667+ AuTraceErrPtr(path.dentry);
1facf9fc 27668+ return path.dentry;
27669+}
27670+
b4510431 27671+void vfsub_call_lkup_one(void *args)
2cbb1c4b 27672+{
b4510431
AM
27673+ struct vfsub_lkup_one_args *a = args;
27674+ *a->errp = vfsub_lkup_one(a->name, a->parent);
2cbb1c4b
JR
27675+}
27676+
1facf9fc 27677+/* ---------------------------------------------------------------------- */
27678+
27679+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
27680+ struct dentry *d2, struct au_hinode *hdir2)
27681+{
27682+ struct dentry *d;
27683+
2cbb1c4b 27684+ lockdep_off();
1facf9fc 27685+ d = lock_rename(d1, d2);
2cbb1c4b 27686+ lockdep_on();
4a4d8108 27687+ au_hn_suspend(hdir1);
1facf9fc 27688+ if (hdir1 != hdir2)
4a4d8108 27689+ au_hn_suspend(hdir2);
1facf9fc 27690+
27691+ return d;
27692+}
27693+
27694+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
27695+ struct dentry *d2, struct au_hinode *hdir2)
27696+{
4a4d8108 27697+ au_hn_resume(hdir1);
1facf9fc 27698+ if (hdir1 != hdir2)
4a4d8108 27699+ au_hn_resume(hdir2);
2cbb1c4b 27700+ lockdep_off();
1facf9fc 27701+ unlock_rename(d1, d2);
2cbb1c4b 27702+ lockdep_on();
1facf9fc 27703+}
27704+
27705+/* ---------------------------------------------------------------------- */
27706+
b4510431 27707+int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl)
1facf9fc 27708+{
27709+ int err;
27710+ struct dentry *d;
27711+
27712+ IMustLock(dir);
27713+
27714+ d = path->dentry;
27715+ path->dentry = d->d_parent;
b752ccd1 27716+ err = security_path_mknod(path, d, mode, 0);
1facf9fc 27717+ path->dentry = d;
27718+ if (unlikely(err))
27719+ goto out;
27720+
b4510431 27721+ err = vfs_create(dir, path->dentry, mode, want_excl);
1facf9fc 27722+ if (!err) {
27723+ struct path tmp = *path;
27724+ int did;
27725+
27726+ vfsub_update_h_iattr(&tmp, &did);
27727+ if (did) {
27728+ tmp.dentry = path->dentry->d_parent;
27729+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
27730+ }
27731+ /*ignore*/
27732+ }
27733+
4f0767ce 27734+out:
1facf9fc 27735+ return err;
27736+}
27737+
27738+int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
27739+{
27740+ int err;
27741+ struct dentry *d;
27742+
27743+ IMustLock(dir);
27744+
27745+ d = path->dentry;
27746+ path->dentry = d->d_parent;
b752ccd1 27747+ err = security_path_symlink(path, d, symname);
1facf9fc 27748+ path->dentry = d;
27749+ if (unlikely(err))
27750+ goto out;
27751+
27752+ err = vfs_symlink(dir, path->dentry, symname);
27753+ if (!err) {
27754+ struct path tmp = *path;
27755+ int did;
27756+
27757+ vfsub_update_h_iattr(&tmp, &did);
27758+ if (did) {
27759+ tmp.dentry = path->dentry->d_parent;
27760+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
27761+ }
27762+ /*ignore*/
27763+ }
27764+
4f0767ce 27765+out:
1facf9fc 27766+ return err;
27767+}
27768+
27769+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
27770+{
27771+ int err;
27772+ struct dentry *d;
27773+
27774+ IMustLock(dir);
27775+
27776+ d = path->dentry;
27777+ path->dentry = d->d_parent;
027c5e7a 27778+ err = security_path_mknod(path, d, mode, new_encode_dev(dev));
1facf9fc 27779+ path->dentry = d;
27780+ if (unlikely(err))
27781+ goto out;
27782+
27783+ err = vfs_mknod(dir, path->dentry, mode, dev);
27784+ if (!err) {
27785+ struct path tmp = *path;
27786+ int did;
27787+
27788+ vfsub_update_h_iattr(&tmp, &did);
27789+ if (did) {
27790+ tmp.dentry = path->dentry->d_parent;
27791+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
27792+ }
27793+ /*ignore*/
27794+ }
27795+
4f0767ce 27796+out:
1facf9fc 27797+ return err;
27798+}
27799+
27800+static int au_test_nlink(struct inode *inode)
27801+{
27802+ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
27803+
27804+ if (!au_test_fs_no_limit_nlink(inode->i_sb)
27805+ || inode->i_nlink < link_max)
27806+ return 0;
27807+ return -EMLINK;
27808+}
27809+
523b37e3
AM
27810+int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path,
27811+ struct inode **delegated_inode)
1facf9fc 27812+{
27813+ int err;
27814+ struct dentry *d;
27815+
27816+ IMustLock(dir);
27817+
27818+ err = au_test_nlink(src_dentry->d_inode);
27819+ if (unlikely(err))
27820+ return err;
27821+
b4510431 27822+ /* we don't call may_linkat() */
1facf9fc 27823+ d = path->dentry;
27824+ path->dentry = d->d_parent;
b752ccd1 27825+ err = security_path_link(src_dentry, path, d);
1facf9fc 27826+ path->dentry = d;
27827+ if (unlikely(err))
27828+ goto out;
27829+
2cbb1c4b 27830+ lockdep_off();
523b37e3 27831+ err = vfs_link(src_dentry, dir, path->dentry, delegated_inode);
2cbb1c4b 27832+ lockdep_on();
1facf9fc 27833+ if (!err) {
27834+ struct path tmp = *path;
27835+ int did;
27836+
27837+ /* fuse has different memory inode for the same inumber */
27838+ vfsub_update_h_iattr(&tmp, &did);
27839+ if (did) {
27840+ tmp.dentry = path->dentry->d_parent;
27841+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
27842+ tmp.dentry = src_dentry;
27843+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
27844+ }
27845+ /*ignore*/
27846+ }
27847+
4f0767ce 27848+out:
1facf9fc 27849+ return err;
27850+}
27851+
27852+int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
523b37e3
AM
27853+ struct inode *dir, struct path *path,
27854+ struct inode **delegated_inode)
1facf9fc 27855+{
27856+ int err;
27857+ struct path tmp = {
27858+ .mnt = path->mnt
27859+ };
27860+ struct dentry *d;
27861+
27862+ IMustLock(dir);
27863+ IMustLock(src_dir);
27864+
27865+ d = path->dentry;
27866+ path->dentry = d->d_parent;
27867+ tmp.dentry = src_dentry->d_parent;
b752ccd1 27868+ err = security_path_rename(&tmp, src_dentry, path, d);
1facf9fc 27869+ path->dentry = d;
27870+ if (unlikely(err))
27871+ goto out;
27872+
2cbb1c4b 27873+ lockdep_off();
523b37e3
AM
27874+ err = vfs_rename(src_dir, src_dentry, dir, path->dentry,
27875+ delegated_inode);
2cbb1c4b 27876+ lockdep_on();
1facf9fc 27877+ if (!err) {
27878+ int did;
27879+
27880+ tmp.dentry = d->d_parent;
27881+ vfsub_update_h_iattr(&tmp, &did);
27882+ if (did) {
27883+ tmp.dentry = src_dentry;
27884+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
27885+ tmp.dentry = src_dentry->d_parent;
27886+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
27887+ }
27888+ /*ignore*/
27889+ }
27890+
4f0767ce 27891+out:
1facf9fc 27892+ return err;
27893+}
27894+
27895+int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
27896+{
27897+ int err;
27898+ struct dentry *d;
27899+
27900+ IMustLock(dir);
27901+
27902+ d = path->dentry;
27903+ path->dentry = d->d_parent;
b752ccd1 27904+ err = security_path_mkdir(path, d, mode);
1facf9fc 27905+ path->dentry = d;
27906+ if (unlikely(err))
27907+ goto out;
27908+
27909+ err = vfs_mkdir(dir, path->dentry, mode);
27910+ if (!err) {
27911+ struct path tmp = *path;
27912+ int did;
27913+
27914+ vfsub_update_h_iattr(&tmp, &did);
27915+ if (did) {
27916+ tmp.dentry = path->dentry->d_parent;
27917+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
27918+ }
27919+ /*ignore*/
27920+ }
27921+
4f0767ce 27922+out:
1facf9fc 27923+ return err;
27924+}
27925+
27926+int vfsub_rmdir(struct inode *dir, struct path *path)
27927+{
27928+ int err;
27929+ struct dentry *d;
27930+
27931+ IMustLock(dir);
27932+
27933+ d = path->dentry;
27934+ path->dentry = d->d_parent;
b752ccd1 27935+ err = security_path_rmdir(path, d);
1facf9fc 27936+ path->dentry = d;
27937+ if (unlikely(err))
27938+ goto out;
27939+
2cbb1c4b 27940+ lockdep_off();
1facf9fc 27941+ err = vfs_rmdir(dir, path->dentry);
2cbb1c4b 27942+ lockdep_on();
1facf9fc 27943+ if (!err) {
27944+ struct path tmp = {
27945+ .dentry = path->dentry->d_parent,
27946+ .mnt = path->mnt
27947+ };
27948+
27949+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
27950+ }
27951+
4f0767ce 27952+out:
1facf9fc 27953+ return err;
27954+}
27955+
27956+/* ---------------------------------------------------------------------- */
27957+
9dbd164d 27958+/* todo: support mmap_sem? */
1facf9fc 27959+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
27960+ loff_t *ppos)
27961+{
27962+ ssize_t err;
27963+
2cbb1c4b 27964+ lockdep_off();
1facf9fc 27965+ err = vfs_read(file, ubuf, count, ppos);
2cbb1c4b 27966+ lockdep_on();
1facf9fc 27967+ if (err >= 0)
27968+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
27969+ return err;
27970+}
27971+
27972+/* todo: kernel_read()? */
27973+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
27974+ loff_t *ppos)
27975+{
27976+ ssize_t err;
27977+ mm_segment_t oldfs;
b752ccd1
AM
27978+ union {
27979+ void *k;
27980+ char __user *u;
27981+ } buf;
1facf9fc 27982+
b752ccd1 27983+ buf.k = kbuf;
1facf9fc 27984+ oldfs = get_fs();
27985+ set_fs(KERNEL_DS);
b752ccd1 27986+ err = vfsub_read_u(file, buf.u, count, ppos);
1facf9fc 27987+ set_fs(oldfs);
27988+ return err;
27989+}
27990+
27991+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
27992+ loff_t *ppos)
27993+{
27994+ ssize_t err;
27995+
2cbb1c4b 27996+ lockdep_off();
1facf9fc 27997+ err = vfs_write(file, ubuf, count, ppos);
2cbb1c4b 27998+ lockdep_on();
1facf9fc 27999+ if (err >= 0)
28000+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
28001+ return err;
28002+}
28003+
28004+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
28005+{
28006+ ssize_t err;
28007+ mm_segment_t oldfs;
b752ccd1
AM
28008+ union {
28009+ void *k;
28010+ const char __user *u;
28011+ } buf;
1facf9fc 28012+
b752ccd1 28013+ buf.k = kbuf;
1facf9fc 28014+ oldfs = get_fs();
28015+ set_fs(KERNEL_DS);
b752ccd1 28016+ err = vfsub_write_u(file, buf.u, count, ppos);
1facf9fc 28017+ set_fs(oldfs);
28018+ return err;
28019+}
28020+
4a4d8108
AM
28021+int vfsub_flush(struct file *file, fl_owner_t id)
28022+{
28023+ int err;
28024+
28025+ err = 0;
523b37e3 28026+ if (file->f_op->flush) {
2cbb1c4b
JR
28027+ if (!au_test_nfs(file->f_dentry->d_sb))
28028+ err = file->f_op->flush(file, id);
28029+ else {
28030+ lockdep_off();
28031+ err = file->f_op->flush(file, id);
28032+ lockdep_on();
28033+ }
4a4d8108
AM
28034+ if (!err)
28035+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
28036+ /*ignore*/
28037+ }
28038+ return err;
28039+}
28040+
392086de 28041+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx)
1facf9fc 28042+{
28043+ int err;
28044+
523b37e3 28045+ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
392086de 28046+
2cbb1c4b 28047+ lockdep_off();
392086de 28048+ err = iterate_dir(file, ctx);
2cbb1c4b 28049+ lockdep_on();
1facf9fc 28050+ if (err >= 0)
28051+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
28052+ return err;
28053+}
28054+
28055+long vfsub_splice_to(struct file *in, loff_t *ppos,
28056+ struct pipe_inode_info *pipe, size_t len,
28057+ unsigned int flags)
28058+{
28059+ long err;
28060+
2cbb1c4b 28061+ lockdep_off();
0fc653ad 28062+ err = do_splice_to(in, ppos, pipe, len, flags);
2cbb1c4b 28063+ lockdep_on();
4a4d8108 28064+ file_accessed(in);
1facf9fc 28065+ if (err >= 0)
28066+ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
28067+ return err;
28068+}
28069+
28070+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
28071+ loff_t *ppos, size_t len, unsigned int flags)
28072+{
28073+ long err;
28074+
2cbb1c4b 28075+ lockdep_off();
0fc653ad 28076+ err = do_splice_from(pipe, out, ppos, len, flags);
2cbb1c4b 28077+ lockdep_on();
1facf9fc 28078+ if (err >= 0)
28079+ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
28080+ return err;
28081+}
28082+
53392da6
AM
28083+int vfsub_fsync(struct file *file, struct path *path, int datasync)
28084+{
28085+ int err;
28086+
28087+ /* file can be NULL */
28088+ lockdep_off();
28089+ err = vfs_fsync(file, datasync);
28090+ lockdep_on();
28091+ if (!err) {
28092+ if (!path) {
28093+ AuDebugOn(!file);
28094+ path = &file->f_path;
28095+ }
28096+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
28097+ }
28098+ return err;
28099+}
28100+
1facf9fc 28101+/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
28102+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
28103+ struct file *h_file)
28104+{
28105+ int err;
28106+ struct inode *h_inode;
c06a8ce3 28107+ struct super_block *h_sb;
1facf9fc 28108+
1facf9fc 28109+ if (!h_file) {
c06a8ce3
AM
28110+ err = vfsub_truncate(h_path, length);
28111+ goto out;
1facf9fc 28112+ }
28113+
c06a8ce3
AM
28114+ h_inode = h_path->dentry->d_inode;
28115+ h_sb = h_inode->i_sb;
28116+ lockdep_off();
28117+ sb_start_write(h_sb);
28118+ lockdep_on();
1facf9fc 28119+ err = locks_verify_truncate(h_inode, h_file, length);
28120+ if (!err)
953406b4 28121+ err = security_path_truncate(h_path);
2cbb1c4b
JR
28122+ if (!err) {
28123+ lockdep_off();
1facf9fc 28124+ err = do_truncate(h_path->dentry, length, attr, h_file);
2cbb1c4b
JR
28125+ lockdep_on();
28126+ }
c06a8ce3
AM
28127+ lockdep_off();
28128+ sb_end_write(h_sb);
28129+ lockdep_on();
1facf9fc 28130+
4f0767ce 28131+out:
1facf9fc 28132+ return err;
28133+}
28134+
28135+/* ---------------------------------------------------------------------- */
28136+
28137+struct au_vfsub_mkdir_args {
28138+ int *errp;
28139+ struct inode *dir;
28140+ struct path *path;
28141+ int mode;
28142+};
28143+
28144+static void au_call_vfsub_mkdir(void *args)
28145+{
28146+ struct au_vfsub_mkdir_args *a = args;
28147+ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
28148+}
28149+
28150+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
28151+{
28152+ int err, do_sio, wkq_err;
28153+
28154+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
28155+ if (!do_sio)
28156+ err = vfsub_mkdir(dir, path, mode);
28157+ else {
28158+ struct au_vfsub_mkdir_args args = {
28159+ .errp = &err,
28160+ .dir = dir,
28161+ .path = path,
28162+ .mode = mode
28163+ };
28164+ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
28165+ if (unlikely(wkq_err))
28166+ err = wkq_err;
28167+ }
28168+
28169+ return err;
28170+}
28171+
28172+struct au_vfsub_rmdir_args {
28173+ int *errp;
28174+ struct inode *dir;
28175+ struct path *path;
28176+};
28177+
28178+static void au_call_vfsub_rmdir(void *args)
28179+{
28180+ struct au_vfsub_rmdir_args *a = args;
28181+ *a->errp = vfsub_rmdir(a->dir, a->path);
28182+}
28183+
28184+int vfsub_sio_rmdir(struct inode *dir, struct path *path)
28185+{
28186+ int err, do_sio, wkq_err;
28187+
28188+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
28189+ if (!do_sio)
28190+ err = vfsub_rmdir(dir, path);
28191+ else {
28192+ struct au_vfsub_rmdir_args args = {
28193+ .errp = &err,
28194+ .dir = dir,
28195+ .path = path
28196+ };
28197+ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
28198+ if (unlikely(wkq_err))
28199+ err = wkq_err;
28200+ }
28201+
28202+ return err;
28203+}
28204+
28205+/* ---------------------------------------------------------------------- */
28206+
28207+struct notify_change_args {
28208+ int *errp;
28209+ struct path *path;
28210+ struct iattr *ia;
523b37e3 28211+ struct inode **delegated_inode;
1facf9fc 28212+};
28213+
28214+static void call_notify_change(void *args)
28215+{
28216+ struct notify_change_args *a = args;
28217+ struct inode *h_inode;
28218+
28219+ h_inode = a->path->dentry->d_inode;
28220+ IMustLock(h_inode);
28221+
28222+ *a->errp = -EPERM;
28223+ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
523b37e3
AM
28224+ *a->errp = notify_change(a->path->dentry, a->ia,
28225+ a->delegated_inode);
1facf9fc 28226+ if (!*a->errp)
28227+ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
28228+ }
28229+ AuTraceErr(*a->errp);
28230+}
28231+
523b37e3
AM
28232+int vfsub_notify_change(struct path *path, struct iattr *ia,
28233+ struct inode **delegated_inode)
1facf9fc 28234+{
28235+ int err;
28236+ struct notify_change_args args = {
523b37e3
AM
28237+ .errp = &err,
28238+ .path = path,
28239+ .ia = ia,
28240+ .delegated_inode = delegated_inode
1facf9fc 28241+ };
28242+
28243+ call_notify_change(&args);
28244+
28245+ return err;
28246+}
28247+
523b37e3
AM
28248+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
28249+ struct inode **delegated_inode)
1facf9fc 28250+{
28251+ int err, wkq_err;
28252+ struct notify_change_args args = {
523b37e3
AM
28253+ .errp = &err,
28254+ .path = path,
28255+ .ia = ia,
28256+ .delegated_inode = delegated_inode
1facf9fc 28257+ };
28258+
28259+ wkq_err = au_wkq_wait(call_notify_change, &args);
28260+ if (unlikely(wkq_err))
28261+ err = wkq_err;
28262+
28263+ return err;
28264+}
28265+
28266+/* ---------------------------------------------------------------------- */
28267+
28268+struct unlink_args {
28269+ int *errp;
28270+ struct inode *dir;
28271+ struct path *path;
523b37e3 28272+ struct inode **delegated_inode;
1facf9fc 28273+};
28274+
28275+static void call_unlink(void *args)
28276+{
28277+ struct unlink_args *a = args;
28278+ struct dentry *d = a->path->dentry;
28279+ struct inode *h_inode;
28280+ const int stop_sillyrename = (au_test_nfs(d->d_sb)
392086de 28281+ && d_count(d) == 1);
1facf9fc 28282+
28283+ IMustLock(a->dir);
28284+
28285+ a->path->dentry = d->d_parent;
28286+ *a->errp = security_path_unlink(a->path, d);
28287+ a->path->dentry = d;
28288+ if (unlikely(*a->errp))
28289+ return;
28290+
28291+ if (!stop_sillyrename)
28292+ dget(d);
28293+ h_inode = d->d_inode;
28294+ if (h_inode)
027c5e7a 28295+ ihold(h_inode);
1facf9fc 28296+
2cbb1c4b 28297+ lockdep_off();
523b37e3 28298+ *a->errp = vfs_unlink(a->dir, d, a->delegated_inode);
2cbb1c4b 28299+ lockdep_on();
1facf9fc 28300+ if (!*a->errp) {
28301+ struct path tmp = {
28302+ .dentry = d->d_parent,
28303+ .mnt = a->path->mnt
28304+ };
28305+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
28306+ }
28307+
28308+ if (!stop_sillyrename)
28309+ dput(d);
28310+ if (h_inode)
28311+ iput(h_inode);
28312+
28313+ AuTraceErr(*a->errp);
28314+}
28315+
28316+/*
28317+ * @dir: must be locked.
28318+ * @dentry: target dentry.
28319+ */
523b37e3
AM
28320+int vfsub_unlink(struct inode *dir, struct path *path,
28321+ struct inode **delegated_inode, int force)
1facf9fc 28322+{
28323+ int err;
28324+ struct unlink_args args = {
523b37e3
AM
28325+ .errp = &err,
28326+ .dir = dir,
28327+ .path = path,
28328+ .delegated_inode = delegated_inode
1facf9fc 28329+ };
28330+
28331+ if (!force)
28332+ call_unlink(&args);
28333+ else {
28334+ int wkq_err;
28335+
28336+ wkq_err = au_wkq_wait(call_unlink, &args);
28337+ if (unlikely(wkq_err))
28338+ err = wkq_err;
28339+ }
28340+
28341+ return err;
28342+}
7f207e10
AM
28343diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
28344--- /usr/share/empty/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
28345+++ linux/fs/aufs/vfsub.h 2014-01-20 20:16:14.749463838 +0100
28346@@ -0,0 +1,282 @@
1facf9fc 28347+/*
523b37e3 28348+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 28349+ *
28350+ * This program, aufs is free software; you can redistribute it and/or modify
28351+ * it under the terms of the GNU General Public License as published by
28352+ * the Free Software Foundation; either version 2 of the License, or
28353+ * (at your option) any later version.
dece6358
AM
28354+ *
28355+ * This program is distributed in the hope that it will be useful,
28356+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28357+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28358+ * GNU General Public License for more details.
28359+ *
28360+ * You should have received a copy of the GNU General Public License
523b37e3 28361+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28362+ */
28363+
28364+/*
28365+ * sub-routines for VFS
28366+ */
28367+
28368+#ifndef __AUFS_VFSUB_H__
28369+#define __AUFS_VFSUB_H__
28370+
28371+#ifdef __KERNEL__
28372+
28373+#include <linux/fs.h>
0c5527e5 28374+#include <linux/lglock.h>
b4510431 28375+#include <linux/mount.h>
7f207e10 28376+#include "debug.h"
1facf9fc 28377+
7f207e10 28378+/* copied from linux/fs/internal.h */
2cbb1c4b 28379+/* todo: BAD approach!! */
c06a8ce3 28380+extern void __mnt_drop_write(struct vfsmount *);
2cbb1c4b 28381+extern spinlock_t inode_sb_list_lock;
7f207e10
AM
28382+
28383+/* ---------------------------------------------------------------------- */
1facf9fc 28384+
28385+/* lock subclass for lower inode */
28386+/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
28387+/* reduce? gave up. */
28388+enum {
523b37e3 28389+ AuLsc_I_Begin = I_MUTEX_NONDIR2, /* 4 */
1facf9fc 28390+ AuLsc_I_PARENT, /* lower inode, parent first */
28391+ AuLsc_I_PARENT2, /* copyup dirs */
dece6358 28392+ AuLsc_I_PARENT3, /* copyup wh */
1facf9fc 28393+ AuLsc_I_CHILD,
28394+ AuLsc_I_CHILD2,
28395+ AuLsc_I_End
28396+};
28397+
28398+/* to debug easier, do not make them inlined functions */
28399+#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
28400+#define IMustLock(i) MtxMustLock(&(i)->i_mutex)
28401+
28402+/* ---------------------------------------------------------------------- */
28403+
7f207e10
AM
28404+static inline void vfsub_drop_nlink(struct inode *inode)
28405+{
28406+ AuDebugOn(!inode->i_nlink);
28407+ drop_nlink(inode);
28408+}
28409+
027c5e7a
AM
28410+static inline void vfsub_dead_dir(struct inode *inode)
28411+{
28412+ AuDebugOn(!S_ISDIR(inode->i_mode));
28413+ inode->i_flags |= S_DEAD;
28414+ clear_nlink(inode);
28415+}
28416+
392086de
AM
28417+static inline int vfsub_native_ro(struct inode *inode)
28418+{
28419+ return (inode->i_sb->s_flags & MS_RDONLY)
28420+ || IS_RDONLY(inode)
28421+ /* || IS_APPEND(inode) */
28422+ || IS_IMMUTABLE(inode);
28423+}
28424+
7f207e10
AM
28425+/* ---------------------------------------------------------------------- */
28426+
28427+int vfsub_update_h_iattr(struct path *h_path, int *did);
28428+struct file *vfsub_dentry_open(struct path *path, int flags);
28429+struct file *vfsub_filp_open(const char *path, int oflags, int mode);
1facf9fc 28430+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
b4510431 28431+
1facf9fc 28432+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
28433+ int len);
b4510431
AM
28434+
28435+struct vfsub_lkup_one_args {
28436+ struct dentry **errp;
28437+ struct qstr *name;
28438+ struct dentry *parent;
28439+};
28440+
28441+static inline struct dentry *vfsub_lkup_one(struct qstr *name,
28442+ struct dentry *parent)
28443+{
28444+ return vfsub_lookup_one_len(name->name, parent, name->len);
28445+}
28446+
28447+void vfsub_call_lkup_one(void *args);
28448+
28449+/* ---------------------------------------------------------------------- */
28450+
28451+static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
28452+{
28453+ int err;
28454+ lockdep_off();
28455+ err = mnt_want_write(mnt);
28456+ lockdep_on();
28457+ return err;
28458+}
28459+
28460+static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
28461+{
28462+ lockdep_off();
28463+ mnt_drop_write(mnt);
28464+ lockdep_on();
28465+}
1facf9fc 28466+
c06a8ce3
AM
28467+static inline void vfsub_mnt_drop_write_file(struct file *file)
28468+{
28469+ lockdep_off();
28470+ mnt_drop_write_file(file);
28471+ lockdep_on();
28472+}
28473+
1facf9fc 28474+/* ---------------------------------------------------------------------- */
28475+
28476+struct au_hinode;
28477+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
28478+ struct dentry *d2, struct au_hinode *hdir2);
28479+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
28480+ struct dentry *d2, struct au_hinode *hdir2);
28481+
537831f9
AM
28482+int vfsub_create(struct inode *dir, struct path *path, int mode,
28483+ bool want_excl);
1facf9fc 28484+int vfsub_symlink(struct inode *dir, struct path *path,
28485+ const char *symname);
28486+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
28487+int vfsub_link(struct dentry *src_dentry, struct inode *dir,
523b37e3 28488+ struct path *path, struct inode **delegated_inode);
1facf9fc 28489+int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
523b37e3
AM
28490+ struct inode *hdir, struct path *path,
28491+ struct inode **delegated_inode);
1facf9fc 28492+int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
28493+int vfsub_rmdir(struct inode *dir, struct path *path);
28494+
28495+/* ---------------------------------------------------------------------- */
28496+
28497+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
28498+ loff_t *ppos);
28499+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
28500+ loff_t *ppos);
28501+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
28502+ loff_t *ppos);
28503+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
28504+ loff_t *ppos);
4a4d8108 28505+int vfsub_flush(struct file *file, fl_owner_t id);
392086de
AM
28506+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx);
28507+
28508+/* just for type-check */
28509+static inline filldir_t au_diractor(int (*func)(struct dir_context *,
28510+ const char *, int, loff_t, u64,
28511+ unsigned))
28512+{
28513+ return (filldir_t)func;
28514+}
28515+
1facf9fc 28516+
c06a8ce3
AM
28517+static inline loff_t vfsub_f_size_read(struct file *file)
28518+{
28519+ return i_size_read(file_inode(file));
28520+}
28521+
4a4d8108
AM
28522+static inline unsigned int vfsub_file_flags(struct file *file)
28523+{
28524+ unsigned int flags;
28525+
28526+ spin_lock(&file->f_lock);
28527+ flags = file->f_flags;
28528+ spin_unlock(&file->f_lock);
28529+
28530+ return flags;
28531+}
1308ab2a 28532+
1facf9fc 28533+static inline void vfsub_file_accessed(struct file *h_file)
28534+{
28535+ file_accessed(h_file);
28536+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
28537+}
28538+
28539+static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
28540+ struct dentry *h_dentry)
28541+{
28542+ struct path h_path = {
28543+ .dentry = h_dentry,
28544+ .mnt = h_mnt
28545+ };
92d182d2 28546+ touch_atime(&h_path);
1facf9fc 28547+ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
28548+}
28549+
0c3ec466
AM
28550+static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts,
28551+ int flags)
28552+{
28553+ return update_time(h_inode, ts, flags);
28554+ /* no vfsub_update_h_iattr() since we don't have struct path */
28555+}
28556+
4a4d8108
AM
28557+long vfsub_splice_to(struct file *in, loff_t *ppos,
28558+ struct pipe_inode_info *pipe, size_t len,
28559+ unsigned int flags);
28560+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
28561+ loff_t *ppos, size_t len, unsigned int flags);
c06a8ce3
AM
28562+
28563+static inline long vfsub_truncate(struct path *path, loff_t length)
28564+{
28565+ long err;
28566+ lockdep_off();
28567+ err = vfs_truncate(path, length);
28568+ lockdep_on();
28569+ return err;
28570+}
28571+
4a4d8108
AM
28572+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
28573+ struct file *h_file);
53392da6 28574+int vfsub_fsync(struct file *file, struct path *path, int datasync);
4a4d8108 28575+
1facf9fc 28576+/* ---------------------------------------------------------------------- */
28577+
28578+static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
28579+{
28580+ loff_t err;
28581+
2cbb1c4b 28582+ lockdep_off();
1facf9fc 28583+ err = vfs_llseek(file, offset, origin);
2cbb1c4b 28584+ lockdep_on();
1facf9fc 28585+ return err;
28586+}
28587+
28588+/* ---------------------------------------------------------------------- */
28589+
28590+/* dirty workaround for strict type of fmode_t */
28591+union vfsub_fmu {
28592+ fmode_t fm;
28593+ unsigned int ui;
28594+};
28595+
28596+static inline unsigned int vfsub_fmode_to_uint(fmode_t fm)
28597+{
28598+ union vfsub_fmu u = {
28599+ .fm = fm
28600+ };
28601+
28602+ BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui));
28603+
28604+ return u.ui;
28605+}
28606+
28607+static inline fmode_t vfsub_uint_to_fmode(unsigned int ui)
28608+{
28609+ union vfsub_fmu u = {
28610+ .ui = ui
28611+ };
28612+
28613+ return u.fm;
28614+}
28615+
4a4d8108
AM
28616+/* ---------------------------------------------------------------------- */
28617+
28618+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
28619+int vfsub_sio_rmdir(struct inode *dir, struct path *path);
523b37e3
AM
28620+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
28621+ struct inode **delegated_inode);
28622+int vfsub_notify_change(struct path *path, struct iattr *ia,
28623+ struct inode **delegated_inode);
28624+int vfsub_unlink(struct inode *dir, struct path *path,
28625+ struct inode **delegated_inode, int force);
4a4d8108 28626+
1facf9fc 28627+#endif /* __KERNEL__ */
28628+#endif /* __AUFS_VFSUB_H__ */
7f207e10
AM
28629diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
28630--- /usr/share/empty/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100
523b37e3 28631+++ linux/fs/aufs/wbr_policy.c 2014-01-20 20:16:14.749463838 +0100
392086de 28632@@ -0,0 +1,756 @@
1facf9fc 28633+/*
523b37e3 28634+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 28635+ *
28636+ * This program, aufs is free software; you can redistribute it and/or modify
28637+ * it under the terms of the GNU General Public License as published by
28638+ * the Free Software Foundation; either version 2 of the License, or
28639+ * (at your option) any later version.
dece6358
AM
28640+ *
28641+ * This program is distributed in the hope that it will be useful,
28642+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28643+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28644+ * GNU General Public License for more details.
28645+ *
28646+ * You should have received a copy of the GNU General Public License
523b37e3 28647+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28648+ */
28649+
28650+/*
28651+ * policies for selecting one among multiple writable branches
28652+ */
28653+
28654+#include <linux/statfs.h>
28655+#include "aufs.h"
28656+
28657+/* subset of cpup_attr() */
28658+static noinline_for_stack
28659+int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
28660+{
28661+ int err, sbits;
28662+ struct iattr ia;
28663+ struct inode *h_isrc;
28664+
28665+ h_isrc = h_src->d_inode;
28666+ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
28667+ ia.ia_mode = h_isrc->i_mode;
28668+ ia.ia_uid = h_isrc->i_uid;
28669+ ia.ia_gid = h_isrc->i_gid;
28670+ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
86dc4139 28671+ au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc->i_flags);
523b37e3
AM
28672+ /* no delegation since it is just created */
28673+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 28674+
28675+ /* is this nfs only? */
28676+ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
28677+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
28678+ ia.ia_mode = h_isrc->i_mode;
523b37e3 28679+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 28680+ }
28681+
28682+ return err;
28683+}
28684+
28685+#define AuCpdown_PARENT_OPQ 1
28686+#define AuCpdown_WHED (1 << 1)
28687+#define AuCpdown_MADE_DIR (1 << 2)
28688+#define AuCpdown_DIROPQ (1 << 3)
28689+#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name)
7f207e10
AM
28690+#define au_fset_cpdown(flags, name) \
28691+ do { (flags) |= AuCpdown_##name; } while (0)
28692+#define au_fclr_cpdown(flags, name) \
28693+ do { (flags) &= ~AuCpdown_##name; } while (0)
1facf9fc 28694+
1facf9fc 28695+static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
c2b27bf2 28696+ unsigned int *flags)
1facf9fc 28697+{
28698+ int err;
28699+ struct dentry *opq_dentry;
28700+
28701+ opq_dentry = au_diropq_create(dentry, bdst);
28702+ err = PTR_ERR(opq_dentry);
28703+ if (IS_ERR(opq_dentry))
28704+ goto out;
28705+ dput(opq_dentry);
c2b27bf2 28706+ au_fset_cpdown(*flags, DIROPQ);
1facf9fc 28707+
4f0767ce 28708+out:
1facf9fc 28709+ return err;
28710+}
28711+
28712+static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
28713+ struct inode *dir, aufs_bindex_t bdst)
28714+{
28715+ int err;
28716+ struct path h_path;
28717+ struct au_branch *br;
28718+
28719+ br = au_sbr(dentry->d_sb, bdst);
28720+ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
28721+ err = PTR_ERR(h_path.dentry);
28722+ if (IS_ERR(h_path.dentry))
28723+ goto out;
28724+
28725+ err = 0;
28726+ if (h_path.dentry->d_inode) {
86dc4139 28727+ h_path.mnt = au_br_mnt(br);
1facf9fc 28728+ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
28729+ dentry);
28730+ }
28731+ dput(h_path.dentry);
28732+
4f0767ce 28733+out:
1facf9fc 28734+ return err;
28735+}
28736+
28737+static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 28738+ struct au_pin *pin,
1facf9fc 28739+ struct dentry *h_parent, void *arg)
28740+{
28741+ int err, rerr;
4a4d8108 28742+ aufs_bindex_t bopq, bstart;
1facf9fc 28743+ struct path h_path;
28744+ struct dentry *parent;
28745+ struct inode *h_dir, *h_inode, *inode, *dir;
c2b27bf2 28746+ unsigned int *flags = arg;
1facf9fc 28747+
28748+ bstart = au_dbstart(dentry);
28749+ /* dentry is di-locked */
28750+ parent = dget_parent(dentry);
28751+ dir = parent->d_inode;
28752+ h_dir = h_parent->d_inode;
28753+ AuDebugOn(h_dir != au_h_iptr(dir, bdst));
28754+ IMustLock(h_dir);
28755+
86dc4139 28756+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
1facf9fc 28757+ if (unlikely(err < 0))
28758+ goto out;
28759+ h_path.dentry = au_h_dptr(dentry, bdst);
28760+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
28761+ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path,
28762+ S_IRWXU | S_IRUGO | S_IXUGO);
28763+ if (unlikely(err))
28764+ goto out_put;
c2b27bf2 28765+ au_fset_cpdown(*flags, MADE_DIR);
1facf9fc 28766+
1facf9fc 28767+ bopq = au_dbdiropq(dentry);
c2b27bf2
AM
28768+ au_fclr_cpdown(*flags, WHED);
28769+ au_fclr_cpdown(*flags, DIROPQ);
1facf9fc 28770+ if (au_dbwh(dentry) == bdst)
c2b27bf2
AM
28771+ au_fset_cpdown(*flags, WHED);
28772+ if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst)
28773+ au_fset_cpdown(*flags, PARENT_OPQ);
1facf9fc 28774+ h_inode = h_path.dentry->d_inode;
28775+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
c2b27bf2
AM
28776+ if (au_ftest_cpdown(*flags, WHED)) {
28777+ err = au_cpdown_dir_opq(dentry, bdst, flags);
1facf9fc 28778+ if (unlikely(err)) {
28779+ mutex_unlock(&h_inode->i_mutex);
28780+ goto out_dir;
28781+ }
28782+ }
28783+
28784+ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart));
28785+ mutex_unlock(&h_inode->i_mutex);
28786+ if (unlikely(err))
28787+ goto out_opq;
28788+
c2b27bf2 28789+ if (au_ftest_cpdown(*flags, WHED)) {
1facf9fc 28790+ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
28791+ if (unlikely(err))
28792+ goto out_opq;
28793+ }
28794+
28795+ inode = dentry->d_inode;
28796+ if (au_ibend(inode) < bdst)
28797+ au_set_ibend(inode, bdst);
28798+ au_set_h_iptr(inode, bdst, au_igrab(h_inode),
28799+ au_hi_flags(inode, /*isdir*/1));
28800+ goto out; /* success */
28801+
28802+ /* revert */
4f0767ce 28803+out_opq:
c2b27bf2 28804+ if (au_ftest_cpdown(*flags, DIROPQ)) {
1facf9fc 28805+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
28806+ rerr = au_diropq_remove(dentry, bdst);
28807+ mutex_unlock(&h_inode->i_mutex);
28808+ if (unlikely(rerr)) {
523b37e3
AM
28809+ AuIOErr("failed removing diropq for %pd b%d (%d)\n",
28810+ dentry, bdst, rerr);
1facf9fc 28811+ err = -EIO;
28812+ goto out;
28813+ }
28814+ }
4f0767ce 28815+out_dir:
c2b27bf2 28816+ if (au_ftest_cpdown(*flags, MADE_DIR)) {
1facf9fc 28817+ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
28818+ if (unlikely(rerr)) {
523b37e3
AM
28819+ AuIOErr("failed removing %pd b%d (%d)\n",
28820+ dentry, bdst, rerr);
1facf9fc 28821+ err = -EIO;
28822+ }
28823+ }
4f0767ce 28824+out_put:
1facf9fc 28825+ au_set_h_dptr(dentry, bdst, NULL);
28826+ if (au_dbend(dentry) == bdst)
28827+ au_update_dbend(dentry);
4f0767ce 28828+out:
1facf9fc 28829+ dput(parent);
28830+ return err;
28831+}
28832+
28833+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
28834+{
28835+ int err;
c2b27bf2 28836+ unsigned int flags;
1facf9fc 28837+
c2b27bf2
AM
28838+ flags = 0;
28839+ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &flags);
1facf9fc 28840+
28841+ return err;
28842+}
28843+
28844+/* ---------------------------------------------------------------------- */
28845+
28846+/* policies for create */
28847+
c2b27bf2 28848+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex)
4a4d8108
AM
28849+{
28850+ int err, i, j, ndentry;
28851+ aufs_bindex_t bopq;
28852+ struct au_dcsub_pages dpages;
28853+ struct au_dpage *dpage;
28854+ struct dentry **dentries, *parent, *d;
28855+
28856+ err = au_dpages_init(&dpages, GFP_NOFS);
28857+ if (unlikely(err))
28858+ goto out;
28859+ parent = dget_parent(dentry);
027c5e7a 28860+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0);
4a4d8108
AM
28861+ if (unlikely(err))
28862+ goto out_free;
28863+
28864+ err = bindex;
28865+ for (i = 0; i < dpages.ndpage; i++) {
28866+ dpage = dpages.dpages + i;
28867+ dentries = dpage->dentries;
28868+ ndentry = dpage->ndentry;
28869+ for (j = 0; j < ndentry; j++) {
28870+ d = dentries[j];
28871+ di_read_lock_parent2(d, !AuLock_IR);
28872+ bopq = au_dbdiropq(d);
28873+ di_read_unlock(d, !AuLock_IR);
28874+ if (bopq >= 0 && bopq < err)
28875+ err = bopq;
28876+ }
28877+ }
28878+
28879+out_free:
28880+ dput(parent);
28881+ au_dpages_free(&dpages);
28882+out:
28883+ return err;
28884+}
28885+
1facf9fc 28886+static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
28887+{
28888+ for (; bindex >= 0; bindex--)
28889+ if (!au_br_rdonly(au_sbr(sb, bindex)))
28890+ return bindex;
28891+ return -EROFS;
28892+}
28893+
28894+/* top down parent */
392086de
AM
28895+static int au_wbr_create_tdp(struct dentry *dentry,
28896+ unsigned int flags __maybe_unused)
1facf9fc 28897+{
28898+ int err;
28899+ aufs_bindex_t bstart, bindex;
28900+ struct super_block *sb;
28901+ struct dentry *parent, *h_parent;
28902+
28903+ sb = dentry->d_sb;
28904+ bstart = au_dbstart(dentry);
28905+ err = bstart;
28906+ if (!au_br_rdonly(au_sbr(sb, bstart)))
28907+ goto out;
28908+
28909+ err = -EROFS;
28910+ parent = dget_parent(dentry);
28911+ for (bindex = au_dbstart(parent); bindex < bstart; bindex++) {
28912+ h_parent = au_h_dptr(parent, bindex);
28913+ if (!h_parent || !h_parent->d_inode)
28914+ continue;
28915+
28916+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
28917+ err = bindex;
28918+ break;
28919+ }
28920+ }
28921+ dput(parent);
28922+
28923+ /* bottom up here */
4a4d8108 28924+ if (unlikely(err < 0)) {
1facf9fc 28925+ err = au_wbr_bu(sb, bstart - 1);
4a4d8108
AM
28926+ if (err >= 0)
28927+ err = au_wbr_nonopq(dentry, err);
28928+ }
1facf9fc 28929+
4f0767ce 28930+out:
1facf9fc 28931+ AuDbg("b%d\n", err);
28932+ return err;
28933+}
28934+
28935+/* ---------------------------------------------------------------------- */
28936+
28937+/* an exception for the policy other than tdp */
28938+static int au_wbr_create_exp(struct dentry *dentry)
28939+{
28940+ int err;
28941+ aufs_bindex_t bwh, bdiropq;
28942+ struct dentry *parent;
28943+
28944+ err = -1;
28945+ bwh = au_dbwh(dentry);
28946+ parent = dget_parent(dentry);
28947+ bdiropq = au_dbdiropq(parent);
28948+ if (bwh >= 0) {
28949+ if (bdiropq >= 0)
28950+ err = min(bdiropq, bwh);
28951+ else
28952+ err = bwh;
28953+ AuDbg("%d\n", err);
28954+ } else if (bdiropq >= 0) {
28955+ err = bdiropq;
28956+ AuDbg("%d\n", err);
28957+ }
28958+ dput(parent);
28959+
4a4d8108
AM
28960+ if (err >= 0)
28961+ err = au_wbr_nonopq(dentry, err);
28962+
1facf9fc 28963+ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
28964+ err = -1;
28965+
28966+ AuDbg("%d\n", err);
28967+ return err;
28968+}
28969+
28970+/* ---------------------------------------------------------------------- */
28971+
28972+/* round robin */
28973+static int au_wbr_create_init_rr(struct super_block *sb)
28974+{
28975+ int err;
28976+
28977+ err = au_wbr_bu(sb, au_sbend(sb));
28978+ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
dece6358 28979+ /* smp_mb(); */
1facf9fc 28980+
28981+ AuDbg("b%d\n", err);
28982+ return err;
28983+}
28984+
392086de 28985+static int au_wbr_create_rr(struct dentry *dentry, unsigned int flags)
1facf9fc 28986+{
28987+ int err, nbr;
28988+ unsigned int u;
28989+ aufs_bindex_t bindex, bend;
28990+ struct super_block *sb;
28991+ atomic_t *next;
28992+
28993+ err = au_wbr_create_exp(dentry);
28994+ if (err >= 0)
28995+ goto out;
28996+
28997+ sb = dentry->d_sb;
28998+ next = &au_sbi(sb)->si_wbr_rr_next;
28999+ bend = au_sbend(sb);
29000+ nbr = bend + 1;
29001+ for (bindex = 0; bindex <= bend; bindex++) {
392086de 29002+ if (!au_ftest_wbr(flags, DIR)) {
1facf9fc 29003+ err = atomic_dec_return(next) + 1;
29004+ /* modulo for 0 is meaningless */
29005+ if (unlikely(!err))
29006+ err = atomic_dec_return(next) + 1;
29007+ } else
29008+ err = atomic_read(next);
29009+ AuDbg("%d\n", err);
29010+ u = err;
29011+ err = u % nbr;
29012+ AuDbg("%d\n", err);
29013+ if (!au_br_rdonly(au_sbr(sb, err)))
29014+ break;
29015+ err = -EROFS;
29016+ }
29017+
4a4d8108
AM
29018+ if (err >= 0)
29019+ err = au_wbr_nonopq(dentry, err);
29020+
4f0767ce 29021+out:
1facf9fc 29022+ AuDbg("%d\n", err);
29023+ return err;
29024+}
29025+
29026+/* ---------------------------------------------------------------------- */
29027+
29028+/* most free space */
392086de 29029+static void au_mfs(struct dentry *dentry, struct dentry *parent)
1facf9fc 29030+{
29031+ struct super_block *sb;
29032+ struct au_branch *br;
29033+ struct au_wbr_mfs *mfs;
392086de 29034+ struct dentry *h_parent;
1facf9fc 29035+ aufs_bindex_t bindex, bend;
29036+ int err;
29037+ unsigned long long b, bavail;
7f207e10 29038+ struct path h_path;
1facf9fc 29039+ /* reduce the stack usage */
29040+ struct kstatfs *st;
29041+
29042+ st = kmalloc(sizeof(*st), GFP_NOFS);
29043+ if (unlikely(!st)) {
29044+ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
29045+ return;
29046+ }
29047+
29048+ bavail = 0;
29049+ sb = dentry->d_sb;
29050+ mfs = &au_sbi(sb)->si_wbr_mfs;
dece6358 29051+ MtxMustLock(&mfs->mfs_lock);
1facf9fc 29052+ mfs->mfs_bindex = -EROFS;
29053+ mfs->mfsrr_bytes = 0;
392086de
AM
29054+ if (!parent) {
29055+ bindex = 0;
29056+ bend = au_sbend(sb);
29057+ } else {
29058+ bindex = au_dbstart(parent);
29059+ bend = au_dbtaildir(parent);
29060+ }
29061+
29062+ for (; bindex <= bend; bindex++) {
29063+ if (parent) {
29064+ h_parent = au_h_dptr(parent, bindex);
29065+ if (!h_parent || !h_parent->d_inode)
29066+ continue;
29067+ }
1facf9fc 29068+ br = au_sbr(sb, bindex);
29069+ if (au_br_rdonly(br))
29070+ continue;
29071+
29072+ /* sb->s_root for NFS is unreliable */
86dc4139 29073+ h_path.mnt = au_br_mnt(br);
7f207e10
AM
29074+ h_path.dentry = h_path.mnt->mnt_root;
29075+ err = vfs_statfs(&h_path, st);
1facf9fc 29076+ if (unlikely(err)) {
29077+ AuWarn1("failed statfs, b%d, %d\n", bindex, err);
29078+ continue;
29079+ }
29080+
29081+ /* when the available size is equal, select the lower one */
29082+ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
29083+ || sizeof(b) < sizeof(st->f_bsize));
29084+ b = st->f_bavail * st->f_bsize;
29085+ br->br_wbr->wbr_bytes = b;
29086+ if (b >= bavail) {
29087+ bavail = b;
29088+ mfs->mfs_bindex = bindex;
29089+ mfs->mfs_jiffy = jiffies;
29090+ }
29091+ }
29092+
29093+ mfs->mfsrr_bytes = bavail;
29094+ AuDbg("b%d\n", mfs->mfs_bindex);
29095+ kfree(st);
29096+}
29097+
392086de 29098+static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags)
1facf9fc 29099+{
29100+ int err;
392086de 29101+ struct dentry *parent;
1facf9fc 29102+ struct super_block *sb;
29103+ struct au_wbr_mfs *mfs;
29104+
29105+ err = au_wbr_create_exp(dentry);
29106+ if (err >= 0)
29107+ goto out;
29108+
29109+ sb = dentry->d_sb;
392086de
AM
29110+ parent = NULL;
29111+ if (au_ftest_wbr(flags, PARENT))
29112+ parent = dget_parent(dentry);
1facf9fc 29113+ mfs = &au_sbi(sb)->si_wbr_mfs;
29114+ mutex_lock(&mfs->mfs_lock);
29115+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
29116+ || mfs->mfs_bindex < 0
29117+ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
392086de 29118+ au_mfs(dentry, parent);
1facf9fc 29119+ mutex_unlock(&mfs->mfs_lock);
29120+ err = mfs->mfs_bindex;
392086de 29121+ dput(parent);
1facf9fc 29122+
4a4d8108
AM
29123+ if (err >= 0)
29124+ err = au_wbr_nonopq(dentry, err);
29125+
4f0767ce 29126+out:
1facf9fc 29127+ AuDbg("b%d\n", err);
29128+ return err;
29129+}
29130+
29131+static int au_wbr_create_init_mfs(struct super_block *sb)
29132+{
29133+ struct au_wbr_mfs *mfs;
29134+
29135+ mfs = &au_sbi(sb)->si_wbr_mfs;
29136+ mutex_init(&mfs->mfs_lock);
29137+ mfs->mfs_jiffy = 0;
29138+ mfs->mfs_bindex = -EROFS;
29139+
29140+ return 0;
29141+}
29142+
29143+static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
29144+{
29145+ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
29146+ return 0;
29147+}
29148+
29149+/* ---------------------------------------------------------------------- */
29150+
29151+/* most free space and then round robin */
392086de 29152+static int au_wbr_create_mfsrr(struct dentry *dentry, unsigned int flags)
1facf9fc 29153+{
29154+ int err;
29155+ struct au_wbr_mfs *mfs;
29156+
392086de 29157+ err = au_wbr_create_mfs(dentry, flags);
1facf9fc 29158+ if (err >= 0) {
29159+ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
dece6358 29160+ mutex_lock(&mfs->mfs_lock);
1facf9fc 29161+ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
392086de 29162+ err = au_wbr_create_rr(dentry, flags);
dece6358 29163+ mutex_unlock(&mfs->mfs_lock);
1facf9fc 29164+ }
29165+
29166+ AuDbg("b%d\n", err);
29167+ return err;
29168+}
29169+
29170+static int au_wbr_create_init_mfsrr(struct super_block *sb)
29171+{
29172+ int err;
29173+
29174+ au_wbr_create_init_mfs(sb); /* ignore */
29175+ err = au_wbr_create_init_rr(sb);
29176+
29177+ return err;
29178+}
29179+
29180+/* ---------------------------------------------------------------------- */
29181+
29182+/* top down parent and most free space */
392086de 29183+static int au_wbr_create_pmfs(struct dentry *dentry, unsigned int flags)
1facf9fc 29184+{
29185+ int err, e2;
29186+ unsigned long long b;
29187+ aufs_bindex_t bindex, bstart, bend;
29188+ struct super_block *sb;
29189+ struct dentry *parent, *h_parent;
29190+ struct au_branch *br;
29191+
392086de 29192+ err = au_wbr_create_tdp(dentry, flags);
1facf9fc 29193+ if (unlikely(err < 0))
29194+ goto out;
29195+ parent = dget_parent(dentry);
29196+ bstart = au_dbstart(parent);
29197+ bend = au_dbtaildir(parent);
29198+ if (bstart == bend)
29199+ goto out_parent; /* success */
29200+
392086de 29201+ e2 = au_wbr_create_mfs(dentry, flags);
1facf9fc 29202+ if (e2 < 0)
29203+ goto out_parent; /* success */
29204+
29205+ /* when the available size is equal, select upper one */
29206+ sb = dentry->d_sb;
29207+ br = au_sbr(sb, err);
29208+ b = br->br_wbr->wbr_bytes;
29209+ AuDbg("b%d, %llu\n", err, b);
29210+
29211+ for (bindex = bstart; bindex <= bend; bindex++) {
29212+ h_parent = au_h_dptr(parent, bindex);
29213+ if (!h_parent || !h_parent->d_inode)
29214+ continue;
29215+
29216+ br = au_sbr(sb, bindex);
29217+ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
29218+ b = br->br_wbr->wbr_bytes;
29219+ err = bindex;
29220+ AuDbg("b%d, %llu\n", err, b);
29221+ }
29222+ }
29223+
4a4d8108
AM
29224+ if (err >= 0)
29225+ err = au_wbr_nonopq(dentry, err);
29226+
4f0767ce 29227+out_parent:
1facf9fc 29228+ dput(parent);
4f0767ce 29229+out:
1facf9fc 29230+ AuDbg("b%d\n", err);
29231+ return err;
29232+}
29233+
29234+/* ---------------------------------------------------------------------- */
29235+
392086de
AM
29236+/*
29237+ * - top down parent
29238+ * - most free space with parent
29239+ * - most free space round-robin regardless parent
29240+ */
29241+static int au_wbr_create_pmfsrr(struct dentry *dentry, unsigned int flags)
29242+{
29243+ int err;
29244+ unsigned long long watermark;
29245+ struct super_block *sb;
29246+ struct au_branch *br;
29247+ struct au_wbr_mfs *mfs;
29248+
29249+ err = au_wbr_create_pmfs(dentry, flags | AuWbr_PARENT);
29250+ if (unlikely(err < 0))
29251+ goto out;
29252+
29253+ sb = dentry->d_sb;
29254+ br = au_sbr(sb, err);
29255+ mfs = &au_sbi(sb)->si_wbr_mfs;
29256+ mutex_lock(&mfs->mfs_lock);
29257+ watermark = mfs->mfsrr_watermark;
29258+ mutex_unlock(&mfs->mfs_lock);
29259+ if (br->br_wbr->wbr_bytes < watermark)
29260+ /* regardless the parent dir */
29261+ err = au_wbr_create_mfsrr(dentry, flags);
29262+
29263+out:
29264+ AuDbg("b%d\n", err);
29265+ return err;
29266+}
29267+
29268+/* ---------------------------------------------------------------------- */
29269+
1facf9fc 29270+/* policies for copyup */
29271+
29272+/* top down parent */
29273+static int au_wbr_copyup_tdp(struct dentry *dentry)
29274+{
392086de 29275+ return au_wbr_create_tdp(dentry, /*flags, anything is ok*/0);
1facf9fc 29276+}
29277+
29278+/* bottom up parent */
29279+static int au_wbr_copyup_bup(struct dentry *dentry)
29280+{
29281+ int err;
29282+ aufs_bindex_t bindex, bstart;
29283+ struct dentry *parent, *h_parent;
29284+ struct super_block *sb;
29285+
29286+ err = -EROFS;
29287+ sb = dentry->d_sb;
29288+ parent = dget_parent(dentry);
29289+ bstart = au_dbstart(parent);
29290+ for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) {
29291+ h_parent = au_h_dptr(parent, bindex);
29292+ if (!h_parent || !h_parent->d_inode)
29293+ continue;
29294+
29295+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
29296+ err = bindex;
29297+ break;
29298+ }
29299+ }
29300+ dput(parent);
29301+
29302+ /* bottom up here */
29303+ if (unlikely(err < 0))
29304+ err = au_wbr_bu(sb, bstart - 1);
29305+
29306+ AuDbg("b%d\n", err);
29307+ return err;
29308+}
29309+
29310+/* bottom up */
29311+static int au_wbr_copyup_bu(struct dentry *dentry)
29312+{
29313+ int err;
4a4d8108 29314+ aufs_bindex_t bstart;
1facf9fc 29315+
4a4d8108
AM
29316+ bstart = au_dbstart(dentry);
29317+ err = au_wbr_bu(dentry->d_sb, bstart);
29318+ AuDbg("b%d\n", err);
29319+ if (err > bstart)
29320+ err = au_wbr_nonopq(dentry, err);
1facf9fc 29321+
29322+ AuDbg("b%d\n", err);
29323+ return err;
29324+}
29325+
29326+/* ---------------------------------------------------------------------- */
29327+
29328+struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
29329+ [AuWbrCopyup_TDP] = {
29330+ .copyup = au_wbr_copyup_tdp
29331+ },
29332+ [AuWbrCopyup_BUP] = {
29333+ .copyup = au_wbr_copyup_bup
29334+ },
29335+ [AuWbrCopyup_BU] = {
29336+ .copyup = au_wbr_copyup_bu
29337+ }
29338+};
29339+
29340+struct au_wbr_create_operations au_wbr_create_ops[] = {
29341+ [AuWbrCreate_TDP] = {
29342+ .create = au_wbr_create_tdp
29343+ },
29344+ [AuWbrCreate_RR] = {
29345+ .create = au_wbr_create_rr,
29346+ .init = au_wbr_create_init_rr
29347+ },
29348+ [AuWbrCreate_MFS] = {
29349+ .create = au_wbr_create_mfs,
29350+ .init = au_wbr_create_init_mfs,
29351+ .fin = au_wbr_create_fin_mfs
29352+ },
29353+ [AuWbrCreate_MFSV] = {
29354+ .create = au_wbr_create_mfs,
29355+ .init = au_wbr_create_init_mfs,
29356+ .fin = au_wbr_create_fin_mfs
29357+ },
29358+ [AuWbrCreate_MFSRR] = {
29359+ .create = au_wbr_create_mfsrr,
29360+ .init = au_wbr_create_init_mfsrr,
29361+ .fin = au_wbr_create_fin_mfs
29362+ },
29363+ [AuWbrCreate_MFSRRV] = {
29364+ .create = au_wbr_create_mfsrr,
29365+ .init = au_wbr_create_init_mfsrr,
29366+ .fin = au_wbr_create_fin_mfs
29367+ },
29368+ [AuWbrCreate_PMFS] = {
29369+ .create = au_wbr_create_pmfs,
29370+ .init = au_wbr_create_init_mfs,
29371+ .fin = au_wbr_create_fin_mfs
29372+ },
29373+ [AuWbrCreate_PMFSV] = {
29374+ .create = au_wbr_create_pmfs,
29375+ .init = au_wbr_create_init_mfs,
29376+ .fin = au_wbr_create_fin_mfs
392086de
AM
29377+ },
29378+ [AuWbrCreate_PMFSRR] = {
29379+ .create = au_wbr_create_pmfsrr,
29380+ .init = au_wbr_create_init_mfsrr,
29381+ .fin = au_wbr_create_fin_mfs
29382+ },
29383+ [AuWbrCreate_PMFSRRV] = {
29384+ .create = au_wbr_create_pmfsrr,
29385+ .init = au_wbr_create_init_mfsrr,
29386+ .fin = au_wbr_create_fin_mfs
1facf9fc 29387+ }
29388+};
7f207e10
AM
29389diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
29390--- /usr/share/empty/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
29391+++ linux/fs/aufs/whout.c 2014-01-20 20:16:14.749463838 +0100
29392@@ -0,0 +1,1052 @@
1facf9fc 29393+/*
523b37e3 29394+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 29395+ *
29396+ * This program, aufs is free software; you can redistribute it and/or modify
29397+ * it under the terms of the GNU General Public License as published by
29398+ * the Free Software Foundation; either version 2 of the License, or
29399+ * (at your option) any later version.
dece6358
AM
29400+ *
29401+ * This program is distributed in the hope that it will be useful,
29402+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29403+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29404+ * GNU General Public License for more details.
29405+ *
29406+ * You should have received a copy of the GNU General Public License
523b37e3 29407+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 29408+ */
29409+
29410+/*
29411+ * whiteout for logical deletion and opaque directory
29412+ */
29413+
1facf9fc 29414+#include "aufs.h"
29415+
29416+#define WH_MASK S_IRUGO
29417+
29418+/*
29419+ * If a directory contains this file, then it is opaque. We start with the
29420+ * .wh. flag so that it is blocked by lookup.
29421+ */
0c3ec466
AM
29422+static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ,
29423+ sizeof(AUFS_WH_DIROPQ) - 1);
1facf9fc 29424+
29425+/*
29426+ * generate whiteout name, which is NOT terminated by NULL.
29427+ * @name: original d_name.name
29428+ * @len: original d_name.len
29429+ * @wh: whiteout qstr
29430+ * returns zero when succeeds, otherwise error.
29431+ * succeeded value as wh->name should be freed by kfree().
29432+ */
29433+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
29434+{
29435+ char *p;
29436+
29437+ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
29438+ return -ENAMETOOLONG;
29439+
29440+ wh->len = name->len + AUFS_WH_PFX_LEN;
29441+ p = kmalloc(wh->len, GFP_NOFS);
29442+ wh->name = p;
29443+ if (p) {
29444+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
29445+ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
29446+ /* smp_mb(); */
29447+ return 0;
29448+ }
29449+ return -ENOMEM;
29450+}
29451+
29452+/* ---------------------------------------------------------------------- */
29453+
29454+/*
29455+ * test if the @wh_name exists under @h_parent.
29456+ * @try_sio specifies the necessary of super-io.
29457+ */
29458+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
29459+ struct au_branch *br, int try_sio)
29460+{
29461+ int err;
29462+ struct dentry *wh_dentry;
1facf9fc 29463+
1facf9fc 29464+ if (!try_sio)
b4510431 29465+ wh_dentry = vfsub_lkup_one(wh_name, h_parent);
1facf9fc 29466+ else
29467+ wh_dentry = au_sio_lkup_one(wh_name, h_parent, br);
29468+ err = PTR_ERR(wh_dentry);
29469+ if (IS_ERR(wh_dentry))
29470+ goto out;
29471+
29472+ err = 0;
29473+ if (!wh_dentry->d_inode)
29474+ goto out_wh; /* success */
29475+
29476+ err = 1;
29477+ if (S_ISREG(wh_dentry->d_inode->i_mode))
29478+ goto out_wh; /* success */
29479+
29480+ err = -EIO;
523b37e3
AM
29481+ AuIOErr("%pd Invalid whiteout entry type 0%o.\n",
29482+ wh_dentry, wh_dentry->d_inode->i_mode);
1facf9fc 29483+
4f0767ce 29484+out_wh:
1facf9fc 29485+ dput(wh_dentry);
4f0767ce 29486+out:
1facf9fc 29487+ return err;
29488+}
29489+
29490+/*
29491+ * test if the @h_dentry sets opaque or not.
29492+ */
29493+int au_diropq_test(struct dentry *h_dentry, struct au_branch *br)
29494+{
29495+ int err;
29496+ struct inode *h_dir;
29497+
29498+ h_dir = h_dentry->d_inode;
29499+ err = au_wh_test(h_dentry, &diropq_name, br,
29500+ au_test_h_perm_sio(h_dir, MAY_EXEC));
29501+ return err;
29502+}
29503+
29504+/*
29505+ * returns a negative dentry whose name is unique and temporary.
29506+ */
29507+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
29508+ struct qstr *prefix)
29509+{
1facf9fc 29510+ struct dentry *dentry;
29511+ int i;
027c5e7a 29512+ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
4a4d8108 29513+ *name, *p;
027c5e7a 29514+ /* strict atomic_t is unnecessary here */
1facf9fc 29515+ static unsigned short cnt;
29516+ struct qstr qs;
29517+
4a4d8108
AM
29518+ BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
29519+
1facf9fc 29520+ name = defname;
027c5e7a
AM
29521+ qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
29522+ if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
1facf9fc 29523+ dentry = ERR_PTR(-ENAMETOOLONG);
4a4d8108 29524+ if (unlikely(qs.len > NAME_MAX))
1facf9fc 29525+ goto out;
29526+ dentry = ERR_PTR(-ENOMEM);
29527+ name = kmalloc(qs.len + 1, GFP_NOFS);
29528+ if (unlikely(!name))
29529+ goto out;
29530+ }
29531+
29532+ /* doubly whiteout-ed */
29533+ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
29534+ p = name + AUFS_WH_PFX_LEN * 2;
29535+ memcpy(p, prefix->name, prefix->len);
29536+ p += prefix->len;
29537+ *p++ = '.';
4a4d8108 29538+ AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
1facf9fc 29539+
29540+ qs.name = name;
29541+ for (i = 0; i < 3; i++) {
b752ccd1 29542+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
1facf9fc 29543+ dentry = au_sio_lkup_one(&qs, h_parent, br);
29544+ if (IS_ERR(dentry) || !dentry->d_inode)
29545+ goto out_name;
29546+ dput(dentry);
29547+ }
0c3ec466 29548+ /* pr_warn("could not get random name\n"); */
1facf9fc 29549+ dentry = ERR_PTR(-EEXIST);
29550+ AuDbg("%.*s\n", AuLNPair(&qs));
29551+ BUG();
29552+
4f0767ce 29553+out_name:
1facf9fc 29554+ if (name != defname)
29555+ kfree(name);
4f0767ce 29556+out:
4a4d8108 29557+ AuTraceErrPtr(dentry);
1facf9fc 29558+ return dentry;
1facf9fc 29559+}
29560+
29561+/*
29562+ * rename the @h_dentry on @br to the whiteouted temporary name.
29563+ */
29564+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
29565+{
29566+ int err;
29567+ struct path h_path = {
86dc4139 29568+ .mnt = au_br_mnt(br)
1facf9fc 29569+ };
523b37e3 29570+ struct inode *h_dir, *delegated;
1facf9fc 29571+ struct dentry *h_parent;
29572+
29573+ h_parent = h_dentry->d_parent; /* dir inode is locked */
29574+ h_dir = h_parent->d_inode;
29575+ IMustLock(h_dir);
29576+
29577+ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
29578+ err = PTR_ERR(h_path.dentry);
29579+ if (IS_ERR(h_path.dentry))
29580+ goto out;
29581+
29582+ /* under the same dir, no need to lock_rename() */
523b37e3
AM
29583+ delegated = NULL;
29584+ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path, &delegated);
1facf9fc 29585+ AuTraceErr(err);
523b37e3
AM
29586+ if (unlikely(err == -EWOULDBLOCK)) {
29587+ pr_warn("cannot retry for NFSv4 delegation"
29588+ " for an internal rename\n");
29589+ iput(delegated);
29590+ }
1facf9fc 29591+ dput(h_path.dentry);
29592+
4f0767ce 29593+out:
4a4d8108 29594+ AuTraceErr(err);
1facf9fc 29595+ return err;
29596+}
29597+
29598+/* ---------------------------------------------------------------------- */
29599+/*
29600+ * functions for removing a whiteout
29601+ */
29602+
29603+static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
29604+{
523b37e3
AM
29605+ int err, force;
29606+ struct inode *delegated;
1facf9fc 29607+
29608+ /*
29609+ * forces superio when the dir has a sticky bit.
29610+ * this may be a violation of unix fs semantics.
29611+ */
29612+ force = (h_dir->i_mode & S_ISVTX)
0c3ec466 29613+ && !uid_eq(current_fsuid(), h_path->dentry->d_inode->i_uid);
523b37e3
AM
29614+ delegated = NULL;
29615+ err = vfsub_unlink(h_dir, h_path, &delegated, force);
29616+ if (unlikely(err == -EWOULDBLOCK)) {
29617+ pr_warn("cannot retry for NFSv4 delegation"
29618+ " for an internal unlink\n");
29619+ iput(delegated);
29620+ }
29621+ return err;
1facf9fc 29622+}
29623+
29624+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
29625+ struct dentry *dentry)
29626+{
29627+ int err;
29628+
29629+ err = do_unlink_wh(h_dir, h_path);
29630+ if (!err && dentry)
29631+ au_set_dbwh(dentry, -1);
29632+
29633+ return err;
29634+}
29635+
29636+static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
29637+ struct au_branch *br)
29638+{
29639+ int err;
29640+ struct path h_path = {
86dc4139 29641+ .mnt = au_br_mnt(br)
1facf9fc 29642+ };
29643+
29644+ err = 0;
b4510431 29645+ h_path.dentry = vfsub_lkup_one(wh, h_parent);
1facf9fc 29646+ if (IS_ERR(h_path.dentry))
29647+ err = PTR_ERR(h_path.dentry);
29648+ else {
29649+ if (h_path.dentry->d_inode
29650+ && S_ISREG(h_path.dentry->d_inode->i_mode))
29651+ err = do_unlink_wh(h_parent->d_inode, &h_path);
29652+ dput(h_path.dentry);
29653+ }
29654+
29655+ return err;
29656+}
29657+
29658+/* ---------------------------------------------------------------------- */
29659+/*
29660+ * initialize/clean whiteout for a branch
29661+ */
29662+
29663+static void au_wh_clean(struct inode *h_dir, struct path *whpath,
29664+ const int isdir)
29665+{
29666+ int err;
523b37e3 29667+ struct inode *delegated;
1facf9fc 29668+
29669+ if (!whpath->dentry->d_inode)
29670+ return;
29671+
86dc4139
AM
29672+ if (isdir)
29673+ err = vfsub_rmdir(h_dir, whpath);
523b37e3
AM
29674+ else {
29675+ delegated = NULL;
29676+ err = vfsub_unlink(h_dir, whpath, &delegated, /*force*/0);
29677+ if (unlikely(err == -EWOULDBLOCK)) {
29678+ pr_warn("cannot retry for NFSv4 delegation"
29679+ " for an internal unlink\n");
29680+ iput(delegated);
29681+ }
29682+ }
1facf9fc 29683+ if (unlikely(err))
523b37e3
AM
29684+ pr_warn("failed removing %pd (%d), ignored.\n",
29685+ whpath->dentry, err);
1facf9fc 29686+}
29687+
29688+static int test_linkable(struct dentry *h_root)
29689+{
29690+ struct inode *h_dir = h_root->d_inode;
29691+
29692+ if (h_dir->i_op->link)
29693+ return 0;
29694+
523b37e3
AM
29695+ pr_err("%pd (%s) doesn't support link(2), use noplink and rw+nolwh\n",
29696+ h_root, au_sbtype(h_root->d_sb));
1facf9fc 29697+ return -ENOSYS;
29698+}
29699+
29700+/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
29701+static int au_whdir(struct inode *h_dir, struct path *path)
29702+{
29703+ int err;
29704+
29705+ err = -EEXIST;
29706+ if (!path->dentry->d_inode) {
29707+ int mode = S_IRWXU;
29708+
29709+ if (au_test_nfs(path->dentry->d_sb))
29710+ mode |= S_IXUGO;
86dc4139 29711+ err = vfsub_mkdir(h_dir, path, mode);
1facf9fc 29712+ } else if (S_ISDIR(path->dentry->d_inode->i_mode))
29713+ err = 0;
29714+ else
523b37e3 29715+ pr_err("unknown %pd exists\n", path->dentry);
1facf9fc 29716+
29717+ return err;
29718+}
29719+
29720+struct au_wh_base {
29721+ const struct qstr *name;
29722+ struct dentry *dentry;
29723+};
29724+
29725+static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
29726+ struct path *h_path)
29727+{
29728+ h_path->dentry = base[AuBrWh_BASE].dentry;
29729+ au_wh_clean(h_dir, h_path, /*isdir*/0);
29730+ h_path->dentry = base[AuBrWh_PLINK].dentry;
29731+ au_wh_clean(h_dir, h_path, /*isdir*/1);
29732+ h_path->dentry = base[AuBrWh_ORPH].dentry;
29733+ au_wh_clean(h_dir, h_path, /*isdir*/1);
29734+}
29735+
29736+/*
29737+ * returns tri-state,
29738+ * minus: error, caller should print the mesage
29739+ * zero: succuess
29740+ * plus: error, caller should NOT print the mesage
29741+ */
29742+static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
29743+ int do_plink, struct au_wh_base base[],
29744+ struct path *h_path)
29745+{
29746+ int err;
29747+ struct inode *h_dir;
29748+
29749+ h_dir = h_root->d_inode;
29750+ h_path->dentry = base[AuBrWh_BASE].dentry;
29751+ au_wh_clean(h_dir, h_path, /*isdir*/0);
29752+ h_path->dentry = base[AuBrWh_PLINK].dentry;
29753+ if (do_plink) {
29754+ err = test_linkable(h_root);
29755+ if (unlikely(err)) {
29756+ err = 1;
29757+ goto out;
29758+ }
29759+
29760+ err = au_whdir(h_dir, h_path);
29761+ if (unlikely(err))
29762+ goto out;
29763+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
29764+ } else
29765+ au_wh_clean(h_dir, h_path, /*isdir*/1);
29766+ h_path->dentry = base[AuBrWh_ORPH].dentry;
29767+ err = au_whdir(h_dir, h_path);
29768+ if (unlikely(err))
29769+ goto out;
29770+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
29771+
4f0767ce 29772+out:
1facf9fc 29773+ return err;
29774+}
29775+
29776+/*
29777+ * for the moment, aufs supports the branch filesystem which does not support
29778+ * link(2). testing on FAT which does not support i_op->setattr() fully either,
29779+ * copyup failed. finally, such filesystem will not be used as the writable
29780+ * branch.
29781+ *
29782+ * returns tri-state, see above.
29783+ */
29784+static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
29785+ int do_plink, struct au_wh_base base[],
29786+ struct path *h_path)
29787+{
29788+ int err;
29789+ struct inode *h_dir;
29790+
1308ab2a 29791+ WbrWhMustWriteLock(wbr);
29792+
1facf9fc 29793+ err = test_linkable(h_root);
29794+ if (unlikely(err)) {
29795+ err = 1;
29796+ goto out;
29797+ }
29798+
29799+ /*
29800+ * todo: should this create be done in /sbin/mount.aufs helper?
29801+ */
29802+ err = -EEXIST;
29803+ h_dir = h_root->d_inode;
29804+ if (!base[AuBrWh_BASE].dentry->d_inode) {
86dc4139
AM
29805+ h_path->dentry = base[AuBrWh_BASE].dentry;
29806+ err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true);
1facf9fc 29807+ } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode))
29808+ err = 0;
29809+ else
523b37e3 29810+ pr_err("unknown %pd2 exists\n", base[AuBrWh_BASE].dentry);
1facf9fc 29811+ if (unlikely(err))
29812+ goto out;
29813+
29814+ h_path->dentry = base[AuBrWh_PLINK].dentry;
29815+ if (do_plink) {
29816+ err = au_whdir(h_dir, h_path);
29817+ if (unlikely(err))
29818+ goto out;
29819+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
29820+ } else
29821+ au_wh_clean(h_dir, h_path, /*isdir*/1);
29822+ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
29823+
29824+ h_path->dentry = base[AuBrWh_ORPH].dentry;
29825+ err = au_whdir(h_dir, h_path);
29826+ if (unlikely(err))
29827+ goto out;
29828+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
29829+
4f0767ce 29830+out:
1facf9fc 29831+ return err;
29832+}
29833+
29834+/*
29835+ * initialize the whiteout base file/dir for @br.
29836+ */
86dc4139 29837+int au_wh_init(struct au_branch *br, struct super_block *sb)
1facf9fc 29838+{
29839+ int err, i;
29840+ const unsigned char do_plink
29841+ = !!au_opt_test(au_mntflags(sb), PLINK);
1facf9fc 29842+ struct inode *h_dir;
86dc4139
AM
29843+ struct path path = br->br_path;
29844+ struct dentry *h_root = path.dentry;
1facf9fc 29845+ struct au_wbr *wbr = br->br_wbr;
29846+ static const struct qstr base_name[] = {
0c3ec466
AM
29847+ [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME,
29848+ sizeof(AUFS_BASE_NAME) - 1),
29849+ [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME,
29850+ sizeof(AUFS_PLINKDIR_NAME) - 1),
29851+ [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME,
29852+ sizeof(AUFS_ORPHDIR_NAME) - 1)
1facf9fc 29853+ };
29854+ struct au_wh_base base[] = {
29855+ [AuBrWh_BASE] = {
29856+ .name = base_name + AuBrWh_BASE,
29857+ .dentry = NULL
29858+ },
29859+ [AuBrWh_PLINK] = {
29860+ .name = base_name + AuBrWh_PLINK,
29861+ .dentry = NULL
29862+ },
29863+ [AuBrWh_ORPH] = {
29864+ .name = base_name + AuBrWh_ORPH,
29865+ .dentry = NULL
29866+ }
29867+ };
29868+
1308ab2a 29869+ if (wbr)
29870+ WbrWhMustWriteLock(wbr);
1facf9fc 29871+
1facf9fc 29872+ for (i = 0; i < AuBrWh_Last; i++) {
29873+ /* doubly whiteouted */
29874+ struct dentry *d;
29875+
29876+ d = au_wh_lkup(h_root, (void *)base[i].name, br);
29877+ err = PTR_ERR(d);
29878+ if (IS_ERR(d))
29879+ goto out;
29880+
29881+ base[i].dentry = d;
29882+ AuDebugOn(wbr
29883+ && wbr->wbr_wh[i]
29884+ && wbr->wbr_wh[i] != base[i].dentry);
29885+ }
29886+
29887+ if (wbr)
29888+ for (i = 0; i < AuBrWh_Last; i++) {
29889+ dput(wbr->wbr_wh[i]);
29890+ wbr->wbr_wh[i] = NULL;
29891+ }
29892+
29893+ err = 0;
1e00d052 29894+ if (!au_br_writable(br->br_perm)) {
4a4d8108 29895+ h_dir = h_root->d_inode;
1facf9fc 29896+ au_wh_init_ro(h_dir, base, &path);
1e00d052 29897+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 29898+ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
29899+ if (err > 0)
29900+ goto out;
29901+ else if (err)
29902+ goto out_err;
1e00d052 29903+ } else {
1facf9fc 29904+ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
29905+ if (err > 0)
29906+ goto out;
29907+ else if (err)
29908+ goto out_err;
1facf9fc 29909+ }
29910+ goto out; /* success */
29911+
4f0767ce 29912+out_err:
523b37e3
AM
29913+ pr_err("an error(%d) on the writable branch %pd(%s)\n",
29914+ err, h_root, au_sbtype(h_root->d_sb));
4f0767ce 29915+out:
1facf9fc 29916+ for (i = 0; i < AuBrWh_Last; i++)
29917+ dput(base[i].dentry);
29918+ return err;
29919+}
29920+
29921+/* ---------------------------------------------------------------------- */
29922+/*
29923+ * whiteouts are all hard-linked usually.
29924+ * when its link count reaches a ceiling, we create a new whiteout base
29925+ * asynchronously.
29926+ */
29927+
29928+struct reinit_br_wh {
29929+ struct super_block *sb;
29930+ struct au_branch *br;
29931+};
29932+
29933+static void reinit_br_wh(void *arg)
29934+{
29935+ int err;
29936+ aufs_bindex_t bindex;
29937+ struct path h_path;
29938+ struct reinit_br_wh *a = arg;
29939+ struct au_wbr *wbr;
523b37e3 29940+ struct inode *dir, *delegated;
1facf9fc 29941+ struct dentry *h_root;
29942+ struct au_hinode *hdir;
29943+
29944+ err = 0;
29945+ wbr = a->br->br_wbr;
29946+ /* big aufs lock */
29947+ si_noflush_write_lock(a->sb);
29948+ if (!au_br_writable(a->br->br_perm))
29949+ goto out;
29950+ bindex = au_br_index(a->sb, a->br->br_id);
29951+ if (unlikely(bindex < 0))
29952+ goto out;
29953+
1308ab2a 29954+ di_read_lock_parent(a->sb->s_root, AuLock_IR);
1facf9fc 29955+ dir = a->sb->s_root->d_inode;
1facf9fc 29956+ hdir = au_hi(dir, bindex);
29957+ h_root = au_h_dptr(a->sb->s_root, bindex);
86dc4139 29958+ AuDebugOn(h_root != au_br_dentry(a->br));
1facf9fc 29959+
4a4d8108 29960+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 29961+ wbr_wh_write_lock(wbr);
29962+ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
29963+ h_root, a->br);
29964+ if (!err) {
86dc4139
AM
29965+ h_path.dentry = wbr->wbr_whbase;
29966+ h_path.mnt = au_br_mnt(a->br);
523b37e3
AM
29967+ delegated = NULL;
29968+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated,
29969+ /*force*/0);
29970+ if (unlikely(err == -EWOULDBLOCK)) {
29971+ pr_warn("cannot retry for NFSv4 delegation"
29972+ " for an internal unlink\n");
29973+ iput(delegated);
29974+ }
1facf9fc 29975+ } else {
523b37e3 29976+ pr_warn("%pd is moved, ignored\n", wbr->wbr_whbase);
1facf9fc 29977+ err = 0;
29978+ }
29979+ dput(wbr->wbr_whbase);
29980+ wbr->wbr_whbase = NULL;
29981+ if (!err)
86dc4139 29982+ err = au_wh_init(a->br, a->sb);
1facf9fc 29983+ wbr_wh_write_unlock(wbr);
4a4d8108 29984+ au_hn_imtx_unlock(hdir);
1308ab2a 29985+ di_read_unlock(a->sb->s_root, AuLock_IR);
1facf9fc 29986+
4f0767ce 29987+out:
1facf9fc 29988+ if (wbr)
29989+ atomic_dec(&wbr->wbr_wh_running);
29990+ atomic_dec(&a->br->br_count);
1facf9fc 29991+ si_write_unlock(a->sb);
027c5e7a 29992+ au_nwt_done(&au_sbi(a->sb)->si_nowait);
1facf9fc 29993+ kfree(arg);
29994+ if (unlikely(err))
29995+ AuIOErr("err %d\n", err);
29996+}
29997+
29998+static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
29999+{
30000+ int do_dec, wkq_err;
30001+ struct reinit_br_wh *arg;
30002+
30003+ do_dec = 1;
30004+ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
30005+ goto out;
30006+
30007+ /* ignore ENOMEM */
30008+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
30009+ if (arg) {
30010+ /*
30011+ * dec(wh_running), kfree(arg) and dec(br_count)
30012+ * in reinit function
30013+ */
30014+ arg->sb = sb;
30015+ arg->br = br;
30016+ atomic_inc(&br->br_count);
53392da6 30017+ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0);
1facf9fc 30018+ if (unlikely(wkq_err)) {
30019+ atomic_dec(&br->br_wbr->wbr_wh_running);
30020+ atomic_dec(&br->br_count);
30021+ kfree(arg);
30022+ }
30023+ do_dec = 0;
30024+ }
30025+
4f0767ce 30026+out:
1facf9fc 30027+ if (do_dec)
30028+ atomic_dec(&br->br_wbr->wbr_wh_running);
30029+}
30030+
30031+/* ---------------------------------------------------------------------- */
30032+
30033+/*
30034+ * create the whiteout @wh.
30035+ */
30036+static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
30037+ struct dentry *wh)
30038+{
30039+ int err;
30040+ struct path h_path = {
30041+ .dentry = wh
30042+ };
30043+ struct au_branch *br;
30044+ struct au_wbr *wbr;
30045+ struct dentry *h_parent;
523b37e3 30046+ struct inode *h_dir, *delegated;
1facf9fc 30047+
30048+ h_parent = wh->d_parent; /* dir inode is locked */
30049+ h_dir = h_parent->d_inode;
30050+ IMustLock(h_dir);
30051+
30052+ br = au_sbr(sb, bindex);
86dc4139 30053+ h_path.mnt = au_br_mnt(br);
1facf9fc 30054+ wbr = br->br_wbr;
30055+ wbr_wh_read_lock(wbr);
30056+ if (wbr->wbr_whbase) {
523b37e3
AM
30057+ delegated = NULL;
30058+ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path, &delegated);
30059+ if (unlikely(err == -EWOULDBLOCK)) {
30060+ pr_warn("cannot retry for NFSv4 delegation"
30061+ " for an internal link\n");
30062+ iput(delegated);
30063+ }
1facf9fc 30064+ if (!err || err != -EMLINK)
30065+ goto out;
30066+
30067+ /* link count full. re-initialize br_whbase. */
30068+ kick_reinit_br_wh(sb, br);
30069+ }
30070+
30071+ /* return this error in this context */
b4510431 30072+ err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true);
1facf9fc 30073+
4f0767ce 30074+out:
1facf9fc 30075+ wbr_wh_read_unlock(wbr);
30076+ return err;
30077+}
30078+
30079+/* ---------------------------------------------------------------------- */
30080+
30081+/*
30082+ * create or remove the diropq.
30083+ */
30084+static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
30085+ unsigned int flags)
30086+{
30087+ struct dentry *opq_dentry, *h_dentry;
30088+ struct super_block *sb;
30089+ struct au_branch *br;
30090+ int err;
30091+
30092+ sb = dentry->d_sb;
30093+ br = au_sbr(sb, bindex);
30094+ h_dentry = au_h_dptr(dentry, bindex);
b4510431 30095+ opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry);
1facf9fc 30096+ if (IS_ERR(opq_dentry))
30097+ goto out;
30098+
30099+ if (au_ftest_diropq(flags, CREATE)) {
30100+ err = link_or_create_wh(sb, bindex, opq_dentry);
30101+ if (!err) {
30102+ au_set_dbdiropq(dentry, bindex);
30103+ goto out; /* success */
30104+ }
30105+ } else {
30106+ struct path tmp = {
30107+ .dentry = opq_dentry,
86dc4139 30108+ .mnt = au_br_mnt(br)
1facf9fc 30109+ };
30110+ err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp);
30111+ if (!err)
30112+ au_set_dbdiropq(dentry, -1);
30113+ }
30114+ dput(opq_dentry);
30115+ opq_dentry = ERR_PTR(err);
30116+
4f0767ce 30117+out:
1facf9fc 30118+ return opq_dentry;
30119+}
30120+
30121+struct do_diropq_args {
30122+ struct dentry **errp;
30123+ struct dentry *dentry;
30124+ aufs_bindex_t bindex;
30125+ unsigned int flags;
30126+};
30127+
30128+static void call_do_diropq(void *args)
30129+{
30130+ struct do_diropq_args *a = args;
30131+ *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
30132+}
30133+
30134+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
30135+ unsigned int flags)
30136+{
30137+ struct dentry *diropq, *h_dentry;
30138+
30139+ h_dentry = au_h_dptr(dentry, bindex);
30140+ if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE))
30141+ diropq = do_diropq(dentry, bindex, flags);
30142+ else {
30143+ int wkq_err;
30144+ struct do_diropq_args args = {
30145+ .errp = &diropq,
30146+ .dentry = dentry,
30147+ .bindex = bindex,
30148+ .flags = flags
30149+ };
30150+
30151+ wkq_err = au_wkq_wait(call_do_diropq, &args);
30152+ if (unlikely(wkq_err))
30153+ diropq = ERR_PTR(wkq_err);
30154+ }
30155+
30156+ return diropq;
30157+}
30158+
30159+/* ---------------------------------------------------------------------- */
30160+
30161+/*
30162+ * lookup whiteout dentry.
30163+ * @h_parent: lower parent dentry which must exist and be locked
30164+ * @base_name: name of dentry which will be whiteouted
30165+ * returns dentry for whiteout.
30166+ */
30167+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
30168+ struct au_branch *br)
30169+{
30170+ int err;
30171+ struct qstr wh_name;
30172+ struct dentry *wh_dentry;
30173+
30174+ err = au_wh_name_alloc(&wh_name, base_name);
30175+ wh_dentry = ERR_PTR(err);
30176+ if (!err) {
b4510431 30177+ wh_dentry = vfsub_lkup_one(&wh_name, h_parent);
1facf9fc 30178+ kfree(wh_name.name);
30179+ }
30180+ return wh_dentry;
30181+}
30182+
30183+/*
30184+ * link/create a whiteout for @dentry on @bindex.
30185+ */
30186+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
30187+ struct dentry *h_parent)
30188+{
30189+ struct dentry *wh_dentry;
30190+ struct super_block *sb;
30191+ int err;
30192+
30193+ sb = dentry->d_sb;
30194+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
30195+ if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) {
30196+ err = link_or_create_wh(sb, bindex, wh_dentry);
30197+ if (!err)
30198+ au_set_dbwh(dentry, bindex);
30199+ else {
30200+ dput(wh_dentry);
30201+ wh_dentry = ERR_PTR(err);
30202+ }
30203+ }
30204+
30205+ return wh_dentry;
30206+}
30207+
30208+/* ---------------------------------------------------------------------- */
30209+
30210+/* Delete all whiteouts in this directory on branch bindex. */
30211+static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
30212+ aufs_bindex_t bindex, struct au_branch *br)
30213+{
30214+ int err;
30215+ unsigned long ul, n;
30216+ struct qstr wh_name;
30217+ char *p;
30218+ struct hlist_head *head;
c06a8ce3 30219+ struct au_vdir_wh *pos;
1facf9fc 30220+ struct au_vdir_destr *str;
30221+
30222+ err = -ENOMEM;
537831f9 30223+ p = (void *)__get_free_page(GFP_NOFS);
1facf9fc 30224+ wh_name.name = p;
30225+ if (unlikely(!wh_name.name))
30226+ goto out;
30227+
30228+ err = 0;
30229+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
30230+ p += AUFS_WH_PFX_LEN;
30231+ n = whlist->nh_num;
30232+ head = whlist->nh_head;
30233+ for (ul = 0; !err && ul < n; ul++, head++) {
c06a8ce3
AM
30234+ hlist_for_each_entry(pos, head, wh_hash) {
30235+ if (pos->wh_bindex != bindex)
1facf9fc 30236+ continue;
30237+
c06a8ce3 30238+ str = &pos->wh_str;
1facf9fc 30239+ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
30240+ memcpy(p, str->name, str->len);
30241+ wh_name.len = AUFS_WH_PFX_LEN + str->len;
30242+ err = unlink_wh_name(h_dentry, &wh_name, br);
30243+ if (!err)
30244+ continue;
30245+ break;
30246+ }
30247+ AuIOErr("whiteout name too long %.*s\n",
30248+ str->len, str->name);
30249+ err = -EIO;
30250+ break;
30251+ }
30252+ }
537831f9 30253+ free_page((unsigned long)wh_name.name);
1facf9fc 30254+
4f0767ce 30255+out:
1facf9fc 30256+ return err;
30257+}
30258+
30259+struct del_wh_children_args {
30260+ int *errp;
30261+ struct dentry *h_dentry;
1308ab2a 30262+ struct au_nhash *whlist;
1facf9fc 30263+ aufs_bindex_t bindex;
30264+ struct au_branch *br;
30265+};
30266+
30267+static void call_del_wh_children(void *args)
30268+{
30269+ struct del_wh_children_args *a = args;
1308ab2a 30270+ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
1facf9fc 30271+}
30272+
30273+/* ---------------------------------------------------------------------- */
30274+
30275+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
30276+{
30277+ struct au_whtmp_rmdir *whtmp;
dece6358 30278+ int err;
1308ab2a 30279+ unsigned int rdhash;
dece6358
AM
30280+
30281+ SiMustAnyLock(sb);
1facf9fc 30282+
30283+ whtmp = kmalloc(sizeof(*whtmp), gfp);
dece6358
AM
30284+ if (unlikely(!whtmp)) {
30285+ whtmp = ERR_PTR(-ENOMEM);
1facf9fc 30286+ goto out;
dece6358 30287+ }
1facf9fc 30288+
30289+ whtmp->dir = NULL;
027c5e7a 30290+ whtmp->br = NULL;
1facf9fc 30291+ whtmp->wh_dentry = NULL;
1308ab2a 30292+ /* no estimation for dir size */
30293+ rdhash = au_sbi(sb)->si_rdhash;
30294+ if (!rdhash)
30295+ rdhash = AUFS_RDHASH_DEF;
30296+ err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
30297+ if (unlikely(err)) {
30298+ kfree(whtmp);
30299+ whtmp = ERR_PTR(err);
30300+ }
dece6358 30301+
4f0767ce 30302+out:
dece6358 30303+ return whtmp;
1facf9fc 30304+}
30305+
30306+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
30307+{
027c5e7a
AM
30308+ if (whtmp->br)
30309+ atomic_dec(&whtmp->br->br_count);
1facf9fc 30310+ dput(whtmp->wh_dentry);
30311+ iput(whtmp->dir);
dece6358 30312+ au_nhash_wh_free(&whtmp->whlist);
1facf9fc 30313+ kfree(whtmp);
30314+}
30315+
30316+/*
30317+ * rmdir the whiteouted temporary named dir @h_dentry.
30318+ * @whlist: whiteouted children.
30319+ */
30320+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
30321+ struct dentry *wh_dentry, struct au_nhash *whlist)
30322+{
30323+ int err;
30324+ struct path h_tmp;
30325+ struct inode *wh_inode, *h_dir;
30326+ struct au_branch *br;
30327+
30328+ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
30329+ IMustLock(h_dir);
30330+
30331+ br = au_sbr(dir->i_sb, bindex);
30332+ wh_inode = wh_dentry->d_inode;
30333+ mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
30334+
30335+ /*
30336+ * someone else might change some whiteouts while we were sleeping.
30337+ * it means this whlist may have an obsoleted entry.
30338+ */
30339+ if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
30340+ err = del_wh_children(wh_dentry, whlist, bindex, br);
30341+ else {
30342+ int wkq_err;
30343+ struct del_wh_children_args args = {
30344+ .errp = &err,
30345+ .h_dentry = wh_dentry,
1308ab2a 30346+ .whlist = whlist,
1facf9fc 30347+ .bindex = bindex,
30348+ .br = br
30349+ };
30350+
30351+ wkq_err = au_wkq_wait(call_del_wh_children, &args);
30352+ if (unlikely(wkq_err))
30353+ err = wkq_err;
30354+ }
30355+ mutex_unlock(&wh_inode->i_mutex);
30356+
30357+ if (!err) {
30358+ h_tmp.dentry = wh_dentry;
86dc4139 30359+ h_tmp.mnt = au_br_mnt(br);
1facf9fc 30360+ err = vfsub_rmdir(h_dir, &h_tmp);
1facf9fc 30361+ }
30362+
30363+ if (!err) {
30364+ if (au_ibstart(dir) == bindex) {
7f207e10 30365+ /* todo: dir->i_mutex is necessary */
1facf9fc 30366+ au_cpup_attr_timesizes(dir);
7f207e10 30367+ vfsub_drop_nlink(dir);
1facf9fc 30368+ }
30369+ return 0; /* success */
30370+ }
30371+
523b37e3 30372+ pr_warn("failed removing %pd(%d), ignored\n", wh_dentry, err);
1facf9fc 30373+ return err;
30374+}
30375+
30376+static void call_rmdir_whtmp(void *args)
30377+{
30378+ int err;
e49829fe 30379+ aufs_bindex_t bindex;
1facf9fc 30380+ struct au_whtmp_rmdir *a = args;
30381+ struct super_block *sb;
30382+ struct dentry *h_parent;
30383+ struct inode *h_dir;
1facf9fc 30384+ struct au_hinode *hdir;
30385+
30386+ /* rmdir by nfsd may cause deadlock with this i_mutex */
30387+ /* mutex_lock(&a->dir->i_mutex); */
e49829fe 30388+ err = -EROFS;
1facf9fc 30389+ sb = a->dir->i_sb;
e49829fe
JR
30390+ si_read_lock(sb, !AuLock_FLUSH);
30391+ if (!au_br_writable(a->br->br_perm))
30392+ goto out;
30393+ bindex = au_br_index(sb, a->br->br_id);
30394+ if (unlikely(bindex < 0))
1facf9fc 30395+ goto out;
30396+
30397+ err = -EIO;
1facf9fc 30398+ ii_write_lock_parent(a->dir);
30399+ h_parent = dget_parent(a->wh_dentry);
30400+ h_dir = h_parent->d_inode;
e49829fe 30401+ hdir = au_hi(a->dir, bindex);
86dc4139
AM
30402+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
30403+ if (unlikely(err))
30404+ goto out_mnt;
4a4d8108 30405+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
e49829fe
JR
30406+ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
30407+ a->br);
86dc4139
AM
30408+ if (!err)
30409+ err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist);
4a4d8108 30410+ au_hn_imtx_unlock(hdir);
86dc4139
AM
30411+ vfsub_mnt_drop_write(au_br_mnt(a->br));
30412+
30413+out_mnt:
1facf9fc 30414+ dput(h_parent);
30415+ ii_write_unlock(a->dir);
4f0767ce 30416+out:
1facf9fc 30417+ /* mutex_unlock(&a->dir->i_mutex); */
1facf9fc 30418+ au_whtmp_rmdir_free(a);
027c5e7a
AM
30419+ si_read_unlock(sb);
30420+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 30421+ if (unlikely(err))
30422+ AuIOErr("err %d\n", err);
30423+}
30424+
30425+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
30426+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
30427+{
30428+ int wkq_err;
e49829fe 30429+ struct super_block *sb;
1facf9fc 30430+
30431+ IMustLock(dir);
30432+
30433+ /* all post-process will be done in do_rmdir_whtmp(). */
e49829fe 30434+ sb = dir->i_sb;
1facf9fc 30435+ args->dir = au_igrab(dir);
e49829fe
JR
30436+ args->br = au_sbr(sb, bindex);
30437+ atomic_inc(&args->br->br_count);
1facf9fc 30438+ args->wh_dentry = dget(wh_dentry);
53392da6 30439+ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0);
1facf9fc 30440+ if (unlikely(wkq_err)) {
523b37e3 30441+ pr_warn("rmdir error %pd (%d), ignored\n", wh_dentry, wkq_err);
1facf9fc 30442+ au_whtmp_rmdir_free(args);
30443+ }
30444+}
7f207e10
AM
30445diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h
30446--- /usr/share/empty/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
30447+++ linux/fs/aufs/whout.h 2014-01-20 20:16:14.749463838 +0100
30448@@ -0,0 +1,86 @@
1facf9fc 30449+/*
523b37e3 30450+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 30451+ *
30452+ * This program, aufs is free software; you can redistribute it and/or modify
30453+ * it under the terms of the GNU General Public License as published by
30454+ * the Free Software Foundation; either version 2 of the License, or
30455+ * (at your option) any later version.
dece6358
AM
30456+ *
30457+ * This program is distributed in the hope that it will be useful,
30458+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30459+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30460+ * GNU General Public License for more details.
30461+ *
30462+ * You should have received a copy of the GNU General Public License
523b37e3 30463+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30464+ */
30465+
30466+/*
30467+ * whiteout for logical deletion and opaque directory
30468+ */
30469+
30470+#ifndef __AUFS_WHOUT_H__
30471+#define __AUFS_WHOUT_H__
30472+
30473+#ifdef __KERNEL__
30474+
1facf9fc 30475+#include "dir.h"
30476+
30477+/* whout.c */
30478+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
30479+struct au_branch;
30480+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
30481+ struct au_branch *br, int try_sio);
30482+int au_diropq_test(struct dentry *h_dentry, struct au_branch *br);
30483+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
30484+ struct qstr *prefix);
30485+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
30486+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
30487+ struct dentry *dentry);
86dc4139 30488+int au_wh_init(struct au_branch *br, struct super_block *sb);
1facf9fc 30489+
30490+/* diropq flags */
30491+#define AuDiropq_CREATE 1
30492+#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name)
7f207e10
AM
30493+#define au_fset_diropq(flags, name) \
30494+ do { (flags) |= AuDiropq_##name; } while (0)
30495+#define au_fclr_diropq(flags, name) \
30496+ do { (flags) &= ~AuDiropq_##name; } while (0)
1facf9fc 30497+
30498+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
30499+ unsigned int flags);
30500+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
30501+ struct au_branch *br);
30502+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
30503+ struct dentry *h_parent);
30504+
30505+/* real rmdir for the whiteout-ed dir */
30506+struct au_whtmp_rmdir {
30507+ struct inode *dir;
e49829fe 30508+ struct au_branch *br;
1facf9fc 30509+ struct dentry *wh_dentry;
dece6358 30510+ struct au_nhash whlist;
1facf9fc 30511+};
30512+
30513+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
30514+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
30515+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
30516+ struct dentry *wh_dentry, struct au_nhash *whlist);
30517+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
30518+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
30519+
30520+/* ---------------------------------------------------------------------- */
30521+
30522+static inline struct dentry *au_diropq_create(struct dentry *dentry,
30523+ aufs_bindex_t bindex)
30524+{
30525+ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
30526+}
30527+
30528+static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
30529+{
30530+ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
30531+}
30532+
30533+#endif /* __KERNEL__ */
30534+#endif /* __AUFS_WHOUT_H__ */
7f207e10
AM
30535diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
30536--- /usr/share/empty/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
30537+++ linux/fs/aufs/wkq.c 2014-01-20 20:16:14.749463838 +0100
30538@@ -0,0 +1,212 @@
1facf9fc 30539+/*
523b37e3 30540+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 30541+ *
30542+ * This program, aufs is free software; you can redistribute it and/or modify
30543+ * it under the terms of the GNU General Public License as published by
30544+ * the Free Software Foundation; either version 2 of the License, or
30545+ * (at your option) any later version.
dece6358
AM
30546+ *
30547+ * This program is distributed in the hope that it will be useful,
30548+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30549+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30550+ * GNU General Public License for more details.
30551+ *
30552+ * You should have received a copy of the GNU General Public License
523b37e3 30553+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30554+ */
30555+
30556+/*
30557+ * workqueue for asynchronous/super-io operations
30558+ * todo: try new dredential scheme
30559+ */
30560+
dece6358 30561+#include <linux/module.h>
1facf9fc 30562+#include "aufs.h"
30563+
9dbd164d 30564+/* internal workqueue named AUFS_WKQ_NAME */
b752ccd1 30565+
9dbd164d 30566+static struct workqueue_struct *au_wkq;
1facf9fc 30567+
30568+struct au_wkinfo {
30569+ struct work_struct wk;
7f207e10 30570+ struct kobject *kobj;
1facf9fc 30571+
30572+ unsigned int flags; /* see wkq.h */
30573+
30574+ au_wkq_func_t func;
30575+ void *args;
30576+
1facf9fc 30577+ struct completion *comp;
30578+};
30579+
30580+/* ---------------------------------------------------------------------- */
30581+
1facf9fc 30582+static void wkq_func(struct work_struct *wk)
30583+{
30584+ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
30585+
2dfbb274 30586+ AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID));
7f207e10
AM
30587+ AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY);
30588+
1facf9fc 30589+ wkinfo->func(wkinfo->args);
1facf9fc 30590+ if (au_ftest_wkq(wkinfo->flags, WAIT))
30591+ complete(wkinfo->comp);
30592+ else {
7f207e10 30593+ kobject_put(wkinfo->kobj);
9dbd164d 30594+ module_put(THIS_MODULE); /* todo: ?? */
1facf9fc 30595+ kfree(wkinfo);
30596+ }
30597+}
30598+
30599+/*
30600+ * Since struct completion is large, try allocating it dynamically.
30601+ */
c2b27bf2 30602+#if 1 /* defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) */
1facf9fc 30603+#define AuWkqCompDeclare(name) struct completion *comp = NULL
30604+
30605+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
30606+{
30607+ *comp = kmalloc(sizeof(**comp), GFP_NOFS);
30608+ if (*comp) {
30609+ init_completion(*comp);
30610+ wkinfo->comp = *comp;
30611+ return 0;
30612+ }
30613+ return -ENOMEM;
30614+}
30615+
30616+static void au_wkq_comp_free(struct completion *comp)
30617+{
30618+ kfree(comp);
30619+}
30620+
30621+#else
30622+
30623+/* no braces */
30624+#define AuWkqCompDeclare(name) \
30625+ DECLARE_COMPLETION_ONSTACK(_ ## name); \
30626+ struct completion *comp = &_ ## name
30627+
30628+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
30629+{
30630+ wkinfo->comp = *comp;
30631+ return 0;
30632+}
30633+
30634+static void au_wkq_comp_free(struct completion *comp __maybe_unused)
30635+{
30636+ /* empty */
30637+}
30638+#endif /* 4KSTACKS */
30639+
53392da6 30640+static void au_wkq_run(struct au_wkinfo *wkinfo)
1facf9fc 30641+{
53392da6
AM
30642+ if (au_ftest_wkq(wkinfo->flags, NEST)) {
30643+ if (au_wkq_test()) {
30644+ AuWarn1("wkq from wkq, due to a dead dir by UDBA?\n");
30645+ AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT));
30646+ }
30647+ } else
30648+ au_dbg_verify_kthread();
30649+
30650+ if (au_ftest_wkq(wkinfo->flags, WAIT)) {
a1f66529 30651+ INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func);
9dbd164d 30652+ queue_work(au_wkq, &wkinfo->wk);
4a4d8108
AM
30653+ } else {
30654+ INIT_WORK(&wkinfo->wk, wkq_func);
30655+ schedule_work(&wkinfo->wk);
30656+ }
1facf9fc 30657+}
30658+
7f207e10
AM
30659+/*
30660+ * Be careful. It is easy to make deadlock happen.
30661+ * processA: lock, wkq and wait
30662+ * processB: wkq and wait, lock in wkq
30663+ * --> deadlock
30664+ */
b752ccd1 30665+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args)
1facf9fc 30666+{
30667+ int err;
30668+ AuWkqCompDeclare(comp);
30669+ struct au_wkinfo wkinfo = {
b752ccd1 30670+ .flags = flags,
1facf9fc 30671+ .func = func,
30672+ .args = args
30673+ };
30674+
30675+ err = au_wkq_comp_alloc(&wkinfo, &comp);
30676+ if (!err) {
53392da6 30677+ au_wkq_run(&wkinfo);
1facf9fc 30678+ /* no timeout, no interrupt */
30679+ wait_for_completion(wkinfo.comp);
30680+ au_wkq_comp_free(comp);
4a4d8108 30681+ destroy_work_on_stack(&wkinfo.wk);
1facf9fc 30682+ }
30683+
30684+ return err;
30685+
30686+}
30687+
027c5e7a
AM
30688+/*
30689+ * Note: dget/dput() in func for aufs dentries are not supported. It will be a
30690+ * problem in a concurrent umounting.
30691+ */
53392da6
AM
30692+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
30693+ unsigned int flags)
1facf9fc 30694+{
30695+ int err;
30696+ struct au_wkinfo *wkinfo;
30697+
30698+ atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
30699+
30700+ /*
30701+ * wkq_func() must free this wkinfo.
30702+ * it highly depends upon the implementation of workqueue.
30703+ */
30704+ err = 0;
30705+ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
30706+ if (wkinfo) {
7f207e10 30707+ wkinfo->kobj = &au_sbi(sb)->si_kobj;
53392da6 30708+ wkinfo->flags = flags & ~AuWkq_WAIT;
1facf9fc 30709+ wkinfo->func = func;
30710+ wkinfo->args = args;
30711+ wkinfo->comp = NULL;
7f207e10 30712+ kobject_get(wkinfo->kobj);
9dbd164d 30713+ __module_get(THIS_MODULE); /* todo: ?? */
1facf9fc 30714+
53392da6 30715+ au_wkq_run(wkinfo);
1facf9fc 30716+ } else {
30717+ err = -ENOMEM;
e49829fe 30718+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 30719+ }
30720+
30721+ return err;
30722+}
30723+
30724+/* ---------------------------------------------------------------------- */
30725+
30726+void au_nwt_init(struct au_nowait_tasks *nwt)
30727+{
30728+ atomic_set(&nwt->nw_len, 0);
4a4d8108 30729+ /* smp_mb(); */ /* atomic_set */
1facf9fc 30730+ init_waitqueue_head(&nwt->nw_wq);
30731+}
30732+
30733+void au_wkq_fin(void)
30734+{
9dbd164d 30735+ destroy_workqueue(au_wkq);
1facf9fc 30736+}
30737+
30738+int __init au_wkq_init(void)
30739+{
9dbd164d 30740+ int err;
b752ccd1
AM
30741+
30742+ err = 0;
86dc4139 30743+ au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE);
9dbd164d
AM
30744+ if (IS_ERR(au_wkq))
30745+ err = PTR_ERR(au_wkq);
30746+ else if (!au_wkq)
30747+ err = -ENOMEM;
b752ccd1
AM
30748+
30749+ return err;
1facf9fc 30750+}
7f207e10
AM
30751diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
30752--- /usr/share/empty/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
30753+++ linux/fs/aufs/wkq.h 2014-01-20 20:16:14.752797282 +0100
30754@@ -0,0 +1,91 @@
1facf9fc 30755+/*
523b37e3 30756+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 30757+ *
30758+ * This program, aufs is free software; you can redistribute it and/or modify
30759+ * it under the terms of the GNU General Public License as published by
30760+ * the Free Software Foundation; either version 2 of the License, or
30761+ * (at your option) any later version.
dece6358
AM
30762+ *
30763+ * This program is distributed in the hope that it will be useful,
30764+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30765+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30766+ * GNU General Public License for more details.
30767+ *
30768+ * You should have received a copy of the GNU General Public License
523b37e3 30769+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30770+ */
30771+
30772+/*
30773+ * workqueue for asynchronous/super-io operations
30774+ * todo: try new credentials management scheme
30775+ */
30776+
30777+#ifndef __AUFS_WKQ_H__
30778+#define __AUFS_WKQ_H__
30779+
30780+#ifdef __KERNEL__
30781+
dece6358
AM
30782+struct super_block;
30783+
1facf9fc 30784+/* ---------------------------------------------------------------------- */
30785+
30786+/*
30787+ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
30788+ */
30789+struct au_nowait_tasks {
30790+ atomic_t nw_len;
30791+ wait_queue_head_t nw_wq;
30792+};
30793+
30794+/* ---------------------------------------------------------------------- */
30795+
30796+typedef void (*au_wkq_func_t)(void *args);
30797+
30798+/* wkq flags */
30799+#define AuWkq_WAIT 1
9dbd164d 30800+#define AuWkq_NEST (1 << 1)
1facf9fc 30801+#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name)
7f207e10
AM
30802+#define au_fset_wkq(flags, name) \
30803+ do { (flags) |= AuWkq_##name; } while (0)
30804+#define au_fclr_wkq(flags, name) \
30805+ do { (flags) &= ~AuWkq_##name; } while (0)
1facf9fc 30806+
9dbd164d
AM
30807+#ifndef CONFIG_AUFS_HNOTIFY
30808+#undef AuWkq_NEST
30809+#define AuWkq_NEST 0
30810+#endif
30811+
1facf9fc 30812+/* wkq.c */
b752ccd1 30813+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args);
53392da6
AM
30814+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
30815+ unsigned int flags);
1facf9fc 30816+void au_nwt_init(struct au_nowait_tasks *nwt);
30817+int __init au_wkq_init(void);
30818+void au_wkq_fin(void);
30819+
30820+/* ---------------------------------------------------------------------- */
30821+
53392da6
AM
30822+static inline int au_wkq_test(void)
30823+{
30824+ return current->flags & PF_WQ_WORKER;
30825+}
30826+
b752ccd1 30827+static inline int au_wkq_wait(au_wkq_func_t func, void *args)
1facf9fc 30828+{
b752ccd1 30829+ return au_wkq_do_wait(AuWkq_WAIT, func, args);
1facf9fc 30830+}
30831+
30832+static inline void au_nwt_done(struct au_nowait_tasks *nwt)
30833+{
e49829fe 30834+ if (atomic_dec_and_test(&nwt->nw_len))
1facf9fc 30835+ wake_up_all(&nwt->nw_wq);
30836+}
30837+
30838+static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
30839+{
30840+ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
30841+ return 0;
30842+}
30843+
30844+#endif /* __KERNEL__ */
30845+#endif /* __AUFS_WKQ_H__ */
7f207e10
AM
30846diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
30847--- /usr/share/empty/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100
523b37e3
AM
30848+++ linux/fs/aufs/xino.c 2014-01-20 20:16:14.752797282 +0100
30849@@ -0,0 +1,1314 @@
1facf9fc 30850+/*
523b37e3 30851+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 30852+ *
30853+ * This program, aufs is free software; you can redistribute it and/or modify
30854+ * it under the terms of the GNU General Public License as published by
30855+ * the Free Software Foundation; either version 2 of the License, or
30856+ * (at your option) any later version.
dece6358
AM
30857+ *
30858+ * This program is distributed in the hope that it will be useful,
30859+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30860+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30861+ * GNU General Public License for more details.
30862+ *
30863+ * You should have received a copy of the GNU General Public License
523b37e3 30864+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30865+ */
30866+
30867+/*
30868+ * external inode number translation table and bitmap
30869+ */
30870+
30871+#include <linux/seq_file.h>
392086de 30872+#include <linux/statfs.h>
1facf9fc 30873+#include "aufs.h"
30874+
9dbd164d 30875+/* todo: unnecessary to support mmap_sem since kernel-space? */
b752ccd1 30876+ssize_t xino_fread(au_readf_t func, struct file *file, void *kbuf, size_t size,
1facf9fc 30877+ loff_t *pos)
30878+{
30879+ ssize_t err;
30880+ mm_segment_t oldfs;
b752ccd1
AM
30881+ union {
30882+ void *k;
30883+ char __user *u;
30884+ } buf;
1facf9fc 30885+
b752ccd1 30886+ buf.k = kbuf;
1facf9fc 30887+ oldfs = get_fs();
30888+ set_fs(KERNEL_DS);
30889+ do {
30890+ /* todo: signal_pending? */
b752ccd1 30891+ err = func(file, buf.u, size, pos);
1facf9fc 30892+ } while (err == -EAGAIN || err == -EINTR);
30893+ set_fs(oldfs);
30894+
30895+#if 0 /* reserved for future use */
30896+ if (err > 0)
30897+ fsnotify_access(file->f_dentry);
30898+#endif
30899+
30900+ return err;
30901+}
30902+
30903+/* ---------------------------------------------------------------------- */
30904+
b752ccd1 30905+static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *kbuf,
1facf9fc 30906+ size_t size, loff_t *pos)
30907+{
30908+ ssize_t err;
30909+ mm_segment_t oldfs;
b752ccd1
AM
30910+ union {
30911+ void *k;
30912+ const char __user *u;
30913+ } buf;
1facf9fc 30914+
b752ccd1 30915+ buf.k = kbuf;
1facf9fc 30916+ oldfs = get_fs();
30917+ set_fs(KERNEL_DS);
1facf9fc 30918+ do {
30919+ /* todo: signal_pending? */
b752ccd1 30920+ err = func(file, buf.u, size, pos);
1facf9fc 30921+ } while (err == -EAGAIN || err == -EINTR);
1facf9fc 30922+ set_fs(oldfs);
30923+
30924+#if 0 /* reserved for future use */
30925+ if (err > 0)
30926+ fsnotify_modify(file->f_dentry);
30927+#endif
30928+
30929+ return err;
30930+}
30931+
30932+struct do_xino_fwrite_args {
30933+ ssize_t *errp;
30934+ au_writef_t func;
30935+ struct file *file;
30936+ void *buf;
30937+ size_t size;
30938+ loff_t *pos;
30939+};
30940+
30941+static void call_do_xino_fwrite(void *args)
30942+{
30943+ struct do_xino_fwrite_args *a = args;
30944+ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
30945+}
30946+
30947+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
30948+ loff_t *pos)
30949+{
30950+ ssize_t err;
30951+
30952+ /* todo: signal block and no wkq? */
b752ccd1
AM
30953+ if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
30954+ lockdep_off();
30955+ err = do_xino_fwrite(func, file, buf, size, pos);
30956+ lockdep_on();
30957+ } else {
30958+ /*
30959+ * it breaks RLIMIT_FSIZE and normal user's limit,
30960+ * users should care about quota and real 'filesystem full.'
30961+ */
1facf9fc 30962+ int wkq_err;
30963+ struct do_xino_fwrite_args args = {
30964+ .errp = &err,
30965+ .func = func,
30966+ .file = file,
30967+ .buf = buf,
30968+ .size = size,
30969+ .pos = pos
30970+ };
30971+
30972+ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
30973+ if (unlikely(wkq_err))
30974+ err = wkq_err;
b752ccd1 30975+ }
1facf9fc 30976+
30977+ return err;
30978+}
30979+
30980+/* ---------------------------------------------------------------------- */
30981+
30982+/*
30983+ * create a new xinofile at the same place/path as @base_file.
30984+ */
30985+struct file *au_xino_create2(struct file *base_file, struct file *copy_src)
30986+{
30987+ struct file *file;
4a4d8108 30988+ struct dentry *base, *parent;
523b37e3 30989+ struct inode *dir, *delegated;
1facf9fc 30990+ struct qstr *name;
1308ab2a 30991+ struct path path;
4a4d8108 30992+ int err;
1facf9fc 30993+
30994+ base = base_file->f_dentry;
30995+ parent = base->d_parent; /* dir inode is locked */
30996+ dir = parent->d_inode;
30997+ IMustLock(dir);
30998+
30999+ file = ERR_PTR(-EINVAL);
31000+ name = &base->d_name;
4a4d8108
AM
31001+ path.dentry = vfsub_lookup_one_len(name->name, parent, name->len);
31002+ if (IS_ERR(path.dentry)) {
31003+ file = (void *)path.dentry;
523b37e3
AM
31004+ pr_err("%pd lookup err %ld\n",
31005+ base, PTR_ERR(path.dentry));
1facf9fc 31006+ goto out;
31007+ }
31008+
31009+ /* no need to mnt_want_write() since we call dentry_open() later */
4a4d8108 31010+ err = vfs_create(dir, path.dentry, S_IRUGO | S_IWUGO, NULL);
1facf9fc 31011+ if (unlikely(err)) {
31012+ file = ERR_PTR(err);
523b37e3 31013+ pr_err("%pd create err %d\n", base, err);
1facf9fc 31014+ goto out_dput;
31015+ }
31016+
c06a8ce3 31017+ path.mnt = base_file->f_path.mnt;
4a4d8108 31018+ file = vfsub_dentry_open(&path,
7f207e10 31019+ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 31020+ /* | __FMODE_NONOTIFY */);
1facf9fc 31021+ if (IS_ERR(file)) {
523b37e3 31022+ pr_err("%pd open err %ld\n", base, PTR_ERR(file));
1facf9fc 31023+ goto out_dput;
31024+ }
31025+
523b37e3
AM
31026+ delegated = NULL;
31027+ err = vfsub_unlink(dir, &file->f_path, &delegated, /*force*/0);
31028+ if (unlikely(err == -EWOULDBLOCK)) {
31029+ pr_warn("cannot retry for NFSv4 delegation"
31030+ " for an internal unlink\n");
31031+ iput(delegated);
31032+ }
1facf9fc 31033+ if (unlikely(err)) {
523b37e3 31034+ pr_err("%pd unlink err %d\n", base, err);
1facf9fc 31035+ goto out_fput;
31036+ }
31037+
31038+ if (copy_src) {
31039+ /* no one can touch copy_src xino */
c06a8ce3 31040+ err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src));
1facf9fc 31041+ if (unlikely(err)) {
523b37e3 31042+ pr_err("%pd copy err %d\n", base, err);
1facf9fc 31043+ goto out_fput;
31044+ }
31045+ }
31046+ goto out_dput; /* success */
31047+
4f0767ce 31048+out_fput:
1facf9fc 31049+ fput(file);
31050+ file = ERR_PTR(err);
4f0767ce 31051+out_dput:
4a4d8108 31052+ dput(path.dentry);
4f0767ce 31053+out:
1facf9fc 31054+ return file;
31055+}
31056+
31057+struct au_xino_lock_dir {
31058+ struct au_hinode *hdir;
31059+ struct dentry *parent;
31060+ struct mutex *mtx;
31061+};
31062+
31063+static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
31064+ struct au_xino_lock_dir *ldir)
31065+{
31066+ aufs_bindex_t brid, bindex;
31067+
31068+ ldir->hdir = NULL;
31069+ bindex = -1;
31070+ brid = au_xino_brid(sb);
31071+ if (brid >= 0)
31072+ bindex = au_br_index(sb, brid);
31073+ if (bindex >= 0) {
31074+ ldir->hdir = au_hi(sb->s_root->d_inode, bindex);
4a4d8108 31075+ au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
1facf9fc 31076+ } else {
31077+ ldir->parent = dget_parent(xino->f_dentry);
31078+ ldir->mtx = &ldir->parent->d_inode->i_mutex;
31079+ mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT);
31080+ }
31081+}
31082+
31083+static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
31084+{
31085+ if (ldir->hdir)
4a4d8108 31086+ au_hn_imtx_unlock(ldir->hdir);
1facf9fc 31087+ else {
31088+ mutex_unlock(ldir->mtx);
31089+ dput(ldir->parent);
31090+ }
31091+}
31092+
31093+/* ---------------------------------------------------------------------- */
31094+
31095+/* trucate xino files asynchronously */
31096+
31097+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex)
31098+{
31099+ int err;
392086de
AM
31100+ unsigned long jiffy;
31101+ blkcnt_t blocks;
1facf9fc 31102+ aufs_bindex_t bi, bend;
392086de 31103+ struct kstatfs *st;
1facf9fc 31104+ struct au_branch *br;
31105+ struct file *new_xino, *file;
31106+ struct super_block *h_sb;
31107+ struct au_xino_lock_dir ldir;
31108+
392086de
AM
31109+ err = -ENOMEM;
31110+ st = kzalloc(sizeof(*st), GFP_NOFS);
31111+ if (unlikely(!st))
31112+ goto out;
31113+
1facf9fc 31114+ err = -EINVAL;
31115+ bend = au_sbend(sb);
31116+ if (unlikely(bindex < 0 || bend < bindex))
392086de 31117+ goto out_st;
1facf9fc 31118+ br = au_sbr(sb, bindex);
31119+ file = br->br_xino.xi_file;
31120+ if (!file)
392086de
AM
31121+ goto out_st;
31122+
31123+ err = vfs_statfs(&file->f_path, st);
31124+ if (unlikely(err))
31125+ AuErr1("statfs err %d, ignored\n", err);
31126+ jiffy = jiffies;
31127+ blocks = file_inode(file)->i_blocks;
31128+ pr_info("begin truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
31129+ bindex, (u64)blocks, st->f_bfree, st->f_blocks);
1facf9fc 31130+
31131+ au_xino_lock_dir(sb, file, &ldir);
31132+ /* mnt_want_write() is unnecessary here */
31133+ new_xino = au_xino_create2(file, file);
31134+ au_xino_unlock_dir(&ldir);
31135+ err = PTR_ERR(new_xino);
392086de
AM
31136+ if (IS_ERR(new_xino)) {
31137+ pr_err("err %d, ignored\n", err);
31138+ goto out_st;
31139+ }
1facf9fc 31140+ err = 0;
31141+ fput(file);
31142+ br->br_xino.xi_file = new_xino;
31143+
86dc4139 31144+ h_sb = au_br_sb(br);
1facf9fc 31145+ for (bi = 0; bi <= bend; bi++) {
31146+ if (unlikely(bi == bindex))
31147+ continue;
31148+ br = au_sbr(sb, bi);
86dc4139 31149+ if (au_br_sb(br) != h_sb)
1facf9fc 31150+ continue;
31151+
31152+ fput(br->br_xino.xi_file);
31153+ br->br_xino.xi_file = new_xino;
31154+ get_file(new_xino);
31155+ }
31156+
392086de
AM
31157+ err = vfs_statfs(&new_xino->f_path, st);
31158+ if (!err) {
31159+ pr_info("end truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
31160+ bindex, (u64)file_inode(new_xino)->i_blocks,
31161+ st->f_bfree, st->f_blocks);
31162+ if (file_inode(new_xino)->i_blocks < blocks)
31163+ au_sbi(sb)->si_xino_jiffy = jiffy;
31164+ } else
31165+ AuErr1("statfs err %d, ignored\n", err);
31166+
31167+out_st:
31168+ kfree(st);
4f0767ce 31169+out:
1facf9fc 31170+ return err;
31171+}
31172+
31173+struct xino_do_trunc_args {
31174+ struct super_block *sb;
31175+ struct au_branch *br;
31176+};
31177+
31178+static void xino_do_trunc(void *_args)
31179+{
31180+ struct xino_do_trunc_args *args = _args;
31181+ struct super_block *sb;
31182+ struct au_branch *br;
31183+ struct inode *dir;
31184+ int err;
31185+ aufs_bindex_t bindex;
31186+
31187+ err = 0;
31188+ sb = args->sb;
31189+ dir = sb->s_root->d_inode;
31190+ br = args->br;
31191+
31192+ si_noflush_write_lock(sb);
31193+ ii_read_lock_parent(dir);
31194+ bindex = au_br_index(sb, br->br_id);
31195+ err = au_xino_trunc(sb, bindex);
1facf9fc 31196+ ii_read_unlock(dir);
31197+ if (unlikely(err))
392086de 31198+ pr_warn("err b%d, (%d)\n", bindex, err);
1facf9fc 31199+ atomic_dec(&br->br_xino_running);
31200+ atomic_dec(&br->br_count);
1facf9fc 31201+ si_write_unlock(sb);
027c5e7a 31202+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 31203+ kfree(args);
31204+}
31205+
392086de
AM
31206+static int xino_trunc_test(struct super_block *sb, struct au_branch *br)
31207+{
31208+ int err;
31209+ struct kstatfs st;
31210+ struct au_sbinfo *sbinfo;
31211+
31212+ /* todo: si_xino_expire and the ratio should be customizable */
31213+ sbinfo = au_sbi(sb);
31214+ if (time_before(jiffies,
31215+ sbinfo->si_xino_jiffy + sbinfo->si_xino_expire))
31216+ return 0;
31217+
31218+ /* truncation border */
31219+ err = vfs_statfs(&br->br_xino.xi_file->f_path, &st);
31220+ if (unlikely(err)) {
31221+ AuErr1("statfs err %d, ignored\n", err);
31222+ return 0;
31223+ }
31224+ if (div64_u64(st.f_bfree * 100, st.f_blocks) >= AUFS_XINO_DEF_TRUNC)
31225+ return 0;
31226+
31227+ return 1;
31228+}
31229+
1facf9fc 31230+static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
31231+{
31232+ struct xino_do_trunc_args *args;
31233+ int wkq_err;
31234+
392086de 31235+ if (!xino_trunc_test(sb, br))
1facf9fc 31236+ return;
31237+
31238+ if (atomic_inc_return(&br->br_xino_running) > 1)
31239+ goto out;
31240+
31241+ /* lock and kfree() will be called in trunc_xino() */
31242+ args = kmalloc(sizeof(*args), GFP_NOFS);
31243+ if (unlikely(!args)) {
31244+ AuErr1("no memory\n");
31245+ goto out_args;
31246+ }
31247+
e49829fe 31248+ atomic_inc(&br->br_count);
1facf9fc 31249+ args->sb = sb;
31250+ args->br = br;
53392da6 31251+ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0);
1facf9fc 31252+ if (!wkq_err)
31253+ return; /* success */
31254+
4a4d8108 31255+ pr_err("wkq %d\n", wkq_err);
e49829fe 31256+ atomic_dec(&br->br_count);
1facf9fc 31257+
4f0767ce 31258+out_args:
1facf9fc 31259+ kfree(args);
4f0767ce 31260+out:
e49829fe 31261+ atomic_dec(&br->br_xino_running);
1facf9fc 31262+}
31263+
31264+/* ---------------------------------------------------------------------- */
31265+
31266+static int au_xino_do_write(au_writef_t write, struct file *file,
31267+ ino_t h_ino, ino_t ino)
31268+{
31269+ loff_t pos;
31270+ ssize_t sz;
31271+
31272+ pos = h_ino;
31273+ if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) {
31274+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
31275+ return -EFBIG;
31276+ }
31277+ pos *= sizeof(ino);
31278+ sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos);
31279+ if (sz == sizeof(ino))
31280+ return 0; /* success */
31281+
31282+ AuIOErr("write failed (%zd)\n", sz);
31283+ return -EIO;
31284+}
31285+
31286+/*
31287+ * write @ino to the xinofile for the specified branch{@sb, @bindex}
31288+ * at the position of @h_ino.
31289+ * even if @ino is zero, it is written to the xinofile and means no entry.
31290+ * if the size of the xino file on a specific filesystem exceeds the watermark,
31291+ * try truncating it.
31292+ */
31293+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
31294+ ino_t ino)
31295+{
31296+ int err;
31297+ unsigned int mnt_flags;
31298+ struct au_branch *br;
31299+
31300+ BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max)
31301+ || ((loff_t)-1) > 0);
dece6358 31302+ SiMustAnyLock(sb);
1facf9fc 31303+
31304+ mnt_flags = au_mntflags(sb);
31305+ if (!au_opt_test(mnt_flags, XINO))
31306+ return 0;
31307+
31308+ br = au_sbr(sb, bindex);
31309+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
31310+ h_ino, ino);
31311+ if (!err) {
31312+ if (au_opt_test(mnt_flags, TRUNC_XINO)
86dc4139 31313+ && au_test_fs_trunc_xino(au_br_sb(br)))
1facf9fc 31314+ xino_try_trunc(sb, br);
31315+ return 0; /* success */
31316+ }
31317+
31318+ AuIOErr("write failed (%d)\n", err);
31319+ return -EIO;
31320+}
31321+
31322+/* ---------------------------------------------------------------------- */
31323+
31324+/* aufs inode number bitmap */
31325+
31326+static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
31327+static ino_t xib_calc_ino(unsigned long pindex, int bit)
31328+{
31329+ ino_t ino;
31330+
31331+ AuDebugOn(bit < 0 || page_bits <= bit);
31332+ ino = AUFS_FIRST_INO + pindex * page_bits + bit;
31333+ return ino;
31334+}
31335+
31336+static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
31337+{
31338+ AuDebugOn(ino < AUFS_FIRST_INO);
31339+ ino -= AUFS_FIRST_INO;
31340+ *pindex = ino / page_bits;
31341+ *bit = ino % page_bits;
31342+}
31343+
31344+static int xib_pindex(struct super_block *sb, unsigned long pindex)
31345+{
31346+ int err;
31347+ loff_t pos;
31348+ ssize_t sz;
31349+ struct au_sbinfo *sbinfo;
31350+ struct file *xib;
31351+ unsigned long *p;
31352+
31353+ sbinfo = au_sbi(sb);
31354+ MtxMustLock(&sbinfo->si_xib_mtx);
31355+ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
31356+ || !au_opt_test(sbinfo->si_mntflags, XINO));
31357+
31358+ if (pindex == sbinfo->si_xib_last_pindex)
31359+ return 0;
31360+
31361+ xib = sbinfo->si_xib;
31362+ p = sbinfo->si_xib_buf;
31363+ pos = sbinfo->si_xib_last_pindex;
31364+ pos *= PAGE_SIZE;
31365+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
31366+ if (unlikely(sz != PAGE_SIZE))
31367+ goto out;
31368+
31369+ pos = pindex;
31370+ pos *= PAGE_SIZE;
c06a8ce3 31371+ if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE)
1facf9fc 31372+ sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
31373+ else {
31374+ memset(p, 0, PAGE_SIZE);
31375+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
31376+ }
31377+ if (sz == PAGE_SIZE) {
31378+ sbinfo->si_xib_last_pindex = pindex;
31379+ return 0; /* success */
31380+ }
31381+
4f0767ce 31382+out:
b752ccd1
AM
31383+ AuIOErr1("write failed (%zd)\n", sz);
31384+ err = sz;
31385+ if (sz >= 0)
31386+ err = -EIO;
31387+ return err;
31388+}
31389+
31390+/* ---------------------------------------------------------------------- */
31391+
31392+static void au_xib_clear_bit(struct inode *inode)
31393+{
31394+ int err, bit;
31395+ unsigned long pindex;
31396+ struct super_block *sb;
31397+ struct au_sbinfo *sbinfo;
31398+
31399+ AuDebugOn(inode->i_nlink);
31400+
31401+ sb = inode->i_sb;
31402+ xib_calc_bit(inode->i_ino, &pindex, &bit);
31403+ AuDebugOn(page_bits <= bit);
31404+ sbinfo = au_sbi(sb);
31405+ mutex_lock(&sbinfo->si_xib_mtx);
31406+ err = xib_pindex(sb, pindex);
31407+ if (!err) {
31408+ clear_bit(bit, sbinfo->si_xib_buf);
31409+ sbinfo->si_xib_next_bit = bit;
31410+ }
31411+ mutex_unlock(&sbinfo->si_xib_mtx);
31412+}
31413+
31414+/* for s_op->delete_inode() */
31415+void au_xino_delete_inode(struct inode *inode, const int unlinked)
31416+{
31417+ int err;
31418+ unsigned int mnt_flags;
31419+ aufs_bindex_t bindex, bend, bi;
31420+ unsigned char try_trunc;
31421+ struct au_iinfo *iinfo;
31422+ struct super_block *sb;
31423+ struct au_hinode *hi;
31424+ struct inode *h_inode;
31425+ struct au_branch *br;
31426+ au_writef_t xwrite;
31427+
31428+ sb = inode->i_sb;
31429+ mnt_flags = au_mntflags(sb);
31430+ if (!au_opt_test(mnt_flags, XINO)
31431+ || inode->i_ino == AUFS_ROOT_INO)
31432+ return;
31433+
31434+ if (unlinked) {
31435+ au_xigen_inc(inode);
31436+ au_xib_clear_bit(inode);
31437+ }
31438+
31439+ iinfo = au_ii(inode);
31440+ if (!iinfo)
31441+ return;
1facf9fc 31442+
b752ccd1
AM
31443+ bindex = iinfo->ii_bstart;
31444+ if (bindex < 0)
31445+ return;
1facf9fc 31446+
b752ccd1
AM
31447+ xwrite = au_sbi(sb)->si_xwrite;
31448+ try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO);
31449+ hi = iinfo->ii_hinode + bindex;
31450+ bend = iinfo->ii_bend;
31451+ for (; bindex <= bend; bindex++, hi++) {
31452+ h_inode = hi->hi_inode;
31453+ if (!h_inode
31454+ || (!unlinked && h_inode->i_nlink))
31455+ continue;
1facf9fc 31456+
b752ccd1
AM
31457+ /* inode may not be revalidated */
31458+ bi = au_br_index(sb, hi->hi_id);
31459+ if (bi < 0)
31460+ continue;
1facf9fc 31461+
b752ccd1
AM
31462+ br = au_sbr(sb, bi);
31463+ err = au_xino_do_write(xwrite, br->br_xino.xi_file,
31464+ h_inode->i_ino, /*ino*/0);
31465+ if (!err && try_trunc
86dc4139 31466+ && au_test_fs_trunc_xino(au_br_sb(br)))
b752ccd1 31467+ xino_try_trunc(sb, br);
1facf9fc 31468+ }
1facf9fc 31469+}
31470+
31471+/* get an unused inode number from bitmap */
31472+ino_t au_xino_new_ino(struct super_block *sb)
31473+{
31474+ ino_t ino;
31475+ unsigned long *p, pindex, ul, pend;
31476+ struct au_sbinfo *sbinfo;
31477+ struct file *file;
31478+ int free_bit, err;
31479+
31480+ if (!au_opt_test(au_mntflags(sb), XINO))
31481+ return iunique(sb, AUFS_FIRST_INO);
31482+
31483+ sbinfo = au_sbi(sb);
31484+ mutex_lock(&sbinfo->si_xib_mtx);
31485+ p = sbinfo->si_xib_buf;
31486+ free_bit = sbinfo->si_xib_next_bit;
31487+ if (free_bit < page_bits && !test_bit(free_bit, p))
31488+ goto out; /* success */
31489+ free_bit = find_first_zero_bit(p, page_bits);
31490+ if (free_bit < page_bits)
31491+ goto out; /* success */
31492+
31493+ pindex = sbinfo->si_xib_last_pindex;
31494+ for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
31495+ err = xib_pindex(sb, ul);
31496+ if (unlikely(err))
31497+ goto out_err;
31498+ free_bit = find_first_zero_bit(p, page_bits);
31499+ if (free_bit < page_bits)
31500+ goto out; /* success */
31501+ }
31502+
31503+ file = sbinfo->si_xib;
c06a8ce3 31504+ pend = vfsub_f_size_read(file) / PAGE_SIZE;
1facf9fc 31505+ for (ul = pindex + 1; ul <= pend; ul++) {
31506+ err = xib_pindex(sb, ul);
31507+ if (unlikely(err))
31508+ goto out_err;
31509+ free_bit = find_first_zero_bit(p, page_bits);
31510+ if (free_bit < page_bits)
31511+ goto out; /* success */
31512+ }
31513+ BUG();
31514+
4f0767ce 31515+out:
1facf9fc 31516+ set_bit(free_bit, p);
7f207e10 31517+ sbinfo->si_xib_next_bit = free_bit + 1;
1facf9fc 31518+ pindex = sbinfo->si_xib_last_pindex;
31519+ mutex_unlock(&sbinfo->si_xib_mtx);
31520+ ino = xib_calc_ino(pindex, free_bit);
31521+ AuDbg("i%lu\n", (unsigned long)ino);
31522+ return ino;
4f0767ce 31523+out_err:
1facf9fc 31524+ mutex_unlock(&sbinfo->si_xib_mtx);
31525+ AuDbg("i0\n");
31526+ return 0;
31527+}
31528+
31529+/*
31530+ * read @ino from xinofile for the specified branch{@sb, @bindex}
31531+ * at the position of @h_ino.
31532+ * if @ino does not exist and @do_new is true, get new one.
31533+ */
31534+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
31535+ ino_t *ino)
31536+{
31537+ int err;
31538+ ssize_t sz;
31539+ loff_t pos;
31540+ struct file *file;
31541+ struct au_sbinfo *sbinfo;
31542+
31543+ *ino = 0;
31544+ if (!au_opt_test(au_mntflags(sb), XINO))
31545+ return 0; /* no xino */
31546+
31547+ err = 0;
31548+ sbinfo = au_sbi(sb);
31549+ pos = h_ino;
31550+ if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) {
31551+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
31552+ return -EFBIG;
31553+ }
31554+ pos *= sizeof(*ino);
31555+
31556+ file = au_sbr(sb, bindex)->br_xino.xi_file;
c06a8ce3 31557+ if (vfsub_f_size_read(file) < pos + sizeof(*ino))
1facf9fc 31558+ return 0; /* no ino */
31559+
31560+ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos);
31561+ if (sz == sizeof(*ino))
31562+ return 0; /* success */
31563+
31564+ err = sz;
31565+ if (unlikely(sz >= 0)) {
31566+ err = -EIO;
31567+ AuIOErr("xino read error (%zd)\n", sz);
31568+ }
31569+
31570+ return err;
31571+}
31572+
31573+/* ---------------------------------------------------------------------- */
31574+
31575+/* create and set a new xino file */
31576+
31577+struct file *au_xino_create(struct super_block *sb, char *fname, int silent)
31578+{
31579+ struct file *file;
31580+ struct dentry *h_parent, *d;
31581+ struct inode *h_dir;
31582+ int err;
31583+
31584+ /*
31585+ * at mount-time, and the xino file is the default path,
4a4d8108 31586+ * hnotify is disabled so we have no notify events to ignore.
1facf9fc 31587+ * when a user specified the xino, we cannot get au_hdir to be ignored.
31588+ */
7f207e10 31589+ file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 31590+ /* | __FMODE_NONOTIFY */,
1facf9fc 31591+ S_IRUGO | S_IWUGO);
31592+ if (IS_ERR(file)) {
31593+ if (!silent)
4a4d8108 31594+ pr_err("open %s(%ld)\n", fname, PTR_ERR(file));
1facf9fc 31595+ return file;
31596+ }
31597+
31598+ /* keep file count */
31599+ h_parent = dget_parent(file->f_dentry);
31600+ h_dir = h_parent->d_inode;
31601+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
31602+ /* mnt_want_write() is unnecessary here */
523b37e3
AM
31603+ /* no delegation since it is just created */
31604+ err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL, /*force*/0);
1facf9fc 31605+ mutex_unlock(&h_dir->i_mutex);
31606+ dput(h_parent);
31607+ if (unlikely(err)) {
31608+ if (!silent)
4a4d8108 31609+ pr_err("unlink %s(%d)\n", fname, err);
1facf9fc 31610+ goto out;
31611+ }
31612+
31613+ err = -EINVAL;
31614+ d = file->f_dentry;
31615+ if (unlikely(sb == d->d_sb)) {
31616+ if (!silent)
4a4d8108 31617+ pr_err("%s must be outside\n", fname);
1facf9fc 31618+ goto out;
31619+ }
31620+ if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
31621+ if (!silent)
4a4d8108
AM
31622+ pr_err("xino doesn't support %s(%s)\n",
31623+ fname, au_sbtype(d->d_sb));
1facf9fc 31624+ goto out;
31625+ }
31626+ return file; /* success */
31627+
4f0767ce 31628+out:
1facf9fc 31629+ fput(file);
31630+ file = ERR_PTR(err);
31631+ return file;
31632+}
31633+
31634+/*
31635+ * find another branch who is on the same filesystem of the specified
31636+ * branch{@btgt}. search until @bend.
31637+ */
31638+static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
31639+ aufs_bindex_t bend)
31640+{
31641+ aufs_bindex_t bindex;
31642+ struct super_block *tgt_sb = au_sbr_sb(sb, btgt);
31643+
31644+ for (bindex = 0; bindex < btgt; bindex++)
31645+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
31646+ return bindex;
31647+ for (bindex++; bindex <= bend; bindex++)
31648+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
31649+ return bindex;
31650+ return -1;
31651+}
31652+
31653+/* ---------------------------------------------------------------------- */
31654+
31655+/*
31656+ * initialize the xinofile for the specified branch @br
31657+ * at the place/path where @base_file indicates.
31658+ * test whether another branch is on the same filesystem or not,
31659+ * if @do_test is true.
31660+ */
31661+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
31662+ struct file *base_file, int do_test)
31663+{
31664+ int err;
31665+ ino_t ino;
31666+ aufs_bindex_t bend, bindex;
31667+ struct au_branch *shared_br, *b;
31668+ struct file *file;
31669+ struct super_block *tgt_sb;
31670+
31671+ shared_br = NULL;
31672+ bend = au_sbend(sb);
31673+ if (do_test) {
86dc4139 31674+ tgt_sb = au_br_sb(br);
1facf9fc 31675+ for (bindex = 0; bindex <= bend; bindex++) {
31676+ b = au_sbr(sb, bindex);
86dc4139 31677+ if (tgt_sb == au_br_sb(b)) {
1facf9fc 31678+ shared_br = b;
31679+ break;
31680+ }
31681+ }
31682+ }
31683+
31684+ if (!shared_br || !shared_br->br_xino.xi_file) {
31685+ struct au_xino_lock_dir ldir;
31686+
31687+ au_xino_lock_dir(sb, base_file, &ldir);
31688+ /* mnt_want_write() is unnecessary here */
31689+ file = au_xino_create2(base_file, NULL);
31690+ au_xino_unlock_dir(&ldir);
31691+ err = PTR_ERR(file);
31692+ if (IS_ERR(file))
31693+ goto out;
31694+ br->br_xino.xi_file = file;
31695+ } else {
31696+ br->br_xino.xi_file = shared_br->br_xino.xi_file;
31697+ get_file(br->br_xino.xi_file);
31698+ }
31699+
31700+ ino = AUFS_ROOT_INO;
31701+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
31702+ h_ino, ino);
b752ccd1
AM
31703+ if (unlikely(err)) {
31704+ fput(br->br_xino.xi_file);
31705+ br->br_xino.xi_file = NULL;
31706+ }
1facf9fc 31707+
4f0767ce 31708+out:
1facf9fc 31709+ return err;
31710+}
31711+
31712+/* ---------------------------------------------------------------------- */
31713+
31714+/* trucate a xino bitmap file */
31715+
31716+/* todo: slow */
31717+static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
31718+{
31719+ int err, bit;
31720+ ssize_t sz;
31721+ unsigned long pindex;
31722+ loff_t pos, pend;
31723+ struct au_sbinfo *sbinfo;
31724+ au_readf_t func;
31725+ ino_t *ino;
31726+ unsigned long *p;
31727+
31728+ err = 0;
31729+ sbinfo = au_sbi(sb);
dece6358 31730+ MtxMustLock(&sbinfo->si_xib_mtx);
1facf9fc 31731+ p = sbinfo->si_xib_buf;
31732+ func = sbinfo->si_xread;
c06a8ce3 31733+ pend = vfsub_f_size_read(file);
1facf9fc 31734+ pos = 0;
31735+ while (pos < pend) {
31736+ sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
31737+ err = sz;
31738+ if (unlikely(sz <= 0))
31739+ goto out;
31740+
31741+ err = 0;
31742+ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
31743+ if (unlikely(*ino < AUFS_FIRST_INO))
31744+ continue;
31745+
31746+ xib_calc_bit(*ino, &pindex, &bit);
31747+ AuDebugOn(page_bits <= bit);
31748+ err = xib_pindex(sb, pindex);
31749+ if (!err)
31750+ set_bit(bit, p);
31751+ else
31752+ goto out;
31753+ }
31754+ }
31755+
4f0767ce 31756+out:
1facf9fc 31757+ return err;
31758+}
31759+
31760+static int xib_restore(struct super_block *sb)
31761+{
31762+ int err;
31763+ aufs_bindex_t bindex, bend;
31764+ void *page;
31765+
31766+ err = -ENOMEM;
31767+ page = (void *)__get_free_page(GFP_NOFS);
31768+ if (unlikely(!page))
31769+ goto out;
31770+
31771+ err = 0;
31772+ bend = au_sbend(sb);
31773+ for (bindex = 0; !err && bindex <= bend; bindex++)
31774+ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0)
31775+ err = do_xib_restore
31776+ (sb, au_sbr(sb, bindex)->br_xino.xi_file, page);
31777+ else
31778+ AuDbg("b%d\n", bindex);
31779+ free_page((unsigned long)page);
31780+
4f0767ce 31781+out:
1facf9fc 31782+ return err;
31783+}
31784+
31785+int au_xib_trunc(struct super_block *sb)
31786+{
31787+ int err;
31788+ ssize_t sz;
31789+ loff_t pos;
31790+ struct au_xino_lock_dir ldir;
31791+ struct au_sbinfo *sbinfo;
31792+ unsigned long *p;
31793+ struct file *file;
31794+
dece6358
AM
31795+ SiMustWriteLock(sb);
31796+
1facf9fc 31797+ err = 0;
31798+ sbinfo = au_sbi(sb);
31799+ if (!au_opt_test(sbinfo->si_mntflags, XINO))
31800+ goto out;
31801+
31802+ file = sbinfo->si_xib;
c06a8ce3 31803+ if (vfsub_f_size_read(file) <= PAGE_SIZE)
1facf9fc 31804+ goto out;
31805+
31806+ au_xino_lock_dir(sb, file, &ldir);
31807+ /* mnt_want_write() is unnecessary here */
31808+ file = au_xino_create2(sbinfo->si_xib, NULL);
31809+ au_xino_unlock_dir(&ldir);
31810+ err = PTR_ERR(file);
31811+ if (IS_ERR(file))
31812+ goto out;
31813+ fput(sbinfo->si_xib);
31814+ sbinfo->si_xib = file;
31815+
31816+ p = sbinfo->si_xib_buf;
31817+ memset(p, 0, PAGE_SIZE);
31818+ pos = 0;
31819+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
31820+ if (unlikely(sz != PAGE_SIZE)) {
31821+ err = sz;
31822+ AuIOErr("err %d\n", err);
31823+ if (sz >= 0)
31824+ err = -EIO;
31825+ goto out;
31826+ }
31827+
31828+ mutex_lock(&sbinfo->si_xib_mtx);
31829+ /* mnt_want_write() is unnecessary here */
31830+ err = xib_restore(sb);
31831+ mutex_unlock(&sbinfo->si_xib_mtx);
31832+
31833+out:
31834+ return err;
31835+}
31836+
31837+/* ---------------------------------------------------------------------- */
31838+
31839+/*
31840+ * xino mount option handlers
31841+ */
31842+static au_readf_t find_readf(struct file *h_file)
31843+{
31844+ const struct file_operations *fop = h_file->f_op;
31845+
523b37e3
AM
31846+ if (fop->read)
31847+ return fop->read;
31848+ if (fop->aio_read)
31849+ return do_sync_read;
1facf9fc 31850+ return ERR_PTR(-ENOSYS);
31851+}
31852+
31853+static au_writef_t find_writef(struct file *h_file)
31854+{
31855+ const struct file_operations *fop = h_file->f_op;
31856+
523b37e3
AM
31857+ if (fop->write)
31858+ return fop->write;
31859+ if (fop->aio_write)
31860+ return do_sync_write;
1facf9fc 31861+ return ERR_PTR(-ENOSYS);
31862+}
31863+
31864+/* xino bitmap */
31865+static void xino_clear_xib(struct super_block *sb)
31866+{
31867+ struct au_sbinfo *sbinfo;
31868+
dece6358
AM
31869+ SiMustWriteLock(sb);
31870+
1facf9fc 31871+ sbinfo = au_sbi(sb);
31872+ sbinfo->si_xread = NULL;
31873+ sbinfo->si_xwrite = NULL;
31874+ if (sbinfo->si_xib)
31875+ fput(sbinfo->si_xib);
31876+ sbinfo->si_xib = NULL;
31877+ free_page((unsigned long)sbinfo->si_xib_buf);
31878+ sbinfo->si_xib_buf = NULL;
31879+}
31880+
31881+static int au_xino_set_xib(struct super_block *sb, struct file *base)
31882+{
31883+ int err;
31884+ loff_t pos;
31885+ struct au_sbinfo *sbinfo;
31886+ struct file *file;
31887+
dece6358
AM
31888+ SiMustWriteLock(sb);
31889+
1facf9fc 31890+ sbinfo = au_sbi(sb);
31891+ file = au_xino_create2(base, sbinfo->si_xib);
31892+ err = PTR_ERR(file);
31893+ if (IS_ERR(file))
31894+ goto out;
31895+ if (sbinfo->si_xib)
31896+ fput(sbinfo->si_xib);
31897+ sbinfo->si_xib = file;
31898+ sbinfo->si_xread = find_readf(file);
31899+ sbinfo->si_xwrite = find_writef(file);
31900+
31901+ err = -ENOMEM;
31902+ if (!sbinfo->si_xib_buf)
31903+ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
31904+ if (unlikely(!sbinfo->si_xib_buf))
31905+ goto out_unset;
31906+
31907+ sbinfo->si_xib_last_pindex = 0;
31908+ sbinfo->si_xib_next_bit = 0;
c06a8ce3 31909+ if (vfsub_f_size_read(file) < PAGE_SIZE) {
1facf9fc 31910+ pos = 0;
31911+ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
31912+ PAGE_SIZE, &pos);
31913+ if (unlikely(err != PAGE_SIZE))
31914+ goto out_free;
31915+ }
31916+ err = 0;
31917+ goto out; /* success */
31918+
4f0767ce 31919+out_free:
1facf9fc 31920+ free_page((unsigned long)sbinfo->si_xib_buf);
b752ccd1
AM
31921+ sbinfo->si_xib_buf = NULL;
31922+ if (err >= 0)
31923+ err = -EIO;
4f0767ce 31924+out_unset:
b752ccd1
AM
31925+ fput(sbinfo->si_xib);
31926+ sbinfo->si_xib = NULL;
31927+ sbinfo->si_xread = NULL;
31928+ sbinfo->si_xwrite = NULL;
4f0767ce 31929+out:
b752ccd1 31930+ return err;
1facf9fc 31931+}
31932+
b752ccd1
AM
31933+/* xino for each branch */
31934+static void xino_clear_br(struct super_block *sb)
31935+{
31936+ aufs_bindex_t bindex, bend;
31937+ struct au_branch *br;
1facf9fc 31938+
b752ccd1
AM
31939+ bend = au_sbend(sb);
31940+ for (bindex = 0; bindex <= bend; bindex++) {
31941+ br = au_sbr(sb, bindex);
31942+ if (!br || !br->br_xino.xi_file)
31943+ continue;
31944+
31945+ fput(br->br_xino.xi_file);
31946+ br->br_xino.xi_file = NULL;
31947+ }
31948+}
31949+
31950+static int au_xino_set_br(struct super_block *sb, struct file *base)
1facf9fc 31951+{
31952+ int err;
b752ccd1
AM
31953+ ino_t ino;
31954+ aufs_bindex_t bindex, bend, bshared;
31955+ struct {
31956+ struct file *old, *new;
31957+ } *fpair, *p;
31958+ struct au_branch *br;
31959+ struct inode *inode;
31960+ au_writef_t writef;
1facf9fc 31961+
b752ccd1
AM
31962+ SiMustWriteLock(sb);
31963+
31964+ err = -ENOMEM;
31965+ bend = au_sbend(sb);
31966+ fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS);
31967+ if (unlikely(!fpair))
1facf9fc 31968+ goto out;
31969+
b752ccd1
AM
31970+ inode = sb->s_root->d_inode;
31971+ ino = AUFS_ROOT_INO;
31972+ writef = au_sbi(sb)->si_xwrite;
31973+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
31974+ br = au_sbr(sb, bindex);
31975+ bshared = is_sb_shared(sb, bindex, bindex - 1);
31976+ if (bshared >= 0) {
31977+ /* shared xino */
31978+ *p = fpair[bshared];
31979+ get_file(p->new);
31980+ }
31981+
31982+ if (!p->new) {
31983+ /* new xino */
31984+ p->old = br->br_xino.xi_file;
31985+ p->new = au_xino_create2(base, br->br_xino.xi_file);
31986+ err = PTR_ERR(p->new);
31987+ if (IS_ERR(p->new)) {
31988+ p->new = NULL;
31989+ goto out_pair;
31990+ }
31991+ }
31992+
31993+ err = au_xino_do_write(writef, p->new,
31994+ au_h_iptr(inode, bindex)->i_ino, ino);
31995+ if (unlikely(err))
31996+ goto out_pair;
31997+ }
31998+
31999+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
32000+ br = au_sbr(sb, bindex);
32001+ if (br->br_xino.xi_file)
32002+ fput(br->br_xino.xi_file);
32003+ get_file(p->new);
32004+ br->br_xino.xi_file = p->new;
32005+ }
1facf9fc 32006+
4f0767ce 32007+out_pair:
b752ccd1
AM
32008+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++)
32009+ if (p->new)
32010+ fput(p->new);
32011+ else
32012+ break;
32013+ kfree(fpair);
4f0767ce 32014+out:
1facf9fc 32015+ return err;
32016+}
b752ccd1
AM
32017+
32018+void au_xino_clr(struct super_block *sb)
32019+{
32020+ struct au_sbinfo *sbinfo;
32021+
32022+ au_xigen_clr(sb);
32023+ xino_clear_xib(sb);
32024+ xino_clear_br(sb);
32025+ sbinfo = au_sbi(sb);
32026+ /* lvalue, do not call au_mntflags() */
32027+ au_opt_clr(sbinfo->si_mntflags, XINO);
32028+}
32029+
32030+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount)
32031+{
32032+ int err, skip;
32033+ struct dentry *parent, *cur_parent;
32034+ struct qstr *dname, *cur_name;
32035+ struct file *cur_xino;
32036+ struct inode *dir;
32037+ struct au_sbinfo *sbinfo;
32038+
32039+ SiMustWriteLock(sb);
32040+
32041+ err = 0;
32042+ sbinfo = au_sbi(sb);
32043+ parent = dget_parent(xino->file->f_dentry);
32044+ if (remount) {
32045+ skip = 0;
32046+ dname = &xino->file->f_dentry->d_name;
32047+ cur_xino = sbinfo->si_xib;
32048+ if (cur_xino) {
32049+ cur_parent = dget_parent(cur_xino->f_dentry);
32050+ cur_name = &cur_xino->f_dentry->d_name;
32051+ skip = (cur_parent == parent
32052+ && dname->len == cur_name->len
32053+ && !memcmp(dname->name, cur_name->name,
32054+ dname->len));
32055+ dput(cur_parent);
32056+ }
32057+ if (skip)
32058+ goto out;
32059+ }
32060+
32061+ au_opt_set(sbinfo->si_mntflags, XINO);
32062+ dir = parent->d_inode;
32063+ mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT);
32064+ /* mnt_want_write() is unnecessary here */
32065+ err = au_xino_set_xib(sb, xino->file);
32066+ if (!err)
32067+ err = au_xigen_set(sb, xino->file);
32068+ if (!err)
32069+ err = au_xino_set_br(sb, xino->file);
32070+ mutex_unlock(&dir->i_mutex);
32071+ if (!err)
32072+ goto out; /* success */
32073+
32074+ /* reset all */
32075+ AuIOErr("failed creating xino(%d).\n", err);
32076+
4f0767ce 32077+out:
b752ccd1
AM
32078+ dput(parent);
32079+ return err;
32080+}
32081+
32082+/* ---------------------------------------------------------------------- */
32083+
32084+/*
32085+ * create a xinofile at the default place/path.
32086+ */
32087+struct file *au_xino_def(struct super_block *sb)
32088+{
32089+ struct file *file;
32090+ char *page, *p;
32091+ struct au_branch *br;
32092+ struct super_block *h_sb;
32093+ struct path path;
32094+ aufs_bindex_t bend, bindex, bwr;
32095+
32096+ br = NULL;
32097+ bend = au_sbend(sb);
32098+ bwr = -1;
32099+ for (bindex = 0; bindex <= bend; bindex++) {
32100+ br = au_sbr(sb, bindex);
32101+ if (au_br_writable(br->br_perm)
86dc4139 32102+ && !au_test_fs_bad_xino(au_br_sb(br))) {
b752ccd1
AM
32103+ bwr = bindex;
32104+ break;
32105+ }
32106+ }
32107+
7f207e10
AM
32108+ if (bwr >= 0) {
32109+ file = ERR_PTR(-ENOMEM);
537831f9 32110+ page = (void *)__get_free_page(GFP_NOFS);
7f207e10
AM
32111+ if (unlikely(!page))
32112+ goto out;
86dc4139 32113+ path.mnt = au_br_mnt(br);
7f207e10
AM
32114+ path.dentry = au_h_dptr(sb->s_root, bwr);
32115+ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
32116+ file = (void *)p;
32117+ if (!IS_ERR(p)) {
32118+ strcat(p, "/" AUFS_XINO_FNAME);
32119+ AuDbg("%s\n", p);
32120+ file = au_xino_create(sb, p, /*silent*/0);
32121+ if (!IS_ERR(file))
32122+ au_xino_brid_set(sb, br->br_id);
32123+ }
537831f9 32124+ free_page((unsigned long)page);
7f207e10
AM
32125+ } else {
32126+ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
32127+ if (IS_ERR(file))
32128+ goto out;
32129+ h_sb = file->f_dentry->d_sb;
32130+ if (unlikely(au_test_fs_bad_xino(h_sb))) {
32131+ pr_err("xino doesn't support %s(%s)\n",
32132+ AUFS_XINO_DEFPATH, au_sbtype(h_sb));
32133+ fput(file);
32134+ file = ERR_PTR(-EINVAL);
32135+ }
32136+ if (!IS_ERR(file))
32137+ au_xino_brid_set(sb, -1);
32138+ }
0c5527e5 32139+
7f207e10
AM
32140+out:
32141+ return file;
32142+}
32143+
32144+/* ---------------------------------------------------------------------- */
32145+
32146+int au_xino_path(struct seq_file *seq, struct file *file)
32147+{
32148+ int err;
32149+
32150+ err = au_seq_path(seq, &file->f_path);
32151+ if (unlikely(err < 0))
32152+ goto out;
32153+
32154+ err = 0;
32155+#define Deleted "\\040(deleted)"
32156+ seq->count -= sizeof(Deleted) - 1;
32157+ AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
32158+ sizeof(Deleted) - 1));
32159+#undef Deleted
32160+
32161+out:
32162+ return err;
32163+}
537831f9
AM
32164diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h
32165--- /usr/share/empty/include/uapi/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
f6b6e03d 32166+++ linux/include/uapi/linux/aufs_type.h 2014-01-27 23:17:06.205534916 +0100
523b37e3 32167@@ -0,0 +1,281 @@
7f207e10 32168+/*
523b37e3 32169+ * Copyright (C) 2005-2014 Junjiro R. Okajima
7f207e10
AM
32170+ *
32171+ * This program, aufs is free software; you can redistribute it and/or modify
32172+ * it under the terms of the GNU General Public License as published by
32173+ * the Free Software Foundation; either version 2 of the License, or
32174+ * (at your option) any later version.
32175+ *
32176+ * This program is distributed in the hope that it will be useful,
32177+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32178+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32179+ * GNU General Public License for more details.
32180+ *
32181+ * You should have received a copy of the GNU General Public License
523b37e3 32182+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
32183+ */
32184+
32185+#ifndef __AUFS_TYPE_H__
32186+#define __AUFS_TYPE_H__
32187+
f6c5ef8b
AM
32188+#define AUFS_NAME "aufs"
32189+
9dbd164d 32190+#ifdef __KERNEL__
f6c5ef8b
AM
32191+/*
32192+ * define it before including all other headers.
32193+ * sched.h may use pr_* macros before defining "current", so define the
32194+ * no-current version first, and re-define later.
32195+ */
32196+#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__
32197+#include <linux/sched.h>
32198+#undef pr_fmt
a2a7ad62
AM
32199+#define pr_fmt(fmt) \
32200+ AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \
32201+ (int)sizeof(current->comm), current->comm, current->pid
9dbd164d
AM
32202+#else
32203+#include <stdint.h>
32204+#include <sys/types.h>
f6c5ef8b 32205+#endif /* __KERNEL__ */
7f207e10 32206+
f6c5ef8b
AM
32207+#include <linux/limits.h>
32208+
f6b6e03d 32209+#define AUFS_VERSION "3.13-20140127"
7f207e10
AM
32210+
32211+/* todo? move this to linux-2.6.19/include/magic.h */
32212+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
32213+
32214+/* ---------------------------------------------------------------------- */
32215+
32216+#ifdef CONFIG_AUFS_BRANCH_MAX_127
9dbd164d 32217+typedef int8_t aufs_bindex_t;
7f207e10
AM
32218+#define AUFS_BRANCH_MAX 127
32219+#else
9dbd164d 32220+typedef int16_t aufs_bindex_t;
7f207e10
AM
32221+#ifdef CONFIG_AUFS_BRANCH_MAX_511
32222+#define AUFS_BRANCH_MAX 511
32223+#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
32224+#define AUFS_BRANCH_MAX 1023
32225+#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
32226+#define AUFS_BRANCH_MAX 32767
32227+#endif
32228+#endif
32229+
32230+#ifdef __KERNEL__
32231+#ifndef AUFS_BRANCH_MAX
32232+#error unknown CONFIG_AUFS_BRANCH_MAX value
32233+#endif
32234+#endif /* __KERNEL__ */
32235+
32236+/* ---------------------------------------------------------------------- */
32237+
7f207e10
AM
32238+#define AUFS_FSTYPE AUFS_NAME
32239+
32240+#define AUFS_ROOT_INO 2
32241+#define AUFS_FIRST_INO 11
32242+
32243+#define AUFS_WH_PFX ".wh."
32244+#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1)
32245+#define AUFS_WH_TMP_LEN 4
86dc4139 32246+/* a limit for rmdir/rename a dir and copyup */
7f207e10
AM
32247+#define AUFS_MAX_NAMELEN (NAME_MAX \
32248+ - AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\
32249+ - 1 /* dot */\
32250+ - AUFS_WH_TMP_LEN) /* hex */
32251+#define AUFS_XINO_FNAME "." AUFS_NAME ".xino"
32252+#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME
392086de
AM
32253+#define AUFS_XINO_DEF_SEC 30 /* seconds */
32254+#define AUFS_XINO_DEF_TRUNC 45 /* percentage */
7f207e10
AM
32255+#define AUFS_DIRWH_DEF 3
32256+#define AUFS_RDCACHE_DEF 10 /* seconds */
027c5e7a 32257+#define AUFS_RDCACHE_MAX 3600 /* seconds */
7f207e10
AM
32258+#define AUFS_RDBLK_DEF 512 /* bytes */
32259+#define AUFS_RDHASH_DEF 32
32260+#define AUFS_WKQ_NAME AUFS_NAME "d"
027c5e7a
AM
32261+#define AUFS_MFS_DEF_SEC 30 /* seconds */
32262+#define AUFS_MFS_MAX_SEC 3600 /* seconds */
86dc4139 32263+#define AUFS_PLINK_WARN 50 /* number of plinks in a single bucket */
7f207e10
AM
32264+
32265+/* pseudo-link maintenace under /proc */
32266+#define AUFS_PLINK_MAINT_NAME "plink_maint"
32267+#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME
32268+#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME
32269+
32270+#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */
32271+#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME
32272+
32273+#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME
32274+#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk"
32275+#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph"
32276+
32277+/* doubly whiteouted */
32278+#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME
32279+#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME
32280+#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME
32281+
1e00d052 32282+/* branch permissions and attributes */
7f207e10
AM
32283+#define AUFS_BRPERM_RW "rw"
32284+#define AUFS_BRPERM_RO "ro"
32285+#define AUFS_BRPERM_RR "rr"
1e00d052
AM
32286+#define AUFS_BRRATTR_WH "wh"
32287+#define AUFS_BRWATTR_NLWH "nolwh"
86dc4139 32288+#define AUFS_BRATTR_UNPIN "unpin"
7f207e10
AM
32289+
32290+/* ---------------------------------------------------------------------- */
32291+
32292+/* ioctl */
32293+enum {
32294+ /* readdir in userspace */
32295+ AuCtl_RDU,
32296+ AuCtl_RDU_INO,
32297+
32298+ /* pathconf wrapper */
027c5e7a
AM
32299+ AuCtl_WBR_FD,
32300+
32301+ /* busy inode */
c2b27bf2
AM
32302+ AuCtl_IBUSY,
32303+
32304+ /* move-down */
32305+ AuCtl_MVDOWN
7f207e10
AM
32306+};
32307+
32308+/* borrowed from linux/include/linux/kernel.h */
32309+#ifndef ALIGN
32310+#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1)
32311+#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
32312+#endif
32313+
32314+/* borrowed from linux/include/linux/compiler-gcc3.h */
32315+#ifndef __aligned
32316+#define __aligned(x) __attribute__((aligned(x)))
53392da6
AM
32317+#endif
32318+
32319+#ifdef __KERNEL__
32320+#ifndef __packed
7f207e10
AM
32321+#define __packed __attribute__((packed))
32322+#endif
53392da6 32323+#endif
7f207e10
AM
32324+
32325+struct au_rdu_cookie {
9dbd164d
AM
32326+ uint64_t h_pos;
32327+ int16_t bindex;
32328+ uint8_t flags;
32329+ uint8_t pad;
32330+ uint32_t generation;
7f207e10
AM
32331+} __aligned(8);
32332+
32333+struct au_rdu_ent {
9dbd164d
AM
32334+ uint64_t ino;
32335+ int16_t bindex;
32336+ uint8_t type;
32337+ uint8_t nlen;
32338+ uint8_t wh;
7f207e10
AM
32339+ char name[0];
32340+} __aligned(8);
32341+
32342+static inline int au_rdu_len(int nlen)
32343+{
32344+ /* include the terminating NULL */
32345+ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1,
9dbd164d 32346+ sizeof(uint64_t));
7f207e10
AM
32347+}
32348+
32349+union au_rdu_ent_ul {
32350+ struct au_rdu_ent __user *e;
9dbd164d 32351+ uint64_t ul;
7f207e10
AM
32352+};
32353+
32354+enum {
32355+ AufsCtlRduV_SZ,
32356+ AufsCtlRduV_End
32357+};
32358+
32359+struct aufs_rdu {
32360+ /* input */
32361+ union {
9dbd164d
AM
32362+ uint64_t sz; /* AuCtl_RDU */
32363+ uint64_t nent; /* AuCtl_RDU_INO */
7f207e10
AM
32364+ };
32365+ union au_rdu_ent_ul ent;
9dbd164d 32366+ uint16_t verify[AufsCtlRduV_End];
7f207e10
AM
32367+
32368+ /* input/output */
9dbd164d 32369+ uint32_t blk;
7f207e10
AM
32370+
32371+ /* output */
32372+ union au_rdu_ent_ul tail;
32373+ /* number of entries which were added in a single call */
9dbd164d
AM
32374+ uint64_t rent;
32375+ uint8_t full;
32376+ uint8_t shwh;
7f207e10
AM
32377+
32378+ struct au_rdu_cookie cookie;
32379+} __aligned(8);
32380+
1e00d052
AM
32381+/* ---------------------------------------------------------------------- */
32382+
32383+struct aufs_wbr_fd {
9dbd164d
AM
32384+ uint32_t oflags;
32385+ int16_t brid;
1e00d052
AM
32386+} __aligned(8);
32387+
32388+/* ---------------------------------------------------------------------- */
32389+
027c5e7a 32390+struct aufs_ibusy {
9dbd164d
AM
32391+ uint64_t ino, h_ino;
32392+ int16_t bindex;
027c5e7a
AM
32393+} __aligned(8);
32394+
1e00d052
AM
32395+/* ---------------------------------------------------------------------- */
32396+
392086de
AM
32397+/* error code for move-down */
32398+/* the actual message strings are implemented in aufs-util.git */
32399+enum {
32400+ EAU_MVDOWN_OPAQUE = 1,
32401+ EAU_MVDOWN_WHITEOUT,
32402+ EAU_MVDOWN_UPPER,
32403+ EAU_MVDOWN_BOTTOM,
32404+ EAU_MVDOWN_NOUPPER,
32405+ EAU_MVDOWN_NOLOWERBR,
32406+ EAU_Last
32407+};
32408+
c2b27bf2 32409+/* flags for move-down */
392086de
AM
32410+#define AUFS_MVDOWN_DMSG 1
32411+#define AUFS_MVDOWN_OWLOWER (1 << 1) /* overwrite lower */
32412+#define AUFS_MVDOWN_KUPPER (1 << 2) /* keep upper */
32413+#define AUFS_MVDOWN_ROLOWER (1 << 3) /* do even if lower is RO */
32414+#define AUFS_MVDOWN_ROLOWER_R (1 << 4) /* did on lower RO */
32415+#define AUFS_MVDOWN_ROUPPER (1 << 5) /* do even if upper is RO */
32416+#define AUFS_MVDOWN_ROUPPER_R (1 << 6) /* did on upper RO */
32417+#define AUFS_MVDOWN_BRID_UPPER (1 << 7) /* upper brid */
32418+#define AUFS_MVDOWN_BRID_LOWER (1 << 8) /* lower brid */
c2b27bf2
AM
32419+/* will be added more */
32420+
392086de
AM
32421+enum {
32422+ AUFS_MVDOWN_UPPER,
32423+ AUFS_MVDOWN_LOWER,
32424+ AUFS_MVDOWN_NARRAY
32425+};
32426+
c2b27bf2 32427+struct aufs_mvdown {
392086de
AM
32428+ uint32_t flags;
32429+ struct {
32430+ int16_t bindex;
32431+ int16_t brid;
32432+ } a[AUFS_MVDOWN_NARRAY];
32433+ int8_t au_errno;
c2b27bf2
AM
32434+ /* will be added more */
32435+} __aligned(8);
32436+
32437+/* ---------------------------------------------------------------------- */
32438+
7f207e10
AM
32439+#define AuCtlType 'A'
32440+#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu)
32441+#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu)
1e00d052
AM
32442+#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \
32443+ struct aufs_wbr_fd)
027c5e7a 32444+#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
392086de
AM
32445+#define AUFS_CTL_MVDOWN _IOWR(AuCtlType, AuCtl_MVDOWN, \
32446+ struct aufs_mvdown)
7f207e10
AM
32447+
32448+#endif /* __AUFS_TYPE_H__ */
This page took 5.684054 seconds and 4 git commands to generate.