]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-aufs3.patch
- fixdeps needs 64-bit file API on some filesystems (like carme-i686)
[packages/kernel.git] / kernel-aufs3.patch
CommitLineData
392086de 1aufs3.x-rcN 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
392086de 25index 115add2..ce305b3 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
392086de 36aufs3.x-rcN base patch
7f207e10 37
392086de
AM
38diff --git a/drivers/block/loop.c b/drivers/block/loop.c
39index 40e7155..6e43ab0 100644
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,
537831f9 67diff --git a/fs/file_table.c b/fs/file_table.c
392086de 68index abdd15a..da0ee1e 100644
537831f9
AM
69--- a/fs/file_table.c
70+++ b/fs/file_table.c
71@@ -36,7 +36,7 @@ struct files_stat_struct files_stat = {
72 .max_files = NR_FILE
73 };
74
75-DEFINE_STATIC_LGLOCK(files_lglock);
76+DEFINE_LGLOCK(files_lglock);
77
78 /* SLAB cache for file structures */
79 static struct kmem_cache *filp_cachep __read_mostly;
392086de
AM
80@@ -360,7 +360,7 @@ static inline int file_list_cpu(struct file *file)
81 }
82
83 /* helper for file_sb_list_add to reduce ifdefs */
84-static inline void __file_sb_list_add(struct file *file, struct super_block *sb)
85+inline void __file_sb_list_add(struct file *file, struct super_block *sb)
86 {
87 struct list_head *list;
88 #ifdef CONFIG_SMP
89@@ -373,6 +373,7 @@ static inline void __file_sb_list_add(struct file *file, struct super_block *sb)
90 #endif
91 list_add(&file->f_u.fu_list, list);
92 }
93+EXPORT_SYMBOL(__file_sb_list_add);
94
95 /**
96 * file_sb_list_add - add a file to the sb's file list
0c3ec466 97diff --git a/fs/inode.c b/fs/inode.c
392086de 98index b33ba8e..9b24434 100644
0c3ec466
AM
99--- a/fs/inode.c
100+++ b/fs/inode.c
392086de 101@@ -1469,7 +1469,7 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
0c3ec466
AM
102 * This does the actual work of updating an inodes time or version. Must have
103 * had called mnt_want_write() before calling this.
104 */
105-static int update_time(struct inode *inode, struct timespec *time, int flags)
106+int update_time(struct inode *inode, struct timespec *time, int flags)
107 {
108 if (inode->i_op->update_time)
109 return inode->i_op->update_time(inode, time, flags);
7f207e10 110diff --git a/fs/splice.c b/fs/splice.c
392086de 111index 3b7ee65..e147583 100644
7f207e10
AM
112--- a/fs/splice.c
113+++ b/fs/splice.c
c06a8ce3 114@@ -1093,8 +1093,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
7f207e10
AM
115 /*
116 * Attempt to initiate a splice from pipe to file.
117 */
118-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
119- loff_t *ppos, size_t len, unsigned int flags)
120+long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
121+ loff_t *ppos, size_t len, unsigned int flags)
122 {
123 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
124 loff_t *, size_t, unsigned int);
392086de 125@@ -1110,9 +1110,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
7f207e10
AM
126 /*
127 * Attempt to initiate a splice from a file to a pipe.
128 */
129-static long do_splice_to(struct file *in, loff_t *ppos,
130- struct pipe_inode_info *pipe, size_t len,
131- unsigned int flags)
132+long do_splice_to(struct file *in, loff_t *ppos,
133+ struct pipe_inode_info *pipe, size_t len,
134+ unsigned int flags)
135 {
136 ssize_t (*splice_read)(struct file *, loff_t *,
137 struct pipe_inode_info *, size_t, unsigned int);
0c3ec466 138diff --git a/include/linux/fs.h b/include/linux/fs.h
392086de 139index 3f40547..36b235e 100644
0c3ec466
AM
140--- a/include/linux/fs.h
141+++ b/include/linux/fs.h
392086de 142@@ -2594,6 +2594,7 @@ extern int inode_change_ok(const struct inode *, struct iattr *);
0c3ec466
AM
143 extern int inode_newsize_ok(const struct inode *, loff_t offset);
144 extern void setattr_copy(struct inode *inode, const struct iattr *attr);
145
146+extern int update_time(struct inode *, struct timespec *, int);
147 extern int file_update_time(struct file *file);
148
149 extern int generic_show_options(struct seq_file *m, struct dentry *root);
1e00d052 150diff --git a/include/linux/splice.h b/include/linux/splice.h
86dc4139 151index 74575cb..bfc6fb6 100644
1e00d052
AM
152--- a/include/linux/splice.h
153+++ b/include/linux/splice.h
86dc4139 154@@ -92,4 +92,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *);
4b3da204
AM
155 extern void spd_release_page(struct splice_pipe_desc *, unsigned int);
156
157 extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
1e00d052
AM
158+
159+extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
160+ loff_t *ppos, size_t len, unsigned int flags);
161+extern long do_splice_to(struct file *in, loff_t *ppos,
162+ struct pipe_inode_info *pipe, size_t len,
163+ unsigned int flags);
164 #endif
392086de 165aufs3.x-rcN standalone patch
7f207e10
AM
166
167diff --git a/fs/file_table.c b/fs/file_table.c
392086de 168index da0ee1e..0a02e12 100644
7f207e10
AM
169--- a/fs/file_table.c
170+++ b/fs/file_table.c
b4510431 171@@ -37,6 +37,7 @@ struct files_stat_struct files_stat = {
0c3ec466
AM
172 };
173
174 DEFINE_LGLOCK(files_lglock);
175+EXPORT_SYMBOL(files_lglock);
176
177 /* SLAB cache for file structures */
178 static struct kmem_cache *filp_cachep __read_mostly;
392086de 179@@ -410,6 +411,8 @@ void file_sb_list_del(struct file *file)
7f207e10
AM
180 }
181 }
182
183+EXPORT_SYMBOL(file_sb_list_del);
1facf9fc 184+
7f207e10
AM
185 #ifdef CONFIG_SMP
186
187 /*
1e00d052 188diff --git a/fs/inode.c b/fs/inode.c
392086de 189index 9b24434..6ee4b0b 100644
1e00d052
AM
190--- a/fs/inode.c
191+++ b/fs/inode.c
392086de 192@@ -57,6 +57,7 @@ static struct hlist_head *inode_hashtable __read_mostly;
4b3da204 193 static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock);
2cbb1c4b
JR
194
195 __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock);
2cbb1c4b 196+EXPORT_SYMBOL(inode_sb_list_lock);
7f207e10
AM
197
198 /*
4b3da204 199 * Empty aops. Can be used for the cases where the user does not
392086de 200@@ -1485,6 +1486,7 @@ int update_time(struct inode *inode, struct timespec *time, int flags)
0c3ec466
AM
201 mark_inode_dirty_sync(inode);
202 return 0;
203 }
204+EXPORT_SYMBOL(update_time);
205
206 /**
207 * touch_atime - update the access time
7f207e10 208diff --git a/fs/namespace.c b/fs/namespace.c
392086de 209index da5c494..f40ae6f 100644
7f207e10
AM
210--- a/fs/namespace.c
211+++ b/fs/namespace.c
86dc4139 212@@ -54,6 +54,7 @@ EXPORT_SYMBOL_GPL(fs_kobj);
0c3ec466
AM
213 * tree or hash is modified or when a vfsmount structure is modified.
214 */
215 DEFINE_BRLOCK(vfsmount_lock);
216+EXPORT_SYMBOL(vfsmount_lock);
217
218 static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
219 {
86dc4139 220@@ -427,6 +428,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
c06a8ce3
AM
221 mnt_dec_writers(real_mount(mnt));
222 preempt_enable();
223 }
224+EXPORT_SYMBOL_GPL(__mnt_drop_write);
225
226 /**
227 * mnt_drop_write - give up write access to a mount
392086de 228@@ -1480,6 +1482,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
7f207e10
AM
229 }
230 return 0;
231 }
232+EXPORT_SYMBOL(iterate_mounts);
233
7eafdf33 234 static void cleanup_group_ids(struct mount *mnt, struct mount *end)
7f207e10
AM
235 {
236diff --git a/fs/notify/group.c b/fs/notify/group.c
1716fcea 237index bd2625b..2ff2a0f 100644
7f207e10
AM
238--- a/fs/notify/group.c
239+++ b/fs/notify/group.c
240@@ -22,6 +22,7 @@
241 #include <linux/srcu.h>
242 #include <linux/rculist.h>
243 #include <linux/wait.h>
244+#include <linux/module.h>
245
246 #include <linux/fsnotify_backend.h>
247 #include "fsnotify.h"
1716fcea
AM
248@@ -65,6 +66,7 @@ void fsnotify_get_group(struct fsnotify_group *group)
249 {
250 atomic_inc(&group->refcnt);
251 }
252+EXPORT_SYMBOL(fsnotify_get_group);
253
254 /*
255 * Drop a reference to a group. Free it if it's through.
256@@ -74,6 +76,7 @@ void fsnotify_put_group(struct fsnotify_group *group)
7f207e10 257 if (atomic_dec_and_test(&group->refcnt))
1716fcea 258 fsnotify_final_destroy_group(group);
7f207e10
AM
259 }
260+EXPORT_SYMBOL(fsnotify_put_group);
261
262 /*
263 * Create a new fsnotify_group and hold a reference for the group returned.
1716fcea 264@@ -102,6 +105,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
7f207e10
AM
265
266 return group;
267 }
268+EXPORT_SYMBOL(fsnotify_alloc_group);
1716fcea
AM
269
270 int fsnotify_fasync(int fd, struct file *file, int on)
271 {
7f207e10 272diff --git a/fs/notify/mark.c b/fs/notify/mark.c
392086de 273index 923fe4a..176b435 100644
7f207e10
AM
274--- a/fs/notify/mark.c
275+++ b/fs/notify/mark.c
392086de 276@@ -109,6 +109,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
7f207e10 277 mark->free_mark(mark);
1716fcea 278 }
7f207e10
AM
279 }
280+EXPORT_SYMBOL(fsnotify_put_mark);
281
282 /*
283 * Any time a mark is getting freed we end up here.
392086de 284@@ -191,6 +192,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark,
1716fcea
AM
285 fsnotify_destroy_mark_locked(mark, group);
286 mutex_unlock(&group->mark_mutex);
7f207e10
AM
287 }
288+EXPORT_SYMBOL(fsnotify_destroy_mark);
289
290 void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask)
291 {
392086de 292@@ -275,6 +277,7 @@ err:
7f207e10
AM
293
294 return ret;
295 }
296+EXPORT_SYMBOL(fsnotify_add_mark);
297
1716fcea
AM
298 int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
299 struct inode *inode, struct vfsmount *mnt, int allow_dups)
392086de 300@@ -336,6 +339,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
7f207e10
AM
301 atomic_set(&mark->refcnt, 1);
302 mark->free_mark = free_mark;
303 }
304+EXPORT_SYMBOL(fsnotify_init_mark);
305
306 static int fsnotify_mark_destroy(void *ignored)
307 {
308diff --git a/fs/open.c b/fs/open.c
392086de 309index d420331..6dd3b03 100644
7f207e10
AM
310--- a/fs/open.c
311+++ b/fs/open.c
c06a8ce3 312@@ -61,6 +61,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
7f207e10
AM
313 mutex_unlock(&dentry->d_inode->i_mutex);
314 return ret;
315 }
316+EXPORT_SYMBOL(do_truncate);
317
1716fcea 318 long vfs_truncate(struct path *path, loff_t length)
7f207e10
AM
319 {
320diff --git a/fs/splice.c b/fs/splice.c
392086de 321index e147583..789f6b2 100644
7f207e10
AM
322--- a/fs/splice.c
323+++ b/fs/splice.c
392086de
AM
324@@ -1106,6 +1106,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
325
326 return splice_write(pipe, out, ppos, len, flags);
7f207e10
AM
327 }
328+EXPORT_SYMBOL(do_splice_from);
329
330 /*
331 * Attempt to initiate a splice from a file to a pipe.
392086de 332@@ -1132,6 +1133,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
7f207e10
AM
333
334 return splice_read(in, ppos, pipe, len, flags);
335 }
336+EXPORT_SYMBOL(do_splice_to);
337
338 /**
339 * splice_direct_to_actor - splices data directly between two non-pipes
340diff --git a/security/commoncap.c b/security/commoncap.c
392086de 341index b9d613e..ba3b618 100644
7f207e10
AM
342--- a/security/commoncap.c
343+++ b/security/commoncap.c
1716fcea 344@@ -988,9 +988,11 @@ int cap_mmap_addr(unsigned long addr)
94337f0d 345 }
7f207e10
AM
346 return ret;
347 }
0c3ec466
AM
348+EXPORT_SYMBOL(cap_mmap_addr);
349
350 int cap_mmap_file(struct file *file, unsigned long reqprot,
351 unsigned long prot, unsigned long flags)
352 {
353 return 0;
354 }
355+EXPORT_SYMBOL(cap_mmap_file);
7f207e10 356diff --git a/security/device_cgroup.c b/security/device_cgroup.c
392086de 357index c123628..efc6f68 100644
7f207e10
AM
358--- a/security/device_cgroup.c
359+++ b/security/device_cgroup.c
f6c5ef8b
AM
360@@ -7,6 +7,7 @@
361 #include <linux/device_cgroup.h>
362 #include <linux/cgroup.h>
363 #include <linux/ctype.h>
364+#include <linux/export.h>
365 #include <linux/list.h>
366 #include <linux/uaccess.h>
367 #include <linux/seq_file.h>
392086de 368@@ -756,6 +757,7 @@ int __devcgroup_inode_permission(struct inode *inode, int mask)
537831f9
AM
369 return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
370 access);
7f207e10 371 }
2cbb1c4b 372+EXPORT_SYMBOL(__devcgroup_inode_permission);
7f207e10
AM
373
374 int devcgroup_inode_mknod(int mode, dev_t dev)
375 {
376diff --git a/security/security.c b/security/security.c
392086de 377index 4dc31f4..1f272bc 100644
7f207e10
AM
378--- a/security/security.c
379+++ b/security/security.c
392086de 380@@ -407,6 +407,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry)
7f207e10
AM
381 return 0;
382 return security_ops->path_rmdir(dir, dentry);
383 }
384+EXPORT_SYMBOL(security_path_rmdir);
385
386 int security_path_unlink(struct path *dir, struct dentry *dentry)
387 {
392086de 388@@ -423,6 +424,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry,
7f207e10
AM
389 return 0;
390 return security_ops->path_symlink(dir, dentry, old_name);
391 }
392+EXPORT_SYMBOL(security_path_symlink);
393
394 int security_path_link(struct dentry *old_dentry, struct path *new_dir,
395 struct dentry *new_dentry)
392086de 396@@ -431,6 +433,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
7f207e10
AM
397 return 0;
398 return security_ops->path_link(old_dentry, new_dir, new_dentry);
399 }
400+EXPORT_SYMBOL(security_path_link);
401
402 int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
403 struct path *new_dir, struct dentry *new_dentry)
392086de 404@@ -449,6 +452,7 @@ int security_path_truncate(struct path *path)
7f207e10
AM
405 return 0;
406 return security_ops->path_truncate(path);
407 }
408+EXPORT_SYMBOL(security_path_truncate);
409
7eafdf33
AM
410 int security_path_chmod(struct path *path, umode_t mode)
411 {
392086de 412@@ -456,6 +460,7 @@ int security_path_chmod(struct path *path, umode_t mode)
7f207e10 413 return 0;
7eafdf33 414 return security_ops->path_chmod(path, mode);
7f207e10
AM
415 }
416+EXPORT_SYMBOL(security_path_chmod);
417
537831f9 418 int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
7f207e10 419 {
392086de 420@@ -463,6 +468,7 @@ int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
7f207e10
AM
421 return 0;
422 return security_ops->path_chown(path, uid, gid);
423 }
424+EXPORT_SYMBOL(security_path_chown);
425
426 int security_path_chroot(struct path *path)
427 {
392086de 428@@ -539,6 +545,7 @@ int security_inode_readlink(struct dentry *dentry)
7f207e10
AM
429 return 0;
430 return security_ops->inode_readlink(dentry);
431 }
432+EXPORT_SYMBOL(security_inode_readlink);
433
434 int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
435 {
392086de 436@@ -553,6 +560,7 @@ int security_inode_permission(struct inode *inode, int mask)
7f207e10 437 return 0;
1e00d052 438 return security_ops->inode_permission(inode, mask);
7f207e10
AM
439 }
440+EXPORT_SYMBOL(security_inode_permission);
441
1e00d052 442 int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
7f207e10 443 {
392086de 444@@ -675,6 +683,7 @@ int security_file_permission(struct file *file, int mask)
7f207e10
AM
445
446 return fsnotify_perm(file, mask);
447 }
448+EXPORT_SYMBOL(security_file_permission);
449
450 int security_file_alloc(struct file *file)
451 {
392086de 452@@ -735,6 +744,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
7f207e10
AM
453 return ret;
454 return ima_file_mmap(file, prot);
455 }
0c3ec466 456+EXPORT_SYMBOL(security_mmap_file);
7f207e10 457
0c3ec466
AM
458 int security_mmap_addr(unsigned long addr)
459 {
7f207e10
AM
460diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs
461--- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100
86dc4139
AM
462+++ linux/Documentation/ABI/testing/debugfs-aufs 2013-07-06 13:20:47.716863966 +0200
463@@ -0,0 +1,50 @@
7f207e10
AM
464+What: /debug/aufs/si_<id>/
465+Date: March 2009
466+Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
467+Description:
468+ Under /debug/aufs, a directory named si_<id> is created
469+ per aufs mount, where <id> is a unique id generated
470+ internally.
1facf9fc 471+
86dc4139
AM
472+What: /debug/aufs/si_<id>/plink
473+Date: Apr 2013
474+Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
475+Description:
476+ It has three lines and shows the information about the
477+ pseudo-link. The first line is a single number
478+ representing a number of buckets. The second line is a
479+ number of pseudo-links per buckets (separated by a
480+ blank). The last line is a single number representing a
481+ total number of psedo-links.
482+ When the aufs mount option 'noplink' is specified, it
483+ will show "1\n0\n0\n".
484+
7f207e10
AM
485+What: /debug/aufs/si_<id>/xib
486+Date: March 2009
487+Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
488+Description:
489+ It shows the consumed blocks by xib (External Inode Number
490+ Bitmap), its block size and file size.
491+ When the aufs mount option 'noxino' is specified, it
492+ will be empty. About XINO files, see the aufs manual.
493+
494+What: /debug/aufs/si_<id>/xino0, xino1 ... xinoN
495+Date: March 2009
496+Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
497+Description:
498+ It shows the consumed blocks by xino (External Inode Number
499+ Translation Table), its link count, block size and file
500+ size.
501+ When the aufs mount option 'noxino' is specified, it
502+ will be empty. About XINO files, see the aufs manual.
503+
504+What: /debug/aufs/si_<id>/xigen
505+Date: March 2009
506+Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
507+Description:
508+ It shows the consumed blocks by xigen (External Inode
509+ Generation Table), its block size and file size.
510+ If CONFIG_AUFS_EXPORT is disabled, this entry will not
511+ be created.
512+ When the aufs mount option 'noxino' is specified, it
513+ will be empty. About XINO files, see the aufs manual.
514diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs
515--- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100
392086de
AM
516+++ linux/Documentation/ABI/testing/sysfs-aufs 2013-10-26 16:51:32.269706994 +0200
517@@ -0,0 +1,31 @@
7f207e10
AM
518+What: /sys/fs/aufs/si_<id>/
519+Date: March 2009
520+Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
521+Description:
522+ Under /sys/fs/aufs, a directory named si_<id> is created
523+ per aufs mount, where <id> is a unique id generated
524+ internally.
525+
526+What: /sys/fs/aufs/si_<id>/br0, br1 ... brN
527+Date: March 2009
528+Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
529+Description:
530+ It shows the abolute path of a member directory (which
531+ is called branch) in aufs, and its permission.
532+
392086de
AM
533+What: /sys/fs/aufs/si_<id>/brid0, brid1 ... bridN
534+Date: July 2013
535+Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
536+Description:
537+ It shows the id of a member directory (which is called
538+ branch) in aufs.
539+
7f207e10
AM
540+What: /sys/fs/aufs/si_<id>/xi_path
541+Date: March 2009
542+Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
543+Description:
544+ It shows the abolute path of XINO (External Inode Number
545+ Bitmap, Translation Table and Generation Table) file
546+ even if it is the default path.
547+ When the aufs mount option 'noxino' is specified, it
548+ will be empty. About XINO files, see the aufs manual.
53392da6
AM
549diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt
550--- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 01:00:00.000000000 +0100
86dc4139 551+++ linux/Documentation/filesystems/aufs/design/01intro.txt 2013-07-06 13:20:47.730197761 +0200
53392da6
AM
552@@ -0,0 +1,162 @@
553+
7a9e40b8 554+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
555+#
556+# This program is free software; you can redistribute it and/or modify
557+# it under the terms of the GNU General Public License as published by
558+# the Free Software Foundation; either version 2 of the License, or
559+# (at your option) any later version.
560+#
561+# This program is distributed in the hope that it will be useful,
562+# but WITHOUT ANY WARRANTY; without even the implied warranty of
563+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
564+# GNU General Public License for more details.
565+#
566+# You should have received a copy of the GNU General Public License
567+# along with this program; if not, write to the Free Software
568+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
569+
570+Introduction
571+----------------------------------------
572+
573+aufs [ei ju: ef es] | [a u f s]
574+1. abbrev. for "advanced multi-layered unification filesystem".
575+2. abbrev. for "another unionfs".
576+3. abbrev. for "auf das" in German which means "on the" in English.
577+ Ex. "Butter aufs Brot"(G) means "butter onto bread"(E).
578+ But "Filesystem aufs Filesystem" is hard to understand.
579+
580+AUFS is a filesystem with features:
581+- multi layered stackable unification filesystem, the member directory
582+ is called as a branch.
583+- branch permission and attribute, 'readonly', 'real-readonly',
584+ 'readwrite', 'whiteout-able', 'link-able whiteout' and their
585+ combination.
586+- internal "file copy-on-write".
587+- logical deletion, whiteout.
588+- dynamic branch manipulation, adding, deleting and changing permission.
589+- allow bypassing aufs, user's direct branch access.
590+- external inode number translation table and bitmap which maintains the
591+ persistent aufs inode number.
592+- seekable directory, including NFS readdir.
593+- file mapping, mmap and sharing pages.
594+- pseudo-link, hardlink over branches.
595+- loopback mounted filesystem as a branch.
596+- several policies to select one among multiple writable branches.
597+- revert a single systemcall when an error occurs in aufs.
598+- and more...
599+
600+
601+Multi Layered Stackable Unification Filesystem
602+----------------------------------------------------------------------
603+Most people already knows what it is.
604+It is a filesystem which unifies several directories and provides a
605+merged single directory. When users access a file, the access will be
606+passed/re-directed/converted (sorry, I am not sure which English word is
607+correct) to the real file on the member filesystem. The member
608+filesystem is called 'lower filesystem' or 'branch' and has a mode
609+'readonly' and 'readwrite.' And the deletion for a file on the lower
610+readonly branch is handled by creating 'whiteout' on the upper writable
611+branch.
612+
613+On LKML, there have been discussions about UnionMount (Jan Blunck,
614+Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took
615+different approaches to implement the merged-view.
616+The former tries putting it into VFS, and the latter implements as a
617+separate filesystem.
618+(If I misunderstand about these implementations, please let me know and
619+I shall correct it. Because it is a long time ago when I read their
620+source files last time).
621+
622+UnionMount's approach will be able to small, but may be hard to share
623+branches between several UnionMount since the whiteout in it is
624+implemented in the inode on branch filesystem and always
625+shared. According to Bharata's post, readdir does not seems to be
626+finished yet.
627+There are several missing features known in this implementations such as
628+- for users, the inode number may change silently. eg. copy-up.
629+- link(2) may break by copy-up.
630+- read(2) may get an obsoleted filedata (fstat(2) too).
631+- fcntl(F_SETLK) may be broken by copy-up.
632+- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
633+ open(O_RDWR).
634+
635+Unionfs has a longer history. When I started implementing a stacking filesystem
636+(Aug 2005), it already existed. It has virtual super_block, inode,
637+dentry and file objects and they have an array pointing lower same kind
638+objects. After contributing many patches for Unionfs, I re-started my
639+project AUFS (Jun 2006).
640+
641+In AUFS, the structure of filesystem resembles to Unionfs, but I
642+implemented my own ideas, approaches and enhancements and it became
643+totally different one.
644+
645+Comparing DM snapshot and fs based implementation
646+- the number of bytes to be copied between devices is much smaller.
647+- the type of filesystem must be one and only.
648+- the fs must be writable, no readonly fs, even for the lower original
649+ device. so the compression fs will not be usable. but if we use
650+ loopback mount, we may address this issue.
651+ for instance,
652+ mount /cdrom/squashfs.img /sq
653+ losetup /sq/ext2.img
654+ losetup /somewhere/cow
655+ dmsetup "snapshot /dev/loop0 /dev/loop1 ..."
656+- it will be difficult (or needs more operations) to extract the
657+ difference between the original device and COW.
658+- DM snapshot-merge may help a lot when users try merging. in the
659+ fs-layer union, users will use rsync(1).
660+
661+
662+Several characters/aspects of aufs
663+----------------------------------------------------------------------
664+
665+Aufs has several characters or aspects.
666+1. a filesystem, callee of VFS helper
667+2. sub-VFS, caller of VFS helper for branches
668+3. a virtual filesystem which maintains persistent inode number
669+4. reader/writer of files on branches such like an application
670+
671+1. Callee of VFS Helper
672+As an ordinary linux filesystem, aufs is a callee of VFS. For instance,
673+unlink(2) from an application reaches sys_unlink() kernel function and
674+then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it
675+calls filesystem specific unlink operation. Actually aufs implements the
676+unlink operation but it behaves like a redirector.
677+
678+2. Caller of VFS Helper for Branches
679+aufs_unlink() passes the unlink request to the branch filesystem as if
680+it were called from VFS. So the called unlink operation of the branch
681+filesystem acts as usual. As a caller of VFS helper, aufs should handle
682+every necessary pre/post operation for the branch filesystem.
683+- acquire the lock for the parent dir on a branch
684+- lookup in a branch
685+- revalidate dentry on a branch
686+- mnt_want_write() for a branch
687+- vfs_unlink() for a branch
688+- mnt_drop_write() for a branch
689+- release the lock on a branch
690+
691+3. Persistent Inode Number
692+One of the most important issue for a filesystem is to maintain inode
693+numbers. This is particularly important to support exporting a
694+filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
695+backend block device for its own. But some storage is necessary to
696+maintain inode number. It may be a large space and may not suit to keep
697+in memory. Aufs rents some space from its first writable branch
698+filesystem (by default) and creates file(s) on it. These files are
699+created by aufs internally and removed soon (currently) keeping opened.
700+Note: Because these files are removed, they are totally gone after
701+ unmounting aufs. It means the inode numbers are not persistent
702+ across unmount or reboot. I have a plan to make them really
703+ persistent which will be important for aufs on NFS server.
704+
705+4. Read/Write Files Internally (copy-on-write)
706+Because a branch can be readonly, when you write a file on it, aufs will
707+"copy-up" it to the upper writable branch internally. And then write the
708+originally requested thing to the file. Generally kernel doesn't
709+open/read/write file actively. In aufs, even a single write may cause a
710+internal "file copy". This behaviour is very similar to cp(1) command.
711+
712+Some people may think it is better to pass such work to user space
713+helper, instead of doing in kernel space. Actually I am still thinking
714+about it. But currently I have implemented it in kernel space.
715diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt linux/Documentation/filesystems/aufs/design/02struct.txt
716--- /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100
392086de 717+++ linux/Documentation/filesystems/aufs/design/02struct.txt 2013-10-26 16:51:32.273040419 +0200
c2b27bf2 718@@ -0,0 +1,243 @@
53392da6 719+
7a9e40b8 720+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
721+#
722+# This program is free software; you can redistribute it and/or modify
723+# it under the terms of the GNU General Public License as published by
724+# the Free Software Foundation; either version 2 of the License, or
725+# (at your option) any later version.
726+#
727+# This program is distributed in the hope that it will be useful,
728+# but WITHOUT ANY WARRANTY; without even the implied warranty of
729+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
730+# GNU General Public License for more details.
731+#
732+# You should have received a copy of the GNU General Public License
733+# along with this program; if not, write to the Free Software
734+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
735+
736+Basic Aufs Internal Structure
737+
738+Superblock/Inode/Dentry/File Objects
739+----------------------------------------------------------------------
740+As like an ordinary filesystem, aufs has its own
741+superblock/inode/dentry/file objects. All these objects have a
742+dynamically allocated array and store the same kind of pointers to the
743+lower filesystem, branch.
744+For example, when you build a union with one readwrite branch and one
745+readonly, mounted /au, /rw and /ro respectively.
746+- /au = /rw + /ro
747+- /ro/fileA exists but /rw/fileA
748+
749+Aufs lookup operation finds /ro/fileA and gets dentry for that. These
750+pointers are stored in a aufs dentry. The array in aufs dentry will be,
751+- [0] = NULL
752+- [1] = /ro/fileA
753+
754+This style of an array is essentially same to the aufs
755+superblock/inode/dentry/file objects.
756+
757+Because aufs supports manipulating branches, ie. add/delete/change
758+dynamically, these objects has its own generation. When branches are
759+changed, the generation in aufs superblock is incremented. And a
760+generation in other object are compared when it is accessed.
761+When a generation in other objects are obsoleted, aufs refreshes the
762+internal array.
763+
764+
765+Superblock
766+----------------------------------------------------------------------
767+Additionally aufs superblock has some data for policies to select one
768+among multiple writable branches, XIB files, pseudo-links and kobject.
769+See below in detail.
770+About the policies which supports copy-down a directory, see policy.txt
771+too.
772+
773+
774+Branch and XINO(External Inode Number Translation Table)
775+----------------------------------------------------------------------
776+Every branch has its own xino (external inode number translation table)
777+file. The xino file is created and unlinked by aufs internally. When two
778+members of a union exist on the same filesystem, they share the single
779+xino file.
780+The struct of a xino file is simple, just a sequence of aufs inode
781+numbers which is indexed by the lower inode number.
782+In the above sample, assume the inode number of /ro/fileA is i111 and
783+aufs assigns the inode number i999 for fileA. Then aufs writes 999 as
784+4(8) bytes at 111 * 4(8) bytes offset in the xino file.
785+
786+When the inode numbers are not contiguous, the xino file will be sparse
787+which has a hole in it and doesn't consume as much disk space as it
788+might appear. If your branch filesystem consumes disk space for such
789+holes, then you should specify 'xino=' option at mounting aufs.
790+
791+Also a writable branch has three kinds of "whiteout bases". All these
792+are existed when the branch is joined to aufs and the names are
793+whiteout-ed doubly, so that users will never see their names in aufs
794+hierarchy.
795+1. a regular file which will be linked to all whiteouts.
796+2. a directory to store a pseudo-link.
797+3. a directory to store an "orphan-ed" file temporary.
798+
799+1. Whiteout Base
800+ When you remove a file on a readonly branch, aufs handles it as a
801+ logical deletion and creates a whiteout on the upper writable branch
802+ as a hardlink of this file in order not to consume inode on the
803+ writable branch.
804+2. Pseudo-link Dir
805+ See below, Pseudo-link.
806+3. Step-Parent Dir
807+ When "fileC" exists on the lower readonly branch only and it is
808+ opened and removed with its parent dir, and then user writes
809+ something into it, then aufs copies-up fileC to this
810+ directory. Because there is no other dir to store fileC. After
811+ creating a file under this dir, the file is unlinked.
812+
813+Because aufs supports manipulating branches, ie. add/delete/change
814+dynamically, a branch has its own id. When the branch order changes, aufs
815+finds the new index by searching the branch id.
816+
817+
818+Pseudo-link
819+----------------------------------------------------------------------
820+Assume "fileA" exists on the lower readonly branch only and it is
821+hardlinked to "fileB" on the branch. When you write something to fileA,
822+aufs copies-up it to the upper writable branch. Additionally aufs
823+creates a hardlink under the Pseudo-link Directory of the writable
824+branch. The inode of a pseudo-link is kept in aufs super_block as a
825+simple list. If fileB is read after unlinking fileA, aufs returns
826+filedata from the pseudo-link instead of the lower readonly
827+branch. Because the pseudo-link is based upon the inode, to keep the
828+inode number by xino (see above) is important.
829+
830+All the hardlinks under the Pseudo-link Directory of the writable branch
831+should be restored in a proper location later. Aufs provides a utility
832+to do this. The userspace helpers executed at remounting and unmounting
833+aufs by default.
834+During this utility is running, it puts aufs into the pseudo-link
835+maintenance mode. In this mode, only the process which began the
836+maintenance mode (and its child processes) is allowed to operate in
837+aufs. Some other processes which are not related to the pseudo-link will
838+be allowed to run too, but the rest have to return an error or wait
839+until the maintenance mode ends. If a process already acquires an inode
840+mutex (in VFS), it has to return an error.
841+
842+
843+XIB(external inode number bitmap)
844+----------------------------------------------------------------------
845+Addition to the xino file per a branch, aufs has an external inode number
846+bitmap in a superblock object. It is also a file such like a xino file.
847+It is a simple bitmap to mark whether the aufs inode number is in-use or
848+not.
849+To reduce the file I/O, aufs prepares a single memory page to cache xib.
850+
851+Aufs implements a feature to truncate/refresh both of xino and xib to
852+reduce the number of consumed disk blocks for these files.
853+
854+
855+Virtual or Vertical Dir, and Readdir in Userspace
856+----------------------------------------------------------------------
857+In order to support multiple layers (branches), aufs readdir operation
858+constructs a virtual dir block on memory. For readdir, aufs calls
859+vfs_readdir() internally for each dir on branches, merges their entries
860+with eliminating the whiteout-ed ones, and sets it to file (dir)
861+object. So the file object has its entry list until it is closed. The
862+entry list will be updated when the file position is zero and becomes
863+old. This decision is made in aufs automatically.
864+
865+The dynamically allocated memory block for the name of entries has a
866+unit of 512 bytes (by default) and stores the names contiguously (no
867+padding). Another block for each entry is handled by kmem_cache too.
868+During building dir blocks, aufs creates hash list and judging whether
869+the entry is whiteouted by its upper branch or already listed.
870+The merged result is cached in the corresponding inode object and
871+maintained by a customizable life-time option.
872+
873+Some people may call it can be a security hole or invite DoS attack
874+since the opened and once readdir-ed dir (file object) holds its entry
875+list and becomes a pressure for system memory. But I'd say it is similar
876+to files under /proc or /sys. The virtual files in them also holds a
877+memory page (generally) while they are opened. When an idea to reduce
878+memory for them is introduced, it will be applied to aufs too.
879+For those who really hate this situation, I've developed readdir(3)
880+library which operates this merging in userspace. You just need to set
881+LD_PRELOAD environment variable, and aufs will not consume no memory in
882+kernel space for readdir(3).
883+
884+
885+Workqueue
886+----------------------------------------------------------------------
887+Aufs sometimes requires privilege access to a branch. For instance,
888+in copy-up/down operation. When a user process is going to make changes
889+to a file which exists in the lower readonly branch only, and the mode
890+of one of ancestor directories may not be writable by a user
891+process. Here aufs copy-up the file with its ancestors and they may
892+require privilege to set its owner/group/mode/etc.
893+This is a typical case of a application character of aufs (see
894+Introduction).
895+
896+Aufs uses workqueue synchronously for this case. It creates its own
897+workqueue. The workqueue is a kernel thread and has privilege. Aufs
898+passes the request to call mkdir or write (for example), and wait for
899+its completion. This approach solves a problem of a signal handler
900+simply.
901+If aufs didn't adopt the workqueue and changed the privilege of the
902+process, and if the mkdir/write call arises SIGXFSZ or other signal,
903+then the user process might gain a privilege or the generated core file
904+was owned by a superuser.
905+
906+Also aufs uses the system global workqueue ("events" kernel thread) too
907+for asynchronous tasks, such like handling inotify/fsnotify, re-creating a
908+whiteout base and etc. This is unrelated to a privilege.
909+Most of aufs operation tries acquiring a rw_semaphore for aufs
910+superblock at the beginning, at the same time waits for the completion
911+of all queued asynchronous tasks.
912+
913+
914+Whiteout
915+----------------------------------------------------------------------
916+The whiteout in aufs is very similar to Unionfs's. That is represented
917+by its filename. UnionMount takes an approach of a file mode, but I am
918+afraid several utilities (find(1) or something) will have to support it.
919+
920+Basically the whiteout represents "logical deletion" which stops aufs to
921+lookup further, but also it represents "dir is opaque" which also stop
922+lookup.
923+
924+In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively.
925+In order to make several functions in a single systemcall to be
926+revertible, aufs adopts an approach to rename a directory to a temporary
927+unique whiteouted name.
928+For example, in rename(2) dir where the target dir already existed, aufs
929+renames the target dir to a temporary unique whiteouted name before the
930+actual rename on a branch and then handles other actions (make it opaque,
931+update the attributes, etc). If an error happens in these actions, aufs
932+simply renames the whiteouted name back and returns an error. If all are
933+succeeded, aufs registers a function to remove the whiteouted unique
934+temporary name completely and asynchronously to the system global
935+workqueue.
936+
937+
938+Copy-up
939+----------------------------------------------------------------------
940+It is a well-known feature or concept.
941+When user modifies a file on a readonly branch, aufs operate "copy-up"
942+internally and makes change to the new file on the upper writable branch.
943+When the trigger systemcall does not update the timestamps of the parent
944+dir, aufs reverts it after copy-up.
c2b27bf2
AM
945+
946+
947+Move-down (aufs3.9 and later)
948+----------------------------------------------------------------------
949+"Copy-up" is one of the essential feature in aufs. It copies a file from
950+the lower readonly branch to the upper writable branch when a user
951+changes something about the file.
952+"Move-down" is an opposite action of copy-up. Basically this action is
953+ran manually instead of automatically and internally.
954+
955+Sometimes users want to move-down a file from the upper writable branch
956+to the lower readonly or writable branch. For instance,
957+- the free space of the upper writable branch is going to run out.
958+- create a new intermediate branch between the upper and lower branch.
959+- etc.
960+
961+For this purpose, use "aumvdown" command in aufs-util.git.
53392da6
AM
962diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt
963--- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100
86dc4139 964+++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2013-07-06 13:20:47.730197761 +0200
53392da6
AM
965@@ -0,0 +1,106 @@
966+
7a9e40b8 967+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
968+#
969+# This program is free software; you can redistribute it and/or modify
970+# it under the terms of the GNU General Public License as published by
971+# the Free Software Foundation; either version 2 of the License, or
972+# (at your option) any later version.
973+#
974+# This program is distributed in the hope that it will be useful,
975+# but WITHOUT ANY WARRANTY; without even the implied warranty of
976+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
977+# GNU General Public License for more details.
978+#
979+# You should have received a copy of the GNU General Public License
980+# along with this program; if not, write to the Free Software
981+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
982+
983+Lookup in a Branch
984+----------------------------------------------------------------------
985+Since aufs has a character of sub-VFS (see Introduction), it operates
986+lookup for branches as VFS does. It may be a heavy work. Generally
987+speaking struct nameidata is a bigger structure and includes many
988+information. But almost all lookup operation in aufs is the simplest
989+case, ie. lookup only an entry directly connected to its parent. Digging
990+down the directory hierarchy is unnecessary.
991+
992+VFS has a function lookup_one_len() for that use, but it is not usable
993+for a branch filesystem which requires struct nameidata. So aufs
994+implements a simple lookup wrapper function. When a branch filesystem
995+allows NULL as nameidata, it calls lookup_one_len(). Otherwise it builds
996+a simplest nameidata and calls lookup_hash().
997+Here aufs applies "a principle in NFSD", ie. if the filesystem supports
998+NFS-export, then it has to support NULL as a nameidata parameter for
999+->create(), ->lookup() and ->d_revalidate(). So the lookup wrapper in
1000+aufs tests if ->s_export_op in the branch is NULL or not.
1001+
1002+When a branch is a remote filesystem, aufs basically trusts its
1003+->d_revalidate(), also aufs forces the hardest revalidate tests for
1004+them.
1005+For d_revalidate, aufs implements three levels of revalidate tests. See
1006+"Revalidate Dentry and UDBA" in detail.
1007+
1008+
1009+Loopback Mount
1010+----------------------------------------------------------------------
1011+Basically aufs supports any type of filesystem and block device for a
1012+branch (actually there are some exceptions). But it is prohibited to add
1013+a loopback mounted one whose backend file exists in a filesystem which is
1014+already added to aufs. The reason is to protect aufs from a recursive
1015+lookup. If it was allowed, the aufs lookup operation might re-enter a
1016+lookup for the loopback mounted branch in the same context, and will
1017+cause a deadlock.
1018+
1019+
1020+Revalidate Dentry and UDBA (User's Direct Branch Access)
1021+----------------------------------------------------------------------
1022+Generally VFS helpers re-validate a dentry as a part of lookup.
1023+0. digging down the directory hierarchy.
1024+1. lock the parent dir by its i_mutex.
1025+2. lookup the final (child) entry.
1026+3. revalidate it.
1027+4. call the actual operation (create, unlink, etc.)
1028+5. unlock the parent dir
1029+
1030+If the filesystem implements its ->d_revalidate() (step 3), then it is
1031+called. Actually aufs implements it and checks the dentry on a branch is
1032+still valid.
1033+But it is not enough. Because aufs has to release the lock for the
1034+parent dir on a branch at the end of ->lookup() (step 2) and
1035+->d_revalidate() (step 3) while the i_mutex of the aufs dir is still
1036+held by VFS.
1037+If the file on a branch is changed directly, eg. bypassing aufs, after
1038+aufs released the lock, then the subsequent operation may cause
1039+something unpleasant result.
1040+
1041+This situation is a result of VFS architecture, ->lookup() and
1042+->d_revalidate() is separated. But I never say it is wrong. It is a good
1043+design from VFS's point of view. It is just not suitable for sub-VFS
1044+character in aufs.
1045+
1046+Aufs supports such case by three level of revalidation which is
1047+selectable by user.
1048+1. Simple Revalidate
1049+ Addition to the native flow in VFS's, confirm the child-parent
1050+ relationship on the branch just after locking the parent dir on the
1051+ branch in the "actual operation" (step 4). When this validation
1052+ fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still
1053+ checks the validation of the dentry on branches.
1054+2. Monitor Changes Internally by Inotify/Fsnotify
1055+ Addition to above, in the "actual operation" (step 4) aufs re-lookup
1056+ the dentry on the branch, and returns EBUSY if it finds different
1057+ dentry.
1058+ Additionally, aufs sets the inotify/fsnotify watch for every dir on branches
1059+ during it is in cache. When the event is notified, aufs registers a
1060+ function to kernel 'events' thread by schedule_work(). And the
1061+ function sets some special status to the cached aufs dentry and inode
1062+ private data. If they are not cached, then aufs has nothing to
1063+ do. When the same file is accessed through aufs (step 0-3) later,
1064+ aufs will detect the status and refresh all necessary data.
1065+ In this mode, aufs has to ignore the event which is fired by aufs
1066+ itself.
1067+3. No Extra Validation
1068+ This is the simplest test and doesn't add any additional revalidation
1069+ test, and skip therevalidatin in step 4. It is useful and improves
1070+ aufs performance when system surely hide the aufs branches from user,
1071+ by over-mounting something (or another method).
1072diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt linux/Documentation/filesystems/aufs/design/04branch.txt
1073--- /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100
86dc4139 1074+++ linux/Documentation/filesystems/aufs/design/04branch.txt 2013-07-06 13:20:47.730197761 +0200
53392da6
AM
1075@@ -0,0 +1,76 @@
1076+
7a9e40b8 1077+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
1078+#
1079+# This program is free software; you can redistribute it and/or modify
1080+# it under the terms of the GNU General Public License as published by
1081+# the Free Software Foundation; either version 2 of the License, or
1082+# (at your option) any later version.
1083+#
1084+# This program is distributed in the hope that it will be useful,
1085+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1086+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1087+# GNU General Public License for more details.
1088+#
1089+# You should have received a copy of the GNU General Public License
1090+# along with this program; if not, write to the Free Software
1091+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1092+
1093+Branch Manipulation
1094+
1095+Since aufs supports dynamic branch manipulation, ie. add/remove a branch
1096+and changing its permission/attribute, there are a lot of works to do.
1097+
1098+
1099+Add a Branch
1100+----------------------------------------------------------------------
1101+o Confirm the adding dir exists outside of aufs, including loopback
1102+ mount.
1103+- and other various attributes...
1104+o Initialize the xino file and whiteout bases if necessary.
1105+ See struct.txt.
1106+
1107+o Check the owner/group/mode of the directory
1108+ When the owner/group/mode of the adding directory differs from the
1109+ existing branch, aufs issues a warning because it may impose a
1110+ security risk.
1111+ For example, when a upper writable branch has a world writable empty
1112+ top directory, a malicious user can create any files on the writable
1113+ branch directly, like copy-up and modify manually. If something like
1114+ /etc/{passwd,shadow} exists on the lower readonly branch but the upper
1115+ writable branch, and the writable branch is world-writable, then a
1116+ malicious guy may create /etc/passwd on the writable branch directly
1117+ and the infected file will be valid in aufs.
1118+ I am afraid it can be a security issue, but nothing to do except
1119+ producing a warning.
1120+
1121+
1122+Delete a Branch
1123+----------------------------------------------------------------------
1124+o Confirm the deleting branch is not busy
1125+ To be general, there is one merit to adopt "remount" interface to
1126+ manipulate branches. It is to discard caches. At deleting a branch,
1127+ aufs checks the still cached (and connected) dentries and inodes. If
1128+ there are any, then they are all in-use. An inode without its
1129+ corresponding dentry can be alive alone (for example, inotify/fsnotify case).
1130+
1131+ For the cached one, aufs checks whether the same named entry exists on
1132+ other branches.
1133+ If the cached one is a directory, because aufs provides a merged view
1134+ to users, as long as one dir is left on any branch aufs can show the
1135+ dir to users. In this case, the branch can be removed from aufs.
1136+ Otherwise aufs rejects deleting the branch.
1137+
1138+ If any file on the deleting branch is opened by aufs, then aufs
1139+ rejects deleting.
1140+
1141+
1142+Modify the Permission of a Branch
1143+----------------------------------------------------------------------
1144+o Re-initialize or remove the xino file and whiteout bases if necessary.
1145+ See struct.txt.
1146+
1147+o rw --> ro: Confirm the modifying branch is not busy
1148+ Aufs rejects the request if any of these conditions are true.
1149+ - a file on the branch is mmap-ed.
1150+ - a regular file on the branch is opened for write and there is no
1151+ same named entry on the upper branch.
1152diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt linux/Documentation/filesystems/aufs/design/05wbr_policy.txt
1153--- /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 01:00:00.000000000 +0100
86dc4139 1154+++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2013-07-06 13:20:47.730197761 +0200
53392da6
AM
1155@@ -0,0 +1,65 @@
1156+
7a9e40b8 1157+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
1158+#
1159+# This program is free software; you can redistribute it and/or modify
1160+# it under the terms of the GNU General Public License as published by
1161+# the Free Software Foundation; either version 2 of the License, or
1162+# (at your option) any later version.
1163+#
1164+# This program is distributed in the hope that it will be useful,
1165+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1166+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1167+# GNU General Public License for more details.
1168+#
1169+# You should have received a copy of the GNU General Public License
1170+# along with this program; if not, write to the Free Software
1171+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1172+
1173+Policies to Select One among Multiple Writable Branches
1174+----------------------------------------------------------------------
1175+When the number of writable branch is more than one, aufs has to decide
1176+the target branch for file creation or copy-up. By default, the highest
1177+writable branch which has the parent (or ancestor) dir of the target
1178+file is chosen (top-down-parent policy).
1179+By user's request, aufs implements some other policies to select the
1180+writable branch, for file creation two policies, round-robin and
1181+most-free-space policies. For copy-up three policies, top-down-parent,
1182+bottom-up-parent and bottom-up policies.
1183+
1184+As expected, the round-robin policy selects the branch in circular. When
1185+you have two writable branches and creates 10 new files, 5 files will be
1186+created for each branch. mkdir(2) systemcall is an exception. When you
1187+create 10 new directories, all will be created on the same branch.
1188+And the most-free-space policy selects the one which has most free
1189+space among the writable branches. The amount of free space will be
1190+checked by aufs internally, and users can specify its time interval.
1191+
1192+The policies for copy-up is more simple,
1193+top-down-parent is equivalent to the same named on in create policy,
1194+bottom-up-parent selects the writable branch where the parent dir
1195+exists and the nearest upper one from the copyup-source,
1196+bottom-up selects the nearest upper writable branch from the
1197+copyup-source, regardless the existence of the parent dir.
1198+
1199+There are some rules or exceptions to apply these policies.
1200+- If there is a readonly branch above the policy-selected branch and
1201+ the parent dir is marked as opaque (a variation of whiteout), or the
1202+ target (creating) file is whiteout-ed on the upper readonly branch,
1203+ then the result of the policy is ignored and the target file will be
1204+ created on the nearest upper writable branch than the readonly branch.
1205+- If there is a writable branch above the policy-selected branch and
1206+ the parent dir is marked as opaque or the target file is whiteouted
1207+ on the branch, then the result of the policy is ignored and the target
1208+ file will be created on the highest one among the upper writable
1209+ branches who has diropq or whiteout. In case of whiteout, aufs removes
1210+ it as usual.
1211+- link(2) and rename(2) systemcalls are exceptions in every policy.
1212+ They try selecting the branch where the source exists as possible
1213+ since copyup a large file will take long time. If it can't be,
1214+ ie. the branch where the source exists is readonly, then they will
1215+ follow the copyup policy.
1216+- There is an exception for rename(2) when the target exists.
1217+ If the rename target exists, aufs compares the index of the branches
1218+ where the source and the target exists and selects the higher
1219+ one. If the selected branch is readonly, then aufs follows the
1220+ copyup policy.
1221diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt
1222--- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 01:00:00.000000000 +0100
86dc4139 1223+++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2013-07-06 13:20:47.730197761 +0200
53392da6
AM
1224@@ -0,0 +1,47 @@
1225+
7a9e40b8 1226+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
1227+#
1228+# This program is free software; you can redistribute it and/or modify
1229+# it under the terms of the GNU General Public License as published by
1230+# the Free Software Foundation; either version 2 of the License, or
1231+# (at your option) any later version.
1232+#
1233+# This program is distributed in the hope that it will be useful,
1234+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1235+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1236+# GNU General Public License for more details.
1237+#
1238+# You should have received a copy of the GNU General Public License
1239+# along with this program; if not, write to the Free Software
1240+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1241+
1242+mmap(2) -- File Memory Mapping
1243+----------------------------------------------------------------------
1244+In aufs, the file-mapped pages are handled by a branch fs directly, no
1245+interaction with aufs. It means aufs_mmap() calls the branch fs's
1246+->mmap().
1247+This approach is simple and good, but there is one problem.
1248+Under /proc, several entries show the mmap-ped files by its path (with
1249+device and inode number), and the printed path will be the path on the
1250+branch fs's instead of virtual aufs's.
1251+This is not a problem in most cases, but some utilities lsof(1) (and its
1252+user) may expect the path on aufs.
1253+
1254+To address this issue, aufs adds a new member called vm_prfile in struct
1255+vm_area_struct (and struct vm_region). The original vm_file points to
1256+the file on the branch fs in order to handle everything correctly as
1257+usual. The new vm_prfile points to a virtual file in aufs, and the
1258+show-functions in procfs refers to vm_prfile if it is set.
1259+Also we need to maintain several other places where touching vm_file
1260+such like
1261+- fork()/clone() copies vma and the reference count of vm_file is
1262+ incremented.
1263+- merging vma maintains the ref count too.
1264+
1265+This is not a good approach. It just faking the printed path. But it
1266+leaves all behaviour around f_mapping unchanged. This is surely an
1267+advantage.
1268+Actually aufs had adopted another complicated approach which calls
1269+generic_file_mmap() and handles struct vm_operations_struct. In this
1270+approach, aufs met a hard problem and I could not solve it without
1271+switching the approach.
1272diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt
1273--- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100
86dc4139 1274+++ linux/Documentation/filesystems/aufs/design/07export.txt 2013-07-06 13:20:47.736864659 +0200
53392da6
AM
1275@@ -0,0 +1,59 @@
1276+
7a9e40b8 1277+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
1278+#
1279+# This program is free software; you can redistribute it and/or modify
1280+# it under the terms of the GNU General Public License as published by
1281+# the Free Software Foundation; either version 2 of the License, or
1282+# (at your option) any later version.
1283+#
1284+# This program is distributed in the hope that it will be useful,
1285+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1286+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1287+# GNU General Public License for more details.
1288+#
1289+# You should have received a copy of the GNU General Public License
1290+# along with this program; if not, write to the Free Software
1291+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1292+
1293+Export Aufs via NFS
1294+----------------------------------------------------------------------
1295+Here is an approach.
1296+- like xino/xib, add a new file 'xigen' which stores aufs inode
1297+ generation.
1298+- iget_locked(): initialize aufs inode generation for a new inode, and
1299+ store it in xigen file.
1300+- destroy_inode(): increment aufs inode generation and store it in xigen
1301+ file. it is necessary even if it is not unlinked, because any data of
1302+ inode may be changed by UDBA.
1303+- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise
1304+ build file handle by
1305+ + branch id (4 bytes)
1306+ + superblock generation (4 bytes)
1307+ + inode number (4 or 8 bytes)
1308+ + parent dir inode number (4 or 8 bytes)
1309+ + inode generation (4 bytes))
1310+ + return value of exportfs_encode_fh() for the parent on a branch (4
1311+ bytes)
1312+ + file handle for a branch (by exportfs_encode_fh())
1313+- fh_to_dentry():
1314+ + find the index of a branch from its id in handle, and check it is
1315+ still exist in aufs.
1316+ + 1st level: get the inode number from handle and search it in cache.
1317+ + 2nd level: if not found, get the parent inode number from handle and
1318+ search it in cache. and then open the parent dir, find the matching
1319+ inode number by vfs_readdir() and get its name, and call
1320+ lookup_one_len() for the target dentry.
1321+ + 3rd level: if the parent dir is not cached, call
1322+ exportfs_decode_fh() for a branch and get the parent on a branch,
1323+ build a pathname of it, convert it a pathname in aufs, call
1324+ path_lookup(). now aufs gets a parent dir dentry, then handle it as
1325+ the 2nd level.
1326+ + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount
1327+ for every branch, but not itself. to get this, (currently) aufs
1328+ searches in current->nsproxy->mnt_ns list. it may not be a good
1329+ idea, but I didn't get other approach.
1330+ + test the generation of the gotten inode.
1331+- every inode operation: they may get EBUSY due to UDBA. in this case,
1332+ convert it into ESTALE for NFSD.
1333+- readdir(): call lockdep_on/off() because filldir in NFSD calls
1334+ lookup_one_len(), vfs_getattr(), encode_fh() and others.
1335diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linux/Documentation/filesystems/aufs/design/08shwh.txt
1336--- /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 01:00:00.000000000 +0100
86dc4139 1337+++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2013-07-06 13:20:47.736864659 +0200
53392da6
AM
1338@@ -0,0 +1,53 @@
1339+
7a9e40b8 1340+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
1341+#
1342+# This program is free software; you can redistribute it and/or modify
1343+# it under the terms of the GNU General Public License as published by
1344+# the Free Software Foundation; either version 2 of the License, or
1345+# (at your option) any later version.
1346+#
1347+# This program is distributed in the hope that it will be useful,
1348+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1349+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1350+# GNU General Public License for more details.
1351+#
1352+# You should have received a copy of the GNU General Public License
1353+# along with this program; if not, write to the Free Software
1354+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1355+
1356+Show Whiteout Mode (shwh)
1357+----------------------------------------------------------------------
1358+Generally aufs hides the name of whiteouts. But in some cases, to show
1359+them is very useful for users. For instance, creating a new middle layer
1360+(branch) by merging existing layers.
1361+
1362+(borrowing aufs1 HOW-TO from a user, Michael Towers)
1363+When you have three branches,
1364+- Bottom: 'system', squashfs (underlying base system), read-only
1365+- Middle: 'mods', squashfs, read-only
1366+- Top: 'overlay', ram (tmpfs), read-write
1367+
1368+The top layer is loaded at boot time and saved at shutdown, to preserve
1369+the changes made to the system during the session.
1370+When larger changes have been made, or smaller changes have accumulated,
1371+the size of the saved top layer data grows. At this point, it would be
1372+nice to be able to merge the two overlay branches ('mods' and 'overlay')
1373+and rewrite the 'mods' squashfs, clearing the top layer and thus
1374+restoring save and load speed.
1375+
1376+This merging is simplified by the use of another aufs mount, of just the
1377+two overlay branches using the 'shwh' option.
1378+# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \
1379+ aufs /livesys/merge_union
1380+
1381+A merged view of these two branches is then available at
1382+/livesys/merge_union, and the new feature is that the whiteouts are
1383+visible!
1384+Note that in 'shwh' mode the aufs mount must be 'ro', which will disable
1385+writing to all branches. Also the default mode for all branches is 'ro'.
1386+It is now possible to save the combined contents of the two overlay
1387+branches to a new squashfs, e.g.:
1388+# mksquashfs /livesys/merge_union /path/to/newmods.squash
1389+
1390+This new squashfs archive can be stored on the boot device and the
1391+initramfs will use it to replace the old one at the next boot.
1392diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt linux/Documentation/filesystems/aufs/design/10dynop.txt
1393--- /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 01:00:00.000000000 +0100
86dc4139 1394+++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2013-07-06 13:20:47.736864659 +0200
53392da6
AM
1395@@ -0,0 +1,47 @@
1396+
7a9e40b8 1397+# Copyright (C) 2010-2013 Junjiro R. Okajima
53392da6
AM
1398+#
1399+# This program is free software; you can redistribute it and/or modify
1400+# it under the terms of the GNU General Public License as published by
1401+# the Free Software Foundation; either version 2 of the License, or
1402+# (at your option) any later version.
1403+#
1404+# This program is distributed in the hope that it will be useful,
1405+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1406+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1407+# GNU General Public License for more details.
1408+#
1409+# You should have received a copy of the GNU General Public License
1410+# along with this program; if not, write to the Free Software
1411+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1412+
1413+Dynamically customizable FS operations
1414+----------------------------------------------------------------------
1415+Generally FS operations (struct inode_operations, struct
1416+address_space_operations, struct file_operations, etc.) are defined as
1417+"static const", but it never means that FS have only one set of
1418+operation. Some FS have multiple sets of them. For instance, ext2 has
1419+three sets, one for XIP, for NOBH, and for normal.
1420+Since aufs overrides and redirects these operations, sometimes aufs has
1421+to change its behaviour according to the branch FS type. More imporantly
1422+VFS acts differently if a function (member in the struct) is set or
1423+not. It means aufs should have several sets of operations and select one
1424+among them according to the branch FS definition.
1425+
1426+In order to solve this problem and not to affect the behavour of VFS,
1427+aufs defines these operations dynamically. For instance, aufs defines
1428+aio_read function for struct file_operations, but it may not be set to
1429+the file_operations. When the branch FS doesn't have it, aufs doesn't
1430+set it to its file_operations while the function definition itself is
1431+still alive. So the behaviour of io_submit(2) will not change, and it
1432+will return an error when aio_read is not defined.
1433+
1434+The lifetime of these dynamically generated operation object is
1435+maintained by aufs branch object. When the branch is removed from aufs,
1436+the reference counter of the object is decremented. When it reaches
1437+zero, the dynamically generated operation object will be freed.
1438+
1439+This approach is designed to support AIO (io_submit), Direcit I/O and
1440+XIP mainly.
1441+Currently this approach is applied to file_operations and
1442+vm_operations_struct for regular files only.
1443diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt linux/Documentation/filesystems/aufs/design/99plan.txt
1444--- /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt 1970-01-01 01:00:00.000000000 +0100
86dc4139 1445+++ linux/Documentation/filesystems/aufs/design/99plan.txt 2013-07-06 13:20:47.736864659 +0200
53392da6
AM
1446@@ -0,0 +1,96 @@
1447+
7a9e40b8 1448+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
1449+#
1450+# This program is free software; you can redistribute it and/or modify
1451+# it under the terms of the GNU General Public License as published by
1452+# the Free Software Foundation; either version 2 of the License, or
1453+# (at your option) any later version.
1454+#
1455+# This program is distributed in the hope that it will be useful,
1456+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1457+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1458+# GNU General Public License for more details.
1459+#
1460+# You should have received a copy of the GNU General Public License
1461+# along with this program; if not, write to the Free Software
1462+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1463+
1464+Plan
1465+
1466+Restoring some features which was implemented in aufs1.
1467+They were dropped in aufs2 in order to make source files simpler and
1468+easier to be reviewed.
1469+
1470+
1471+Test Only the Highest One for the Directory Permission (dirperm1 option)
1472+----------------------------------------------------------------------
1473+Let's try case study.
1474+- aufs has two branches, upper readwrite and lower readonly.
1475+ /au = /rw + /ro
1476+- "dirA" exists under /ro, but /rw. and its mode is 0700.
1477+- user invoked "chmod a+rx /au/dirA"
1478+- then "dirA" becomes world readable?
1479+
1480+In this case, /ro/dirA is still 0700 since it exists in readonly branch,
1481+or it may be a natively readonly filesystem. If aufs respects the lower
1482+branch, it should not respond readdir request from other users. But user
1483+allowed it by chmod. Should really aufs rejects showing the entries
1484+under /ro/dirA?
1485+
1486+To be honest, I don't have a best solution for this case. So I
1487+implemented 'dirperm1' and 'nodirperm1' option in aufs1, and leave it to
1488+users.
1489+When dirperm1 is specified, aufs checks only the highest one for the
1490+directory permission, and shows the entries. Otherwise, as usual, checks
1491+every dir existing on all branches and rejects the request.
1492+
1493+As a side effect, dirperm1 option improves the performance of aufs
1494+because the number of permission check is reduced.
1495+
1496+
1497+Being Another Aufs's Readonly Branch (robr)
1498+----------------------------------------------------------------------
1499+Aufs1 allows aufs to be another aufs's readonly branch.
1500+This feature was developed by a user's request. But it may not be used
1501+currecnly.
1502+
1503+
1504+Copy-up on Open (coo=)
1505+----------------------------------------------------------------------
1506+By default the internal copy-up is executed when it is really necessary.
1507+It is not done when a file is opened for writing, but when write(2) is
1508+done. Users who have many (over 100) branches want to know and analyse
1509+when and what file is copied-up. To insert a new upper branch which
1510+contains such files only may improve the performance of aufs.
1511+
1512+Aufs1 implemented "coo=none | leaf | all" option.
1513+
1514+
1515+Refresh the Opened File (refrof)
1516+----------------------------------------------------------------------
1517+This option is implemented in aufs1 but incomplete.
1518+
1519+When user reads from a file, he expects to get its latest filedata
1520+generally. If the file is removed and a new same named file is created,
1521+the content he gets is unchanged, ie. the unlinked filedata.
1522+
1523+Let's try case study again.
1524+- aufs has two branches.
1525+ /au = /rw + /ro
1526+- "fileA" exists under /ro, but /rw.
1527+- user opened "/au/fileA".
1528+- he or someone else inserts a branch (/new) between /rw and /ro.
1529+ /au = /rw + /new + /ro
1530+- the new branch has "fileA".
1531+- user reads from the opened "fileA"
1532+- which filedata should aufs return, from /ro or /new?
1533+
1534+Some people says it has to be "from /ro" and it is a semantics of Unix.
1535+The others say it should be "from /new" because the file is not removed
1536+and it is equivalent to the case of someone else modifies the file.
1537+
1538+Here again I don't have a best and final answer. I got an idea to
1539+implement 'refrof' and 'norefrof' option. When 'refrof' (REFResh the
1540+Opened File) is specified (by default), aufs returns the filedata from
1541+/new.
1542+Otherwise from /new.
1543diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README
1544--- /usr/share/empty/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100
392086de
AM
1545+++ linux/Documentation/filesystems/aufs/README 2013-10-26 16:51:32.273040419 +0200
1546@@ -0,0 +1,347 @@
53392da6
AM
1547+
1548+Aufs3 -- advanced multi layered unification filesystem version 3.x
1549+http://aufs.sf.net
1550+Junjiro R. Okajima
1551+
1552+
1553+0. Introduction
1554+----------------------------------------
1555+In the early days, aufs was entirely re-designed and re-implemented
1556+Unionfs Version 1.x series. After many original ideas, approaches,
1557+improvements and implementations, it becomes totally different from
1558+Unionfs while keeping the basic features.
1559+Recently, Unionfs Version 2.x series begin taking some of the same
1560+approaches to aufs1's.
1561+Unionfs is being developed by Professor Erez Zadok at Stony Brook
1562+University and his team.
1563+
1564+Aufs3 supports linux-3.0 and later.
1565+If you want older kernel version support, try aufs2-2.6.git or
1566+aufs2-standalone.git repository, aufs1 from CVS on SourceForge.
1567+
1568+Note: it becomes clear that "Aufs was rejected. Let's give it up."
1569+According to Christoph Hellwig, linux rejects all union-type filesystems
1570+but UnionMount.
1571+<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
1572+
1573+
1574+1. Features
1575+----------------------------------------
1576+- unite several directories into a single virtual filesystem. The member
1577+ directory is called as a branch.
1578+- you can specify the permission flags to the branch, which are 'readonly',
1579+ 'readwrite' and 'whiteout-able.'
1580+- by upper writable branch, internal copyup and whiteout, files/dirs on
1581+ readonly branch are modifiable logically.
1582+- dynamic branch manipulation, add, del.
1583+- etc...
1584+
1585+Also there are many enhancements in aufs1, such as:
1586+- readdir(3) in userspace.
1587+- keep inode number by external inode number table
1588+- keep the timestamps of file/dir in internal copyup operation
1589+- seekable directory, supporting NFS readdir.
1590+- whiteout is hardlinked in order to reduce the consumption of inodes
1591+ on branch
1592+- do not copyup, nor create a whiteout when it is unnecessary
1593+- revert a single systemcall when an error occurs in aufs
1594+- remount interface instead of ioctl
1595+- maintain /etc/mtab by an external command, /sbin/mount.aufs.
1596+- loopback mounted filesystem as a branch
1597+- kernel thread for removing the dir who has a plenty of whiteouts
1598+- support copyup sparse file (a file which has a 'hole' in it)
1599+- default permission flags for branches
1600+- selectable permission flags for ro branch, whether whiteout can
1601+ exist or not
1602+- export via NFS.
1603+- support <sysfs>/fs/aufs and <debugfs>/aufs.
1604+- support multiple writable branches, some policies to select one
1605+ among multiple writable branches.
1606+- a new semantics for link(2) and rename(2) to support multiple
1607+ writable branches.
1608+- no glibc changes are required.
1609+- pseudo hardlink (hardlink over branches)
1610+- allow a direct access manually to a file on branch, e.g. bypassing aufs.
1611+ including NFS or remote filesystem branch.
1612+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
1613+- and more...
1614+
1615+Currently these features are dropped temporary from aufs3.
1616+See design/08plan.txt in detail.
1617+- test only the highest one for the directory permission (dirperm1)
1618+- copyup on open (coo=)
1619+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
1620+ (robr)
1621+- statistics of aufs thread (/sys/fs/aufs/stat)
1622+- delegation mode (dlgt)
1623+ a delegation of the internal branch access to support task I/O
1624+ accounting, which also supports Linux Security Modules (LSM) mainly
1625+ for Suse AppArmor.
1626+- intent.open/create (file open in a single lookup)
1627+
1628+Features or just an idea in the future (see also design/*.txt),
1629+- reorder the branch index without del/re-add.
1630+- permanent xino files for NFSD
1631+- an option for refreshing the opened files after add/del branches
1632+- 'move' policy for copy-up between two writable branches, after
1633+ checking free space.
1634+- light version, without branch manipulation. (unnecessary?)
1635+- copyup in userspace
1636+- inotify in userspace
1637+- readv/writev
1638+- xattr, acl
1639+
1640+
1641+2. Download
1642+----------------------------------------
1e00d052
AM
1643+There were three GIT trees for aufs3, aufs3-linux.git,
1644+aufs3-standalone.git, and aufs-util.git. Note that there is no "3" in
1645+"aufs-util.git."
1646+While the aufs-util is always necessary, you need either of aufs3-linux
1647+or aufs3-standalone.
1648+
1649+The aufs3-linux tree includes the whole linux mainline GIT tree,
1650+git://git.kernel.org/.../torvalds/linux.git.
1651+And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
b4510431 1652+build aufs3 as an external kernel module.
1e00d052
AM
1653+
1654+On the other hand, the aufs3-standalone tree has only aufs source files
53392da6
AM
1655+and necessary patches, and you can select CONFIG_AUFS_FS=m.
1656+
1657+You will find GIT branches whose name is in form of "aufs3.x" where "x"
1658+represents the linux kernel version, "linux-3.x". For instance,
1e00d052
AM
1659+"aufs3.0" is for linux-3.0. For latest "linux-3.x-rcN", use
1660+"aufs3.x-rcN" branch.
1661+
1662+o aufs3-linux tree
1663+$ git clone --reference /your/linux/git/tree \
86dc4139 1664+ git://git.code.sf.net/p/aufs/aufs3-linux aufs-aufs3-linux \
1e00d052
AM
1665+ aufs3-linux.git
1666+- if you don't have linux GIT tree, then remove "--reference ..."
1667+$ cd aufs3-linux.git
1668+$ git checkout origin/aufs3.0
53392da6
AM
1669+
1670+o aufs3-standalone tree
86dc4139 1671+$ git clone git://git.code.sf.net/p/aufs/aufs3-standalone \
53392da6
AM
1672+ aufs3-standalone.git
1673+$ cd aufs3-standalone.git
1674+$ git checkout origin/aufs3.0
1675+
1676+o aufs-util tree
86dc4139 1677+$ git clone git://git.code.sf.net/p/aufs/aufs-util \
53392da6
AM
1678+ aufs-util.git
1679+$ cd aufs-util.git
1680+$ git checkout origin/aufs3.0
1681+
9dbd164d
AM
1682+Note: The 3.x-rcN branch is to be used with `rc' kernel versions ONLY.
1683+The minor version number, 'x' in '3.x', of aufs may not always
1684+follow the minor version number of the kernel.
1685+Because changes in the kernel that cause the use of a new
1686+minor version number do not always require changes to aufs-util.
1687+
1688+Since aufs-util has its own minor version number, you may not be
1689+able to find a GIT branch in aufs-util for your kernel's
1690+exact minor version number.
1691+In this case, you should git-checkout the branch for the
53392da6 1692+nearest lower number.
9dbd164d
AM
1693+
1694+For (an unreleased) example:
1695+If you are using "linux-3.10" and the "aufs3.10" branch
7eafdf33 1696+does not exist in aufs-util repository, then "aufs3.9", "aufs3.8"
9dbd164d
AM
1697+or something numerically smaller is the branch for your kernel.
1698+
53392da6
AM
1699+Also you can view all branches by
1700+ $ git branch -a
1701+
1702+
1703+3. Configuration and Compilation
1704+----------------------------------------
1705+Make sure you have git-checkout'ed the correct branch.
1706+
1e00d052 1707+For aufs3-linux tree,
c06a8ce3 1708+- enable CONFIG_AUFS_FS.
1e00d052
AM
1709+- set other aufs configurations if necessary.
1710+
53392da6
AM
1711+For aufs3-standalone tree,
1712+There are several ways to build.
1713+
1714+1.
1715+- apply ./aufs3-kbuild.patch to your kernel source files.
1716+- apply ./aufs3-base.patch too.
1717+- apply ./aufs3-proc_map.patch too, if you want to make /proc/PID/maps (and
1718+ others including lsof(1)) show the file path on aufs instead of the
1719+ path on the branch fs.
1720+- apply ./aufs3-standalone.patch too, if you have a plan to set
1721+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs3-standalone.patch.
537831f9
AM
1722+- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
1723+ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
c06a8ce3 1724+- enable CONFIG_AUFS_FS, you can select either
53392da6
AM
1725+ =m or =y.
1726+- and build your kernel as usual.
1727+- install the built kernel.
c06a8ce3
AM
1728+ Note: Since linux-3.9, every filesystem module requires an alias
1729+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
1730+ modules.aliases file if you set CONFIG_AUFS_FS=m.
7eafdf33
AM
1731+- install the header files too by "make headers_install" to the
1732+ directory where you specify. By default, it is $PWD/usr.
b4510431 1733+ "make help" shows a brief note for headers_install.
53392da6
AM
1734+- and reboot your system.
1735+
1736+2.
1737+- module only (CONFIG_AUFS_FS=m).
1738+- apply ./aufs3-base.patch to your kernel source files.
1739+- apply ./aufs3-proc_map.patch too to your kernel source files,
1740+ if you want to make /proc/PID/maps (and others including lsof(1)) show
1741+ the file path on aufs instead of the path on the branch fs.
1742+- apply ./aufs3-standalone.patch too.
1743+- build your kernel, don't forget "make headers_install", and reboot.
1744+- edit ./config.mk and set other aufs configurations if necessary.
b4510431 1745+ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
53392da6
AM
1746+ every aufs configurations.
1747+- build the module by simple "make".
c06a8ce3
AM
1748+ Note: Since linux-3.9, every filesystem module requires an alias
1749+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
1750+ modules.aliases file.
53392da6
AM
1751+- you can specify ${KDIR} make variable which points to your kernel
1752+ source tree.
1753+- install the files
1754+ + run "make install" to install the aufs module, or copy the built
b4510431
AM
1755+ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply).
1756+ + run "make install_headers" (instead of headers_install) to install
1757+ the modified aufs header file (you can specify DESTDIR which is
1758+ available in aufs standalone version's Makefile only), or copy
1759+ $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever
1760+ you like manually. By default, the target directory is $PWD/usr.
53392da6
AM
1761+- no need to apply aufs3-kbuild.patch, nor copying source files to your
1762+ kernel source tree.
1763+
b4510431 1764+Note: The header file aufs_type.h is necessary to build aufs-util
53392da6
AM
1765+ as well as "make headers_install" in the kernel source tree.
1766+ headers_install is subject to be forgotten, but it is essentially
1767+ necessary, not only for building aufs-util.
1768+ You may not meet problems without headers_install in some older
1769+ version though.
1770+
1771+And then,
1772+- read README in aufs-util, build and install it
9dbd164d
AM
1773+- note that your distribution may contain an obsoleted version of
1774+ aufs_type.h in /usr/include/linux or something. When you build aufs
1775+ utilities, make sure that your compiler refers the correct aufs header
1776+ file which is built by "make headers_install."
53392da6
AM
1777+- if you want to use readdir(3) in userspace or pathconf(3) wrapper,
1778+ then run "make install_ulib" too. And refer to the aufs manual in
1779+ detail.
1780+
1781+
1782+4. Usage
1783+----------------------------------------
1784+At first, make sure aufs-util are installed, and please read the aufs
1785+manual, aufs.5 in aufs-util.git tree.
1786+$ man -l aufs.5
1787+
1788+And then,
1789+$ mkdir /tmp/rw /tmp/aufs
1790+# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs
1791+
1792+Here is another example. The result is equivalent.
1793+# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
1794+ Or
1795+# mount -t aufs -o br:/tmp/rw none /tmp/aufs
1796+# mount -o remount,append:${HOME} /tmp/aufs
1797+
1798+Then, you can see whole tree of your home dir through /tmp/aufs. If
1799+you modify a file under /tmp/aufs, the one on your home directory is
1800+not affected, instead the same named file will be newly created under
1801+/tmp/rw. And all of your modification to a file will be applied to
1802+the one under /tmp/rw. This is called the file based Copy on Write
1803+(COW) method.
1804+Aufs mount options are described in aufs.5.
1805+If you run chroot or something and make your aufs as a root directory,
1806+then you need to customize the shutdown script. See the aufs manual in
1807+detail.
1808+
1809+Additionally, there are some sample usages of aufs which are a
1810+diskless system with network booting, and LiveCD over NFS.
1811+See sample dir in CVS tree on SourceForge.
1812+
1813+
1814+5. Contact
1815+----------------------------------------
1816+When you have any problems or strange behaviour in aufs, please let me
1817+know with:
1818+- /proc/mounts (instead of the output of mount(8))
1819+- /sys/module/aufs/*
1820+- /sys/fs/aufs/* (if you have them)
1821+- /debug/aufs/* (if you have them)
1822+- linux kernel version
1823+ if your kernel is not plain, for example modified by distributor,
1824+ the url where i can download its source is necessary too.
1825+- aufs version which was printed at loading the module or booting the
1826+ system, instead of the date you downloaded.
1827+- configuration (define/undefine CONFIG_AUFS_xxx)
1828+- kernel configuration or /proc/config.gz (if you have it)
1829+- behaviour which you think to be incorrect
1830+- actual operation, reproducible one is better
1831+- mailto: aufs-users at lists.sourceforge.net
1832+
1833+Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches,
1834+and Feature Requests) on SourceForge. Please join and write to
1835+aufs-users ML.
1836+
1837+
1838+6. Acknowledgements
1839+----------------------------------------
1840+Thanks to everyone who have tried and are using aufs, whoever
1841+have reported a bug or any feedback.
1842+
1843+Especially donators:
1844+Tomas Matejicek(slax.org) made a donation (much more than once).
1845+ Since Apr 2010, Tomas M (the author of Slax and Linux Live
1846+ scripts) is making "doubling" donations.
1847+ Unfortunately I cannot list all of the donators, but I really
b4510431 1848+ appreciate.
53392da6
AM
1849+ It ends Aug 2010, but the ordinary donation URL is still available.
1850+ <http://sourceforge.net/donate/index.php?group_id=167503>
1851+Dai Itasaka made a donation (2007/8).
1852+Chuck Smith made a donation (2008/4, 10 and 12).
1853+Henk Schoneveld made a donation (2008/9).
1854+Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10).
1855+Francois Dupoux made a donation (2008/11).
1856+Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public
1857+ aufs2 GIT tree (2009/2).
1858+William Grant made a donation (2009/3).
1859+Patrick Lane made a donation (2009/4).
1860+The Mail Archive (mail-archive.com) made donations (2009/5).
1861+Nippy Networks (Ed Wildgoose) made a donation (2009/7).
1862+New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11).
1863+Pavel Pronskiy made a donation (2011/2).
1864+Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy
1865+ Networks (Ed Wildgoose) made a donation for hardware (2011/3).
537831f9
AM
1866+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
1867+11).
1e00d052 1868+Sam Liddicott made a donation (2011/9).
86dc4139
AM
1869+Era Scarecrow made a donation (2013/4).
1870+Bor Ratajc made a donation (2013/4).
1871+Alessandro Gorreta made a donation (2013/4).
1872+POIRETTE Marc made a donation (2013/4).
1873+Alessandro Gorreta made a donation (2013/4).
1874+lauri kasvandik made a donation (2013/5).
392086de
AM
1875+"pemasu from Finland" made a donation (2013/7).
1876+The Parted Magic Project made a donation (2013/9).
53392da6
AM
1877+
1878+Thank you very much.
1879+Donations are always, including future donations, very important and
1880+helpful for me to keep on developing aufs.
1881+
1882+
1883+7.
1884+----------------------------------------
1885+If you are an experienced user, no explanation is needed. Aufs is
1886+just a linux filesystem.
1887+
1888+
1889+Enjoy!
1890+
1891+# Local variables: ;
1892+# mode: text;
1893+# End: ;
7f207e10
AM
1894diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
1895--- /usr/share/empty/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100
86dc4139 1896+++ linux/fs/aufs/aufs.h 2013-07-06 13:20:47.736864659 +0200
2cbb1c4b 1897@@ -0,0 +1,60 @@
7f207e10 1898+/*
7a9e40b8 1899+ * Copyright (C) 2005-2013 Junjiro R. Okajima
7f207e10
AM
1900+ *
1901+ * This program, aufs is free software; you can redistribute it and/or modify
1902+ * it under the terms of the GNU General Public License as published by
1903+ * the Free Software Foundation; either version 2 of the License, or
1904+ * (at your option) any later version.
1905+ *
1906+ * This program is distributed in the hope that it will be useful,
1907+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1908+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1909+ * GNU General Public License for more details.
1910+ *
1911+ * You should have received a copy of the GNU General Public License
1912+ * along with this program; if not, write to the Free Software
1913+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1914+ */
1915+
1916+/*
1917+ * all header files
1918+ */
1919+
1920+#ifndef __AUFS_H__
1921+#define __AUFS_H__
1922+
1923+#ifdef __KERNEL__
1924+
1925+#define AuStub(type, name, body, ...) \
1926+ static inline type name(__VA_ARGS__) { body; }
1927+
1928+#define AuStubVoid(name, ...) \
1929+ AuStub(void, name, , __VA_ARGS__)
1930+#define AuStubInt0(name, ...) \
1931+ AuStub(int, name, return 0, __VA_ARGS__)
1932+
1933+#include "debug.h"
1934+
1935+#include "branch.h"
1936+#include "cpup.h"
1937+#include "dcsub.h"
1938+#include "dbgaufs.h"
1939+#include "dentry.h"
1940+#include "dir.h"
1941+#include "dynop.h"
1942+#include "file.h"
1943+#include "fstype.h"
1944+#include "inode.h"
1945+#include "loop.h"
1946+#include "module.h"
7f207e10
AM
1947+#include "opts.h"
1948+#include "rwsem.h"
1949+#include "spl.h"
1950+#include "super.h"
1951+#include "sysaufs.h"
1952+#include "vfsub.h"
1953+#include "whout.h"
1954+#include "wkq.h"
1955+
1956+#endif /* __KERNEL__ */
1957+#endif /* __AUFS_H__ */
1958diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
1959--- /usr/share/empty/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
1960+++ linux/fs/aufs/branch.c 2013-10-26 16:51:32.273040419 +0200
1961@@ -0,0 +1,1212 @@
7f207e10 1962+/*
7a9e40b8 1963+ * Copyright (C) 2005-2013 Junjiro R. Okajima
7f207e10
AM
1964+ *
1965+ * This program, aufs is free software; you can redistribute it and/or modify
1966+ * it under the terms of the GNU General Public License as published by
1967+ * the Free Software Foundation; either version 2 of the License, or
1968+ * (at your option) any later version.
1969+ *
1970+ * This program is distributed in the hope that it will be useful,
1971+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1972+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1973+ * GNU General Public License for more details.
1974+ *
1975+ * You should have received a copy of the GNU General Public License
1976+ * along with this program; if not, write to the Free Software
1977+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1978+ */
1979+
1980+/*
1981+ * branch management
1982+ */
1983+
027c5e7a 1984+#include <linux/compat.h>
7f207e10
AM
1985+#include <linux/statfs.h>
1986+#include "aufs.h"
1987+
1988+/*
1989+ * free a single branch
1facf9fc 1990+ */
86dc4139
AM
1991+
1992+/* prohibit rmdir to the root of the branch */
1993+/* todo: another new flag? */
1994+static void au_br_dflags_force(struct au_branch *br)
1995+{
1996+ struct dentry *h_dentry;
1997+
1998+ h_dentry = au_br_dentry(br);
1999+ spin_lock(&h_dentry->d_lock);
2000+ br->br_dflags = h_dentry->d_flags & DCACHE_MOUNTED;
2001+ h_dentry->d_flags |= DCACHE_MOUNTED;
2002+ spin_unlock(&h_dentry->d_lock);
2003+}
2004+
2005+/* restore its d_flags */
2006+static void au_br_dflags_restore(struct au_branch *br)
2007+{
2008+ struct dentry *h_dentry;
2009+
2010+ if (br->br_dflags)
2011+ return;
2012+
2013+ h_dentry = au_br_dentry(br);
2014+ spin_lock(&h_dentry->d_lock);
2015+ h_dentry->d_flags &= ~DCACHE_MOUNTED;
2016+ spin_unlock(&h_dentry->d_lock);
2017+}
2018+
1facf9fc 2019+static void au_br_do_free(struct au_branch *br)
2020+{
2021+ int i;
2022+ struct au_wbr *wbr;
4a4d8108 2023+ struct au_dykey **key;
1facf9fc 2024+
027c5e7a
AM
2025+ au_hnotify_fin_br(br);
2026+
1facf9fc 2027+ if (br->br_xino.xi_file)
2028+ fput(br->br_xino.xi_file);
2029+ mutex_destroy(&br->br_xino.xi_nondir_mtx);
2030+
2031+ AuDebugOn(atomic_read(&br->br_count));
2032+
2033+ wbr = br->br_wbr;
2034+ if (wbr) {
2035+ for (i = 0; i < AuBrWh_Last; i++)
2036+ dput(wbr->wbr_wh[i]);
2037+ AuDebugOn(atomic_read(&wbr->wbr_wh_running));
dece6358 2038+ AuRwDestroy(&wbr->wbr_wh_rwsem);
1facf9fc 2039+ }
2040+
4a4d8108
AM
2041+ key = br->br_dykey;
2042+ for (i = 0; i < AuBrDynOp; i++, key++)
2043+ if (*key)
2044+ au_dy_put(*key);
2045+ else
2046+ break;
2047+
86dc4139
AM
2048+ au_br_dflags_restore(br);
2049+
537831f9
AM
2050+ /* recursive lock, s_umount of branch's */
2051+ lockdep_off();
86dc4139 2052+ path_put(&br->br_path);
537831f9 2053+ lockdep_on();
1facf9fc 2054+ kfree(wbr);
2055+ kfree(br);
2056+}
2057+
2058+/*
2059+ * frees all branches
2060+ */
2061+void au_br_free(struct au_sbinfo *sbinfo)
2062+{
2063+ aufs_bindex_t bmax;
2064+ struct au_branch **br;
2065+
dece6358
AM
2066+ AuRwMustWriteLock(&sbinfo->si_rwsem);
2067+
1facf9fc 2068+ bmax = sbinfo->si_bend + 1;
2069+ br = sbinfo->si_branch;
2070+ while (bmax--)
2071+ au_br_do_free(*br++);
2072+}
2073+
2074+/*
2075+ * find the index of a branch which is specified by @br_id.
2076+ */
2077+int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
2078+{
2079+ aufs_bindex_t bindex, bend;
2080+
2081+ bend = au_sbend(sb);
2082+ for (bindex = 0; bindex <= bend; bindex++)
2083+ if (au_sbr_id(sb, bindex) == br_id)
2084+ return bindex;
2085+ return -1;
2086+}
2087+
2088+/* ---------------------------------------------------------------------- */
2089+
2090+/*
2091+ * add a branch
2092+ */
2093+
b752ccd1
AM
2094+static int test_overlap(struct super_block *sb, struct dentry *h_adding,
2095+ struct dentry *h_root)
1facf9fc 2096+{
b752ccd1
AM
2097+ if (unlikely(h_adding == h_root
2098+ || au_test_loopback_overlap(sb, h_adding)))
1facf9fc 2099+ return 1;
b752ccd1
AM
2100+ if (h_adding->d_sb != h_root->d_sb)
2101+ return 0;
2102+ return au_test_subdir(h_adding, h_root)
2103+ || au_test_subdir(h_root, h_adding);
1facf9fc 2104+}
2105+
2106+/*
2107+ * returns a newly allocated branch. @new_nbranch is a number of branches
2108+ * after adding a branch.
2109+ */
2110+static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
2111+ int perm)
2112+{
2113+ struct au_branch *add_branch;
2114+ struct dentry *root;
4a4d8108 2115+ int err;
1facf9fc 2116+
4a4d8108 2117+ err = -ENOMEM;
1facf9fc 2118+ root = sb->s_root;
2119+ add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS);
2120+ if (unlikely(!add_branch))
2121+ goto out;
2122+
027c5e7a
AM
2123+ err = au_hnotify_init_br(add_branch, perm);
2124+ if (unlikely(err))
2125+ goto out_br;
2126+
1facf9fc 2127+ add_branch->br_wbr = NULL;
2128+ if (au_br_writable(perm)) {
2129+ /* may be freed separately at changing the branch permission */
2130+ add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr),
2131+ GFP_NOFS);
2132+ if (unlikely(!add_branch->br_wbr))
027c5e7a 2133+ goto out_hnotify;
1facf9fc 2134+ }
2135+
4a4d8108
AM
2136+ err = au_sbr_realloc(au_sbi(sb), new_nbranch);
2137+ if (!err)
2138+ err = au_di_realloc(au_di(root), new_nbranch);
2139+ if (!err)
2140+ err = au_ii_realloc(au_ii(root->d_inode), new_nbranch);
2141+ if (!err)
2142+ return add_branch; /* success */
1facf9fc 2143+
1facf9fc 2144+ kfree(add_branch->br_wbr);
4a4d8108 2145+
027c5e7a
AM
2146+out_hnotify:
2147+ au_hnotify_fin_br(add_branch);
4f0767ce 2148+out_br:
1facf9fc 2149+ kfree(add_branch);
4f0767ce 2150+out:
4a4d8108 2151+ return ERR_PTR(err);
1facf9fc 2152+}
2153+
2154+/*
2155+ * test if the branch permission is legal or not.
2156+ */
2157+static int test_br(struct inode *inode, int brperm, char *path)
2158+{
2159+ int err;
2160+
4a4d8108
AM
2161+ err = (au_br_writable(brperm) && IS_RDONLY(inode));
2162+ if (!err)
2163+ goto out;
1facf9fc 2164+
4a4d8108
AM
2165+ err = -EINVAL;
2166+ pr_err("write permission for readonly mount or inode, %s\n", path);
2167+
4f0767ce 2168+out:
1facf9fc 2169+ return err;
2170+}
2171+
2172+/*
2173+ * returns:
2174+ * 0: success, the caller will add it
2175+ * plus: success, it is already unified, the caller should ignore it
2176+ * minus: error
2177+ */
2178+static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
2179+{
2180+ int err;
2181+ aufs_bindex_t bend, bindex;
2182+ struct dentry *root;
2183+ struct inode *inode, *h_inode;
2184+
2185+ root = sb->s_root;
2186+ bend = au_sbend(sb);
2187+ if (unlikely(bend >= 0
2188+ && au_find_dbindex(root, add->path.dentry) >= 0)) {
2189+ err = 1;
2190+ if (!remount) {
2191+ err = -EINVAL;
4a4d8108 2192+ pr_err("%s duplicated\n", add->pathname);
1facf9fc 2193+ }
2194+ goto out;
2195+ }
2196+
2197+ err = -ENOSPC; /* -E2BIG; */
2198+ if (unlikely(AUFS_BRANCH_MAX <= add->bindex
2199+ || AUFS_BRANCH_MAX - 1 <= bend)) {
4a4d8108 2200+ pr_err("number of branches exceeded %s\n", add->pathname);
1facf9fc 2201+ goto out;
2202+ }
2203+
2204+ err = -EDOM;
2205+ if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) {
4a4d8108 2206+ pr_err("bad index %d\n", add->bindex);
1facf9fc 2207+ goto out;
2208+ }
2209+
2210+ inode = add->path.dentry->d_inode;
2211+ err = -ENOENT;
2212+ if (unlikely(!inode->i_nlink)) {
4a4d8108 2213+ pr_err("no existence %s\n", add->pathname);
1facf9fc 2214+ goto out;
2215+ }
2216+
2217+ err = -EINVAL;
2218+ if (unlikely(inode->i_sb == sb)) {
4a4d8108 2219+ pr_err("%s must be outside\n", add->pathname);
1facf9fc 2220+ goto out;
2221+ }
2222+
2223+ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
4a4d8108
AM
2224+ pr_err("unsupported filesystem, %s (%s)\n",
2225+ add->pathname, au_sbtype(inode->i_sb));
1facf9fc 2226+ goto out;
2227+ }
2228+
2229+ err = test_br(add->path.dentry->d_inode, add->perm, add->pathname);
2230+ if (unlikely(err))
2231+ goto out;
2232+
2233+ if (bend < 0)
2234+ return 0; /* success */
2235+
2236+ err = -EINVAL;
2237+ for (bindex = 0; bindex <= bend; bindex++)
2238+ if (unlikely(test_overlap(sb, add->path.dentry,
2239+ au_h_dptr(root, bindex)))) {
4a4d8108 2240+ pr_err("%s is overlapped\n", add->pathname);
1facf9fc 2241+ goto out;
2242+ }
2243+
2244+ err = 0;
2245+ if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
2246+ h_inode = au_h_dptr(root, 0)->d_inode;
2247+ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
0c3ec466
AM
2248+ || !uid_eq(h_inode->i_uid, inode->i_uid)
2249+ || !gid_eq(h_inode->i_gid, inode->i_gid))
2250+ pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
2251+ add->pathname,
2252+ i_uid_read(inode), i_gid_read(inode),
2253+ (inode->i_mode & S_IALLUGO),
2254+ i_uid_read(h_inode), i_gid_read(h_inode),
2255+ (h_inode->i_mode & S_IALLUGO));
1facf9fc 2256+ }
2257+
4f0767ce 2258+out:
1facf9fc 2259+ return err;
2260+}
2261+
2262+/*
2263+ * initialize or clean the whiteouts for an adding branch
2264+ */
2265+static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
86dc4139 2266+ int new_perm)
1facf9fc 2267+{
2268+ int err, old_perm;
2269+ aufs_bindex_t bindex;
2270+ struct mutex *h_mtx;
2271+ struct au_wbr *wbr;
2272+ struct au_hinode *hdir;
2273+
86dc4139
AM
2274+ err = vfsub_mnt_want_write(au_br_mnt(br));
2275+ if (unlikely(err))
2276+ goto out;
2277+
1facf9fc 2278+ wbr = br->br_wbr;
2279+ old_perm = br->br_perm;
2280+ br->br_perm = new_perm;
2281+ hdir = NULL;
2282+ h_mtx = NULL;
2283+ bindex = au_br_index(sb, br->br_id);
2284+ if (0 <= bindex) {
2285+ hdir = au_hi(sb->s_root->d_inode, bindex);
4a4d8108 2286+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 2287+ } else {
86dc4139 2288+ h_mtx = &au_br_dentry(br)->d_inode->i_mutex;
1facf9fc 2289+ mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
2290+ }
2291+ if (!wbr)
86dc4139 2292+ err = au_wh_init(br, sb);
1facf9fc 2293+ else {
2294+ wbr_wh_write_lock(wbr);
86dc4139 2295+ err = au_wh_init(br, sb);
1facf9fc 2296+ wbr_wh_write_unlock(wbr);
2297+ }
2298+ if (hdir)
4a4d8108 2299+ au_hn_imtx_unlock(hdir);
1facf9fc 2300+ else
2301+ mutex_unlock(h_mtx);
86dc4139 2302+ vfsub_mnt_drop_write(au_br_mnt(br));
1facf9fc 2303+ br->br_perm = old_perm;
2304+
2305+ if (!err && wbr && !au_br_writable(new_perm)) {
2306+ kfree(wbr);
2307+ br->br_wbr = NULL;
2308+ }
2309+
86dc4139 2310+out:
1facf9fc 2311+ return err;
2312+}
2313+
2314+static int au_wbr_init(struct au_branch *br, struct super_block *sb,
86dc4139 2315+ int perm)
1facf9fc 2316+{
2317+ int err;
4a4d8108 2318+ struct kstatfs kst;
1facf9fc 2319+ struct au_wbr *wbr;
2320+
2321+ wbr = br->br_wbr;
dece6358 2322+ au_rw_init(&wbr->wbr_wh_rwsem);
1facf9fc 2323+ memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh));
2324+ atomic_set(&wbr->wbr_wh_running, 0);
2325+ wbr->wbr_bytes = 0;
2326+
4a4d8108
AM
2327+ /*
2328+ * a limit for rmdir/rename a dir
2329+ * cf. AUFS_MAX_NAMELEN in include/linux/aufs_type.h
2330+ */
86dc4139 2331+ err = vfs_statfs(&br->br_path, &kst);
4a4d8108
AM
2332+ if (unlikely(err))
2333+ goto out;
2334+ err = -EINVAL;
2335+ if (kst.f_namelen >= NAME_MAX)
86dc4139 2336+ err = au_br_init_wh(sb, br, perm);
4a4d8108
AM
2337+ else
2338+ pr_err("%.*s(%s), unsupported namelen %ld\n",
86dc4139
AM
2339+ AuDLNPair(au_br_dentry(br)),
2340+ au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen);
1facf9fc 2341+
4f0767ce 2342+out:
1facf9fc 2343+ return err;
2344+}
2345+
2346+/* intialize a new branch */
2347+static int au_br_init(struct au_branch *br, struct super_block *sb,
2348+ struct au_opt_add *add)
2349+{
2350+ int err;
2351+
2352+ err = 0;
2353+ memset(&br->br_xino, 0, sizeof(br->br_xino));
2354+ mutex_init(&br->br_xino.xi_nondir_mtx);
2355+ br->br_perm = add->perm;
86dc4139
AM
2356+ BUILD_BUG_ON(sizeof(br->br_dflags)
2357+ != sizeof(br->br_path.dentry->d_flags));
2358+ br->br_dflags = DCACHE_MOUNTED;
2359+ br->br_path = add->path; /* set first, path_get() later */
4a4d8108
AM
2360+ spin_lock_init(&br->br_dykey_lock);
2361+ memset(br->br_dykey, 0, sizeof(br->br_dykey));
1facf9fc 2362+ atomic_set(&br->br_count, 0);
1facf9fc 2363+ atomic_set(&br->br_xino_running, 0);
2364+ br->br_id = au_new_br_id(sb);
7f207e10 2365+ AuDebugOn(br->br_id < 0);
1facf9fc 2366+
2367+ if (au_br_writable(add->perm)) {
86dc4139 2368+ err = au_wbr_init(br, sb, add->perm);
1facf9fc 2369+ if (unlikely(err))
b752ccd1 2370+ goto out_err;
1facf9fc 2371+ }
2372+
2373+ if (au_opt_test(au_mntflags(sb), XINO)) {
2374+ err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino,
2375+ au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
2376+ if (unlikely(err)) {
2377+ AuDebugOn(br->br_xino.xi_file);
b752ccd1 2378+ goto out_err;
1facf9fc 2379+ }
2380+ }
2381+
2382+ sysaufs_br_init(br);
86dc4139 2383+ path_get(&br->br_path);
b752ccd1 2384+ goto out; /* success */
1facf9fc 2385+
4f0767ce 2386+out_err:
86dc4139 2387+ memset(&br->br_path, 0, sizeof(br->br_path));
4f0767ce 2388+out:
1facf9fc 2389+ return err;
2390+}
2391+
2392+static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
2393+ struct au_branch *br, aufs_bindex_t bend,
2394+ aufs_bindex_t amount)
2395+{
2396+ struct au_branch **brp;
2397+
dece6358
AM
2398+ AuRwMustWriteLock(&sbinfo->si_rwsem);
2399+
1facf9fc 2400+ brp = sbinfo->si_branch + bindex;
2401+ memmove(brp + 1, brp, sizeof(*brp) * amount);
2402+ *brp = br;
2403+ sbinfo->si_bend++;
2404+ if (unlikely(bend < 0))
2405+ sbinfo->si_bend = 0;
2406+}
2407+
2408+static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
2409+ aufs_bindex_t bend, aufs_bindex_t amount)
2410+{
2411+ struct au_hdentry *hdp;
2412+
1308ab2a 2413+ AuRwMustWriteLock(&dinfo->di_rwsem);
2414+
1facf9fc 2415+ hdp = dinfo->di_hdentry + bindex;
2416+ memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
2417+ au_h_dentry_init(hdp);
2418+ dinfo->di_bend++;
2419+ if (unlikely(bend < 0))
2420+ dinfo->di_bstart = 0;
2421+}
2422+
2423+static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
2424+ aufs_bindex_t bend, aufs_bindex_t amount)
2425+{
2426+ struct au_hinode *hip;
2427+
1308ab2a 2428+ AuRwMustWriteLock(&iinfo->ii_rwsem);
2429+
1facf9fc 2430+ hip = iinfo->ii_hinode + bindex;
2431+ memmove(hip + 1, hip, sizeof(*hip) * amount);
2432+ hip->hi_inode = NULL;
4a4d8108 2433+ au_hn_init(hip);
1facf9fc 2434+ iinfo->ii_bend++;
2435+ if (unlikely(bend < 0))
2436+ iinfo->ii_bstart = 0;
2437+}
2438+
86dc4139
AM
2439+static void au_br_do_add(struct super_block *sb, struct au_branch *br,
2440+ aufs_bindex_t bindex)
1facf9fc 2441+{
86dc4139 2442+ struct dentry *root, *h_dentry;
1facf9fc 2443+ struct inode *root_inode;
2444+ aufs_bindex_t bend, amount;
2445+
86dc4139
AM
2446+ au_br_dflags_force(br);
2447+
1facf9fc 2448+ root = sb->s_root;
2449+ root_inode = root->d_inode;
1facf9fc 2450+ bend = au_sbend(sb);
2451+ amount = bend + 1 - bindex;
86dc4139 2452+ h_dentry = au_br_dentry(br);
53392da6 2453+ au_sbilist_lock();
1facf9fc 2454+ au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount);
2455+ au_br_do_add_hdp(au_di(root), bindex, bend, amount);
2456+ au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount);
2457+ au_set_h_dptr(root, bindex, dget(h_dentry));
2458+ au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode),
2459+ /*flags*/0);
53392da6 2460+ au_sbilist_unlock();
1facf9fc 2461+}
2462+
2463+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
2464+{
2465+ int err;
1facf9fc 2466+ aufs_bindex_t bend, add_bindex;
2467+ struct dentry *root, *h_dentry;
2468+ struct inode *root_inode;
2469+ struct au_branch *add_branch;
2470+
2471+ root = sb->s_root;
2472+ root_inode = root->d_inode;
2473+ IMustLock(root_inode);
2474+ err = test_add(sb, add, remount);
2475+ if (unlikely(err < 0))
2476+ goto out;
2477+ if (err) {
2478+ err = 0;
2479+ goto out; /* success */
2480+ }
2481+
2482+ bend = au_sbend(sb);
2483+ add_branch = au_br_alloc(sb, bend + 2, add->perm);
2484+ err = PTR_ERR(add_branch);
2485+ if (IS_ERR(add_branch))
2486+ goto out;
2487+
2488+ err = au_br_init(add_branch, sb, add);
2489+ if (unlikely(err)) {
2490+ au_br_do_free(add_branch);
2491+ goto out;
2492+ }
2493+
2494+ add_bindex = add->bindex;
1facf9fc 2495+ if (!remount)
86dc4139 2496+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 2497+ else {
2498+ sysaufs_brs_del(sb, add_bindex);
86dc4139 2499+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 2500+ sysaufs_brs_add(sb, add_bindex);
2501+ }
2502+
86dc4139 2503+ h_dentry = add->path.dentry;
1308ab2a 2504+ if (!add_bindex) {
1facf9fc 2505+ au_cpup_attr_all(root_inode, /*force*/1);
1308ab2a 2506+ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
2507+ } else
1facf9fc 2508+ au_add_nlink(root_inode, h_dentry->d_inode);
1facf9fc 2509+
2510+ /*
4a4d8108 2511+ * this test/set prevents aufs from handling unnecesary notify events
027c5e7a 2512+ * of xino files, in case of re-adding a writable branch which was
1facf9fc 2513+ * once detached from aufs.
2514+ */
2515+ if (au_xino_brid(sb) < 0
2516+ && au_br_writable(add_branch->br_perm)
2517+ && !au_test_fs_bad_xino(h_dentry->d_sb)
2518+ && add_branch->br_xino.xi_file
2519+ && add_branch->br_xino.xi_file->f_dentry->d_parent == h_dentry)
2520+ au_xino_brid_set(sb, add_branch->br_id);
2521+
4f0767ce 2522+out:
1facf9fc 2523+ return err;
2524+}
2525+
2526+/* ---------------------------------------------------------------------- */
2527+
2528+/*
2529+ * delete a branch
2530+ */
2531+
2532+/* to show the line number, do not make it inlined function */
4a4d8108 2533+#define AuVerbose(do_info, fmt, ...) do { \
1facf9fc 2534+ if (do_info) \
4a4d8108 2535+ pr_info(fmt, ##__VA_ARGS__); \
1facf9fc 2536+} while (0)
2537+
027c5e7a
AM
2538+static int au_test_ibusy(struct inode *inode, aufs_bindex_t bstart,
2539+ aufs_bindex_t bend)
2540+{
2541+ return (inode && !S_ISDIR(inode->i_mode)) || bstart == bend;
2542+}
2543+
2544+static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t bstart,
2545+ aufs_bindex_t bend)
2546+{
2547+ return au_test_ibusy(dentry->d_inode, bstart, bend);
2548+}
2549+
1facf9fc 2550+/*
2551+ * test if the branch is deletable or not.
2552+ */
2553+static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
b752ccd1 2554+ unsigned int sigen, const unsigned int verbose)
1facf9fc 2555+{
2556+ int err, i, j, ndentry;
2557+ aufs_bindex_t bstart, bend;
1facf9fc 2558+ struct au_dcsub_pages dpages;
2559+ struct au_dpage *dpage;
2560+ struct dentry *d;
1facf9fc 2561+
2562+ err = au_dpages_init(&dpages, GFP_NOFS);
2563+ if (unlikely(err))
2564+ goto out;
2565+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
2566+ if (unlikely(err))
2567+ goto out_dpages;
2568+
1facf9fc 2569+ for (i = 0; !err && i < dpages.ndpage; i++) {
2570+ dpage = dpages.dpages + i;
2571+ ndentry = dpage->ndentry;
2572+ for (j = 0; !err && j < ndentry; j++) {
2573+ d = dpage->dentries[j];
392086de 2574+ AuDebugOn(!d_count(d));
027c5e7a 2575+ if (!au_digen_test(d, sigen)) {
1facf9fc 2576+ di_read_lock_child(d, AuLock_IR);
027c5e7a
AM
2577+ if (unlikely(au_dbrange_test(d))) {
2578+ di_read_unlock(d, AuLock_IR);
2579+ continue;
2580+ }
2581+ } else {
1facf9fc 2582+ di_write_lock_child(d);
027c5e7a
AM
2583+ if (unlikely(au_dbrange_test(d))) {
2584+ di_write_unlock(d);
2585+ continue;
2586+ }
1facf9fc 2587+ err = au_reval_dpath(d, sigen);
2588+ if (!err)
2589+ di_downgrade_lock(d, AuLock_IR);
2590+ else {
2591+ di_write_unlock(d);
2592+ break;
2593+ }
2594+ }
2595+
027c5e7a 2596+ /* AuDbgDentry(d); */
1facf9fc 2597+ bstart = au_dbstart(d);
2598+ bend = au_dbend(d);
2599+ if (bstart <= bindex
2600+ && bindex <= bend
2601+ && au_h_dptr(d, bindex)
027c5e7a 2602+ && au_test_dbusy(d, bstart, bend)) {
1facf9fc 2603+ err = -EBUSY;
2604+ AuVerbose(verbose, "busy %.*s\n", AuDLNPair(d));
027c5e7a 2605+ AuDbgDentry(d);
1facf9fc 2606+ }
2607+ di_read_unlock(d, AuLock_IR);
2608+ }
2609+ }
2610+
4f0767ce 2611+out_dpages:
1facf9fc 2612+ au_dpages_free(&dpages);
4f0767ce 2613+out:
1facf9fc 2614+ return err;
2615+}
2616+
2617+static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
b752ccd1 2618+ unsigned int sigen, const unsigned int verbose)
1facf9fc 2619+{
2620+ int err;
7f207e10
AM
2621+ unsigned long long max, ull;
2622+ struct inode *i, **array;
1facf9fc 2623+ aufs_bindex_t bstart, bend;
1facf9fc 2624+
7f207e10
AM
2625+ array = au_iarray_alloc(sb, &max);
2626+ err = PTR_ERR(array);
2627+ if (IS_ERR(array))
2628+ goto out;
2629+
1facf9fc 2630+ err = 0;
7f207e10
AM
2631+ AuDbg("b%d\n", bindex);
2632+ for (ull = 0; !err && ull < max; ull++) {
2633+ i = array[ull];
2634+ if (i->i_ino == AUFS_ROOT_INO)
1facf9fc 2635+ continue;
2636+
7f207e10 2637+ /* AuDbgInode(i); */
537831f9 2638+ if (au_iigen(i, NULL) == sigen)
1facf9fc 2639+ ii_read_lock_child(i);
2640+ else {
2641+ ii_write_lock_child(i);
027c5e7a
AM
2642+ err = au_refresh_hinode_self(i);
2643+ au_iigen_dec(i);
1facf9fc 2644+ if (!err)
2645+ ii_downgrade_lock(i);
2646+ else {
2647+ ii_write_unlock(i);
2648+ break;
2649+ }
2650+ }
2651+
2652+ bstart = au_ibstart(i);
2653+ bend = au_ibend(i);
2654+ if (bstart <= bindex
2655+ && bindex <= bend
2656+ && au_h_iptr(i, bindex)
027c5e7a 2657+ && au_test_ibusy(i, bstart, bend)) {
1facf9fc 2658+ err = -EBUSY;
2659+ AuVerbose(verbose, "busy i%lu\n", i->i_ino);
7f207e10 2660+ AuDbgInode(i);
1facf9fc 2661+ }
2662+ ii_read_unlock(i);
2663+ }
7f207e10 2664+ au_iarray_free(array, max);
1facf9fc 2665+
7f207e10 2666+out:
1facf9fc 2667+ return err;
2668+}
2669+
b752ccd1
AM
2670+static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
2671+ const unsigned int verbose)
1facf9fc 2672+{
2673+ int err;
2674+ unsigned int sigen;
2675+
2676+ sigen = au_sigen(root->d_sb);
2677+ DiMustNoWaiters(root);
2678+ IiMustNoWaiters(root->d_inode);
2679+ di_write_unlock(root);
b752ccd1 2680+ err = test_dentry_busy(root, bindex, sigen, verbose);
1facf9fc 2681+ if (!err)
b752ccd1 2682+ err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
1facf9fc 2683+ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
2684+
2685+ return err;
2686+}
2687+
2688+static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
2689+ const aufs_bindex_t bindex,
2690+ const aufs_bindex_t bend)
2691+{
2692+ struct au_branch **brp, **p;
2693+
dece6358
AM
2694+ AuRwMustWriteLock(&sbinfo->si_rwsem);
2695+
1facf9fc 2696+ brp = sbinfo->si_branch + bindex;
2697+ if (bindex < bend)
2698+ memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex));
2699+ sbinfo->si_branch[0 + bend] = NULL;
2700+ sbinfo->si_bend--;
2701+
53392da6 2702+ p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 2703+ if (p)
2704+ sbinfo->si_branch = p;
4a4d8108 2705+ /* harmless error */
1facf9fc 2706+}
2707+
2708+static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
2709+ const aufs_bindex_t bend)
2710+{
2711+ struct au_hdentry *hdp, *p;
2712+
1308ab2a 2713+ AuRwMustWriteLock(&dinfo->di_rwsem);
2714+
4a4d8108 2715+ hdp = dinfo->di_hdentry;
1facf9fc 2716+ if (bindex < bend)
4a4d8108
AM
2717+ memmove(hdp + bindex, hdp + bindex + 1,
2718+ sizeof(*hdp) * (bend - bindex));
2719+ hdp[0 + bend].hd_dentry = NULL;
1facf9fc 2720+ dinfo->di_bend--;
2721+
53392da6 2722+ p = krealloc(hdp, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 2723+ if (p)
2724+ dinfo->di_hdentry = p;
4a4d8108 2725+ /* harmless error */
1facf9fc 2726+}
2727+
2728+static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
2729+ const aufs_bindex_t bend)
2730+{
2731+ struct au_hinode *hip, *p;
2732+
1308ab2a 2733+ AuRwMustWriteLock(&iinfo->ii_rwsem);
2734+
1facf9fc 2735+ hip = iinfo->ii_hinode + bindex;
2736+ if (bindex < bend)
2737+ memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex));
2738+ iinfo->ii_hinode[0 + bend].hi_inode = NULL;
4a4d8108 2739+ au_hn_init(iinfo->ii_hinode + bend);
1facf9fc 2740+ iinfo->ii_bend--;
2741+
53392da6 2742+ p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 2743+ if (p)
2744+ iinfo->ii_hinode = p;
4a4d8108 2745+ /* harmless error */
1facf9fc 2746+}
2747+
2748+static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
2749+ struct au_branch *br)
2750+{
2751+ aufs_bindex_t bend;
2752+ struct au_sbinfo *sbinfo;
53392da6
AM
2753+ struct dentry *root, *h_root;
2754+ struct inode *inode, *h_inode;
2755+ struct au_hinode *hinode;
1facf9fc 2756+
dece6358
AM
2757+ SiMustWriteLock(sb);
2758+
1facf9fc 2759+ root = sb->s_root;
2760+ inode = root->d_inode;
1facf9fc 2761+ sbinfo = au_sbi(sb);
2762+ bend = sbinfo->si_bend;
2763+
53392da6
AM
2764+ h_root = au_h_dptr(root, bindex);
2765+ hinode = au_hi(inode, bindex);
2766+ h_inode = au_igrab(hinode->hi_inode);
2767+ au_hiput(hinode);
1facf9fc 2768+
53392da6 2769+ au_sbilist_lock();
1facf9fc 2770+ au_br_do_del_brp(sbinfo, bindex, bend);
2771+ au_br_do_del_hdp(au_di(root), bindex, bend);
2772+ au_br_do_del_hip(au_ii(inode), bindex, bend);
53392da6
AM
2773+ au_sbilist_unlock();
2774+
2775+ dput(h_root);
2776+ iput(h_inode);
2777+ au_br_do_free(br);
1facf9fc 2778+}
2779+
2780+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
2781+{
2782+ int err, rerr, i;
2783+ unsigned int mnt_flags;
2784+ aufs_bindex_t bindex, bend, br_id;
2785+ unsigned char do_wh, verbose;
2786+ struct au_branch *br;
2787+ struct au_wbr *wbr;
2788+
2789+ err = 0;
2790+ bindex = au_find_dbindex(sb->s_root, del->h_path.dentry);
2791+ if (bindex < 0) {
2792+ if (remount)
2793+ goto out; /* success */
2794+ err = -ENOENT;
4a4d8108 2795+ pr_err("%s no such branch\n", del->pathname);
1facf9fc 2796+ goto out;
2797+ }
2798+ AuDbg("bindex b%d\n", bindex);
2799+
2800+ err = -EBUSY;
2801+ mnt_flags = au_mntflags(sb);
2802+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
2803+ bend = au_sbend(sb);
2804+ if (unlikely(!bend)) {
2805+ AuVerbose(verbose, "no more branches left\n");
2806+ goto out;
2807+ }
2808+ br = au_sbr(sb, bindex);
86dc4139 2809+ AuDebugOn(!path_equal(&br->br_path, &del->h_path));
1facf9fc 2810+ i = atomic_read(&br->br_count);
2811+ if (unlikely(i)) {
2812+ AuVerbose(verbose, "%d file(s) opened\n", i);
e49829fe 2813+ goto out;
1facf9fc 2814+ }
2815+
2816+ wbr = br->br_wbr;
2817+ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
2818+ if (do_wh) {
1308ab2a 2819+ /* instead of WbrWhMustWriteLock(wbr) */
2820+ SiMustWriteLock(sb);
1facf9fc 2821+ for (i = 0; i < AuBrWh_Last; i++) {
2822+ dput(wbr->wbr_wh[i]);
2823+ wbr->wbr_wh[i] = NULL;
2824+ }
2825+ }
2826+
b752ccd1 2827+ err = test_children_busy(sb->s_root, bindex, verbose);
1facf9fc 2828+ if (unlikely(err)) {
2829+ if (do_wh)
2830+ goto out_wh;
2831+ goto out;
2832+ }
2833+
2834+ err = 0;
2835+ br_id = br->br_id;
2836+ if (!remount)
2837+ au_br_do_del(sb, bindex, br);
2838+ else {
2839+ sysaufs_brs_del(sb, bindex);
2840+ au_br_do_del(sb, bindex, br);
2841+ sysaufs_brs_add(sb, bindex);
2842+ }
2843+
1308ab2a 2844+ if (!bindex) {
1facf9fc 2845+ au_cpup_attr_all(sb->s_root->d_inode, /*force*/1);
1308ab2a 2846+ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
2847+ } else
1facf9fc 2848+ au_sub_nlink(sb->s_root->d_inode, del->h_path.dentry->d_inode);
2849+ if (au_opt_test(mnt_flags, PLINK))
2850+ au_plink_half_refresh(sb, br_id);
2851+
b752ccd1 2852+ if (au_xino_brid(sb) == br_id)
1facf9fc 2853+ au_xino_brid_set(sb, -1);
2854+ goto out; /* success */
2855+
4f0767ce 2856+out_wh:
1facf9fc 2857+ /* revert */
86dc4139 2858+ rerr = au_br_init_wh(sb, br, br->br_perm);
1facf9fc 2859+ if (rerr)
0c3ec466
AM
2860+ pr_warn("failed re-creating base whiteout, %s. (%d)\n",
2861+ del->pathname, rerr);
4f0767ce 2862+out:
1facf9fc 2863+ return err;
2864+}
2865+
2866+/* ---------------------------------------------------------------------- */
2867+
027c5e7a
AM
2868+static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg)
2869+{
2870+ int err;
2871+ aufs_bindex_t bstart, bend;
2872+ struct aufs_ibusy ibusy;
2873+ struct inode *inode, *h_inode;
2874+
2875+ err = -EPERM;
2876+ if (unlikely(!capable(CAP_SYS_ADMIN)))
2877+ goto out;
2878+
2879+ err = copy_from_user(&ibusy, arg, sizeof(ibusy));
2880+ if (!err)
2881+ err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino));
2882+ if (unlikely(err)) {
2883+ err = -EFAULT;
2884+ AuTraceErr(err);
2885+ goto out;
2886+ }
2887+
2888+ err = -EINVAL;
2889+ si_read_lock(sb, AuLock_FLUSH);
2890+ if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbend(sb)))
2891+ goto out_unlock;
2892+
2893+ err = 0;
2894+ ibusy.h_ino = 0; /* invalid */
2895+ inode = ilookup(sb, ibusy.ino);
2896+ if (!inode
2897+ || inode->i_ino == AUFS_ROOT_INO
2898+ || is_bad_inode(inode))
2899+ goto out_unlock;
2900+
2901+ ii_read_lock_child(inode);
2902+ bstart = au_ibstart(inode);
2903+ bend = au_ibend(inode);
2904+ if (bstart <= ibusy.bindex && ibusy.bindex <= bend) {
2905+ h_inode = au_h_iptr(inode, ibusy.bindex);
2906+ if (h_inode && au_test_ibusy(inode, bstart, bend))
2907+ ibusy.h_ino = h_inode->i_ino;
2908+ }
2909+ ii_read_unlock(inode);
2910+ iput(inode);
2911+
2912+out_unlock:
2913+ si_read_unlock(sb);
2914+ if (!err) {
2915+ err = __put_user(ibusy.h_ino, &arg->h_ino);
2916+ if (unlikely(err)) {
2917+ err = -EFAULT;
2918+ AuTraceErr(err);
2919+ }
2920+ }
2921+out:
2922+ return err;
2923+}
2924+
2925+long au_ibusy_ioctl(struct file *file, unsigned long arg)
2926+{
2927+ return au_ibusy(file->f_dentry->d_sb, (void __user *)arg);
2928+}
2929+
2930+#ifdef CONFIG_COMPAT
2931+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg)
2932+{
2933+ return au_ibusy(file->f_dentry->d_sb, compat_ptr(arg));
2934+}
2935+#endif
2936+
2937+/* ---------------------------------------------------------------------- */
2938+
1facf9fc 2939+/*
2940+ * change a branch permission
2941+ */
2942+
dece6358
AM
2943+static void au_warn_ima(void)
2944+{
2945+#ifdef CONFIG_IMA
1308ab2a 2946+ /* since it doesn't support mark_files_ro() */
027c5e7a 2947+ AuWarn1("RW -> RO makes IMA to produce wrong message\n");
dece6358
AM
2948+#endif
2949+}
2950+
1facf9fc 2951+static int do_need_sigen_inc(int a, int b)
2952+{
2953+ return au_br_whable(a) && !au_br_whable(b);
2954+}
2955+
2956+static int need_sigen_inc(int old, int new)
2957+{
2958+ return do_need_sigen_inc(old, new)
2959+ || do_need_sigen_inc(new, old);
2960+}
2961+
7f207e10
AM
2962+static unsigned long long au_farray_cb(void *a,
2963+ unsigned long long max __maybe_unused,
2964+ void *arg)
2965+{
2966+ unsigned long long n;
2967+ struct file **p, *f;
2968+ struct super_block *sb = arg;
2969+
2970+ n = 0;
2971+ p = a;
0c3ec466 2972+ lg_global_lock(&files_lglock);
7f207e10
AM
2973+ do_file_list_for_each_entry(sb, f) {
2974+ if (au_fi(f)
027c5e7a 2975+ && file_count(f)
c06a8ce3 2976+ && !special_file(file_inode(f)->i_mode)) {
7f207e10
AM
2977+ get_file(f);
2978+ *p++ = f;
2979+ n++;
2980+ AuDebugOn(n > max);
2981+ }
2982+ } while_file_list_for_each_entry;
0c3ec466 2983+ lg_global_unlock(&files_lglock);
7f207e10
AM
2984+
2985+ return n;
2986+}
2987+
2988+static struct file **au_farray_alloc(struct super_block *sb,
2989+ unsigned long long *max)
2990+{
2991+ *max = atomic_long_read(&au_sbi(sb)->si_nfiles);
2992+ return au_array_alloc(max, au_farray_cb, sb);
2993+}
2994+
2995+static void au_farray_free(struct file **a, unsigned long long max)
2996+{
2997+ unsigned long long ull;
2998+
2999+ for (ull = 0; ull < max; ull++)
3000+ if (a[ull])
3001+ fput(a[ull]);
3002+ au_array_free(a);
3003+}
3004+
1facf9fc 3005+static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
3006+{
7f207e10 3007+ int err, do_warn;
027c5e7a 3008+ unsigned int mnt_flags;
7f207e10 3009+ unsigned long long ull, max;
e49829fe 3010+ aufs_bindex_t br_id;
027c5e7a 3011+ unsigned char verbose;
7f207e10 3012+ struct file *file, *hf, **array;
e49829fe
JR
3013+ struct inode *inode;
3014+ struct au_hfile *hfile;
1facf9fc 3015+
027c5e7a
AM
3016+ mnt_flags = au_mntflags(sb);
3017+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
3018+
7f207e10
AM
3019+ array = au_farray_alloc(sb, &max);
3020+ err = PTR_ERR(array);
3021+ if (IS_ERR(array))
1facf9fc 3022+ goto out;
3023+
7f207e10 3024+ do_warn = 0;
e49829fe 3025+ br_id = au_sbr_id(sb, bindex);
7f207e10
AM
3026+ for (ull = 0; ull < max; ull++) {
3027+ file = array[ull];
1facf9fc 3028+
7f207e10 3029+ /* AuDbg("%.*s\n", AuDLNPair(file->f_dentry)); */
1facf9fc 3030+ fi_read_lock(file);
3031+ if (unlikely(au_test_mmapped(file))) {
3032+ err = -EBUSY;
027c5e7a
AM
3033+ AuVerbose(verbose, "mmapped %.*s\n",
3034+ AuDLNPair(file->f_dentry));
7f207e10 3035+ AuDbgFile(file);
1facf9fc 3036+ FiMustNoWaiters(file);
3037+ fi_read_unlock(file);
7f207e10 3038+ goto out_array;
1facf9fc 3039+ }
3040+
c06a8ce3 3041+ inode = file_inode(file);
e49829fe
JR
3042+ hfile = &au_fi(file)->fi_htop;
3043+ hf = hfile->hf_file;
3044+ if (!S_ISREG(inode->i_mode)
1facf9fc 3045+ || !(file->f_mode & FMODE_WRITE)
e49829fe 3046+ || hfile->hf_br->br_id != br_id
7f207e10
AM
3047+ || !(hf->f_mode & FMODE_WRITE))
3048+ array[ull] = NULL;
3049+ else {
3050+ do_warn = 1;
3051+ get_file(file);
1facf9fc 3052+ }
3053+
1facf9fc 3054+ FiMustNoWaiters(file);
3055+ fi_read_unlock(file);
7f207e10
AM
3056+ fput(file);
3057+ }
1facf9fc 3058+
3059+ err = 0;
7f207e10 3060+ if (do_warn)
dece6358 3061+ au_warn_ima();
7f207e10
AM
3062+
3063+ for (ull = 0; ull < max; ull++) {
3064+ file = array[ull];
3065+ if (!file)
3066+ continue;
3067+
1facf9fc 3068+ /* todo: already flushed? */
3069+ /* cf. fs/super.c:mark_files_ro() */
7f207e10
AM
3070+ /* fi_read_lock(file); */
3071+ hfile = &au_fi(file)->fi_htop;
3072+ hf = hfile->hf_file;
3073+ /* fi_read_unlock(file); */
027c5e7a 3074+ spin_lock(&hf->f_lock);
1facf9fc 3075+ hf->f_mode &= ~FMODE_WRITE;
027c5e7a 3076+ spin_unlock(&hf->f_lock);
1facf9fc 3077+ if (!file_check_writeable(hf)) {
c06a8ce3 3078+ __mnt_drop_write(hf->f_path.mnt);
1facf9fc 3079+ file_release_write(hf);
1facf9fc 3080+ }
3081+ }
3082+
7f207e10
AM
3083+out_array:
3084+ au_farray_free(array, max);
4f0767ce 3085+out:
7f207e10 3086+ AuTraceErr(err);
1facf9fc 3087+ return err;
3088+}
3089+
3090+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 3091+ int *do_refresh)
1facf9fc 3092+{
3093+ int err, rerr;
3094+ aufs_bindex_t bindex;
3095+ struct dentry *root;
3096+ struct au_branch *br;
3097+
3098+ root = sb->s_root;
1facf9fc 3099+ bindex = au_find_dbindex(root, mod->h_root);
3100+ if (bindex < 0) {
3101+ if (remount)
3102+ return 0; /* success */
3103+ err = -ENOENT;
4a4d8108 3104+ pr_err("%s no such branch\n", mod->path);
1facf9fc 3105+ goto out;
3106+ }
3107+ AuDbg("bindex b%d\n", bindex);
3108+
3109+ err = test_br(mod->h_root->d_inode, mod->perm, mod->path);
3110+ if (unlikely(err))
3111+ goto out;
3112+
3113+ br = au_sbr(sb, bindex);
86dc4139 3114+ AuDebugOn(mod->h_root != au_br_dentry(br));
1facf9fc 3115+ if (br->br_perm == mod->perm)
3116+ return 0; /* success */
3117+
3118+ if (au_br_writable(br->br_perm)) {
3119+ /* remove whiteout base */
86dc4139 3120+ err = au_br_init_wh(sb, br, mod->perm);
1facf9fc 3121+ if (unlikely(err))
3122+ goto out;
3123+
3124+ if (!au_br_writable(mod->perm)) {
3125+ /* rw --> ro, file might be mmapped */
3126+ DiMustNoWaiters(root);
3127+ IiMustNoWaiters(root->d_inode);
3128+ di_write_unlock(root);
3129+ err = au_br_mod_files_ro(sb, bindex);
3130+ /* aufs_write_lock() calls ..._child() */
3131+ di_write_lock_child(root);
3132+
3133+ if (unlikely(err)) {
3134+ rerr = -ENOMEM;
3135+ br->br_wbr = kmalloc(sizeof(*br->br_wbr),
3136+ GFP_NOFS);
86dc4139
AM
3137+ if (br->br_wbr)
3138+ rerr = au_wbr_init(br, sb, br->br_perm);
1facf9fc 3139+ if (unlikely(rerr)) {
3140+ AuIOErr("nested error %d (%d)\n",
3141+ rerr, err);
3142+ br->br_perm = mod->perm;
3143+ }
3144+ }
3145+ }
3146+ } else if (au_br_writable(mod->perm)) {
3147+ /* ro --> rw */
3148+ err = -ENOMEM;
3149+ br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS);
3150+ if (br->br_wbr) {
86dc4139 3151+ err = au_wbr_init(br, sb, mod->perm);
1facf9fc 3152+ if (unlikely(err)) {
3153+ kfree(br->br_wbr);
3154+ br->br_wbr = NULL;
3155+ }
3156+ }
3157+ }
3158+
3159+ if (!err) {
86dc4139
AM
3160+ if ((br->br_perm & AuBrAttr_UNPIN)
3161+ && !(mod->perm & AuBrAttr_UNPIN))
3162+ au_br_dflags_force(br);
3163+ else if (!(br->br_perm & AuBrAttr_UNPIN)
3164+ && (mod->perm & AuBrAttr_UNPIN))
3165+ au_br_dflags_restore(br);
7f207e10 3166+ *do_refresh |= need_sigen_inc(br->br_perm, mod->perm);
1facf9fc 3167+ br->br_perm = mod->perm;
3168+ }
3169+
4f0767ce 3170+out:
7f207e10 3171+ AuTraceErr(err);
1facf9fc 3172+ return err;
3173+}
7f207e10
AM
3174diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
3175--- /usr/share/empty/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100
392086de
AM
3176+++ linux/fs/aufs/branch.h 2013-10-26 16:51:32.273040419 +0200
3177@@ -0,0 +1,265 @@
1facf9fc 3178+/*
7a9e40b8 3179+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 3180+ *
3181+ * This program, aufs is free software; you can redistribute it and/or modify
3182+ * it under the terms of the GNU General Public License as published by
3183+ * the Free Software Foundation; either version 2 of the License, or
3184+ * (at your option) any later version.
dece6358
AM
3185+ *
3186+ * This program is distributed in the hope that it will be useful,
3187+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3188+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3189+ * GNU General Public License for more details.
3190+ *
3191+ * You should have received a copy of the GNU General Public License
3192+ * along with this program; if not, write to the Free Software
3193+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 3194+ */
3195+
3196+/*
3197+ * branch filesystems and xino for them
3198+ */
3199+
3200+#ifndef __AUFS_BRANCH_H__
3201+#define __AUFS_BRANCH_H__
3202+
3203+#ifdef __KERNEL__
3204+
1facf9fc 3205+#include <linux/mount.h>
4a4d8108 3206+#include "dynop.h"
1facf9fc 3207+#include "rwsem.h"
3208+#include "super.h"
3209+
3210+/* ---------------------------------------------------------------------- */
3211+
3212+/* a xino file */
3213+struct au_xino_file {
3214+ struct file *xi_file;
3215+ struct mutex xi_nondir_mtx;
3216+
3217+ /* todo: make xino files an array to support huge inode number */
3218+
3219+#ifdef CONFIG_DEBUG_FS
3220+ struct dentry *xi_dbgaufs;
3221+#endif
3222+};
3223+
3224+/* members for writable branch only */
3225+enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
3226+struct au_wbr {
dece6358 3227+ struct au_rwsem wbr_wh_rwsem;
1facf9fc 3228+ struct dentry *wbr_wh[AuBrWh_Last];
4a4d8108 3229+ atomic_t wbr_wh_running;
1facf9fc 3230+#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
3231+#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
3232+#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
3233+
3234+ /* mfs mode */
3235+ unsigned long long wbr_bytes;
3236+};
3237+
4a4d8108
AM
3238+/* ext2 has 3 types of operations at least, ext3 has 4 */
3239+#define AuBrDynOp (AuDyLast * 4)
3240+
1716fcea
AM
3241+#ifdef CONFIG_AUFS_HFSNOTIFY
3242+/* support for asynchronous destruction */
3243+struct au_br_hfsnotify {
3244+ struct fsnotify_group *hfsn_group;
3245+};
3246+#endif
3247+
392086de
AM
3248+/* sysfs entries */
3249+struct au_brsysfs {
3250+ char name[16];
3251+ struct attribute attr;
3252+};
3253+
3254+enum {
3255+ AuBrSysfs_BR,
3256+ AuBrSysfs_BRID,
3257+ AuBrSysfs_Last
3258+};
3259+
1facf9fc 3260+/* protected by superblock rwsem */
3261+struct au_branch {
3262+ struct au_xino_file br_xino;
3263+
3264+ aufs_bindex_t br_id;
3265+
3266+ int br_perm;
86dc4139
AM
3267+ unsigned int br_dflags;
3268+ struct path br_path;
4a4d8108
AM
3269+ spinlock_t br_dykey_lock;
3270+ struct au_dykey *br_dykey[AuBrDynOp];
1facf9fc 3271+ atomic_t br_count;
3272+
3273+ struct au_wbr *br_wbr;
3274+
3275+ /* xino truncation */
1facf9fc 3276+ atomic_t br_xino_running;
3277+
027c5e7a 3278+#ifdef CONFIG_AUFS_HFSNOTIFY
1716fcea 3279+ struct au_br_hfsnotify *br_hfsn;
027c5e7a
AM
3280+#endif
3281+
1facf9fc 3282+#ifdef CONFIG_SYSFS
392086de
AM
3283+ /* entries under sysfs per mount-point */
3284+ struct au_brsysfs br_sysfs[AuBrSysfs_Last];
1facf9fc 3285+#endif
3286+};
3287+
3288+/* ---------------------------------------------------------------------- */
3289+
86dc4139
AM
3290+static inline struct vfsmount *au_br_mnt(struct au_branch *br)
3291+{
3292+ return br->br_path.mnt;
3293+}
3294+
3295+static inline struct dentry *au_br_dentry(struct au_branch *br)
3296+{
3297+ return br->br_path.dentry;
3298+}
3299+
3300+static inline struct super_block *au_br_sb(struct au_branch *br)
3301+{
3302+ return au_br_mnt(br)->mnt_sb;
3303+}
3304+
1e00d052
AM
3305+/* branch permissions and attributes */
3306+#define AuBrPerm_RW 1 /* writable, hardlinkable wh */
3307+#define AuBrPerm_RO (1 << 1) /* readonly */
3308+#define AuBrPerm_RR (1 << 2) /* natively readonly */
3309+#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
1facf9fc 3310+
1e00d052 3311+#define AuBrRAttr_WH (1 << 3) /* whiteout-able */
1facf9fc 3312+
1e00d052 3313+#define AuBrWAttr_NoLinkWH (1 << 4) /* un-hardlinkable whiteouts */
1facf9fc 3314+
86dc4139
AM
3315+#define AuBrAttr_UNPIN (1 << 5) /* rename-able top dir of
3316+ branch */
3317+
1facf9fc 3318+static inline int au_br_writable(int brperm)
3319+{
1e00d052 3320+ return brperm & AuBrPerm_RW;
1facf9fc 3321+}
3322+
3323+static inline int au_br_whable(int brperm)
3324+{
1e00d052
AM
3325+ return brperm & (AuBrPerm_RW | AuBrRAttr_WH);
3326+}
3327+
3328+static inline int au_br_wh_linkable(int brperm)
3329+{
3330+ return !(brperm & AuBrWAttr_NoLinkWH);
1facf9fc 3331+}
3332+
3333+static inline int au_br_rdonly(struct au_branch *br)
3334+{
86dc4139 3335+ return ((au_br_sb(br)->s_flags & MS_RDONLY)
1facf9fc 3336+ || !au_br_writable(br->br_perm))
3337+ ? -EROFS : 0;
3338+}
3339+
4a4d8108 3340+static inline int au_br_hnotifyable(int brperm __maybe_unused)
1facf9fc 3341+{
4a4d8108 3342+#ifdef CONFIG_AUFS_HNOTIFY
1e00d052 3343+ return !(brperm & AuBrPerm_RR);
1facf9fc 3344+#else
3345+ return 0;
3346+#endif
3347+}
3348+
3349+/* ---------------------------------------------------------------------- */
3350+
3351+/* branch.c */
3352+struct au_sbinfo;
3353+void au_br_free(struct au_sbinfo *sinfo);
3354+int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
3355+struct au_opt_add;
3356+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
3357+struct au_opt_del;
3358+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
027c5e7a
AM
3359+long au_ibusy_ioctl(struct file *file, unsigned long arg);
3360+#ifdef CONFIG_COMPAT
3361+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
3362+#endif
1facf9fc 3363+struct au_opt_mod;
3364+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 3365+ int *do_refresh);
1facf9fc 3366+
3367+/* xino.c */
3368+static const loff_t au_loff_max = LLONG_MAX;
3369+
3370+int au_xib_trunc(struct super_block *sb);
3371+ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size,
3372+ loff_t *pos);
3373+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
3374+ loff_t *pos);
3375+struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
3376+struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
3377+ino_t au_xino_new_ino(struct super_block *sb);
b752ccd1 3378+void au_xino_delete_inode(struct inode *inode, const int unlinked);
1facf9fc 3379+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
3380+ ino_t ino);
3381+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
3382+ ino_t *ino);
3383+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
3384+ struct file *base_file, int do_test);
3385+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
3386+
3387+struct au_opt_xino;
3388+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
3389+void au_xino_clr(struct super_block *sb);
3390+struct file *au_xino_def(struct super_block *sb);
3391+int au_xino_path(struct seq_file *seq, struct file *file);
3392+
3393+/* ---------------------------------------------------------------------- */
3394+
3395+/* Superblock to branch */
3396+static inline
3397+aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
3398+{
3399+ return au_sbr(sb, bindex)->br_id;
3400+}
3401+
3402+static inline
3403+struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
3404+{
86dc4139 3405+ return au_br_mnt(au_sbr(sb, bindex));
1facf9fc 3406+}
3407+
3408+static inline
3409+struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
3410+{
86dc4139 3411+ return au_br_sb(au_sbr(sb, bindex));
1facf9fc 3412+}
3413+
3414+static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
3415+{
e49829fe 3416+ atomic_dec(&au_sbr(sb, bindex)->br_count);
1facf9fc 3417+}
3418+
3419+static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
3420+{
3421+ return au_sbr(sb, bindex)->br_perm;
3422+}
3423+
3424+static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
3425+{
3426+ return au_br_whable(au_sbr_perm(sb, bindex));
3427+}
3428+
3429+/* ---------------------------------------------------------------------- */
3430+
3431+/*
3432+ * wbr_wh_read_lock, wbr_wh_write_lock
3433+ * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
3434+ */
3435+AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
3436+
dece6358
AM
3437+#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
3438+#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
3439+#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
3440+
1facf9fc 3441+#endif /* __KERNEL__ */
3442+#endif /* __AUFS_BRANCH_H__ */
7f207e10
AM
3443diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
3444--- /usr/share/empty/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100
86dc4139 3445+++ linux/fs/aufs/conf.mk 2013-07-06 13:20:47.740198107 +0200
2cbb1c4b 3446@@ -0,0 +1,38 @@
4a4d8108
AM
3447+
3448+AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
3449+
3450+define AuConf
3451+ifdef ${1}
3452+AuConfStr += ${1}=${${1}}
3453+endif
3454+endef
3455+
b752ccd1 3456+AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
e49829fe 3457+ SBILIST \
7f207e10 3458+ HNOTIFY HFSNOTIFY \
4a4d8108
AM
3459+ EXPORT INO_T_64 \
3460+ RDU \
2cbb1c4b 3461+ PROC_MAP \
4a4d8108
AM
3462+ SP_IATTR \
3463+ SHWH \
3464+ BR_RAMFS \
3465+ BR_FUSE POLL \
3466+ BR_HFSPLUS \
3467+ BDEV_LOOP \
b752ccd1
AM
3468+ DEBUG MAGIC_SYSRQ
3469+$(foreach i, ${AuConfAll}, \
4a4d8108
AM
3470+ $(eval $(call AuConf,CONFIG_AUFS_${i})))
3471+
3472+AuConfName = ${obj}/conf.str
3473+${AuConfName}.tmp: FORCE
3474+ @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
3475+${AuConfName}: ${AuConfName}.tmp
3476+ @diff -q $< $@ > /dev/null 2>&1 || { \
3477+ echo ' GEN ' $@; \
3478+ cp -p $< $@; \
3479+ }
3480+FORCE:
3481+clean-files += ${AuConfName} ${AuConfName}.tmp
3482+${obj}/sysfs.o: ${AuConfName}
b752ccd1
AM
3483+
3484+-include ${srctree}/${src}/conf_priv.mk
7f207e10
AM
3485diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
3486--- /usr/share/empty/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
3487+++ linux/fs/aufs/cpup.c 2013-10-26 16:51:32.273040419 +0200
3488@@ -0,0 +1,1268 @@
1facf9fc 3489+/*
7a9e40b8 3490+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 3491+ *
3492+ * This program, aufs is free software; you can redistribute it and/or modify
3493+ * it under the terms of the GNU General Public License as published by
3494+ * the Free Software Foundation; either version 2 of the License, or
3495+ * (at your option) any later version.
dece6358
AM
3496+ *
3497+ * This program is distributed in the hope that it will be useful,
3498+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3499+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3500+ * GNU General Public License for more details.
3501+ *
3502+ * You should have received a copy of the GNU General Public License
3503+ * along with this program; if not, write to the Free Software
3504+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 3505+ */
3506+
3507+/*
3508+ * copy-up functions, see wbr_policy.c for copy-down
3509+ */
3510+
3511+#include <linux/fs_stack.h>
dece6358 3512+#include <linux/mm.h>
1facf9fc 3513+#include "aufs.h"
3514+
86dc4139 3515+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags)
1facf9fc 3516+{
3517+ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
367653fa 3518+ | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT;
1facf9fc 3519+
86dc4139
AM
3520+ BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags));
3521+
3522+ dst->i_flags |= iflags & ~mask;
1facf9fc 3523+ if (au_test_fs_notime(dst->i_sb))
3524+ dst->i_flags |= S_NOATIME | S_NOCMTIME;
3525+}
3526+
3527+void au_cpup_attr_timesizes(struct inode *inode)
3528+{
3529+ struct inode *h_inode;
3530+
3531+ h_inode = au_h_iptr(inode, au_ibstart(inode));
3532+ fsstack_copy_attr_times(inode, h_inode);
4a4d8108 3533+ fsstack_copy_inode_size(inode, h_inode);
1facf9fc 3534+}
3535+
3536+void au_cpup_attr_nlink(struct inode *inode, int force)
3537+{
3538+ struct inode *h_inode;
3539+ struct super_block *sb;
3540+ aufs_bindex_t bindex, bend;
3541+
3542+ sb = inode->i_sb;
3543+ bindex = au_ibstart(inode);
3544+ h_inode = au_h_iptr(inode, bindex);
3545+ if (!force
3546+ && !S_ISDIR(h_inode->i_mode)
3547+ && au_opt_test(au_mntflags(sb), PLINK)
3548+ && au_plink_test(inode))
3549+ return;
3550+
7eafdf33
AM
3551+ /*
3552+ * 0 can happen in revalidating.
3553+ * h_inode->i_mutex is not held, but it is harmless since once i_nlink
3554+ * reaches 0, it will never become positive.
3555+ */
92d182d2 3556+ set_nlink(inode, h_inode->i_nlink);
1facf9fc 3557+
3558+ /*
3559+ * fewer nlink makes find(1) noisy, but larger nlink doesn't.
3560+ * it may includes whplink directory.
3561+ */
3562+ if (S_ISDIR(h_inode->i_mode)) {
3563+ bend = au_ibend(inode);
3564+ for (bindex++; bindex <= bend; bindex++) {
3565+ h_inode = au_h_iptr(inode, bindex);
3566+ if (h_inode)
3567+ au_add_nlink(inode, h_inode);
3568+ }
3569+ }
3570+}
3571+
3572+void au_cpup_attr_changeable(struct inode *inode)
3573+{
3574+ struct inode *h_inode;
3575+
3576+ h_inode = au_h_iptr(inode, au_ibstart(inode));
3577+ inode->i_mode = h_inode->i_mode;
3578+ inode->i_uid = h_inode->i_uid;
3579+ inode->i_gid = h_inode->i_gid;
3580+ au_cpup_attr_timesizes(inode);
86dc4139 3581+ au_cpup_attr_flags(inode, h_inode->i_flags);
1facf9fc 3582+}
3583+
3584+void au_cpup_igen(struct inode *inode, struct inode *h_inode)
3585+{
3586+ struct au_iinfo *iinfo = au_ii(inode);
3587+
1308ab2a 3588+ IiMustWriteLock(inode);
3589+
1facf9fc 3590+ iinfo->ii_higen = h_inode->i_generation;
3591+ iinfo->ii_hsb1 = h_inode->i_sb;
3592+}
3593+
3594+void au_cpup_attr_all(struct inode *inode, int force)
3595+{
3596+ struct inode *h_inode;
3597+
3598+ h_inode = au_h_iptr(inode, au_ibstart(inode));
3599+ au_cpup_attr_changeable(inode);
3600+ if (inode->i_nlink > 0)
3601+ au_cpup_attr_nlink(inode, force);
3602+ inode->i_rdev = h_inode->i_rdev;
3603+ inode->i_blkbits = h_inode->i_blkbits;
3604+ au_cpup_igen(inode, h_inode);
3605+}
3606+
3607+/* ---------------------------------------------------------------------- */
3608+
3609+/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
3610+
3611+/* keep the timestamps of the parent dir when cpup */
3612+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
3613+ struct path *h_path)
3614+{
3615+ struct inode *h_inode;
3616+
3617+ dt->dt_dentry = dentry;
3618+ dt->dt_h_path = *h_path;
3619+ h_inode = h_path->dentry->d_inode;
3620+ dt->dt_atime = h_inode->i_atime;
3621+ dt->dt_mtime = h_inode->i_mtime;
3622+ /* smp_mb(); */
3623+}
3624+
3625+void au_dtime_revert(struct au_dtime *dt)
3626+{
3627+ struct iattr attr;
3628+ int err;
3629+
3630+ attr.ia_atime = dt->dt_atime;
3631+ attr.ia_mtime = dt->dt_mtime;
3632+ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
3633+ | ATTR_ATIME | ATTR_ATIME_SET;
3634+
3635+ err = vfsub_notify_change(&dt->dt_h_path, &attr);
3636+ if (unlikely(err))
0c3ec466 3637+ pr_warn("restoring timestamps failed(%d). ignored\n", err);
1facf9fc 3638+}
3639+
3640+/* ---------------------------------------------------------------------- */
3641+
86dc4139
AM
3642+/* internal use only */
3643+struct au_cpup_reg_attr {
3644+ int valid;
3645+ struct kstat st;
3646+ unsigned int iflags; /* inode->i_flags */
3647+};
3648+
1facf9fc 3649+static noinline_for_stack
86dc4139
AM
3650+int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src,
3651+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 3652+{
3653+ int err, sbits;
3654+ struct iattr ia;
3655+ struct path h_path;
1308ab2a 3656+ struct inode *h_isrc, *h_idst;
86dc4139 3657+ struct kstat *h_st;
1facf9fc 3658+
3659+ h_path.dentry = au_h_dptr(dst, bindex);
1308ab2a 3660+ h_idst = h_path.dentry->d_inode;
1facf9fc 3661+ h_path.mnt = au_sbr_mnt(dst->d_sb, bindex);
3662+ h_isrc = h_src->d_inode;
1308ab2a 3663+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
1facf9fc 3664+ | ATTR_ATIME | ATTR_MTIME
3665+ | ATTR_ATIME_SET | ATTR_MTIME_SET;
86dc4139
AM
3666+ if (h_src_attr && h_src_attr->valid) {
3667+ h_st = &h_src_attr->st;
3668+ ia.ia_uid = h_st->uid;
3669+ ia.ia_gid = h_st->gid;
3670+ ia.ia_atime = h_st->atime;
3671+ ia.ia_mtime = h_st->mtime;
3672+ if (h_idst->i_mode != h_st->mode
3673+ && !S_ISLNK(h_idst->i_mode)) {
3674+ ia.ia_valid |= ATTR_MODE;
3675+ ia.ia_mode = h_st->mode;
3676+ }
3677+ sbits = !!(h_st->mode & (S_ISUID | S_ISGID));
3678+ au_cpup_attr_flags(h_idst, h_src_attr->iflags);
3679+ } else {
3680+ ia.ia_uid = h_isrc->i_uid;
3681+ ia.ia_gid = h_isrc->i_gid;
3682+ ia.ia_atime = h_isrc->i_atime;
3683+ ia.ia_mtime = h_isrc->i_mtime;
3684+ if (h_idst->i_mode != h_isrc->i_mode
3685+ && !S_ISLNK(h_idst->i_mode)) {
3686+ ia.ia_valid |= ATTR_MODE;
3687+ ia.ia_mode = h_isrc->i_mode;
3688+ }
3689+ sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
3690+ au_cpup_attr_flags(h_idst, h_isrc->i_flags);
1308ab2a 3691+ }
1facf9fc 3692+ err = vfsub_notify_change(&h_path, &ia);
3693+
3694+ /* is this nfs only? */
3695+ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
3696+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
3697+ ia.ia_mode = h_isrc->i_mode;
3698+ err = vfsub_notify_change(&h_path, &ia);
3699+ }
3700+
3701+ return err;
3702+}
3703+
3704+/* ---------------------------------------------------------------------- */
3705+
3706+static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
3707+ char *buf, unsigned long blksize)
3708+{
3709+ int err;
3710+ size_t sz, rbytes, wbytes;
3711+ unsigned char all_zero;
3712+ char *p, *zp;
3713+ struct mutex *h_mtx;
3714+ /* reduce stack usage */
3715+ struct iattr *ia;
3716+
3717+ zp = page_address(ZERO_PAGE(0));
3718+ if (unlikely(!zp))
3719+ return -ENOMEM; /* possible? */
3720+
3721+ err = 0;
3722+ all_zero = 0;
3723+ while (len) {
3724+ AuDbg("len %lld\n", len);
3725+ sz = blksize;
3726+ if (len < blksize)
3727+ sz = len;
3728+
3729+ rbytes = 0;
3730+ /* todo: signal_pending? */
3731+ while (!rbytes || err == -EAGAIN || err == -EINTR) {
3732+ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
3733+ err = rbytes;
3734+ }
3735+ if (unlikely(err < 0))
3736+ break;
3737+
3738+ all_zero = 0;
3739+ if (len >= rbytes && rbytes == blksize)
3740+ all_zero = !memcmp(buf, zp, rbytes);
3741+ if (!all_zero) {
3742+ wbytes = rbytes;
3743+ p = buf;
3744+ while (wbytes) {
3745+ size_t b;
3746+
3747+ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
3748+ err = b;
3749+ /* todo: signal_pending? */
3750+ if (unlikely(err == -EAGAIN || err == -EINTR))
3751+ continue;
3752+ if (unlikely(err < 0))
3753+ break;
3754+ wbytes -= b;
3755+ p += b;
3756+ }
392086de
AM
3757+ if (unlikely(err < 0))
3758+ break;
1facf9fc 3759+ } else {
3760+ loff_t res;
3761+
3762+ AuLabel(hole);
3763+ res = vfsub_llseek(dst, rbytes, SEEK_CUR);
3764+ err = res;
3765+ if (unlikely(res < 0))
3766+ break;
3767+ }
3768+ len -= rbytes;
3769+ err = 0;
3770+ }
3771+
3772+ /* the last block may be a hole */
3773+ if (!err && all_zero) {
3774+ AuLabel(last hole);
3775+
3776+ err = 1;
3777+ if (au_test_nfs(dst->f_dentry->d_sb)) {
3778+ /* nfs requires this step to make last hole */
3779+ /* is this only nfs? */
3780+ do {
3781+ /* todo: signal_pending? */
3782+ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
3783+ } while (err == -EAGAIN || err == -EINTR);
3784+ if (err == 1)
3785+ dst->f_pos--;
3786+ }
3787+
3788+ if (err == 1) {
3789+ ia = (void *)buf;
3790+ ia->ia_size = dst->f_pos;
3791+ ia->ia_valid = ATTR_SIZE | ATTR_FILE;
3792+ ia->ia_file = dst;
c06a8ce3 3793+ h_mtx = &file_inode(dst)->i_mutex;
1facf9fc 3794+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
3795+ err = vfsub_notify_change(&dst->f_path, ia);
3796+ mutex_unlock(h_mtx);
3797+ }
3798+ }
3799+
3800+ return err;
3801+}
3802+
3803+int au_copy_file(struct file *dst, struct file *src, loff_t len)
3804+{
3805+ int err;
3806+ unsigned long blksize;
3807+ unsigned char do_kfree;
3808+ char *buf;
3809+
3810+ err = -ENOMEM;
3811+ blksize = dst->f_dentry->d_sb->s_blocksize;
3812+ if (!blksize || PAGE_SIZE < blksize)
3813+ blksize = PAGE_SIZE;
3814+ AuDbg("blksize %lu\n", blksize);
3815+ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
3816+ if (do_kfree)
3817+ buf = kmalloc(blksize, GFP_NOFS);
3818+ else
3819+ buf = (void *)__get_free_page(GFP_NOFS);
3820+ if (unlikely(!buf))
3821+ goto out;
3822+
3823+ if (len > (1 << 22))
3824+ AuDbg("copying a large file %lld\n", (long long)len);
3825+
3826+ src->f_pos = 0;
3827+ dst->f_pos = 0;
3828+ err = au_do_copy_file(dst, src, len, buf, blksize);
3829+ if (do_kfree)
3830+ kfree(buf);
3831+ else
3832+ free_page((unsigned long)buf);
3833+
4f0767ce 3834+out:
1facf9fc 3835+ return err;
3836+}
3837+
3838+/*
3839+ * to support a sparse file which is opened with O_APPEND,
3840+ * we need to close the file.
3841+ */
c2b27bf2 3842+static int au_cp_regular(struct au_cp_generic *cpg)
1facf9fc 3843+{
3844+ int err, i;
3845+ enum { SRC, DST };
3846+ struct {
3847+ aufs_bindex_t bindex;
3848+ unsigned int flags;
3849+ struct dentry *dentry;
392086de 3850+ int force_wr;
1facf9fc 3851+ struct file *file;
3852+ void *label, *label_file;
3853+ } *f, file[] = {
3854+ {
c2b27bf2 3855+ .bindex = cpg->bsrc,
1facf9fc 3856+ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
1facf9fc 3857+ .label = &&out,
3858+ .label_file = &&out_src
3859+ },
3860+ {
c2b27bf2 3861+ .bindex = cpg->bdst,
1facf9fc 3862+ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
392086de 3863+ .force_wr = !!au_ftest_cpup(cpg->flags, RWDST),
1facf9fc 3864+ .label = &&out_src,
3865+ .label_file = &&out_dst
3866+ }
3867+ };
3868+ struct super_block *sb;
3869+
3870+ /* bsrc branch can be ro/rw. */
c2b27bf2 3871+ sb = cpg->dentry->d_sb;
1facf9fc 3872+ f = file;
3873+ for (i = 0; i < 2; i++, f++) {
c2b27bf2
AM
3874+ f->dentry = au_h_dptr(cpg->dentry, f->bindex);
3875+ f->file = au_h_open(cpg->dentry, f->bindex, f->flags,
392086de 3876+ /*file*/NULL, f->force_wr);
1facf9fc 3877+ err = PTR_ERR(f->file);
3878+ if (IS_ERR(f->file))
3879+ goto *f->label;
3880+ err = -EINVAL;
3881+ if (unlikely(!f->file->f_op))
3882+ goto *f->label_file;
3883+ }
3884+
3885+ /* try stopping to update while we copyup */
3886+ IMustLock(file[SRC].dentry->d_inode);
c2b27bf2 3887+ err = au_copy_file(file[DST].file, file[SRC].file, cpg->len);
1facf9fc 3888+
4f0767ce 3889+out_dst:
1facf9fc 3890+ fput(file[DST].file);
3891+ au_sbr_put(sb, file[DST].bindex);
4f0767ce 3892+out_src:
1facf9fc 3893+ fput(file[SRC].file);
3894+ au_sbr_put(sb, file[SRC].bindex);
4f0767ce 3895+out:
1facf9fc 3896+ return err;
3897+}
3898+
c2b27bf2 3899+static int au_do_cpup_regular(struct au_cp_generic *cpg,
86dc4139 3900+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 3901+{
3902+ int err, rerr;
3903+ loff_t l;
86dc4139
AM
3904+ struct path h_path;
3905+ struct inode *h_src_inode;
1facf9fc 3906+
3907+ err = 0;
c2b27bf2 3908+ h_src_inode = au_h_iptr(cpg->dentry->d_inode, cpg->bsrc);
86dc4139 3909+ l = i_size_read(h_src_inode);
c2b27bf2
AM
3910+ if (cpg->len == -1 || l < cpg->len)
3911+ cpg->len = l;
3912+ if (cpg->len) {
86dc4139
AM
3913+ /* try stopping to update while we are referencing */
3914+ mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD);
c2b27bf2 3915+ au_pin_hdir_unlock(cpg->pin);
1facf9fc 3916+
c2b27bf2
AM
3917+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
3918+ h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc);
86dc4139
AM
3919+ h_src_attr->iflags = h_src_inode->i_flags;
3920+ err = vfs_getattr(&h_path, &h_src_attr->st);
3921+ if (unlikely(err)) {
3922+ mutex_unlock(&h_src_inode->i_mutex);
3923+ goto out;
3924+ }
3925+ h_src_attr->valid = 1;
c2b27bf2 3926+ err = au_cp_regular(cpg);
86dc4139 3927+ mutex_unlock(&h_src_inode->i_mutex);
c2b27bf2 3928+ rerr = au_pin_hdir_relock(cpg->pin);
86dc4139
AM
3929+ if (!err && rerr)
3930+ err = rerr;
1facf9fc 3931+ }
3932+
4f0767ce 3933+out:
1facf9fc 3934+ return err;
3935+}
3936+
3937+static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
3938+ struct inode *h_dir)
3939+{
3940+ int err, symlen;
3941+ mm_segment_t old_fs;
b752ccd1
AM
3942+ union {
3943+ char *k;
3944+ char __user *u;
3945+ } sym;
1facf9fc 3946+
3947+ err = -ENOSYS;
3948+ if (unlikely(!h_src->d_inode->i_op->readlink))
3949+ goto out;
3950+
3951+ err = -ENOMEM;
537831f9 3952+ sym.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 3953+ if (unlikely(!sym.k))
1facf9fc 3954+ goto out;
3955+
9dbd164d 3956+ /* unnecessary to support mmap_sem since symlink is not mmap-able */
1facf9fc 3957+ old_fs = get_fs();
3958+ set_fs(KERNEL_DS);
b752ccd1 3959+ symlen = h_src->d_inode->i_op->readlink(h_src, sym.u, PATH_MAX);
1facf9fc 3960+ err = symlen;
3961+ set_fs(old_fs);
3962+
3963+ if (symlen > 0) {
b752ccd1
AM
3964+ sym.k[symlen] = 0;
3965+ err = vfsub_symlink(h_dir, h_path, sym.k);
1facf9fc 3966+ }
537831f9 3967+ free_page((unsigned long)sym.k);
1facf9fc 3968+
4f0767ce 3969+out:
1facf9fc 3970+ return err;
3971+}
3972+
1facf9fc 3973+static noinline_for_stack
c2b27bf2 3974+int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent,
86dc4139 3975+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 3976+{
3977+ int err;
3978+ umode_t mode;
3979+ unsigned int mnt_flags;
3980+ unsigned char isdir;
c2b27bf2 3981+ const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 3982+ struct au_dtime dt;
3983+ struct path h_path;
3984+ struct dentry *h_src, *h_dst, *h_parent;
3985+ struct inode *h_inode, *h_dir;
3986+ struct super_block *sb;
3987+
3988+ /* bsrc branch can be ro/rw. */
c2b27bf2 3989+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
1facf9fc 3990+ h_inode = h_src->d_inode;
c2b27bf2 3991+ AuDebugOn(h_inode != au_h_iptr(cpg->dentry->d_inode, cpg->bsrc));
1facf9fc 3992+
3993+ /* try stopping to be referenced while we are creating */
c2b27bf2
AM
3994+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
3995+ if (au_ftest_cpup(cpg->flags, RENAME))
86dc4139
AM
3996+ AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX,
3997+ AUFS_WH_PFX_LEN));
1facf9fc 3998+ h_parent = h_dst->d_parent; /* dir inode is locked */
3999+ h_dir = h_parent->d_inode;
4000+ IMustLock(h_dir);
4001+ AuDebugOn(h_parent != h_dst->d_parent);
4002+
c2b27bf2
AM
4003+ sb = cpg->dentry->d_sb;
4004+ h_path.mnt = au_sbr_mnt(sb, cpg->bdst);
1facf9fc 4005+ if (do_dt) {
4006+ h_path.dentry = h_parent;
4007+ au_dtime_store(&dt, dst_parent, &h_path);
4008+ }
4009+ h_path.dentry = h_dst;
4010+
4011+ isdir = 0;
4012+ mode = h_inode->i_mode;
4013+ switch (mode & S_IFMT) {
4014+ case S_IFREG:
b4510431
AM
4015+ err = vfsub_create(h_dir, &h_path, mode | S_IWUSR,
4016+ /*want_excl*/true);
1facf9fc 4017+ if (!err)
c2b27bf2 4018+ err = au_do_cpup_regular(cpg, h_src_attr);
1facf9fc 4019+ break;
4020+ case S_IFDIR:
4021+ isdir = 1;
4022+ err = vfsub_mkdir(h_dir, &h_path, mode);
4023+ if (!err) {
4024+ /*
4025+ * strange behaviour from the users view,
4026+ * particularry setattr case
4027+ */
c2b27bf2 4028+ if (au_ibstart(dst_parent->d_inode) == cpg->bdst)
1facf9fc 4029+ au_cpup_attr_nlink(dst_parent->d_inode,
4030+ /*force*/1);
c2b27bf2 4031+ au_cpup_attr_nlink(cpg->dentry->d_inode, /*force*/1);
1facf9fc 4032+ }
4033+ break;
4034+ case S_IFLNK:
4035+ err = au_do_cpup_symlink(&h_path, h_src, h_dir);
4036+ break;
4037+ case S_IFCHR:
4038+ case S_IFBLK:
4039+ AuDebugOn(!capable(CAP_MKNOD));
4040+ /*FALLTHROUGH*/
4041+ case S_IFIFO:
4042+ case S_IFSOCK:
4043+ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
4044+ break;
4045+ default:
4046+ AuIOErr("Unknown inode type 0%o\n", mode);
4047+ err = -EIO;
4048+ }
4049+
4050+ mnt_flags = au_mntflags(sb);
4051+ if (!au_opt_test(mnt_flags, UDBA_NONE)
4052+ && !isdir
4053+ && au_opt_test(mnt_flags, XINO)
4054+ && h_inode->i_nlink == 1
4055+ /* todo: unnecessary? */
c2b27bf2
AM
4056+ /* && cpg->dentry->d_inode->i_nlink == 1 */
4057+ && cpg->bdst < cpg->bsrc
4058+ && !au_ftest_cpup(cpg->flags, KEEPLINO))
4059+ au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0);
1facf9fc 4060+ /* ignore this error */
4061+
4062+ if (do_dt)
4063+ au_dtime_revert(&dt);
4064+ return err;
4065+}
4066+
392086de 4067+static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path)
86dc4139
AM
4068+{
4069+ int err;
392086de 4070+ struct dentry *dentry, *h_dentry, *h_parent, *parent;
86dc4139 4071+ struct inode *h_dir;
392086de 4072+ aufs_bindex_t bdst;
86dc4139 4073+
392086de
AM
4074+ dentry = cpg->dentry;
4075+ bdst = cpg->bdst;
4076+ h_dentry = au_h_dptr(dentry, bdst);
4077+ if (!au_ftest_cpup(cpg->flags, OVERWRITE)) {
4078+ dget(h_dentry);
4079+ au_set_h_dptr(dentry, bdst, NULL);
4080+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
4081+ if (!err)
4082+ h_path->dentry = dget(au_h_dptr(dentry, bdst));
86dc4139 4083+ au_set_h_dptr(dentry, bdst, h_dentry);
392086de
AM
4084+ } else {
4085+ err = 0;
4086+ parent = dget_parent(dentry);
4087+ h_parent = au_h_dptr(parent, bdst);
4088+ dput(parent);
4089+ h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
4090+ if (IS_ERR(h_path->dentry))
4091+ err = PTR_ERR(h_path->dentry);
86dc4139 4092+ }
392086de
AM
4093+ if (unlikely(err))
4094+ goto out;
86dc4139 4095+
86dc4139
AM
4096+ h_parent = h_dentry->d_parent; /* dir inode is locked */
4097+ h_dir = h_parent->d_inode;
4098+ IMustLock(h_dir);
4099+ AuDbg("%.*s %.*s\n", AuDLNPair(h_dentry), AuDLNPair(h_path->dentry));
4100+ err = vfsub_rename(h_dir, h_dentry, h_dir, h_path);
4101+ dput(h_path->dentry);
4102+
4103+out:
4104+ return err;
4105+}
4106+
1facf9fc 4107+/*
4108+ * copyup the @dentry from @bsrc to @bdst.
4109+ * the caller must set the both of lower dentries.
4110+ * @len is for truncating when it is -1 copyup the entire file.
4111+ * in link/rename cases, @dst_parent may be different from the real one.
c2b27bf2 4112+ * basic->bsrc can be larger than basic->bdst.
1facf9fc 4113+ */
c2b27bf2 4114+static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 4115+{
4116+ int err, rerr;
4117+ aufs_bindex_t old_ibstart;
4118+ unsigned char isdir, plink;
1facf9fc 4119+ struct dentry *h_src, *h_dst, *h_parent;
4120+ struct inode *dst_inode, *h_dir, *inode;
4121+ struct super_block *sb;
86dc4139 4122+ struct au_branch *br;
c2b27bf2
AM
4123+ /* to reuduce stack size */
4124+ struct {
4125+ struct au_dtime dt;
4126+ struct path h_path;
4127+ struct au_cpup_reg_attr h_src_attr;
4128+ } *a;
1facf9fc 4129+
c2b27bf2
AM
4130+ err = -ENOMEM;
4131+ a = kmalloc(sizeof(*a), GFP_NOFS);
4132+ if (unlikely(!a))
4133+ goto out;
4134+ a->h_src_attr.valid = 0;
1facf9fc 4135+
c2b27bf2
AM
4136+ sb = cpg->dentry->d_sb;
4137+ br = au_sbr(sb, cpg->bdst);
4138+ a->h_path.mnt = au_br_mnt(br);
4139+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
1facf9fc 4140+ h_parent = h_dst->d_parent; /* dir inode is locked */
4141+ h_dir = h_parent->d_inode;
4142+ IMustLock(h_dir);
4143+
c2b27bf2
AM
4144+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
4145+ inode = cpg->dentry->d_inode;
1facf9fc 4146+
4147+ if (!dst_parent)
c2b27bf2 4148+ dst_parent = dget_parent(cpg->dentry);
1facf9fc 4149+ else
4150+ dget(dst_parent);
4151+
4152+ plink = !!au_opt_test(au_mntflags(sb), PLINK);
c2b27bf2 4153+ dst_inode = au_h_iptr(inode, cpg->bdst);
1facf9fc 4154+ if (dst_inode) {
4155+ if (unlikely(!plink)) {
4156+ err = -EIO;
027c5e7a
AM
4157+ AuIOErr("hi%lu(i%lu) exists on b%d "
4158+ "but plink is disabled\n",
c2b27bf2
AM
4159+ dst_inode->i_ino, inode->i_ino, cpg->bdst);
4160+ goto out_parent;
1facf9fc 4161+ }
4162+
4163+ if (dst_inode->i_nlink) {
c2b27bf2 4164+ const int do_dt = au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 4165+
c2b27bf2 4166+ h_src = au_plink_lkup(inode, cpg->bdst);
1facf9fc 4167+ err = PTR_ERR(h_src);
4168+ if (IS_ERR(h_src))
c2b27bf2 4169+ goto out_parent;
1facf9fc 4170+ if (unlikely(!h_src->d_inode)) {
4171+ err = -EIO;
4172+ AuIOErr("i%lu exists on a upper branch "
027c5e7a
AM
4173+ "but not pseudo-linked\n",
4174+ inode->i_ino);
1facf9fc 4175+ dput(h_src);
c2b27bf2 4176+ goto out_parent;
1facf9fc 4177+ }
4178+
4179+ if (do_dt) {
c2b27bf2
AM
4180+ a->h_path.dentry = h_parent;
4181+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
1facf9fc 4182+ }
86dc4139 4183+
c2b27bf2
AM
4184+ a->h_path.dentry = h_dst;
4185+ err = vfsub_link(h_src, h_dir, &a->h_path);
4186+ if (!err && au_ftest_cpup(cpg->flags, RENAME))
392086de 4187+ err = au_do_ren_after_cpup(cpg, &a->h_path);
1facf9fc 4188+ if (do_dt)
c2b27bf2 4189+ au_dtime_revert(&a->dt);
1facf9fc 4190+ dput(h_src);
c2b27bf2 4191+ goto out_parent;
1facf9fc 4192+ } else
4193+ /* todo: cpup_wh_file? */
4194+ /* udba work */
4a4d8108 4195+ au_update_ibrange(inode, /*do_put_zero*/1);
1facf9fc 4196+ }
4197+
86dc4139 4198+ isdir = S_ISDIR(inode->i_mode);
1facf9fc 4199+ old_ibstart = au_ibstart(inode);
c2b27bf2 4200+ err = cpup_entry(cpg, dst_parent, &a->h_src_attr);
1facf9fc 4201+ if (unlikely(err))
86dc4139 4202+ goto out_rev;
1facf9fc 4203+ dst_inode = h_dst->d_inode;
4204+ mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
86dc4139 4205+ /* todo: necessary? */
c2b27bf2 4206+ /* au_pin_hdir_unlock(cpg->pin); */
1facf9fc 4207+
c2b27bf2 4208+ err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &a->h_src_attr);
86dc4139
AM
4209+ if (unlikely(err)) {
4210+ /* todo: necessary? */
c2b27bf2 4211+ /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */
86dc4139
AM
4212+ mutex_unlock(&dst_inode->i_mutex);
4213+ goto out_rev;
4214+ }
4215+
c2b27bf2 4216+ if (cpg->bdst < old_ibstart) {
86dc4139 4217+ if (S_ISREG(inode->i_mode)) {
c2b27bf2 4218+ err = au_dy_iaop(inode, cpg->bdst, dst_inode);
86dc4139 4219+ if (unlikely(err)) {
c2b27bf2
AM
4220+ /* ignore an error */
4221+ /* au_pin_hdir_relock(cpg->pin); */
86dc4139
AM
4222+ mutex_unlock(&dst_inode->i_mutex);
4223+ goto out_rev;
4a4d8108 4224+ }
4a4d8108 4225+ }
c2b27bf2
AM
4226+ au_set_ibstart(inode, cpg->bdst);
4227+ } else
4228+ au_set_ibend(inode, cpg->bdst);
4229+ au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode),
86dc4139
AM
4230+ au_hi_flags(inode, isdir));
4231+
4232+ /* todo: necessary? */
c2b27bf2 4233+ /* err = au_pin_hdir_relock(cpg->pin); */
86dc4139
AM
4234+ mutex_unlock(&dst_inode->i_mutex);
4235+ if (unlikely(err))
4236+ goto out_rev;
4237+
4238+ if (!isdir
4239+ && h_src->d_inode->i_nlink > 1
4240+ && plink)
c2b27bf2 4241+ au_plink_append(inode, cpg->bdst, h_dst);
86dc4139 4242+
c2b27bf2
AM
4243+ if (au_ftest_cpup(cpg->flags, RENAME)) {
4244+ a->h_path.dentry = h_dst;
392086de 4245+ err = au_do_ren_after_cpup(cpg, &a->h_path);
86dc4139
AM
4246+ }
4247+ if (!err)
c2b27bf2 4248+ goto out_parent; /* success */
1facf9fc 4249+
4250+ /* revert */
4a4d8108 4251+out_rev:
c2b27bf2
AM
4252+ a->h_path.dentry = h_parent;
4253+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
4254+ a->h_path.dentry = h_dst;
86dc4139
AM
4255+ rerr = 0;
4256+ if (h_dst->d_inode) {
4257+ if (!isdir)
c2b27bf2 4258+ rerr = vfsub_unlink(h_dir, &a->h_path, /*force*/0);
86dc4139 4259+ else
c2b27bf2 4260+ rerr = vfsub_rmdir(h_dir, &a->h_path);
86dc4139 4261+ }
c2b27bf2 4262+ au_dtime_revert(&a->dt);
1facf9fc 4263+ if (rerr) {
4264+ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
4265+ err = -EIO;
4266+ }
c2b27bf2 4267+out_parent:
1facf9fc 4268+ dput(dst_parent);
c2b27bf2
AM
4269+ kfree(a);
4270+out:
1facf9fc 4271+ return err;
4272+}
4273+
c2b27bf2 4274+#if 0 /* unused */
1facf9fc 4275+struct au_cpup_single_args {
4276+ int *errp;
c2b27bf2 4277+ struct au_cp_generic *cpg;
1facf9fc 4278+ struct dentry *dst_parent;
4279+};
4280+
4281+static void au_call_cpup_single(void *args)
4282+{
4283+ struct au_cpup_single_args *a = args;
86dc4139 4284+
c2b27bf2
AM
4285+ au_pin_hdir_acquire_nest(a->cpg->pin);
4286+ *a->errp = au_cpup_single(a->cpg, a->dst_parent);
4287+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 4288+}
c2b27bf2 4289+#endif
1facf9fc 4290+
53392da6
AM
4291+/*
4292+ * prevent SIGXFSZ in copy-up.
4293+ * testing CAP_MKNOD is for generic fs,
4294+ * but CAP_FSETID is for xfs only, currently.
4295+ */
86dc4139 4296+static int au_cpup_sio_test(struct au_pin *pin, umode_t mode)
53392da6
AM
4297+{
4298+ int do_sio;
86dc4139
AM
4299+ struct super_block *sb;
4300+ struct inode *h_dir;
53392da6
AM
4301+
4302+ do_sio = 0;
86dc4139 4303+ sb = au_pinned_parent(pin)->d_sb;
53392da6
AM
4304+ if (!au_wkq_test()
4305+ && (!au_sbi(sb)->si_plink_maint_pid
4306+ || au_plink_maint(sb, AuLock_NOPLM))) {
4307+ switch (mode & S_IFMT) {
4308+ case S_IFREG:
4309+ /* no condition about RLIMIT_FSIZE and the file size */
4310+ do_sio = 1;
4311+ break;
4312+ case S_IFCHR:
4313+ case S_IFBLK:
4314+ do_sio = !capable(CAP_MKNOD);
4315+ break;
4316+ }
4317+ if (!do_sio)
4318+ do_sio = ((mode & (S_ISUID | S_ISGID))
4319+ && !capable(CAP_FSETID));
86dc4139
AM
4320+ /* this workaround may be removed in the future */
4321+ if (!do_sio) {
4322+ h_dir = au_pinned_h_dir(pin);
4323+ do_sio = h_dir->i_mode & S_ISVTX;
4324+ }
53392da6
AM
4325+ }
4326+
4327+ return do_sio;
4328+}
4329+
c2b27bf2
AM
4330+#if 0 /* unused */
4331+int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 4332+{
4333+ int err, wkq_err;
1facf9fc 4334+ struct dentry *h_dentry;
4335+
c2b27bf2 4336+ h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
86dc4139 4337+ if (!au_cpup_sio_test(pin, h_dentry->d_inode->i_mode))
c2b27bf2 4338+ err = au_cpup_single(cpg, dst_parent);
1facf9fc 4339+ else {
4340+ struct au_cpup_single_args args = {
4341+ .errp = &err,
c2b27bf2
AM
4342+ .cpg = cpg,
4343+ .dst_parent = dst_parent
1facf9fc 4344+ };
4345+ wkq_err = au_wkq_wait(au_call_cpup_single, &args);
4346+ if (unlikely(wkq_err))
4347+ err = wkq_err;
4348+ }
4349+
4350+ return err;
4351+}
c2b27bf2 4352+#endif
1facf9fc 4353+
4354+/*
4355+ * copyup the @dentry from the first active lower branch to @bdst,
4356+ * using au_cpup_single().
4357+ */
c2b27bf2 4358+static int au_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 4359+{
4360+ int err;
c2b27bf2
AM
4361+ unsigned int flags_orig;
4362+ struct dentry *dentry;
4363+
4364+ AuDebugOn(cpg->bsrc < 0);
1facf9fc 4365+
c2b27bf2 4366+ dentry = cpg->dentry;
86dc4139 4367+ DiMustWriteLock(dentry);
1facf9fc 4368+
c2b27bf2 4369+ err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1);
1facf9fc 4370+ if (!err) {
c2b27bf2
AM
4371+ flags_orig = cpg->flags;
4372+ au_fset_cpup(cpg->flags, RENAME);
4373+ err = au_cpup_single(cpg, NULL);
4374+ cpg->flags = flags_orig;
1facf9fc 4375+ if (!err)
4376+ return 0; /* success */
4377+
4378+ /* revert */
c2b27bf2
AM
4379+ au_set_h_dptr(dentry, cpg->bdst, NULL);
4380+ au_set_dbstart(dentry, cpg->bsrc);
1facf9fc 4381+ }
4382+
4383+ return err;
4384+}
4385+
4386+struct au_cpup_simple_args {
4387+ int *errp;
c2b27bf2 4388+ struct au_cp_generic *cpg;
1facf9fc 4389+};
4390+
4391+static void au_call_cpup_simple(void *args)
4392+{
4393+ struct au_cpup_simple_args *a = args;
86dc4139 4394+
c2b27bf2
AM
4395+ au_pin_hdir_acquire_nest(a->cpg->pin);
4396+ *a->errp = au_cpup_simple(a->cpg);
4397+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 4398+}
4399+
c2b27bf2 4400+static int au_do_sio_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 4401+{
4402+ int err, wkq_err;
c2b27bf2
AM
4403+ struct dentry *dentry, *parent;
4404+ struct file *h_file;
1facf9fc 4405+ struct inode *h_dir;
4406+
c2b27bf2
AM
4407+ dentry = cpg->dentry;
4408+ h_file = NULL;
4409+ if (au_ftest_cpup(cpg->flags, HOPEN)) {
4410+ AuDebugOn(cpg->bsrc < 0);
392086de 4411+ h_file = au_h_open_pre(dentry, cpg->bsrc, /*force_wr*/0);
c2b27bf2
AM
4412+ err = PTR_ERR(h_file);
4413+ if (IS_ERR(h_file))
4414+ goto out;
4415+ }
4416+
1facf9fc 4417+ parent = dget_parent(dentry);
c2b27bf2 4418+ h_dir = au_h_iptr(parent->d_inode, cpg->bdst);
53392da6 4419+ if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
c2b27bf2
AM
4420+ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode))
4421+ err = au_cpup_simple(cpg);
1facf9fc 4422+ else {
4423+ struct au_cpup_simple_args args = {
4424+ .errp = &err,
c2b27bf2 4425+ .cpg = cpg
1facf9fc 4426+ };
4427+ wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
4428+ if (unlikely(wkq_err))
4429+ err = wkq_err;
4430+ }
4431+
4432+ dput(parent);
c2b27bf2
AM
4433+ if (h_file)
4434+ au_h_open_post(dentry, cpg->bsrc, h_file);
4435+
4436+out:
1facf9fc 4437+ return err;
4438+}
4439+
c2b27bf2 4440+int au_sio_cpup_simple(struct au_cp_generic *cpg)
367653fa 4441+{
c2b27bf2
AM
4442+ aufs_bindex_t bsrc, bend;
4443+ struct dentry *dentry, *h_dentry;
367653fa 4444+
c2b27bf2
AM
4445+ if (cpg->bsrc < 0) {
4446+ dentry = cpg->dentry;
4447+ bend = au_dbend(dentry);
4448+ for (bsrc = cpg->bdst + 1; bsrc <= bend; bsrc++) {
4449+ h_dentry = au_h_dptr(dentry, bsrc);
4450+ if (h_dentry) {
4451+ AuDebugOn(!h_dentry->d_inode);
4452+ break;
4453+ }
4454+ }
4455+ AuDebugOn(bsrc > bend);
4456+ cpg->bsrc = bsrc;
367653fa 4457+ }
c2b27bf2
AM
4458+ AuDebugOn(cpg->bsrc <= cpg->bdst);
4459+ return au_do_sio_cpup_simple(cpg);
4460+}
367653fa 4461+
c2b27bf2
AM
4462+int au_sio_cpdown_simple(struct au_cp_generic *cpg)
4463+{
4464+ AuDebugOn(cpg->bdst <= cpg->bsrc);
4465+ return au_do_sio_cpup_simple(cpg);
367653fa
AM
4466+}
4467+
1facf9fc 4468+/* ---------------------------------------------------------------------- */
4469+
4470+/*
4471+ * copyup the deleted file for writing.
4472+ */
c2b27bf2
AM
4473+static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry,
4474+ struct file *file)
1facf9fc 4475+{
4476+ int err;
c2b27bf2
AM
4477+ unsigned int flags_orig;
4478+ aufs_bindex_t bsrc_orig;
1facf9fc 4479+ struct dentry *h_d_dst, *h_d_start;
c2b27bf2 4480+ struct au_dinfo *dinfo;
4a4d8108 4481+ struct au_hdentry *hdp;
1facf9fc 4482+
c2b27bf2 4483+ dinfo = au_di(cpg->dentry);
1308ab2a 4484+ AuRwMustWriteLock(&dinfo->di_rwsem);
4485+
c2b27bf2
AM
4486+ bsrc_orig = cpg->bsrc;
4487+ cpg->bsrc = dinfo->di_bstart;
4a4d8108 4488+ hdp = dinfo->di_hdentry;
c2b27bf2
AM
4489+ h_d_dst = hdp[0 + cpg->bdst].hd_dentry;
4490+ dinfo->di_bstart = cpg->bdst;
4491+ hdp[0 + cpg->bdst].hd_dentry = wh_dentry;
86dc4139 4492+ h_d_start = NULL;
027c5e7a 4493+ if (file) {
c2b27bf2
AM
4494+ h_d_start = hdp[0 + cpg->bsrc].hd_dentry;
4495+ hdp[0 + cpg->bsrc].hd_dentry = au_hf_top(file)->f_dentry;
027c5e7a 4496+ }
c2b27bf2
AM
4497+ flags_orig = cpg->flags;
4498+ cpg->flags = !AuCpup_DTIME;
4499+ err = au_cpup_single(cpg, /*h_parent*/NULL);
4500+ cpg->flags = flags_orig;
027c5e7a
AM
4501+ if (file) {
4502+ if (!err)
4503+ err = au_reopen_nondir(file);
c2b27bf2 4504+ hdp[0 + cpg->bsrc].hd_dentry = h_d_start;
1facf9fc 4505+ }
c2b27bf2
AM
4506+ hdp[0 + cpg->bdst].hd_dentry = h_d_dst;
4507+ dinfo->di_bstart = cpg->bsrc;
4508+ cpg->bsrc = bsrc_orig;
1facf9fc 4509+
4510+ return err;
4511+}
4512+
c2b27bf2 4513+static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 4514+{
4515+ int err;
c2b27bf2 4516+ aufs_bindex_t bdst;
1facf9fc 4517+ struct au_dtime dt;
c2b27bf2 4518+ struct dentry *dentry, *parent, *h_parent, *wh_dentry;
1facf9fc 4519+ struct au_branch *br;
4520+ struct path h_path;
4521+
c2b27bf2
AM
4522+ dentry = cpg->dentry;
4523+ bdst = cpg->bdst;
1facf9fc 4524+ br = au_sbr(dentry->d_sb, bdst);
4525+ parent = dget_parent(dentry);
4526+ h_parent = au_h_dptr(parent, bdst);
4527+ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
4528+ err = PTR_ERR(wh_dentry);
4529+ if (IS_ERR(wh_dentry))
4530+ goto out;
4531+
4532+ h_path.dentry = h_parent;
86dc4139 4533+ h_path.mnt = au_br_mnt(br);
1facf9fc 4534+ au_dtime_store(&dt, parent, &h_path);
c2b27bf2 4535+ err = au_do_cpup_wh(cpg, wh_dentry, file);
1facf9fc 4536+ if (unlikely(err))
4537+ goto out_wh;
4538+
4539+ dget(wh_dentry);
4540+ h_path.dentry = wh_dentry;
4a4d8108
AM
4541+ if (!S_ISDIR(wh_dentry->d_inode->i_mode))
4542+ err = vfsub_unlink(h_parent->d_inode, &h_path, /*force*/0);
4543+ else
4544+ err = vfsub_rmdir(h_parent->d_inode, &h_path);
1facf9fc 4545+ if (unlikely(err)) {
4546+ AuIOErr("failed remove copied-up tmp file %.*s(%d)\n",
4547+ AuDLNPair(wh_dentry), err);
4548+ err = -EIO;
4549+ }
4550+ au_dtime_revert(&dt);
4551+ au_set_hi_wh(dentry->d_inode, bdst, wh_dentry);
4552+
4f0767ce 4553+out_wh:
1facf9fc 4554+ dput(wh_dentry);
4f0767ce 4555+out:
1facf9fc 4556+ dput(parent);
4557+ return err;
4558+}
4559+
4560+struct au_cpup_wh_args {
4561+ int *errp;
c2b27bf2 4562+ struct au_cp_generic *cpg;
1facf9fc 4563+ struct file *file;
4564+};
4565+
4566+static void au_call_cpup_wh(void *args)
4567+{
4568+ struct au_cpup_wh_args *a = args;
86dc4139 4569+
c2b27bf2
AM
4570+ au_pin_hdir_acquire_nest(a->cpg->pin);
4571+ *a->errp = au_cpup_wh(a->cpg, a->file);
4572+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 4573+}
4574+
c2b27bf2 4575+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 4576+{
4577+ int err, wkq_err;
c2b27bf2
AM
4578+ aufs_bindex_t bdst;
4579+ struct dentry *dentry, *parent, *h_orph, *h_parent, *h_dentry;
86dc4139 4580+ struct inode *dir, *h_dir, *h_tmpdir;
1facf9fc 4581+ struct au_wbr *wbr;
c2b27bf2 4582+ struct au_pin wh_pin, *pin_orig;
1facf9fc 4583+
c2b27bf2
AM
4584+ dentry = cpg->dentry;
4585+ bdst = cpg->bdst;
1facf9fc 4586+ parent = dget_parent(dentry);
4587+ dir = parent->d_inode;
4588+ h_orph = NULL;
4589+ h_parent = NULL;
4590+ h_dir = au_igrab(au_h_iptr(dir, bdst));
4591+ h_tmpdir = h_dir;
c2b27bf2 4592+ pin_orig = NULL;
1facf9fc 4593+ if (!h_dir->i_nlink) {
4594+ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
4595+ h_orph = wbr->wbr_orph;
4596+
4597+ h_parent = dget(au_h_dptr(parent, bdst));
1facf9fc 4598+ au_set_h_dptr(parent, bdst, dget(h_orph));
4599+ h_tmpdir = h_orph->d_inode;
1facf9fc 4600+ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
4601+
1facf9fc 4602+ if (file)
4a4d8108 4603+ h_dentry = au_hf_top(file)->f_dentry;
1facf9fc 4604+ else
4605+ h_dentry = au_h_dptr(dentry, au_dbstart(dentry));
dece6358 4606+ mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
4a4d8108 4607+ /* todo: au_h_open_pre()? */
86dc4139 4608+
c2b27bf2 4609+ pin_orig = cpg->pin;
86dc4139 4610+ au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT,
c2b27bf2
AM
4611+ AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED);
4612+ cpg->pin = &wh_pin;
1facf9fc 4613+ }
4614+
53392da6 4615+ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
c2b27bf2
AM
4616+ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode))
4617+ err = au_cpup_wh(cpg, file);
1facf9fc 4618+ else {
4619+ struct au_cpup_wh_args args = {
4620+ .errp = &err,
c2b27bf2
AM
4621+ .cpg = cpg,
4622+ .file = file
1facf9fc 4623+ };
4624+ wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
4625+ if (unlikely(wkq_err))
4626+ err = wkq_err;
4627+ }
4628+
4629+ if (h_orph) {
4630+ mutex_unlock(&h_tmpdir->i_mutex);
4a4d8108 4631+ /* todo: au_h_open_post()? */
1facf9fc 4632+ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
1facf9fc 4633+ au_set_h_dptr(parent, bdst, h_parent);
c2b27bf2
AM
4634+ AuDebugOn(!pin_orig);
4635+ cpg->pin = pin_orig;
1facf9fc 4636+ }
4637+ iput(h_dir);
4638+ dput(parent);
4639+
4640+ return err;
4641+}
4642+
4643+/* ---------------------------------------------------------------------- */
4644+
4645+/*
4646+ * generic routine for both of copy-up and copy-down.
4647+ */
4648+/* cf. revalidate function in file.c */
4649+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
4650+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 4651+ struct au_pin *pin,
1facf9fc 4652+ struct dentry *h_parent, void *arg),
4653+ void *arg)
4654+{
4655+ int err;
4656+ struct au_pin pin;
4657+ struct dentry *d, *parent, *h_parent, *real_parent;
4658+
4659+ err = 0;
4660+ parent = dget_parent(dentry);
4661+ if (IS_ROOT(parent))
4662+ goto out;
4663+
4664+ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
4665+ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
4666+
4667+ /* do not use au_dpage */
4668+ real_parent = parent;
4669+ while (1) {
4670+ dput(parent);
4671+ parent = dget_parent(dentry);
4672+ h_parent = au_h_dptr(parent, bdst);
4673+ if (h_parent)
4674+ goto out; /* success */
4675+
4676+ /* find top dir which is necessary to cpup */
4677+ do {
4678+ d = parent;
4679+ dput(parent);
4680+ parent = dget_parent(d);
4681+ di_read_lock_parent3(parent, !AuLock_IR);
4682+ h_parent = au_h_dptr(parent, bdst);
4683+ di_read_unlock(parent, !AuLock_IR);
4684+ } while (!h_parent);
4685+
4686+ if (d != real_parent)
4687+ di_write_lock_child3(d);
4688+
4689+ /* somebody else might create while we were sleeping */
4690+ if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) {
4691+ if (au_h_dptr(d, bdst))
4692+ au_update_dbstart(d);
4693+
4694+ au_pin_set_dentry(&pin, d);
4695+ err = au_do_pin(&pin);
4696+ if (!err) {
86dc4139 4697+ err = cp(d, bdst, &pin, h_parent, arg);
1facf9fc 4698+ au_unpin(&pin);
4699+ }
4700+ }
4701+
4702+ if (d != real_parent)
4703+ di_write_unlock(d);
4704+ if (unlikely(err))
4705+ break;
4706+ }
4707+
4f0767ce 4708+out:
1facf9fc 4709+ dput(parent);
4710+ return err;
4711+}
4712+
4713+static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 4714+ struct au_pin *pin,
1facf9fc 4715+ struct dentry *h_parent __maybe_unused ,
4716+ void *arg __maybe_unused)
4717+{
c2b27bf2
AM
4718+ struct au_cp_generic cpg = {
4719+ .dentry = dentry,
4720+ .bdst = bdst,
4721+ .bsrc = -1,
4722+ .len = 0,
4723+ .pin = pin,
4724+ .flags = AuCpup_DTIME
4725+ };
4726+ return au_sio_cpup_simple(&cpg);
1facf9fc 4727+}
4728+
4729+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
4730+{
4731+ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
4732+}
4733+
4734+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
4735+{
4736+ int err;
4737+ struct dentry *parent;
4738+ struct inode *dir;
4739+
4740+ parent = dget_parent(dentry);
4741+ dir = parent->d_inode;
4742+ err = 0;
4743+ if (au_h_iptr(dir, bdst))
4744+ goto out;
4745+
4746+ di_read_unlock(parent, AuLock_IR);
4747+ di_write_lock_parent(parent);
4748+ /* someone else might change our inode while we were sleeping */
4749+ if (!au_h_iptr(dir, bdst))
4750+ err = au_cpup_dirs(dentry, bdst);
4751+ di_downgrade_lock(parent, AuLock_IR);
4752+
4f0767ce 4753+out:
1facf9fc 4754+ dput(parent);
4755+ return err;
4756+}
7f207e10
AM
4757diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
4758--- /usr/share/empty/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100
392086de
AM
4759+++ linux/fs/aufs/cpup.h 2013-10-26 16:51:32.273040419 +0200
4760@@ -0,0 +1,95 @@
1facf9fc 4761+/*
7a9e40b8 4762+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 4763+ *
4764+ * This program, aufs is free software; you can redistribute it and/or modify
4765+ * it under the terms of the GNU General Public License as published by
4766+ * the Free Software Foundation; either version 2 of the License, or
4767+ * (at your option) any later version.
dece6358
AM
4768+ *
4769+ * This program is distributed in the hope that it will be useful,
4770+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4771+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4772+ * GNU General Public License for more details.
4773+ *
4774+ * You should have received a copy of the GNU General Public License
4775+ * along with this program; if not, write to the Free Software
4776+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 4777+ */
4778+
4779+/*
4780+ * copy-up/down functions
4781+ */
4782+
4783+#ifndef __AUFS_CPUP_H__
4784+#define __AUFS_CPUP_H__
4785+
4786+#ifdef __KERNEL__
4787+
dece6358 4788+#include <linux/path.h>
1facf9fc 4789+
dece6358
AM
4790+struct inode;
4791+struct file;
86dc4139 4792+struct au_pin;
dece6358 4793+
86dc4139 4794+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags);
1facf9fc 4795+void au_cpup_attr_timesizes(struct inode *inode);
4796+void au_cpup_attr_nlink(struct inode *inode, int force);
4797+void au_cpup_attr_changeable(struct inode *inode);
4798+void au_cpup_igen(struct inode *inode, struct inode *h_inode);
4799+void au_cpup_attr_all(struct inode *inode, int force);
4800+
4801+/* ---------------------------------------------------------------------- */
4802+
c2b27bf2
AM
4803+struct au_cp_generic {
4804+ struct dentry *dentry;
4805+ aufs_bindex_t bdst, bsrc;
4806+ loff_t len;
4807+ struct au_pin *pin;
4808+ unsigned int flags;
4809+};
4810+
1facf9fc 4811+/* cpup flags */
392086de
AM
4812+#define AuCpup_DTIME 1 /* do dtime_store/revert */
4813+#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino,
4814+ for link(2) */
4815+#define AuCpup_RENAME (1 << 2) /* rename after cpup */
4816+#define AuCpup_HOPEN (1 << 3) /* call h_open_pre/post() in
4817+ cpup */
4818+#define AuCpup_OVERWRITE (1 << 4) /* allow overwriting the
4819+ existing entry */
4820+#define AuCpup_RWDST (1 << 5) /* force write target even if
4821+ the branch is marked as RO */
c2b27bf2 4822+
1facf9fc 4823+#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name)
7f207e10
AM
4824+#define au_fset_cpup(flags, name) \
4825+ do { (flags) |= AuCpup_##name; } while (0)
4826+#define au_fclr_cpup(flags, name) \
4827+ do { (flags) &= ~AuCpup_##name; } while (0)
1facf9fc 4828+
4829+int au_copy_file(struct file *dst, struct file *src, loff_t len);
c2b27bf2
AM
4830+int au_sio_cpup_simple(struct au_cp_generic *cpg);
4831+int au_sio_cpdown_simple(struct au_cp_generic *cpg);
4832+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file);
1facf9fc 4833+
4834+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
4835+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 4836+ struct au_pin *pin,
1facf9fc 4837+ struct dentry *h_parent, void *arg),
4838+ void *arg);
4839+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
4840+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
4841+
4842+/* ---------------------------------------------------------------------- */
4843+
4844+/* keep timestamps when copyup */
4845+struct au_dtime {
4846+ struct dentry *dt_dentry;
4847+ struct path dt_h_path;
4848+ struct timespec dt_atime, dt_mtime;
4849+};
4850+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
4851+ struct path *h_path);
4852+void au_dtime_revert(struct au_dtime *dt);
4853+
4854+#endif /* __KERNEL__ */
4855+#endif /* __AUFS_CPUP_H__ */
7f207e10
AM
4856diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
4857--- /usr/share/empty/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
86dc4139
AM
4858+++ linux/fs/aufs/dbgaufs.c 2013-07-06 13:20:47.740198107 +0200
4859@@ -0,0 +1,433 @@
1facf9fc 4860+/*
7a9e40b8 4861+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 4862+ *
4863+ * This program, aufs is free software; you can redistribute it and/or modify
4864+ * it under the terms of the GNU General Public License as published by
4865+ * the Free Software Foundation; either version 2 of the License, or
4866+ * (at your option) any later version.
dece6358
AM
4867+ *
4868+ * This program is distributed in the hope that it will be useful,
4869+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4870+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4871+ * GNU General Public License for more details.
4872+ *
4873+ * You should have received a copy of the GNU General Public License
4874+ * along with this program; if not, write to the Free Software
4875+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 4876+ */
4877+
4878+/*
4879+ * debugfs interface
4880+ */
4881+
4882+#include <linux/debugfs.h>
4883+#include "aufs.h"
4884+
4885+#ifndef CONFIG_SYSFS
4886+#error DEBUG_FS depends upon SYSFS
4887+#endif
4888+
4889+static struct dentry *dbgaufs;
4890+static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
4891+
4892+/* 20 is max digits length of ulong 64 */
4893+struct dbgaufs_arg {
4894+ int n;
4895+ char a[20 * 4];
4896+};
4897+
4898+/*
4899+ * common function for all XINO files
4900+ */
4901+static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
4902+ struct file *file)
4903+{
4904+ kfree(file->private_data);
4905+ return 0;
4906+}
4907+
4908+static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
4909+{
4910+ int err;
4911+ struct kstat st;
4912+ struct dbgaufs_arg *p;
4913+
4914+ err = -ENOMEM;
4915+ p = kmalloc(sizeof(*p), GFP_NOFS);
4916+ if (unlikely(!p))
4917+ goto out;
4918+
4919+ err = 0;
4920+ p->n = 0;
4921+ file->private_data = p;
4922+ if (!xf)
4923+ goto out;
4924+
c06a8ce3 4925+ err = vfs_getattr(&xf->f_path, &st);
1facf9fc 4926+ if (!err) {
4927+ if (do_fcnt)
4928+ p->n = snprintf
4929+ (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n",
4930+ (long)file_count(xf), st.blocks, st.blksize,
4931+ (long long)st.size);
4932+ else
4933+ p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n",
4934+ st.blocks, st.blksize,
4935+ (long long)st.size);
4936+ AuDebugOn(p->n >= sizeof(p->a));
4937+ } else {
4938+ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
4939+ err = 0;
4940+ }
4941+
4f0767ce 4942+out:
1facf9fc 4943+ return err;
4944+
4945+}
4946+
4947+static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
4948+ size_t count, loff_t *ppos)
4949+{
4950+ struct dbgaufs_arg *p;
4951+
4952+ p = file->private_data;
4953+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
4954+}
4955+
4956+/* ---------------------------------------------------------------------- */
4957+
86dc4139
AM
4958+struct dbgaufs_plink_arg {
4959+ int n;
4960+ char a[];
4961+};
4962+
4963+static int dbgaufs_plink_release(struct inode *inode __maybe_unused,
4964+ struct file *file)
4965+{
4966+ free_page((unsigned long)file->private_data);
4967+ return 0;
4968+}
4969+
4970+static int dbgaufs_plink_open(struct inode *inode, struct file *file)
4971+{
4972+ int err, i, limit;
4973+ unsigned long n, sum;
4974+ struct dbgaufs_plink_arg *p;
4975+ struct au_sbinfo *sbinfo;
4976+ struct super_block *sb;
4977+ struct au_sphlhead *sphl;
4978+
4979+ err = -ENOMEM;
4980+ p = (void *)get_zeroed_page(GFP_NOFS);
4981+ if (unlikely(!p))
4982+ goto out;
4983+
4984+ err = -EFBIG;
4985+ sbinfo = inode->i_private;
4986+ sb = sbinfo->si_sb;
4987+ si_noflush_read_lock(sb);
4988+ if (au_opt_test(au_mntflags(sb), PLINK)) {
4989+ limit = PAGE_SIZE - sizeof(p->n);
4990+
4991+ /* the number of buckets */
4992+ n = snprintf(p->a + p->n, limit, "%d\n", AuPlink_NHASH);
4993+ p->n += n;
4994+ limit -= n;
4995+
4996+ sum = 0;
4997+ for (i = 0, sphl = sbinfo->si_plink;
4998+ i < AuPlink_NHASH;
4999+ i++, sphl++) {
5000+ n = au_sphl_count(sphl);
5001+ sum += n;
5002+
5003+ n = snprintf(p->a + p->n, limit, "%lu ", n);
5004+ p->n += n;
5005+ limit -= n;
5006+ if (unlikely(limit <= 0))
5007+ goto out_free;
5008+ }
5009+ p->a[p->n - 1] = '\n';
5010+
5011+ /* the sum of plinks */
5012+ n = snprintf(p->a + p->n, limit, "%lu\n", sum);
5013+ p->n += n;
5014+ limit -= n;
5015+ if (unlikely(limit <= 0))
5016+ goto out_free;
5017+ } else {
5018+#define str "1\n0\n0\n"
5019+ p->n = sizeof(str) - 1;
5020+ strcpy(p->a, str);
5021+#undef str
5022+ }
5023+ si_read_unlock(sb);
5024+
5025+ err = 0;
5026+ file->private_data = p;
5027+ goto out; /* success */
5028+
5029+out_free:
5030+ free_page((unsigned long)p);
5031+out:
5032+ return err;
5033+}
5034+
5035+static ssize_t dbgaufs_plink_read(struct file *file, char __user *buf,
5036+ size_t count, loff_t *ppos)
5037+{
5038+ struct dbgaufs_plink_arg *p;
5039+
5040+ p = file->private_data;
5041+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
5042+}
5043+
5044+static const struct file_operations dbgaufs_plink_fop = {
5045+ .owner = THIS_MODULE,
5046+ .open = dbgaufs_plink_open,
5047+ .release = dbgaufs_plink_release,
5048+ .read = dbgaufs_plink_read
5049+};
5050+
5051+/* ---------------------------------------------------------------------- */
5052+
1facf9fc 5053+static int dbgaufs_xib_open(struct inode *inode, struct file *file)
5054+{
5055+ int err;
5056+ struct au_sbinfo *sbinfo;
5057+ struct super_block *sb;
5058+
5059+ sbinfo = inode->i_private;
5060+ sb = sbinfo->si_sb;
5061+ si_noflush_read_lock(sb);
5062+ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0);
5063+ si_read_unlock(sb);
5064+ return err;
5065+}
5066+
5067+static const struct file_operations dbgaufs_xib_fop = {
4a4d8108 5068+ .owner = THIS_MODULE,
1facf9fc 5069+ .open = dbgaufs_xib_open,
5070+ .release = dbgaufs_xi_release,
5071+ .read = dbgaufs_xi_read
5072+};
5073+
5074+/* ---------------------------------------------------------------------- */
5075+
5076+#define DbgaufsXi_PREFIX "xi"
5077+
5078+static int dbgaufs_xino_open(struct inode *inode, struct file *file)
5079+{
5080+ int err;
5081+ long l;
5082+ struct au_sbinfo *sbinfo;
5083+ struct super_block *sb;
5084+ struct file *xf;
5085+ struct qstr *name;
5086+
5087+ err = -ENOENT;
5088+ xf = NULL;
5089+ name = &file->f_dentry->d_name;
5090+ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
5091+ || memcmp(name->name, DbgaufsXi_PREFIX,
5092+ sizeof(DbgaufsXi_PREFIX) - 1)))
5093+ goto out;
9dbd164d 5094+ err = kstrtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
1facf9fc 5095+ if (unlikely(err))
5096+ goto out;
5097+
5098+ sbinfo = inode->i_private;
5099+ sb = sbinfo->si_sb;
5100+ si_noflush_read_lock(sb);
5101+ if (l <= au_sbend(sb)) {
5102+ xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file;
5103+ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1);
5104+ } else
5105+ err = -ENOENT;
5106+ si_read_unlock(sb);
5107+
4f0767ce 5108+out:
1facf9fc 5109+ return err;
5110+}
5111+
5112+static const struct file_operations dbgaufs_xino_fop = {
4a4d8108 5113+ .owner = THIS_MODULE,
1facf9fc 5114+ .open = dbgaufs_xino_open,
5115+ .release = dbgaufs_xi_release,
5116+ .read = dbgaufs_xi_read
5117+};
5118+
5119+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
5120+{
5121+ aufs_bindex_t bend;
5122+ struct au_branch *br;
5123+ struct au_xino_file *xi;
5124+
5125+ if (!au_sbi(sb)->si_dbgaufs)
5126+ return;
5127+
5128+ bend = au_sbend(sb);
5129+ for (; bindex <= bend; bindex++) {
5130+ br = au_sbr(sb, bindex);
5131+ xi = &br->br_xino;
c06a8ce3
AM
5132+ debugfs_remove(xi->xi_dbgaufs);
5133+ xi->xi_dbgaufs = NULL;
1facf9fc 5134+ }
5135+}
5136+
5137+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
5138+{
5139+ struct au_sbinfo *sbinfo;
5140+ struct dentry *parent;
5141+ struct au_branch *br;
5142+ struct au_xino_file *xi;
5143+ aufs_bindex_t bend;
5144+ char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */
5145+
5146+ sbinfo = au_sbi(sb);
5147+ parent = sbinfo->si_dbgaufs;
5148+ if (!parent)
5149+ return;
5150+
5151+ bend = au_sbend(sb);
5152+ for (; bindex <= bend; bindex++) {
5153+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
5154+ br = au_sbr(sb, bindex);
5155+ xi = &br->br_xino;
5156+ AuDebugOn(xi->xi_dbgaufs);
5157+ xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
5158+ sbinfo, &dbgaufs_xino_fop);
5159+ /* ignore an error */
5160+ if (unlikely(!xi->xi_dbgaufs))
5161+ AuWarn1("failed %s under debugfs\n", name);
5162+ }
5163+}
5164+
5165+/* ---------------------------------------------------------------------- */
5166+
5167+#ifdef CONFIG_AUFS_EXPORT
5168+static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
5169+{
5170+ int err;
5171+ struct au_sbinfo *sbinfo;
5172+ struct super_block *sb;
5173+
5174+ sbinfo = inode->i_private;
5175+ sb = sbinfo->si_sb;
5176+ si_noflush_read_lock(sb);
5177+ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0);
5178+ si_read_unlock(sb);
5179+ return err;
5180+}
5181+
5182+static const struct file_operations dbgaufs_xigen_fop = {
4a4d8108 5183+ .owner = THIS_MODULE,
1facf9fc 5184+ .open = dbgaufs_xigen_open,
5185+ .release = dbgaufs_xi_release,
5186+ .read = dbgaufs_xi_read
5187+};
5188+
5189+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
5190+{
5191+ int err;
5192+
dece6358
AM
5193+ /*
5194+ * This function is a dynamic '__init' fucntion actually,
5195+ * so the tiny check for si_rwsem is unnecessary.
5196+ */
5197+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
5198+
1facf9fc 5199+ err = -EIO;
5200+ sbinfo->si_dbgaufs_xigen = debugfs_create_file
5201+ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
5202+ &dbgaufs_xigen_fop);
5203+ if (sbinfo->si_dbgaufs_xigen)
5204+ err = 0;
5205+
5206+ return err;
5207+}
5208+#else
5209+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
5210+{
5211+ return 0;
5212+}
5213+#endif /* CONFIG_AUFS_EXPORT */
5214+
5215+/* ---------------------------------------------------------------------- */
5216+
5217+void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
5218+{
dece6358
AM
5219+ /*
5220+ * This function is a dynamic '__init' fucntion actually,
5221+ * so the tiny check for si_rwsem is unnecessary.
5222+ */
5223+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
5224+
1facf9fc 5225+ debugfs_remove_recursive(sbinfo->si_dbgaufs);
5226+ sbinfo->si_dbgaufs = NULL;
5227+ kobject_put(&sbinfo->si_kobj);
5228+}
5229+
5230+int dbgaufs_si_init(struct au_sbinfo *sbinfo)
5231+{
5232+ int err;
5233+ char name[SysaufsSiNameLen];
5234+
dece6358
AM
5235+ /*
5236+ * This function is a dynamic '__init' fucntion actually,
5237+ * so the tiny check for si_rwsem is unnecessary.
5238+ */
5239+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
5240+
1facf9fc 5241+ err = -ENOENT;
5242+ if (!dbgaufs) {
5243+ AuErr1("/debug/aufs is uninitialized\n");
5244+ goto out;
5245+ }
5246+
5247+ err = -EIO;
5248+ sysaufs_name(sbinfo, name);
5249+ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
5250+ if (unlikely(!sbinfo->si_dbgaufs))
5251+ goto out;
5252+ kobject_get(&sbinfo->si_kobj);
5253+
5254+ sbinfo->si_dbgaufs_xib = debugfs_create_file
5255+ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
5256+ &dbgaufs_xib_fop);
5257+ if (unlikely(!sbinfo->si_dbgaufs_xib))
5258+ goto out_dir;
5259+
86dc4139
AM
5260+ sbinfo->si_dbgaufs_plink = debugfs_create_file
5261+ ("plink", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
5262+ &dbgaufs_plink_fop);
5263+ if (unlikely(!sbinfo->si_dbgaufs_plink))
5264+ goto out_dir;
5265+
1facf9fc 5266+ err = dbgaufs_xigen_init(sbinfo);
5267+ if (!err)
5268+ goto out; /* success */
5269+
4f0767ce 5270+out_dir:
1facf9fc 5271+ dbgaufs_si_fin(sbinfo);
4f0767ce 5272+out:
1facf9fc 5273+ return err;
5274+}
5275+
5276+/* ---------------------------------------------------------------------- */
5277+
5278+void dbgaufs_fin(void)
5279+{
5280+ debugfs_remove(dbgaufs);
5281+}
5282+
5283+int __init dbgaufs_init(void)
5284+{
5285+ int err;
5286+
5287+ err = -EIO;
5288+ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
5289+ if (dbgaufs)
5290+ err = 0;
5291+ return err;
5292+}
7f207e10
AM
5293diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
5294--- /usr/share/empty/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
86dc4139 5295+++ linux/fs/aufs/dbgaufs.h 2013-07-06 13:20:47.740198107 +0200
f6c5ef8b 5296@@ -0,0 +1,49 @@
1facf9fc 5297+/*
7a9e40b8 5298+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 5299+ *
5300+ * This program, aufs is free software; you can redistribute it and/or modify
5301+ * it under the terms of the GNU General Public License as published by
5302+ * the Free Software Foundation; either version 2 of the License, or
5303+ * (at your option) any later version.
dece6358
AM
5304+ *
5305+ * This program is distributed in the hope that it will be useful,
5306+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5307+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5308+ * GNU General Public License for more details.
5309+ *
5310+ * You should have received a copy of the GNU General Public License
5311+ * along with this program; if not, write to the Free Software
5312+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 5313+ */
5314+
5315+/*
5316+ * debugfs interface
5317+ */
5318+
5319+#ifndef __DBGAUFS_H__
5320+#define __DBGAUFS_H__
5321+
5322+#ifdef __KERNEL__
5323+
dece6358 5324+struct super_block;
1facf9fc 5325+struct au_sbinfo;
dece6358 5326+
1facf9fc 5327+#ifdef CONFIG_DEBUG_FS
5328+/* dbgaufs.c */
5329+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
5330+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
5331+void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
5332+int dbgaufs_si_init(struct au_sbinfo *sbinfo);
5333+void dbgaufs_fin(void);
5334+int __init dbgaufs_init(void);
1facf9fc 5335+#else
4a4d8108
AM
5336+AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
5337+AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
5338+AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
5339+AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
5340+AuStubVoid(dbgaufs_fin, void)
5341+AuStubInt0(__init dbgaufs_init, void)
1facf9fc 5342+#endif /* CONFIG_DEBUG_FS */
5343+
5344+#endif /* __KERNEL__ */
5345+#endif /* __DBGAUFS_H__ */
7f207e10
AM
5346diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
5347--- /usr/share/empty/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100
392086de 5348+++ linux/fs/aufs/dcsub.c 2013-10-26 16:51:29.579631476 +0200
027c5e7a 5349@@ -0,0 +1,243 @@
1facf9fc 5350+/*
7a9e40b8 5351+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 5352+ *
5353+ * This program, aufs is free software; you can redistribute it and/or modify
5354+ * it under the terms of the GNU General Public License as published by
5355+ * the Free Software Foundation; either version 2 of the License, or
5356+ * (at your option) any later version.
dece6358
AM
5357+ *
5358+ * This program is distributed in the hope that it will be useful,
5359+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5360+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5361+ * GNU General Public License for more details.
5362+ *
5363+ * You should have received a copy of the GNU General Public License
5364+ * along with this program; if not, write to the Free Software
5365+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 5366+ */
5367+
5368+/*
5369+ * sub-routines for dentry cache
5370+ */
5371+
5372+#include "aufs.h"
5373+
5374+static void au_dpage_free(struct au_dpage *dpage)
5375+{
5376+ int i;
5377+ struct dentry **p;
5378+
5379+ p = dpage->dentries;
5380+ for (i = 0; i < dpage->ndentry; i++)
5381+ dput(*p++);
5382+ free_page((unsigned long)dpage->dentries);
5383+}
5384+
5385+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
5386+{
5387+ int err;
5388+ void *p;
5389+
5390+ err = -ENOMEM;
5391+ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
5392+ if (unlikely(!dpages->dpages))
5393+ goto out;
5394+
5395+ p = (void *)__get_free_page(gfp);
5396+ if (unlikely(!p))
5397+ goto out_dpages;
5398+
5399+ dpages->dpages[0].ndentry = 0;
5400+ dpages->dpages[0].dentries = p;
5401+ dpages->ndpage = 1;
5402+ return 0; /* success */
5403+
4f0767ce 5404+out_dpages:
1facf9fc 5405+ kfree(dpages->dpages);
4f0767ce 5406+out:
1facf9fc 5407+ return err;
5408+}
5409+
5410+void au_dpages_free(struct au_dcsub_pages *dpages)
5411+{
5412+ int i;
5413+ struct au_dpage *p;
5414+
5415+ p = dpages->dpages;
5416+ for (i = 0; i < dpages->ndpage; i++)
5417+ au_dpage_free(p++);
5418+ kfree(dpages->dpages);
5419+}
5420+
5421+static int au_dpages_append(struct au_dcsub_pages *dpages,
5422+ struct dentry *dentry, gfp_t gfp)
5423+{
5424+ int err, sz;
5425+ struct au_dpage *dpage;
5426+ void *p;
5427+
5428+ dpage = dpages->dpages + dpages->ndpage - 1;
5429+ sz = PAGE_SIZE / sizeof(dentry);
5430+ if (unlikely(dpage->ndentry >= sz)) {
5431+ AuLabel(new dpage);
5432+ err = -ENOMEM;
5433+ sz = dpages->ndpage * sizeof(*dpages->dpages);
5434+ p = au_kzrealloc(dpages->dpages, sz,
5435+ sz + sizeof(*dpages->dpages), gfp);
5436+ if (unlikely(!p))
5437+ goto out;
5438+
5439+ dpages->dpages = p;
5440+ dpage = dpages->dpages + dpages->ndpage;
5441+ p = (void *)__get_free_page(gfp);
5442+ if (unlikely(!p))
5443+ goto out;
5444+
5445+ dpage->ndentry = 0;
5446+ dpage->dentries = p;
5447+ dpages->ndpage++;
5448+ }
5449+
392086de 5450+ AuDebugOn(!d_count(dentry));
027c5e7a 5451+ dpage->dentries[dpage->ndentry++] = dget_dlock(dentry);
1facf9fc 5452+ return 0; /* success */
5453+
4f0767ce 5454+out:
1facf9fc 5455+ return err;
5456+}
5457+
5458+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
5459+ au_dpages_test test, void *arg)
5460+{
5461+ int err;
027c5e7a 5462+ struct dentry *this_parent;
1facf9fc 5463+ struct list_head *next;
5464+ struct super_block *sb = root->d_sb;
5465+
5466+ err = 0;
027c5e7a
AM
5467+ write_seqlock(&rename_lock);
5468+ this_parent = root;
5469+ spin_lock(&this_parent->d_lock);
4f0767ce 5470+repeat:
1facf9fc 5471+ next = this_parent->d_subdirs.next;
4f0767ce 5472+resume:
1facf9fc 5473+ if (this_parent->d_sb == sb
5474+ && !IS_ROOT(this_parent)
027c5e7a 5475+ && au_di(this_parent)
392086de 5476+ && d_count(this_parent)
1facf9fc 5477+ && (!test || test(this_parent, arg))) {
5478+ err = au_dpages_append(dpages, this_parent, GFP_ATOMIC);
5479+ if (unlikely(err))
5480+ goto out;
5481+ }
5482+
5483+ while (next != &this_parent->d_subdirs) {
5484+ struct list_head *tmp = next;
5485+ struct dentry *dentry = list_entry(tmp, struct dentry,
5486+ d_u.d_child);
027c5e7a 5487+
1facf9fc 5488+ next = tmp->next;
027c5e7a 5489+ spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
392086de 5490+ if (d_count(dentry)) {
027c5e7a
AM
5491+ if (!list_empty(&dentry->d_subdirs)) {
5492+ spin_unlock(&this_parent->d_lock);
5493+ spin_release(&dentry->d_lock.dep_map, 1,
5494+ _RET_IP_);
5495+ this_parent = dentry;
5496+ spin_acquire(&this_parent->d_lock.dep_map, 0, 1,
5497+ _RET_IP_);
5498+ goto repeat;
5499+ }
5500+ if (dentry->d_sb == sb
5501+ && au_di(dentry)
5502+ && (!test || test(dentry, arg)))
5503+ err = au_dpages_append(dpages, dentry,
5504+ GFP_ATOMIC);
1facf9fc 5505+ }
027c5e7a
AM
5506+ spin_unlock(&dentry->d_lock);
5507+ if (unlikely(err))
5508+ goto out;
1facf9fc 5509+ }
5510+
5511+ if (this_parent != root) {
027c5e7a
AM
5512+ struct dentry *tmp;
5513+ struct dentry *child;
5514+
5515+ tmp = this_parent->d_parent;
5516+ rcu_read_lock();
5517+ spin_unlock(&this_parent->d_lock);
5518+ child = this_parent;
5519+ this_parent = tmp;
5520+ spin_lock(&this_parent->d_lock);
5521+ rcu_read_unlock();
5522+ next = child->d_u.d_child.next;
1facf9fc 5523+ goto resume;
5524+ }
027c5e7a 5525+
4f0767ce 5526+out:
027c5e7a
AM
5527+ spin_unlock(&this_parent->d_lock);
5528+ write_sequnlock(&rename_lock);
1facf9fc 5529+ return err;
5530+}
5531+
5532+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
5533+ int do_include, au_dpages_test test, void *arg)
5534+{
5535+ int err;
5536+
5537+ err = 0;
027c5e7a
AM
5538+ write_seqlock(&rename_lock);
5539+ spin_lock(&dentry->d_lock);
5540+ if (do_include
392086de 5541+ && d_count(dentry)
027c5e7a 5542+ && (!test || test(dentry, arg)))
1facf9fc 5543+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
5544+ spin_unlock(&dentry->d_lock);
5545+ if (unlikely(err))
5546+ goto out;
5547+
5548+ /*
5549+ * vfsmount_lock is unnecessary since this is a traverse in a single
5550+ * mount
5551+ */
1facf9fc 5552+ while (!IS_ROOT(dentry)) {
027c5e7a
AM
5553+ dentry = dentry->d_parent; /* rename_lock is locked */
5554+ spin_lock(&dentry->d_lock);
392086de 5555+ if (d_count(dentry)
027c5e7a 5556+ && (!test || test(dentry, arg)))
1facf9fc 5557+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
5558+ spin_unlock(&dentry->d_lock);
5559+ if (unlikely(err))
5560+ break;
1facf9fc 5561+ }
5562+
4f0767ce 5563+out:
027c5e7a 5564+ write_sequnlock(&rename_lock);
1facf9fc 5565+ return err;
5566+}
5567+
027c5e7a
AM
5568+static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg)
5569+{
5570+ return au_di(dentry) && dentry->d_sb == arg;
5571+}
5572+
5573+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
5574+ struct dentry *dentry, int do_include)
5575+{
5576+ return au_dcsub_pages_rev(dpages, dentry, do_include,
5577+ au_dcsub_dpages_aufs, dentry->d_sb);
5578+}
5579+
4a4d8108 5580+int au_test_subdir(struct dentry *d1, struct dentry *d2)
1facf9fc 5581+{
4a4d8108
AM
5582+ struct path path[2] = {
5583+ {
5584+ .dentry = d1
5585+ },
5586+ {
5587+ .dentry = d2
5588+ }
5589+ };
1facf9fc 5590+
4a4d8108 5591+ return path_is_under(path + 0, path + 1);
1facf9fc 5592+}
7f207e10
AM
5593diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
5594--- /usr/share/empty/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100
86dc4139 5595+++ linux/fs/aufs/dcsub.h 2013-07-06 13:20:47.740198107 +0200
f6c5ef8b 5596@@ -0,0 +1,94 @@
1facf9fc 5597+/*
7a9e40b8 5598+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 5599+ *
5600+ * This program, aufs is free software; you can redistribute it and/or modify
5601+ * it under the terms of the GNU General Public License as published by
5602+ * the Free Software Foundation; either version 2 of the License, or
5603+ * (at your option) any later version.
dece6358
AM
5604+ *
5605+ * This program is distributed in the hope that it will be useful,
5606+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5607+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5608+ * GNU General Public License for more details.
5609+ *
5610+ * You should have received a copy of the GNU General Public License
5611+ * along with this program; if not, write to the Free Software
5612+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 5613+ */
5614+
5615+/*
5616+ * sub-routines for dentry cache
5617+ */
5618+
5619+#ifndef __AUFS_DCSUB_H__
5620+#define __AUFS_DCSUB_H__
5621+
5622+#ifdef __KERNEL__
5623+
7f207e10 5624+#include <linux/dcache.h>
027c5e7a 5625+#include <linux/fs.h>
dece6358
AM
5626+
5627+struct dentry;
1facf9fc 5628+
5629+struct au_dpage {
5630+ int ndentry;
5631+ struct dentry **dentries;
5632+};
5633+
5634+struct au_dcsub_pages {
5635+ int ndpage;
5636+ struct au_dpage *dpages;
5637+};
5638+
5639+/* ---------------------------------------------------------------------- */
5640+
7f207e10 5641+/* dcsub.c */
1facf9fc 5642+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
5643+void au_dpages_free(struct au_dcsub_pages *dpages);
5644+typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
5645+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
5646+ au_dpages_test test, void *arg);
5647+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
5648+ int do_include, au_dpages_test test, void *arg);
027c5e7a
AM
5649+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
5650+ struct dentry *dentry, int do_include);
4a4d8108 5651+int au_test_subdir(struct dentry *d1, struct dentry *d2);
1facf9fc 5652+
7f207e10
AM
5653+/* ---------------------------------------------------------------------- */
5654+
027c5e7a
AM
5655+static inline int au_d_hashed_positive(struct dentry *d)
5656+{
5657+ int err;
5658+ struct inode *inode = d->d_inode;
5659+ err = 0;
5660+ if (unlikely(d_unhashed(d) || !inode || !inode->i_nlink))
5661+ err = -ENOENT;
5662+ return err;
5663+}
5664+
5665+static inline int au_d_alive(struct dentry *d)
5666+{
5667+ int err;
5668+ struct inode *inode;
5669+ err = 0;
5670+ if (!IS_ROOT(d))
5671+ err = au_d_hashed_positive(d);
5672+ else {
5673+ inode = d->d_inode;
5674+ if (unlikely(d_unlinked(d) || !inode || !inode->i_nlink))
5675+ err = -ENOENT;
5676+ }
5677+ return err;
5678+}
5679+
5680+static inline int au_alive_dir(struct dentry *d)
7f207e10 5681+{
027c5e7a
AM
5682+ int err;
5683+ err = au_d_alive(d);
5684+ if (unlikely(err || IS_DEADDIR(d->d_inode)))
5685+ err = -ENOENT;
5686+ return err;
7f207e10
AM
5687+}
5688+
1facf9fc 5689+#endif /* __KERNEL__ */
5690+#endif /* __AUFS_DCSUB_H__ */
7f207e10
AM
5691diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
5692--- /usr/share/empty/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
5693+++ linux/fs/aufs/debug.c 2013-10-26 16:51:32.273040419 +0200
5694@@ -0,0 +1,518 @@
1facf9fc 5695+/*
7a9e40b8 5696+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 5697+ *
5698+ * This program, aufs is free software; you can redistribute it and/or modify
5699+ * it under the terms of the GNU General Public License as published by
5700+ * the Free Software Foundation; either version 2 of the License, or
5701+ * (at your option) any later version.
dece6358
AM
5702+ *
5703+ * This program is distributed in the hope that it will be useful,
5704+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5705+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5706+ * GNU General Public License for more details.
5707+ *
5708+ * You should have received a copy of the GNU General Public License
5709+ * along with this program; if not, write to the Free Software
5710+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 5711+ */
5712+
5713+/*
5714+ * debug print functions
5715+ */
5716+
7f207e10 5717+#include <linux/vt_kern.h>
1facf9fc 5718+#include "aufs.h"
5719+
392086de
AM
5720+/* Returns 0, or -errno. arg is in kp->arg. */
5721+static int param_atomic_t_set(const char *val, const struct kernel_param *kp)
5722+{
5723+ int err, n;
5724+
5725+ err = kstrtoint(val, 0, &n);
5726+ if (!err) {
5727+ if (n > 0)
5728+ au_debug_on();
5729+ else
5730+ au_debug_off();
5731+ }
5732+ return err;
5733+}
5734+
5735+/* Returns length written or -errno. Buffer is 4k (ie. be short!) */
5736+static int param_atomic_t_get(char *buffer, const struct kernel_param *kp)
5737+{
5738+ atomic_t *a;
5739+
5740+ a = kp->arg;
5741+ return sprintf(buffer, "%d", atomic_read(a));
5742+}
5743+
5744+static struct kernel_param_ops param_ops_atomic_t = {
5745+ .set = param_atomic_t_set,
5746+ .get = param_atomic_t_get
5747+ /* void (*free)(void *arg) */
5748+};
5749+
5750+atomic_t aufs_debug = ATOMIC_INIT(0);
1facf9fc 5751+MODULE_PARM_DESC(debug, "debug print");
392086de 5752+module_param_named(debug, aufs_debug, atomic_t, S_IRUGO | S_IWUSR | S_IWGRP);
1facf9fc 5753+
5754+char *au_plevel = KERN_DEBUG;
e49829fe
JR
5755+#define dpri(fmt, ...) do { \
5756+ if ((au_plevel \
5757+ && strcmp(au_plevel, KERN_DEBUG)) \
5758+ || au_debug_test()) \
5759+ printk("%s" fmt, au_plevel, ##__VA_ARGS__); \
1facf9fc 5760+} while (0)
5761+
5762+/* ---------------------------------------------------------------------- */
5763+
5764+void au_dpri_whlist(struct au_nhash *whlist)
5765+{
5766+ unsigned long ul, n;
5767+ struct hlist_head *head;
c06a8ce3 5768+ struct au_vdir_wh *pos;
1facf9fc 5769+
5770+ n = whlist->nh_num;
5771+ head = whlist->nh_head;
5772+ for (ul = 0; ul < n; ul++) {
c06a8ce3 5773+ hlist_for_each_entry(pos, head, wh_hash)
1facf9fc 5774+ dpri("b%d, %.*s, %d\n",
c06a8ce3
AM
5775+ pos->wh_bindex,
5776+ pos->wh_str.len, pos->wh_str.name,
5777+ pos->wh_str.len);
1facf9fc 5778+ head++;
5779+ }
5780+}
5781+
5782+void au_dpri_vdir(struct au_vdir *vdir)
5783+{
5784+ unsigned long ul;
5785+ union au_vdir_deblk_p p;
5786+ unsigned char *o;
5787+
5788+ if (!vdir || IS_ERR(vdir)) {
5789+ dpri("err %ld\n", PTR_ERR(vdir));
5790+ return;
5791+ }
5792+
5793+ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n",
5794+ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
5795+ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
5796+ for (ul = 0; ul < vdir->vd_nblk; ul++) {
5797+ p.deblk = vdir->vd_deblk[ul];
5798+ o = p.deblk;
5799+ dpri("[%lu]: %p\n", ul, o);
5800+ }
5801+}
5802+
53392da6 5803+static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn,
1facf9fc 5804+ struct dentry *wh)
5805+{
5806+ char *n = NULL;
5807+ int l = 0;
5808+
5809+ if (!inode || IS_ERR(inode)) {
5810+ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
5811+ return -1;
5812+ }
5813+
c2b27bf2 5814+ /* the type of i_blocks depends upon CONFIG_LBDAF */
1facf9fc 5815+ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
5816+ && sizeof(inode->i_blocks) != sizeof(u64));
5817+ if (wh) {
5818+ n = (void *)wh->d_name.name;
5819+ l = wh->d_name.len;
5820+ }
5821+
53392da6
AM
5822+ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
5823+ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
5824+ bindex, inode,
1facf9fc 5825+ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
5826+ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
5827+ i_size_read(inode), (unsigned long long)inode->i_blocks,
53392da6 5828+ hn, (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
1facf9fc 5829+ inode->i_mapping ? inode->i_mapping->nrpages : 0,
b752ccd1
AM
5830+ inode->i_state, inode->i_flags, inode->i_version,
5831+ inode->i_generation,
1facf9fc 5832+ l ? ", wh " : "", l, n);
5833+ return 0;
5834+}
5835+
5836+void au_dpri_inode(struct inode *inode)
5837+{
5838+ struct au_iinfo *iinfo;
5839+ aufs_bindex_t bindex;
53392da6 5840+ int err, hn;
1facf9fc 5841+
53392da6 5842+ err = do_pri_inode(-1, inode, -1, NULL);
1facf9fc 5843+ if (err || !au_test_aufs(inode->i_sb))
5844+ return;
5845+
5846+ iinfo = au_ii(inode);
5847+ if (!iinfo)
5848+ return;
5849+ dpri("i-1: bstart %d, bend %d, gen %d\n",
537831f9 5850+ iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode, NULL));
1facf9fc 5851+ if (iinfo->ii_bstart < 0)
5852+ return;
53392da6
AM
5853+ hn = 0;
5854+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++) {
5855+ hn = !!au_hn(iinfo->ii_hinode + bindex);
5856+ do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode, hn,
1facf9fc 5857+ iinfo->ii_hinode[0 + bindex].hi_whdentry);
53392da6 5858+ }
1facf9fc 5859+}
5860+
2cbb1c4b
JR
5861+void au_dpri_dalias(struct inode *inode)
5862+{
5863+ struct dentry *d;
5864+
5865+ spin_lock(&inode->i_lock);
c06a8ce3 5866+ hlist_for_each_entry(d, &inode->i_dentry, d_alias)
2cbb1c4b
JR
5867+ au_dpri_dentry(d);
5868+ spin_unlock(&inode->i_lock);
5869+}
5870+
1facf9fc 5871+static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
5872+{
5873+ struct dentry *wh = NULL;
53392da6 5874+ int hn;
1facf9fc 5875+
5876+ if (!dentry || IS_ERR(dentry)) {
5877+ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
5878+ return -1;
5879+ }
5880+ /* do not call dget_parent() here */
027c5e7a 5881+ /* note: access d_xxx without d_lock */
1facf9fc 5882+ dpri("d%d: %.*s?/%.*s, %s, cnt %d, flags 0x%x\n",
5883+ bindex,
5884+ AuDLNPair(dentry->d_parent), AuDLNPair(dentry),
5885+ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
392086de 5886+ d_count(dentry), dentry->d_flags);
53392da6 5887+ hn = -1;
1facf9fc 5888+ if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) {
5889+ struct au_iinfo *iinfo = au_ii(dentry->d_inode);
53392da6
AM
5890+ if (iinfo) {
5891+ hn = !!au_hn(iinfo->ii_hinode + bindex);
1facf9fc 5892+ wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
53392da6 5893+ }
1facf9fc 5894+ }
53392da6 5895+ do_pri_inode(bindex, dentry->d_inode, hn, wh);
1facf9fc 5896+ return 0;
5897+}
5898+
5899+void au_dpri_dentry(struct dentry *dentry)
5900+{
5901+ struct au_dinfo *dinfo;
5902+ aufs_bindex_t bindex;
5903+ int err;
4a4d8108 5904+ struct au_hdentry *hdp;
1facf9fc 5905+
5906+ err = do_pri_dentry(-1, dentry);
5907+ if (err || !au_test_aufs(dentry->d_sb))
5908+ return;
5909+
5910+ dinfo = au_di(dentry);
5911+ if (!dinfo)
5912+ return;
5913+ dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d\n",
5914+ dinfo->di_bstart, dinfo->di_bend,
5915+ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry));
5916+ if (dinfo->di_bstart < 0)
5917+ return;
4a4d8108 5918+ hdp = dinfo->di_hdentry;
1facf9fc 5919+ for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++)
4a4d8108 5920+ do_pri_dentry(bindex, hdp[0 + bindex].hd_dentry);
1facf9fc 5921+}
5922+
5923+static int do_pri_file(aufs_bindex_t bindex, struct file *file)
5924+{
5925+ char a[32];
5926+
5927+ if (!file || IS_ERR(file)) {
5928+ dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
5929+ return -1;
5930+ }
5931+ a[0] = 0;
5932+ if (bindex < 0
5933+ && file->f_dentry
5934+ && au_test_aufs(file->f_dentry->d_sb)
5935+ && au_fi(file))
e49829fe 5936+ snprintf(a, sizeof(a), ", gen %d, mmapped %d",
2cbb1c4b 5937+ au_figen(file), atomic_read(&au_fi(file)->fi_mmapped));
b752ccd1 5938+ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
1facf9fc 5939+ bindex, file->f_mode, file->f_flags, (long)file_count(file),
b752ccd1 5940+ file->f_version, file->f_pos, a);
1facf9fc 5941+ if (file->f_dentry)
5942+ do_pri_dentry(bindex, file->f_dentry);
5943+ return 0;
5944+}
5945+
5946+void au_dpri_file(struct file *file)
5947+{
5948+ struct au_finfo *finfo;
4a4d8108
AM
5949+ struct au_fidir *fidir;
5950+ struct au_hfile *hfile;
1facf9fc 5951+ aufs_bindex_t bindex;
5952+ int err;
5953+
5954+ err = do_pri_file(-1, file);
5955+ if (err || !file->f_dentry || !au_test_aufs(file->f_dentry->d_sb))
5956+ return;
5957+
5958+ finfo = au_fi(file);
5959+ if (!finfo)
5960+ return;
4a4d8108 5961+ if (finfo->fi_btop < 0)
1facf9fc 5962+ return;
4a4d8108
AM
5963+ fidir = finfo->fi_hdir;
5964+ if (!fidir)
5965+ do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
5966+ else
e49829fe
JR
5967+ for (bindex = finfo->fi_btop;
5968+ bindex >= 0 && bindex <= fidir->fd_bbot;
4a4d8108
AM
5969+ bindex++) {
5970+ hfile = fidir->fd_hfile + bindex;
5971+ do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
5972+ }
1facf9fc 5973+}
5974+
5975+static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
5976+{
5977+ struct vfsmount *mnt;
5978+ struct super_block *sb;
5979+
5980+ if (!br || IS_ERR(br))
5981+ goto out;
86dc4139 5982+ mnt = au_br_mnt(br);
1facf9fc 5983+ if (!mnt || IS_ERR(mnt))
5984+ goto out;
5985+ sb = mnt->mnt_sb;
5986+ if (!sb || IS_ERR(sb))
5987+ goto out;
5988+
1e00d052 5989+ dpri("s%d: {perm 0x%x, id %d, cnt %d, wbr %p}, "
b752ccd1 5990+ "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
1facf9fc 5991+ "xino %d\n",
1e00d052
AM
5992+ bindex, br->br_perm, br->br_id, atomic_read(&br->br_count),
5993+ br->br_wbr, au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
b752ccd1 5994+ sb->s_flags, sb->s_count,
1facf9fc 5995+ atomic_read(&sb->s_active), !!br->br_xino.xi_file);
5996+ return 0;
5997+
4f0767ce 5998+out:
1facf9fc 5999+ dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
6000+ return -1;
6001+}
6002+
6003+void au_dpri_sb(struct super_block *sb)
6004+{
6005+ struct au_sbinfo *sbinfo;
6006+ aufs_bindex_t bindex;
6007+ int err;
6008+ /* to reuduce stack size */
6009+ struct {
6010+ struct vfsmount mnt;
6011+ struct au_branch fake;
6012+ } *a;
6013+
6014+ /* this function can be called from magic sysrq */
6015+ a = kzalloc(sizeof(*a), GFP_ATOMIC);
6016+ if (unlikely(!a)) {
6017+ dpri("no memory\n");
6018+ return;
6019+ }
6020+
6021+ a->mnt.mnt_sb = sb;
6022+ a->fake.br_perm = 0;
86dc4139 6023+ a->fake.br_path.mnt = &a->mnt;
1facf9fc 6024+ a->fake.br_xino.xi_file = NULL;
6025+ atomic_set(&a->fake.br_count, 0);
6026+ smp_mb(); /* atomic_set */
6027+ err = do_pri_br(-1, &a->fake);
6028+ kfree(a);
6029+ dpri("dev 0x%x\n", sb->s_dev);
6030+ if (err || !au_test_aufs(sb))
6031+ return;
6032+
6033+ sbinfo = au_sbi(sb);
6034+ if (!sbinfo)
6035+ return;
6036+ dpri("nw %d, gen %u, kobj %d\n",
6037+ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
6038+ atomic_read(&sbinfo->si_kobj.kref.refcount));
6039+ for (bindex = 0; bindex <= sbinfo->si_bend; bindex++)
6040+ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
6041+}
6042+
6043+/* ---------------------------------------------------------------------- */
6044+
6045+void au_dbg_sleep_jiffy(int jiffy)
6046+{
6047+ while (jiffy)
6048+ jiffy = schedule_timeout_uninterruptible(jiffy);
6049+}
6050+
6051+void au_dbg_iattr(struct iattr *ia)
6052+{
c06a8ce3
AM
6053+#define AuBit(name) \
6054+ do { \
6055+ if (ia->ia_valid & ATTR_ ## name) \
6056+ dpri(#name "\n"); \
6057+ } while (0)
1facf9fc 6058+ AuBit(MODE);
6059+ AuBit(UID);
6060+ AuBit(GID);
6061+ AuBit(SIZE);
6062+ AuBit(ATIME);
6063+ AuBit(MTIME);
6064+ AuBit(CTIME);
6065+ AuBit(ATIME_SET);
6066+ AuBit(MTIME_SET);
6067+ AuBit(FORCE);
6068+ AuBit(ATTR_FLAG);
6069+ AuBit(KILL_SUID);
6070+ AuBit(KILL_SGID);
6071+ AuBit(FILE);
6072+ AuBit(KILL_PRIV);
6073+ AuBit(OPEN);
6074+ AuBit(TIMES_SET);
6075+#undef AuBit
6076+ dpri("ia_file %p\n", ia->ia_file);
6077+}
6078+
6079+/* ---------------------------------------------------------------------- */
6080+
027c5e7a
AM
6081+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
6082+{
6083+ struct inode *h_inode, *inode = dentry->d_inode;
6084+ struct dentry *h_dentry;
6085+ aufs_bindex_t bindex, bend, bi;
6086+
6087+ if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */)
6088+ return;
6089+
6090+ bend = au_dbend(dentry);
6091+ bi = au_ibend(inode);
6092+ if (bi < bend)
6093+ bend = bi;
6094+ bindex = au_dbstart(dentry);
6095+ bi = au_ibstart(inode);
6096+ if (bi > bindex)
6097+ bindex = bi;
6098+
6099+ for (; bindex <= bend; bindex++) {
6100+ h_dentry = au_h_dptr(dentry, bindex);
6101+ if (!h_dentry)
6102+ continue;
6103+ h_inode = au_h_iptr(inode, bindex);
6104+ if (unlikely(h_inode != h_dentry->d_inode)) {
392086de 6105+ au_debug_on();
027c5e7a
AM
6106+ AuDbg("b%d, %s:%d\n", bindex, func, line);
6107+ AuDbgDentry(dentry);
6108+ AuDbgInode(inode);
392086de 6109+ au_debug_off();
027c5e7a
AM
6110+ BUG();
6111+ }
6112+ }
6113+}
6114+
1facf9fc 6115+void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen)
6116+{
6117+ struct dentry *parent;
6118+
6119+ parent = dget_parent(dentry);
027c5e7a
AM
6120+ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
6121+ AuDebugOn(IS_ROOT(dentry));
6122+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 6123+ dput(parent);
6124+}
6125+
6126+void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen)
6127+{
6128+ struct dentry *parent;
027c5e7a 6129+ struct inode *inode;
1facf9fc 6130+
6131+ parent = dget_parent(dentry);
027c5e7a
AM
6132+ inode = dentry->d_inode;
6133+ AuDebugOn(inode && S_ISDIR(dentry->d_inode->i_mode));
6134+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 6135+ dput(parent);
6136+}
6137+
6138+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
6139+{
6140+ int err, i, j;
6141+ struct au_dcsub_pages dpages;
6142+ struct au_dpage *dpage;
6143+ struct dentry **dentries;
6144+
6145+ err = au_dpages_init(&dpages, GFP_NOFS);
6146+ AuDebugOn(err);
027c5e7a 6147+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
1facf9fc 6148+ AuDebugOn(err);
6149+ for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
6150+ dpage = dpages.dpages + i;
6151+ dentries = dpage->dentries;
6152+ for (j = dpage->ndentry - 1; !err && j >= 0; j--)
027c5e7a 6153+ AuDebugOn(au_digen_test(dentries[j], sigen));
1facf9fc 6154+ }
6155+ au_dpages_free(&dpages);
6156+}
6157+
1facf9fc 6158+void au_dbg_verify_kthread(void)
6159+{
53392da6 6160+ if (au_wkq_test()) {
1facf9fc 6161+ au_dbg_blocked();
1e00d052
AM
6162+ /*
6163+ * It may be recursive, but udba=notify between two aufs mounts,
6164+ * where a single ro branch is shared, is not a problem.
6165+ */
6166+ /* WARN_ON(1); */
1facf9fc 6167+ }
6168+}
6169+
6170+/* ---------------------------------------------------------------------- */
6171+
6172+void au_debug_sbinfo_init(struct au_sbinfo *sbinfo __maybe_unused)
6173+{
6174+#ifdef AuForceNoPlink
6175+ au_opt_clr(sbinfo->si_mntflags, PLINK);
6176+#endif
6177+#ifdef AuForceNoXino
6178+ au_opt_clr(sbinfo->si_mntflags, XINO);
6179+#endif
6180+#ifdef AuForceNoRefrof
6181+ au_opt_clr(sbinfo->si_mntflags, REFROF);
6182+#endif
4a4d8108
AM
6183+#ifdef AuForceHnotify
6184+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_HNOTIFY);
1facf9fc 6185+#endif
1308ab2a 6186+#ifdef AuForceRd0
6187+ sbinfo->si_rdblk = 0;
6188+ sbinfo->si_rdhash = 0;
6189+#endif
1facf9fc 6190+}
6191+
6192+int __init au_debug_init(void)
6193+{
6194+ aufs_bindex_t bindex;
6195+ struct au_vdir_destr destr;
6196+
6197+ bindex = -1;
6198+ AuDebugOn(bindex >= 0);
6199+
6200+ destr.len = -1;
6201+ AuDebugOn(destr.len < NAME_MAX);
6202+
6203+#ifdef CONFIG_4KSTACKS
0c3ec466 6204+ pr_warn("CONFIG_4KSTACKS is defined.\n");
1facf9fc 6205+#endif
6206+
6207+#ifdef AuForceNoBrs
6208+ sysaufs_brs = 0;
6209+#endif
6210+
6211+ return 0;
6212+}
7f207e10
AM
6213diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
6214--- /usr/share/empty/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100
392086de
AM
6215+++ linux/fs/aufs/debug.h 2013-10-26 16:51:32.273040419 +0200
6216@@ -0,0 +1,249 @@
1facf9fc 6217+/*
7a9e40b8 6218+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 6219+ *
6220+ * This program, aufs is free software; you can redistribute it and/or modify
6221+ * it under the terms of the GNU General Public License as published by
6222+ * the Free Software Foundation; either version 2 of the License, or
6223+ * (at your option) any later version.
dece6358
AM
6224+ *
6225+ * This program is distributed in the hope that it will be useful,
6226+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6227+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6228+ * GNU General Public License for more details.
6229+ *
6230+ * You should have received a copy of the GNU General Public License
6231+ * along with this program; if not, write to the Free Software
6232+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 6233+ */
6234+
6235+/*
6236+ * debug print functions
6237+ */
6238+
6239+#ifndef __AUFS_DEBUG_H__
6240+#define __AUFS_DEBUG_H__
6241+
6242+#ifdef __KERNEL__
6243+
392086de 6244+#include <linux/atomic.h>
4a4d8108
AM
6245+#include <linux/module.h>
6246+#include <linux/kallsyms.h>
1facf9fc 6247+#include <linux/sysrq.h>
4a4d8108 6248+
1facf9fc 6249+#ifdef CONFIG_AUFS_DEBUG
6250+#define AuDebugOn(a) BUG_ON(a)
6251+
6252+/* module parameter */
392086de
AM
6253+extern atomic_t aufs_debug;
6254+static inline void au_debug_on(void)
1facf9fc 6255+{
392086de
AM
6256+ atomic_inc(&aufs_debug);
6257+}
6258+static inline void au_debug_off(void)
6259+{
6260+ atomic_dec_if_positive(&aufs_debug);
1facf9fc 6261+}
6262+
6263+static inline int au_debug_test(void)
6264+{
392086de 6265+ return atomic_read(&aufs_debug) > 0;
1facf9fc 6266+}
6267+#else
6268+#define AuDebugOn(a) do {} while (0)
392086de
AM
6269+AuStubVoid(au_debug_on, void)
6270+AuStubVoid(au_debug_off, void)
4a4d8108 6271+AuStubInt0(au_debug_test, void)
1facf9fc 6272+#endif /* CONFIG_AUFS_DEBUG */
6273+
392086de
AM
6274+#define param_check_atomic_t(name, p) __param_check(name, p, atomic_t)
6275+
1facf9fc 6276+/* ---------------------------------------------------------------------- */
6277+
6278+/* debug print */
6279+
4a4d8108 6280+#define AuDbg(fmt, ...) do { \
1facf9fc 6281+ if (au_debug_test()) \
4a4d8108 6282+ pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
1facf9fc 6283+} while (0)
4a4d8108
AM
6284+#define AuLabel(l) AuDbg(#l "\n")
6285+#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__)
6286+#define AuWarn1(fmt, ...) do { \
1facf9fc 6287+ static unsigned char _c; \
6288+ if (!_c++) \
0c3ec466 6289+ pr_warn(fmt, ##__VA_ARGS__); \
1facf9fc 6290+} while (0)
6291+
4a4d8108 6292+#define AuErr1(fmt, ...) do { \
1facf9fc 6293+ static unsigned char _c; \
6294+ if (!_c++) \
4a4d8108 6295+ pr_err(fmt, ##__VA_ARGS__); \
1facf9fc 6296+} while (0)
6297+
4a4d8108 6298+#define AuIOErr1(fmt, ...) do { \
1facf9fc 6299+ static unsigned char _c; \
6300+ if (!_c++) \
4a4d8108 6301+ AuIOErr(fmt, ##__VA_ARGS__); \
1facf9fc 6302+} while (0)
6303+
6304+#define AuUnsupportMsg "This operation is not supported." \
6305+ " Please report this application to aufs-users ML."
4a4d8108
AM
6306+#define AuUnsupport(fmt, ...) do { \
6307+ pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
1facf9fc 6308+ dump_stack(); \
6309+} while (0)
6310+
6311+#define AuTraceErr(e) do { \
6312+ if (unlikely((e) < 0)) \
6313+ AuDbg("err %d\n", (int)(e)); \
6314+} while (0)
6315+
6316+#define AuTraceErrPtr(p) do { \
6317+ if (IS_ERR(p)) \
6318+ AuDbg("err %ld\n", PTR_ERR(p)); \
6319+} while (0)
6320+
6321+/* dirty macros for debug print, use with "%.*s" and caution */
6322+#define AuLNPair(qstr) (qstr)->len, (qstr)->name
6323+#define AuDLNPair(d) AuLNPair(&(d)->d_name)
6324+
6325+/* ---------------------------------------------------------------------- */
6326+
6327+struct au_sbinfo;
6328+struct au_finfo;
dece6358 6329+struct dentry;
1facf9fc 6330+#ifdef CONFIG_AUFS_DEBUG
6331+extern char *au_plevel;
6332+struct au_nhash;
6333+void au_dpri_whlist(struct au_nhash *whlist);
6334+struct au_vdir;
6335+void au_dpri_vdir(struct au_vdir *vdir);
dece6358 6336+struct inode;
1facf9fc 6337+void au_dpri_inode(struct inode *inode);
2cbb1c4b 6338+void au_dpri_dalias(struct inode *inode);
1facf9fc 6339+void au_dpri_dentry(struct dentry *dentry);
dece6358 6340+struct file;
1facf9fc 6341+void au_dpri_file(struct file *filp);
dece6358 6342+struct super_block;
1facf9fc 6343+void au_dpri_sb(struct super_block *sb);
6344+
6345+void au_dbg_sleep_jiffy(int jiffy);
dece6358 6346+struct iattr;
1facf9fc 6347+void au_dbg_iattr(struct iattr *ia);
6348+
027c5e7a
AM
6349+#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__)
6350+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line);
1facf9fc 6351+void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen);
6352+void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen);
6353+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
1facf9fc 6354+void au_dbg_verify_kthread(void);
6355+
6356+int __init au_debug_init(void);
6357+void au_debug_sbinfo_init(struct au_sbinfo *sbinfo);
6358+#define AuDbgWhlist(w) do { \
6359+ AuDbg(#w "\n"); \
6360+ au_dpri_whlist(w); \
6361+} while (0)
6362+
6363+#define AuDbgVdir(v) do { \
6364+ AuDbg(#v "\n"); \
6365+ au_dpri_vdir(v); \
6366+} while (0)
6367+
6368+#define AuDbgInode(i) do { \
6369+ AuDbg(#i "\n"); \
6370+ au_dpri_inode(i); \
6371+} while (0)
6372+
2cbb1c4b
JR
6373+#define AuDbgDAlias(i) do { \
6374+ AuDbg(#i "\n"); \
6375+ au_dpri_dalias(i); \
6376+} while (0)
6377+
1facf9fc 6378+#define AuDbgDentry(d) do { \
6379+ AuDbg(#d "\n"); \
6380+ au_dpri_dentry(d); \
6381+} while (0)
6382+
6383+#define AuDbgFile(f) do { \
6384+ AuDbg(#f "\n"); \
6385+ au_dpri_file(f); \
6386+} while (0)
6387+
6388+#define AuDbgSb(sb) do { \
6389+ AuDbg(#sb "\n"); \
6390+ au_dpri_sb(sb); \
6391+} while (0)
6392+
6393+#define AuDbgSleep(sec) do { \
6394+ AuDbg("sleep %d sec\n", sec); \
6395+ ssleep(sec); \
6396+} while (0)
6397+
6398+#define AuDbgSleepJiffy(jiffy) do { \
6399+ AuDbg("sleep %d jiffies\n", jiffy); \
6400+ au_dbg_sleep_jiffy(jiffy); \
6401+} while (0)
6402+
6403+#define AuDbgIAttr(ia) do { \
6404+ AuDbg("ia_valid 0x%x\n", (ia)->ia_valid); \
6405+ au_dbg_iattr(ia); \
6406+} while (0)
4a4d8108
AM
6407+
6408+#define AuDbgSym(addr) do { \
6409+ char sym[KSYM_SYMBOL_LEN]; \
6410+ sprint_symbol(sym, (unsigned long)addr); \
6411+ AuDbg("%s\n", sym); \
6412+} while (0)
6413+
6414+#define AuInfoSym(addr) do { \
6415+ char sym[KSYM_SYMBOL_LEN]; \
6416+ sprint_symbol(sym, (unsigned long)addr); \
6417+ AuInfo("%s\n", sym); \
6418+} while (0)
1facf9fc 6419+#else
027c5e7a 6420+AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
4a4d8108
AM
6421+AuStubVoid(au_dbg_verify_dir_parent, struct dentry *dentry, unsigned int sigen)
6422+AuStubVoid(au_dbg_verify_nondir_parent, struct dentry *dentry,
6423+ unsigned int sigen)
6424+AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
6425+AuStubVoid(au_dbg_verify_kthread, void)
6426+AuStubInt0(__init au_debug_init, void)
6427+AuStubVoid(au_debug_sbinfo_init, struct au_sbinfo *sbinfo)
1facf9fc 6428+
1facf9fc 6429+#define AuDbgWhlist(w) do {} while (0)
6430+#define AuDbgVdir(v) do {} while (0)
6431+#define AuDbgInode(i) do {} while (0)
2cbb1c4b 6432+#define AuDbgDAlias(i) do {} while (0)
1facf9fc 6433+#define AuDbgDentry(d) do {} while (0)
6434+#define AuDbgFile(f) do {} while (0)
6435+#define AuDbgSb(sb) do {} while (0)
6436+#define AuDbgSleep(sec) do {} while (0)
6437+#define AuDbgSleepJiffy(jiffy) do {} while (0)
6438+#define AuDbgIAttr(ia) do {} while (0)
4a4d8108
AM
6439+#define AuDbgSym(addr) do {} while (0)
6440+#define AuInfoSym(addr) do {} while (0)
1facf9fc 6441+#endif /* CONFIG_AUFS_DEBUG */
6442+
6443+/* ---------------------------------------------------------------------- */
6444+
6445+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
6446+int __init au_sysrq_init(void);
6447+void au_sysrq_fin(void);
6448+
6449+#ifdef CONFIG_HW_CONSOLE
6450+#define au_dbg_blocked() do { \
6451+ WARN_ON(1); \
0c5527e5 6452+ handle_sysrq('w'); \
1facf9fc 6453+} while (0)
6454+#else
4a4d8108 6455+AuStubVoid(au_dbg_blocked, void)
1facf9fc 6456+#endif
6457+
6458+#else
4a4d8108
AM
6459+AuStubInt0(__init au_sysrq_init, void)
6460+AuStubVoid(au_sysrq_fin, void)
6461+AuStubVoid(au_dbg_blocked, void)
1facf9fc 6462+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
6463+
6464+#endif /* __KERNEL__ */
6465+#endif /* __AUFS_DEBUG_H__ */
7f207e10
AM
6466diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
6467--- /usr/share/empty/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100
86dc4139
AM
6468+++ linux/fs/aufs/dentry.c 2013-07-06 13:20:47.740198107 +0200
6469@@ -0,0 +1,1065 @@
1facf9fc 6470+/*
7a9e40b8 6471+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 6472+ *
6473+ * This program, aufs is free software; you can redistribute it and/or modify
6474+ * it under the terms of the GNU General Public License as published by
6475+ * the Free Software Foundation; either version 2 of the License, or
6476+ * (at your option) any later version.
dece6358
AM
6477+ *
6478+ * This program is distributed in the hope that it will be useful,
6479+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6480+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6481+ * GNU General Public License for more details.
6482+ *
6483+ * You should have received a copy of the GNU General Public License
6484+ * along with this program; if not, write to the Free Software
6485+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 6486+ */
6487+
6488+/*
6489+ * lookup and dentry operations
6490+ */
6491+
dece6358 6492+#include <linux/namei.h>
1facf9fc 6493+#include "aufs.h"
6494+
1facf9fc 6495+#define AuLkup_ALLOW_NEG 1
6496+#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name)
7f207e10
AM
6497+#define au_fset_lkup(flags, name) \
6498+ do { (flags) |= AuLkup_##name; } while (0)
6499+#define au_fclr_lkup(flags, name) \
6500+ do { (flags) &= ~AuLkup_##name; } while (0)
1facf9fc 6501+
6502+struct au_do_lookup_args {
6503+ unsigned int flags;
6504+ mode_t type;
1facf9fc 6505+};
6506+
6507+/*
6508+ * returns positive/negative dentry, NULL or an error.
6509+ * NULL means whiteout-ed or not-found.
6510+ */
6511+static struct dentry*
6512+au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
6513+ aufs_bindex_t bindex, struct qstr *wh_name,
6514+ struct au_do_lookup_args *args)
6515+{
6516+ struct dentry *h_dentry;
6517+ struct inode *h_inode, *inode;
1facf9fc 6518+ struct au_branch *br;
6519+ int wh_found, opq;
6520+ unsigned char wh_able;
6521+ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
6522+
1facf9fc 6523+ wh_found = 0;
6524+ br = au_sbr(dentry->d_sb, bindex);
6525+ wh_able = !!au_br_whable(br->br_perm);
6526+ if (wh_able)
6527+ wh_found = au_wh_test(h_parent, wh_name, br, /*try_sio*/0);
6528+ h_dentry = ERR_PTR(wh_found);
6529+ if (!wh_found)
6530+ goto real_lookup;
6531+ if (unlikely(wh_found < 0))
6532+ goto out;
6533+
6534+ /* We found a whiteout */
6535+ /* au_set_dbend(dentry, bindex); */
6536+ au_set_dbwh(dentry, bindex);
6537+ if (!allow_neg)
6538+ return NULL; /* success */
6539+
4f0767ce 6540+real_lookup:
b4510431 6541+ h_dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
1facf9fc 6542+ if (IS_ERR(h_dentry))
6543+ goto out;
6544+
6545+ h_inode = h_dentry->d_inode;
6546+ if (!h_inode) {
6547+ if (!allow_neg)
6548+ goto out_neg;
6549+ } else if (wh_found
6550+ || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
6551+ goto out_neg;
6552+
6553+ if (au_dbend(dentry) <= bindex)
6554+ au_set_dbend(dentry, bindex);
6555+ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
6556+ au_set_dbstart(dentry, bindex);
6557+ au_set_h_dptr(dentry, bindex, h_dentry);
6558+
6559+ inode = dentry->d_inode;
6560+ if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able
6561+ || (inode && !S_ISDIR(inode->i_mode)))
6562+ goto out; /* success */
6563+
6564+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
6565+ opq = au_diropq_test(h_dentry, br);
6566+ mutex_unlock(&h_inode->i_mutex);
6567+ if (opq > 0)
6568+ au_set_dbdiropq(dentry, bindex);
6569+ else if (unlikely(opq < 0)) {
6570+ au_set_h_dptr(dentry, bindex, NULL);
6571+ h_dentry = ERR_PTR(opq);
6572+ }
6573+ goto out;
6574+
4f0767ce 6575+out_neg:
1facf9fc 6576+ dput(h_dentry);
6577+ h_dentry = NULL;
4f0767ce 6578+out:
1facf9fc 6579+ return h_dentry;
6580+}
6581+
dece6358
AM
6582+static int au_test_shwh(struct super_block *sb, const struct qstr *name)
6583+{
6584+ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
6585+ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
6586+ return -EPERM;
6587+ return 0;
6588+}
6589+
1facf9fc 6590+/*
6591+ * returns the number of lower positive dentries,
6592+ * otherwise an error.
6593+ * can be called at unlinking with @type is zero.
6594+ */
537831f9 6595+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type)
1facf9fc 6596+{
6597+ int npositive, err;
6598+ aufs_bindex_t bindex, btail, bdiropq;
6599+ unsigned char isdir;
6600+ struct qstr whname;
6601+ struct au_do_lookup_args args = {
b4510431 6602+ .flags = 0,
537831f9 6603+ .type = type
1facf9fc 6604+ };
6605+ const struct qstr *name = &dentry->d_name;
6606+ struct dentry *parent;
6607+ struct inode *inode;
6608+
dece6358
AM
6609+ err = au_test_shwh(dentry->d_sb, name);
6610+ if (unlikely(err))
1facf9fc 6611+ goto out;
6612+
6613+ err = au_wh_name_alloc(&whname, name);
6614+ if (unlikely(err))
6615+ goto out;
6616+
6617+ inode = dentry->d_inode;
6618+ isdir = !!(inode && S_ISDIR(inode->i_mode));
6619+ if (!type)
6620+ au_fset_lkup(args.flags, ALLOW_NEG);
6621+
6622+ npositive = 0;
4a4d8108 6623+ parent = dget_parent(dentry);
1facf9fc 6624+ btail = au_dbtaildir(parent);
6625+ for (bindex = bstart; bindex <= btail; bindex++) {
6626+ struct dentry *h_parent, *h_dentry;
6627+ struct inode *h_inode, *h_dir;
6628+
6629+ h_dentry = au_h_dptr(dentry, bindex);
6630+ if (h_dentry) {
6631+ if (h_dentry->d_inode)
6632+ npositive++;
6633+ if (type != S_IFDIR)
6634+ break;
6635+ continue;
6636+ }
6637+ h_parent = au_h_dptr(parent, bindex);
6638+ if (!h_parent)
6639+ continue;
6640+ h_dir = h_parent->d_inode;
6641+ if (!h_dir || !S_ISDIR(h_dir->i_mode))
6642+ continue;
6643+
6644+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
6645+ h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
6646+ &args);
6647+ mutex_unlock(&h_dir->i_mutex);
6648+ err = PTR_ERR(h_dentry);
6649+ if (IS_ERR(h_dentry))
4a4d8108 6650+ goto out_parent;
1facf9fc 6651+ au_fclr_lkup(args.flags, ALLOW_NEG);
6652+
6653+ if (au_dbwh(dentry) >= 0)
6654+ break;
6655+ if (!h_dentry)
6656+ continue;
6657+ h_inode = h_dentry->d_inode;
6658+ if (!h_inode)
6659+ continue;
6660+ npositive++;
6661+ if (!args.type)
6662+ args.type = h_inode->i_mode & S_IFMT;
6663+ if (args.type != S_IFDIR)
6664+ break;
6665+ else if (isdir) {
6666+ /* the type of lower may be different */
6667+ bdiropq = au_dbdiropq(dentry);
6668+ if (bdiropq >= 0 && bdiropq <= bindex)
6669+ break;
6670+ }
6671+ }
6672+
6673+ if (npositive) {
6674+ AuLabel(positive);
6675+ au_update_dbstart(dentry);
6676+ }
6677+ err = npositive;
6678+ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
027c5e7a 6679+ && au_dbstart(dentry) < 0)) {
1facf9fc 6680+ err = -EIO;
027c5e7a
AM
6681+ AuIOErr("both of real entry and whiteout found, %.*s, err %d\n",
6682+ AuDLNPair(dentry), err);
6683+ }
1facf9fc 6684+
4f0767ce 6685+out_parent:
4a4d8108 6686+ dput(parent);
1facf9fc 6687+ kfree(whname.name);
4f0767ce 6688+out:
1facf9fc 6689+ return err;
6690+}
6691+
6692+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
6693+ struct au_branch *br)
6694+{
6695+ struct dentry *dentry;
6696+ int wkq_err;
6697+
6698+ if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC))
b4510431 6699+ dentry = vfsub_lkup_one(name, parent);
1facf9fc 6700+ else {
b4510431
AM
6701+ struct vfsub_lkup_one_args args = {
6702+ .errp = &dentry,
6703+ .name = name,
6704+ .parent = parent
1facf9fc 6705+ };
6706+
b4510431 6707+ wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args);
1facf9fc 6708+ if (unlikely(wkq_err))
6709+ dentry = ERR_PTR(wkq_err);
6710+ }
6711+
6712+ return dentry;
6713+}
6714+
6715+/*
6716+ * lookup @dentry on @bindex which should be negative.
6717+ */
86dc4139 6718+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh)
1facf9fc 6719+{
6720+ int err;
6721+ struct dentry *parent, *h_parent, *h_dentry;
86dc4139 6722+ struct au_branch *br;
1facf9fc 6723+
1facf9fc 6724+ parent = dget_parent(dentry);
6725+ h_parent = au_h_dptr(parent, bindex);
86dc4139
AM
6726+ br = au_sbr(dentry->d_sb, bindex);
6727+ if (wh)
6728+ h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
6729+ else
6730+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent, br);
1facf9fc 6731+ err = PTR_ERR(h_dentry);
6732+ if (IS_ERR(h_dentry))
6733+ goto out;
6734+ if (unlikely(h_dentry->d_inode)) {
6735+ err = -EIO;
027c5e7a
AM
6736+ AuIOErr("%.*s should be negative on b%d.\n",
6737+ AuDLNPair(h_dentry), bindex);
1facf9fc 6738+ dput(h_dentry);
6739+ goto out;
6740+ }
6741+
4a4d8108 6742+ err = 0;
1facf9fc 6743+ if (bindex < au_dbstart(dentry))
6744+ au_set_dbstart(dentry, bindex);
6745+ if (au_dbend(dentry) < bindex)
6746+ au_set_dbend(dentry, bindex);
6747+ au_set_h_dptr(dentry, bindex, h_dentry);
1facf9fc 6748+
4f0767ce 6749+out:
1facf9fc 6750+ dput(parent);
6751+ return err;
6752+}
6753+
6754+/* ---------------------------------------------------------------------- */
6755+
6756+/* subset of struct inode */
6757+struct au_iattr {
6758+ unsigned long i_ino;
6759+ /* unsigned int i_nlink; */
0c3ec466
AM
6760+ kuid_t i_uid;
6761+ kgid_t i_gid;
1facf9fc 6762+ u64 i_version;
6763+/*
6764+ loff_t i_size;
6765+ blkcnt_t i_blocks;
6766+*/
6767+ umode_t i_mode;
6768+};
6769+
6770+static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
6771+{
6772+ ia->i_ino = h_inode->i_ino;
6773+ /* ia->i_nlink = h_inode->i_nlink; */
6774+ ia->i_uid = h_inode->i_uid;
6775+ ia->i_gid = h_inode->i_gid;
6776+ ia->i_version = h_inode->i_version;
6777+/*
6778+ ia->i_size = h_inode->i_size;
6779+ ia->i_blocks = h_inode->i_blocks;
6780+*/
6781+ ia->i_mode = (h_inode->i_mode & S_IFMT);
6782+}
6783+
6784+static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
6785+{
6786+ return ia->i_ino != h_inode->i_ino
6787+ /* || ia->i_nlink != h_inode->i_nlink */
0c3ec466 6788+ || !uid_eq(ia->i_uid, h_inode->i_uid)
2dfbb274 6789+ || !gid_eq(ia->i_gid, h_inode->i_gid)
1facf9fc 6790+ || ia->i_version != h_inode->i_version
6791+/*
6792+ || ia->i_size != h_inode->i_size
6793+ || ia->i_blocks != h_inode->i_blocks
6794+*/
6795+ || ia->i_mode != (h_inode->i_mode & S_IFMT);
6796+}
6797+
6798+static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
6799+ struct au_branch *br)
6800+{
6801+ int err;
6802+ struct au_iattr ia;
6803+ struct inode *h_inode;
6804+ struct dentry *h_d;
6805+ struct super_block *h_sb;
6806+
6807+ err = 0;
6808+ memset(&ia, -1, sizeof(ia));
6809+ h_sb = h_dentry->d_sb;
6810+ h_inode = h_dentry->d_inode;
6811+ if (h_inode)
6812+ au_iattr_save(&ia, h_inode);
6813+ else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
6814+ /* nfs d_revalidate may return 0 for negative dentry */
6815+ /* fuse d_revalidate always return 0 for negative dentry */
6816+ goto out;
6817+
6818+ /* main purpose is namei.c:cached_lookup() and d_revalidate */
b4510431 6819+ h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent);
1facf9fc 6820+ err = PTR_ERR(h_d);
6821+ if (IS_ERR(h_d))
6822+ goto out;
6823+
6824+ err = 0;
6825+ if (unlikely(h_d != h_dentry
6826+ || h_d->d_inode != h_inode
6827+ || (h_inode && au_iattr_test(&ia, h_inode))))
6828+ err = au_busy_or_stale();
6829+ dput(h_d);
6830+
4f0767ce 6831+out:
1facf9fc 6832+ AuTraceErr(err);
6833+ return err;
6834+}
6835+
6836+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
6837+ struct dentry *h_parent, struct au_branch *br)
6838+{
6839+ int err;
6840+
6841+ err = 0;
027c5e7a
AM
6842+ if (udba == AuOpt_UDBA_REVAL
6843+ && !au_test_fs_remote(h_dentry->d_sb)) {
1facf9fc 6844+ IMustLock(h_dir);
6845+ err = (h_dentry->d_parent->d_inode != h_dir);
027c5e7a 6846+ } else if (udba != AuOpt_UDBA_NONE)
1facf9fc 6847+ err = au_h_verify_dentry(h_dentry, h_parent, br);
6848+
6849+ return err;
6850+}
6851+
6852+/* ---------------------------------------------------------------------- */
6853+
027c5e7a 6854+static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
1facf9fc 6855+{
027c5e7a 6856+ int err;
1facf9fc 6857+ aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq;
027c5e7a
AM
6858+ struct au_hdentry tmp, *p, *q;
6859+ struct au_dinfo *dinfo;
6860+ struct super_block *sb;
1facf9fc 6861+
027c5e7a 6862+ DiMustWriteLock(dentry);
1308ab2a 6863+
027c5e7a
AM
6864+ sb = dentry->d_sb;
6865+ dinfo = au_di(dentry);
1facf9fc 6866+ bend = dinfo->di_bend;
6867+ bwh = dinfo->di_bwh;
6868+ bdiropq = dinfo->di_bdiropq;
027c5e7a 6869+ p = dinfo->di_hdentry + dinfo->di_bstart;
1facf9fc 6870+ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
027c5e7a 6871+ if (!p->hd_dentry)
1facf9fc 6872+ continue;
6873+
027c5e7a
AM
6874+ new_bindex = au_br_index(sb, p->hd_id);
6875+ if (new_bindex == bindex)
1facf9fc 6876+ continue;
1facf9fc 6877+
1facf9fc 6878+ if (dinfo->di_bwh == bindex)
6879+ bwh = new_bindex;
6880+ if (dinfo->di_bdiropq == bindex)
6881+ bdiropq = new_bindex;
6882+ if (new_bindex < 0) {
6883+ au_hdput(p);
6884+ p->hd_dentry = NULL;
6885+ continue;
6886+ }
6887+
6888+ /* swap two lower dentries, and loop again */
6889+ q = dinfo->di_hdentry + new_bindex;
6890+ tmp = *q;
6891+ *q = *p;
6892+ *p = tmp;
6893+ if (tmp.hd_dentry) {
6894+ bindex--;
6895+ p--;
6896+ }
6897+ }
6898+
1facf9fc 6899+ dinfo->di_bwh = -1;
6900+ if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))
6901+ dinfo->di_bwh = bwh;
6902+
6903+ dinfo->di_bdiropq = -1;
6904+ if (bdiropq >= 0
6905+ && bdiropq <= au_sbend(sb)
6906+ && au_sbr_whable(sb, bdiropq))
6907+ dinfo->di_bdiropq = bdiropq;
6908+
027c5e7a
AM
6909+ err = -EIO;
6910+ dinfo->di_bstart = -1;
6911+ dinfo->di_bend = -1;
1facf9fc 6912+ bend = au_dbend(parent);
6913+ p = dinfo->di_hdentry;
6914+ for (bindex = 0; bindex <= bend; bindex++, p++)
6915+ if (p->hd_dentry) {
6916+ dinfo->di_bstart = bindex;
6917+ break;
6918+ }
6919+
027c5e7a
AM
6920+ if (dinfo->di_bstart >= 0) {
6921+ p = dinfo->di_hdentry + bend;
6922+ for (bindex = bend; bindex >= 0; bindex--, p--)
6923+ if (p->hd_dentry) {
6924+ dinfo->di_bend = bindex;
6925+ err = 0;
6926+ break;
6927+ }
6928+ }
6929+
6930+ return err;
1facf9fc 6931+}
6932+
027c5e7a 6933+static void au_do_hide(struct dentry *dentry)
1facf9fc 6934+{
027c5e7a 6935+ struct inode *inode;
1facf9fc 6936+
027c5e7a
AM
6937+ inode = dentry->d_inode;
6938+ if (inode) {
6939+ if (!S_ISDIR(inode->i_mode)) {
6940+ if (inode->i_nlink && !d_unhashed(dentry))
6941+ drop_nlink(inode);
6942+ } else {
6943+ clear_nlink(inode);
6944+ /* stop next lookup */
6945+ inode->i_flags |= S_DEAD;
6946+ }
6947+ smp_mb(); /* necessary? */
6948+ }
6949+ d_drop(dentry);
6950+}
1308ab2a 6951+
027c5e7a
AM
6952+static int au_hide_children(struct dentry *parent)
6953+{
6954+ int err, i, j, ndentry;
6955+ struct au_dcsub_pages dpages;
6956+ struct au_dpage *dpage;
6957+ struct dentry *dentry;
1facf9fc 6958+
027c5e7a 6959+ err = au_dpages_init(&dpages, GFP_NOFS);
1facf9fc 6960+ if (unlikely(err))
6961+ goto out;
027c5e7a
AM
6962+ err = au_dcsub_pages(&dpages, parent, NULL, NULL);
6963+ if (unlikely(err))
6964+ goto out_dpages;
1facf9fc 6965+
027c5e7a
AM
6966+ /* in reverse order */
6967+ for (i = dpages.ndpage - 1; i >= 0; i--) {
6968+ dpage = dpages.dpages + i;
6969+ ndentry = dpage->ndentry;
6970+ for (j = ndentry - 1; j >= 0; j--) {
6971+ dentry = dpage->dentries[j];
6972+ if (dentry != parent)
6973+ au_do_hide(dentry);
6974+ }
6975+ }
1facf9fc 6976+
027c5e7a
AM
6977+out_dpages:
6978+ au_dpages_free(&dpages);
4f0767ce 6979+out:
027c5e7a 6980+ return err;
1facf9fc 6981+}
6982+
027c5e7a 6983+static void au_hide(struct dentry *dentry)
1facf9fc 6984+{
027c5e7a
AM
6985+ int err;
6986+ struct inode *inode;
1facf9fc 6987+
027c5e7a
AM
6988+ AuDbgDentry(dentry);
6989+ inode = dentry->d_inode;
6990+ if (inode && S_ISDIR(inode->i_mode)) {
6991+ /* shrink_dcache_parent(dentry); */
6992+ err = au_hide_children(dentry);
6993+ if (unlikely(err))
6994+ AuIOErr("%.*s, failed hiding children, ignored %d\n",
6995+ AuDLNPair(dentry), err);
6996+ }
6997+ au_do_hide(dentry);
6998+}
1facf9fc 6999+
027c5e7a
AM
7000+/*
7001+ * By adding a dirty branch, a cached dentry may be affected in various ways.
7002+ *
7003+ * a dirty branch is added
7004+ * - on the top of layers
7005+ * - in the middle of layers
7006+ * - to the bottom of layers
7007+ *
7008+ * on the added branch there exists
7009+ * - a whiteout
7010+ * - a diropq
7011+ * - a same named entry
7012+ * + exist
7013+ * * negative --> positive
7014+ * * positive --> positive
7015+ * - type is unchanged
7016+ * - type is changed
7017+ * + doesn't exist
7018+ * * negative --> negative
7019+ * * positive --> negative (rejected by au_br_del() for non-dir case)
7020+ * - none
7021+ */
7022+static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
7023+ struct au_dinfo *tmp)
7024+{
7025+ int err;
7026+ aufs_bindex_t bindex, bend;
7027+ struct {
7028+ struct dentry *dentry;
7029+ struct inode *inode;
7030+ mode_t mode;
7031+ } orig_h, tmp_h;
7032+ struct au_hdentry *hd;
7033+ struct inode *inode, *h_inode;
7034+ struct dentry *h_dentry;
7035+
7036+ err = 0;
7037+ AuDebugOn(dinfo->di_bstart < 0);
7038+ orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry;
7039+ orig_h.inode = orig_h.dentry->d_inode;
7040+ orig_h.mode = 0;
7041+ if (orig_h.inode)
7042+ orig_h.mode = orig_h.inode->i_mode & S_IFMT;
7043+ memset(&tmp_h, 0, sizeof(tmp_h));
7044+ if (tmp->di_bstart >= 0) {
7045+ tmp_h.dentry = tmp->di_hdentry[tmp->di_bstart].hd_dentry;
7046+ tmp_h.inode = tmp_h.dentry->d_inode;
7047+ if (tmp_h.inode)
7048+ tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
7049+ }
7050+
7051+ inode = dentry->d_inode;
7052+ if (!orig_h.inode) {
7053+ AuDbg("nagative originally\n");
7054+ if (inode) {
7055+ au_hide(dentry);
7056+ goto out;
7057+ }
7058+ AuDebugOn(inode);
7059+ AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
7060+ AuDebugOn(dinfo->di_bdiropq != -1);
7061+
7062+ if (!tmp_h.inode) {
7063+ AuDbg("negative --> negative\n");
7064+ /* should have only one negative lower */
7065+ if (tmp->di_bstart >= 0
7066+ && tmp->di_bstart < dinfo->di_bstart) {
7067+ AuDebugOn(tmp->di_bstart != tmp->di_bend);
7068+ AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
7069+ au_set_h_dptr(dentry, dinfo->di_bstart, NULL);
7070+ au_di_cp(dinfo, tmp);
7071+ hd = tmp->di_hdentry + tmp->di_bstart;
7072+ au_set_h_dptr(dentry, tmp->di_bstart,
7073+ dget(hd->hd_dentry));
7074+ }
7075+ au_dbg_verify_dinode(dentry);
7076+ } else {
7077+ AuDbg("negative --> positive\n");
7078+ /*
7079+ * similar to the behaviour of creating with bypassing
7080+ * aufs.
7081+ * unhash it in order to force an error in the
7082+ * succeeding create operation.
7083+ * we should not set S_DEAD here.
7084+ */
7085+ d_drop(dentry);
7086+ /* au_di_swap(tmp, dinfo); */
7087+ au_dbg_verify_dinode(dentry);
7088+ }
7089+ } else {
7090+ AuDbg("positive originally\n");
7091+ /* inode may be NULL */
7092+ AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode);
7093+ if (!tmp_h.inode) {
7094+ AuDbg("positive --> negative\n");
7095+ /* or bypassing aufs */
7096+ au_hide(dentry);
7097+ if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_bstart)
7098+ dinfo->di_bwh = tmp->di_bwh;
7099+ if (inode)
7100+ err = au_refresh_hinode_self(inode);
7101+ au_dbg_verify_dinode(dentry);
7102+ } else if (orig_h.mode == tmp_h.mode) {
7103+ AuDbg("positive --> positive, same type\n");
7104+ if (!S_ISDIR(orig_h.mode)
7105+ && dinfo->di_bstart > tmp->di_bstart) {
7106+ /*
7107+ * similar to the behaviour of removing and
7108+ * creating.
7109+ */
7110+ au_hide(dentry);
7111+ if (inode)
7112+ err = au_refresh_hinode_self(inode);
7113+ au_dbg_verify_dinode(dentry);
7114+ } else {
7115+ /* fill empty slots */
7116+ if (dinfo->di_bstart > tmp->di_bstart)
7117+ dinfo->di_bstart = tmp->di_bstart;
7118+ if (dinfo->di_bend < tmp->di_bend)
7119+ dinfo->di_bend = tmp->di_bend;
7120+ dinfo->di_bwh = tmp->di_bwh;
7121+ dinfo->di_bdiropq = tmp->di_bdiropq;
7122+ hd = tmp->di_hdentry;
7123+ bend = dinfo->di_bend;
7124+ for (bindex = tmp->di_bstart; bindex <= bend;
7125+ bindex++) {
7126+ if (au_h_dptr(dentry, bindex))
7127+ continue;
7128+ h_dentry = hd[bindex].hd_dentry;
7129+ if (!h_dentry)
7130+ continue;
7131+ h_inode = h_dentry->d_inode;
7132+ AuDebugOn(!h_inode);
7133+ AuDebugOn(orig_h.mode
7134+ != (h_inode->i_mode
7135+ & S_IFMT));
7136+ au_set_h_dptr(dentry, bindex,
7137+ dget(h_dentry));
7138+ }
7139+ err = au_refresh_hinode(inode, dentry);
7140+ au_dbg_verify_dinode(dentry);
7141+ }
7142+ } else {
7143+ AuDbg("positive --> positive, different type\n");
7144+ /* similar to the behaviour of removing and creating */
7145+ au_hide(dentry);
7146+ if (inode)
7147+ err = au_refresh_hinode_self(inode);
7148+ au_dbg_verify_dinode(dentry);
7149+ }
7150+ }
7151+
7152+out:
7153+ return err;
7154+}
7155+
7156+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
7157+{
7158+ int err, ebrange;
7159+ unsigned int sigen;
7160+ struct au_dinfo *dinfo, *tmp;
7161+ struct super_block *sb;
7162+ struct inode *inode;
7163+
7164+ DiMustWriteLock(dentry);
7165+ AuDebugOn(IS_ROOT(dentry));
7166+ AuDebugOn(!parent->d_inode);
7167+
7168+ sb = dentry->d_sb;
7169+ inode = dentry->d_inode;
7170+ sigen = au_sigen(sb);
7171+ err = au_digen_test(parent, sigen);
7172+ if (unlikely(err))
7173+ goto out;
7174+
7175+ dinfo = au_di(dentry);
7176+ err = au_di_realloc(dinfo, au_sbend(sb) + 1);
7177+ if (unlikely(err))
7178+ goto out;
7179+ ebrange = au_dbrange_test(dentry);
7180+ if (!ebrange)
7181+ ebrange = au_do_refresh_hdentry(dentry, parent);
7182+
7183+ if (d_unhashed(dentry) || ebrange) {
7184+ AuDebugOn(au_dbstart(dentry) < 0 && au_dbend(dentry) >= 0);
7185+ if (inode)
7186+ err = au_refresh_hinode_self(inode);
7187+ au_dbg_verify_dinode(dentry);
7188+ if (!err)
7189+ goto out_dgen; /* success */
7190+ goto out;
7191+ }
7192+
7193+ /* temporary dinfo */
7194+ AuDbgDentry(dentry);
7195+ err = -ENOMEM;
7196+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
7197+ if (unlikely(!tmp))
7198+ goto out;
7199+ au_di_swap(tmp, dinfo);
7200+ /* returns the number of positive dentries */
7201+ /*
7202+ * if current working dir is removed, it returns an error.
7203+ * but the dentry is legal.
7204+ */
537831f9 7205+ err = au_lkup_dentry(dentry, /*bstart*/0, /*type*/0);
027c5e7a
AM
7206+ AuDbgDentry(dentry);
7207+ au_di_swap(tmp, dinfo);
7208+ if (err == -ENOENT)
7209+ err = 0;
7210+ if (err >= 0) {
7211+ /* compare/refresh by dinfo */
7212+ AuDbgDentry(dentry);
7213+ err = au_refresh_by_dinfo(dentry, dinfo, tmp);
7214+ au_dbg_verify_dinode(dentry);
7215+ AuTraceErr(err);
7216+ }
7217+ au_rw_write_unlock(&tmp->di_rwsem);
7218+ au_di_free(tmp);
7219+ if (unlikely(err))
7220+ goto out;
7221+
7222+out_dgen:
7223+ au_update_digen(dentry);
7224+out:
7225+ if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) {
7226+ AuIOErr("failed refreshing %.*s, %d\n",
7227+ AuDLNPair(dentry), err);
7228+ AuDbgDentry(dentry);
7229+ }
7230+ AuTraceErr(err);
7231+ return err;
7232+}
7233+
b4510431
AM
7234+static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags,
7235+ struct dentry *dentry, aufs_bindex_t bindex)
027c5e7a
AM
7236+{
7237+ int err, valid;
027c5e7a
AM
7238+
7239+ err = 0;
7240+ if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE))
7241+ goto out;
027c5e7a
AM
7242+
7243+ AuDbg("b%d\n", bindex);
b4510431
AM
7244+ /*
7245+ * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
7246+ * due to whiteout and branch permission.
7247+ */
7248+ flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
7249+ | LOOKUP_FOLLOW | LOOKUP_EXCL);
7250+ /* it may return tri-state */
7251+ valid = h_dentry->d_op->d_revalidate(h_dentry, flags);
1facf9fc 7252+
7253+ if (unlikely(valid < 0))
7254+ err = valid;
7255+ else if (!valid)
7256+ err = -EINVAL;
7257+
4f0767ce 7258+out:
1facf9fc 7259+ AuTraceErr(err);
7260+ return err;
7261+}
7262+
7263+/* todo: remove this */
7264+static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
b4510431 7265+ unsigned int flags, int do_udba)
1facf9fc 7266+{
7267+ int err;
7268+ umode_t mode, h_mode;
7269+ aufs_bindex_t bindex, btail, bstart, ibs, ibe;
7270+ unsigned char plus, unhashed, is_root, h_plus;
4a4d8108 7271+ struct inode *h_inode, *h_cached_inode;
1facf9fc 7272+ struct dentry *h_dentry;
7273+ struct qstr *name, *h_name;
7274+
7275+ err = 0;
7276+ plus = 0;
7277+ mode = 0;
1facf9fc 7278+ ibs = -1;
7279+ ibe = -1;
7280+ unhashed = !!d_unhashed(dentry);
7281+ is_root = !!IS_ROOT(dentry);
7282+ name = &dentry->d_name;
7283+
7284+ /*
7f207e10
AM
7285+ * Theoretically, REVAL test should be unnecessary in case of
7286+ * {FS,I}NOTIFY.
7287+ * But {fs,i}notify doesn't fire some necessary events,
1facf9fc 7288+ * IN_ATTRIB for atime/nlink/pageio
7289+ * IN_DELETE for NFS dentry
7290+ * Let's do REVAL test too.
7291+ */
7292+ if (do_udba && inode) {
7293+ mode = (inode->i_mode & S_IFMT);
7294+ plus = (inode->i_nlink > 0);
1facf9fc 7295+ ibs = au_ibstart(inode);
7296+ ibe = au_ibend(inode);
7297+ }
7298+
7299+ bstart = au_dbstart(dentry);
7300+ btail = bstart;
7301+ if (inode && S_ISDIR(inode->i_mode))
7302+ btail = au_dbtaildir(dentry);
7303+ for (bindex = bstart; bindex <= btail; bindex++) {
7304+ h_dentry = au_h_dptr(dentry, bindex);
7305+ if (!h_dentry)
7306+ continue;
7307+
7308+ AuDbg("b%d, %.*s\n", bindex, AuDLNPair(h_dentry));
027c5e7a 7309+ spin_lock(&h_dentry->d_lock);
1facf9fc 7310+ h_name = &h_dentry->d_name;
7311+ if (unlikely(do_udba
7312+ && !is_root
7313+ && (unhashed != !!d_unhashed(h_dentry)
7314+ || name->len != h_name->len
7315+ || memcmp(name->name, h_name->name, name->len))
7316+ )) {
7317+ AuDbg("unhash 0x%x 0x%x, %.*s %.*s\n",
7318+ unhashed, d_unhashed(h_dentry),
7319+ AuDLNPair(dentry), AuDLNPair(h_dentry));
027c5e7a 7320+ spin_unlock(&h_dentry->d_lock);
1facf9fc 7321+ goto err;
7322+ }
027c5e7a 7323+ spin_unlock(&h_dentry->d_lock);
1facf9fc 7324+
b4510431 7325+ err = au_do_h_d_reval(h_dentry, flags, dentry, bindex);
1facf9fc 7326+ if (unlikely(err))
7327+ /* do not goto err, to keep the errno */
7328+ break;
7329+
7330+ /* todo: plink too? */
7331+ if (!do_udba)
7332+ continue;
7333+
7334+ /* UDBA tests */
7335+ h_inode = h_dentry->d_inode;
7336+ if (unlikely(!!inode != !!h_inode))
7337+ goto err;
7338+
7339+ h_plus = plus;
7340+ h_mode = mode;
7341+ h_cached_inode = h_inode;
7342+ if (h_inode) {
7343+ h_mode = (h_inode->i_mode & S_IFMT);
7344+ h_plus = (h_inode->i_nlink > 0);
7345+ }
7346+ if (inode && ibs <= bindex && bindex <= ibe)
7347+ h_cached_inode = au_h_iptr(inode, bindex);
7348+
7349+ if (unlikely(plus != h_plus
7350+ || mode != h_mode
7351+ || h_cached_inode != h_inode))
7352+ goto err;
7353+ continue;
7354+
7355+ err:
7356+ err = -EINVAL;
7357+ break;
7358+ }
7359+
7360+ return err;
7361+}
7362+
027c5e7a 7363+/* todo: consolidate with do_refresh() and au_reval_for_attr() */
1facf9fc 7364+static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
7365+{
7366+ int err;
7367+ struct dentry *parent;
1facf9fc 7368+
027c5e7a 7369+ if (!au_digen_test(dentry, sigen))
1facf9fc 7370+ return 0;
7371+
7372+ parent = dget_parent(dentry);
7373+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 7374+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 7375+ au_dbg_verify_gen(parent, sigen);
027c5e7a 7376+ err = au_refresh_dentry(dentry, parent);
1facf9fc 7377+ di_read_unlock(parent, AuLock_IR);
7378+ dput(parent);
027c5e7a 7379+ AuTraceErr(err);
1facf9fc 7380+ return err;
7381+}
7382+
7383+int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
7384+{
7385+ int err;
7386+ struct dentry *d, *parent;
7387+ struct inode *inode;
7388+
027c5e7a 7389+ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
1facf9fc 7390+ return simple_reval_dpath(dentry, sigen);
7391+
7392+ /* slow loop, keep it simple and stupid */
7393+ /* cf: au_cpup_dirs() */
7394+ err = 0;
7395+ parent = NULL;
027c5e7a 7396+ while (au_digen_test(dentry, sigen)) {
1facf9fc 7397+ d = dentry;
7398+ while (1) {
7399+ dput(parent);
7400+ parent = dget_parent(d);
027c5e7a 7401+ if (!au_digen_test(parent, sigen))
1facf9fc 7402+ break;
7403+ d = parent;
7404+ }
7405+
7406+ inode = d->d_inode;
7407+ if (d != dentry)
027c5e7a 7408+ di_write_lock_child2(d);
1facf9fc 7409+
7410+ /* someone might update our dentry while we were sleeping */
027c5e7a
AM
7411+ if (au_digen_test(d, sigen)) {
7412+ /*
7413+ * todo: consolidate with simple_reval_dpath(),
7414+ * do_refresh() and au_reval_for_attr().
7415+ */
1facf9fc 7416+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 7417+ err = au_refresh_dentry(d, parent);
1facf9fc 7418+ di_read_unlock(parent, AuLock_IR);
7419+ }
7420+
7421+ if (d != dentry)
7422+ di_write_unlock(d);
7423+ dput(parent);
7424+ if (unlikely(err))
7425+ break;
7426+ }
7427+
7428+ return err;
7429+}
7430+
7431+/*
7432+ * if valid returns 1, otherwise 0.
7433+ */
b4510431 7434+static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags)
1facf9fc 7435+{
7436+ int valid, err;
7437+ unsigned int sigen;
7438+ unsigned char do_udba;
7439+ struct super_block *sb;
7440+ struct inode *inode;
7441+
027c5e7a 7442+ /* todo: support rcu-walk? */
b4510431 7443+ if (flags & LOOKUP_RCU)
027c5e7a
AM
7444+ return -ECHILD;
7445+
7446+ valid = 0;
7447+ if (unlikely(!au_di(dentry)))
7448+ goto out;
7449+
7450+ inode = dentry->d_inode;
7451+ if (inode && is_bad_inode(inode))
7452+ goto out;
7453+
e49829fe 7454+ valid = 1;
1facf9fc 7455+ sb = dentry->d_sb;
e49829fe
JR
7456+ /*
7457+ * todo: very ugly
7458+ * i_mutex of parent dir may be held,
7459+ * but we should not return 'invalid' due to busy.
7460+ */
7461+ err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM);
7462+ if (unlikely(err)) {
7463+ valid = err;
027c5e7a 7464+ AuTraceErr(err);
e49829fe
JR
7465+ goto out;
7466+ }
027c5e7a
AM
7467+ if (unlikely(au_dbrange_test(dentry))) {
7468+ err = -EINVAL;
7469+ AuTraceErr(err);
7470+ goto out_dgrade;
1facf9fc 7471+ }
027c5e7a
AM
7472+
7473+ sigen = au_sigen(sb);
7474+ if (au_digen_test(dentry, sigen)) {
1facf9fc 7475+ AuDebugOn(IS_ROOT(dentry));
027c5e7a
AM
7476+ err = au_reval_dpath(dentry, sigen);
7477+ if (unlikely(err)) {
7478+ AuTraceErr(err);
1facf9fc 7479+ goto out_dgrade;
027c5e7a 7480+ }
1facf9fc 7481+ }
7482+ di_downgrade_lock(dentry, AuLock_IR);
7483+
1facf9fc 7484+ err = -EINVAL;
027c5e7a
AM
7485+ if (inode && (IS_DEADDIR(inode) || !inode->i_nlink))
7486+ goto out_inval;
7487+
1facf9fc 7488+ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
7489+ if (do_udba && inode) {
7490+ aufs_bindex_t bstart = au_ibstart(inode);
027c5e7a 7491+ struct inode *h_inode;
1facf9fc 7492+
027c5e7a
AM
7493+ if (bstart >= 0) {
7494+ h_inode = au_h_iptr(inode, bstart);
7495+ if (h_inode && au_test_higen(inode, h_inode))
7496+ goto out_inval;
7497+ }
1facf9fc 7498+ }
7499+
b4510431 7500+ err = h_d_revalidate(dentry, inode, flags, do_udba);
027c5e7a 7501+ if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) {
1facf9fc 7502+ err = -EIO;
027c5e7a
AM
7503+ AuDbg("both of real entry and whiteout found, %.*s, err %d\n",
7504+ AuDLNPair(dentry), err);
7505+ }
e49829fe 7506+ goto out_inval;
1facf9fc 7507+
4f0767ce 7508+out_dgrade:
1facf9fc 7509+ di_downgrade_lock(dentry, AuLock_IR);
e49829fe 7510+out_inval:
1facf9fc 7511+ aufs_read_unlock(dentry, AuLock_IR);
7512+ AuTraceErr(err);
7513+ valid = !err;
e49829fe 7514+out:
027c5e7a 7515+ if (!valid) {
e49829fe 7516+ AuDbg("%.*s invalid, %d\n", AuDLNPair(dentry), valid);
027c5e7a
AM
7517+ d_drop(dentry);
7518+ }
1facf9fc 7519+ return valid;
7520+}
7521+
7522+static void aufs_d_release(struct dentry *dentry)
7523+{
027c5e7a 7524+ if (au_di(dentry)) {
4a4d8108
AM
7525+ au_di_fin(dentry);
7526+ au_hn_di_reinit(dentry);
1facf9fc 7527+ }
1facf9fc 7528+}
7529+
4a4d8108 7530+const struct dentry_operations aufs_dop = {
c06a8ce3
AM
7531+ .d_revalidate = aufs_d_revalidate,
7532+ .d_weak_revalidate = aufs_d_revalidate,
7533+ .d_release = aufs_d_release
1facf9fc 7534+};
7f207e10
AM
7535diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
7536--- /usr/share/empty/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
86dc4139 7537+++ linux/fs/aufs/dentry.h 2013-07-06 13:20:47.740198107 +0200
537831f9 7538@@ -0,0 +1,234 @@
1facf9fc 7539+/*
7a9e40b8 7540+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 7541+ *
7542+ * This program, aufs is free software; you can redistribute it and/or modify
7543+ * it under the terms of the GNU General Public License as published by
7544+ * the Free Software Foundation; either version 2 of the License, or
7545+ * (at your option) any later version.
dece6358
AM
7546+ *
7547+ * This program is distributed in the hope that it will be useful,
7548+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7549+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7550+ * GNU General Public License for more details.
7551+ *
7552+ * You should have received a copy of the GNU General Public License
7553+ * along with this program; if not, write to the Free Software
7554+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 7555+ */
7556+
7557+/*
7558+ * lookup and dentry operations
7559+ */
7560+
7561+#ifndef __AUFS_DENTRY_H__
7562+#define __AUFS_DENTRY_H__
7563+
7564+#ifdef __KERNEL__
7565+
dece6358 7566+#include <linux/dcache.h>
1facf9fc 7567+#include "rwsem.h"
7568+
1facf9fc 7569+struct au_hdentry {
7570+ struct dentry *hd_dentry;
027c5e7a 7571+ aufs_bindex_t hd_id;
1facf9fc 7572+};
7573+
7574+struct au_dinfo {
7575+ atomic_t di_generation;
7576+
dece6358 7577+ struct au_rwsem di_rwsem;
1facf9fc 7578+ aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq;
7579+ struct au_hdentry *di_hdentry;
4a4d8108 7580+} ____cacheline_aligned_in_smp;
1facf9fc 7581+
7582+/* ---------------------------------------------------------------------- */
7583+
7584+/* dentry.c */
4a4d8108 7585+extern const struct dentry_operations aufs_dop;
1facf9fc 7586+struct au_branch;
1facf9fc 7587+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
7588+ struct au_branch *br);
7589+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
7590+ struct dentry *h_parent, struct au_branch *br);
7591+
537831f9 7592+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type);
86dc4139 7593+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh);
027c5e7a 7594+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
1facf9fc 7595+int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
7596+
7597+/* dinfo.c */
4a4d8108 7598+void au_di_init_once(void *_di);
027c5e7a
AM
7599+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
7600+void au_di_free(struct au_dinfo *dinfo);
7601+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
7602+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
4a4d8108
AM
7603+int au_di_init(struct dentry *dentry);
7604+void au_di_fin(struct dentry *dentry);
1facf9fc 7605+int au_di_realloc(struct au_dinfo *dinfo, int nbr);
7606+
7607+void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
7608+void di_read_unlock(struct dentry *d, int flags);
7609+void di_downgrade_lock(struct dentry *d, int flags);
7610+void di_write_lock(struct dentry *d, unsigned int lsc);
7611+void di_write_unlock(struct dentry *d);
7612+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
7613+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
7614+void di_write_unlock2(struct dentry *d1, struct dentry *d2);
7615+
7616+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
2cbb1c4b 7617+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
1facf9fc 7618+aufs_bindex_t au_dbtail(struct dentry *dentry);
7619+aufs_bindex_t au_dbtaildir(struct dentry *dentry);
7620+
7621+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
7622+ struct dentry *h_dentry);
027c5e7a
AM
7623+int au_digen_test(struct dentry *dentry, unsigned int sigen);
7624+int au_dbrange_test(struct dentry *dentry);
1facf9fc 7625+void au_update_digen(struct dentry *dentry);
7626+void au_update_dbrange(struct dentry *dentry, int do_put_zero);
7627+void au_update_dbstart(struct dentry *dentry);
7628+void au_update_dbend(struct dentry *dentry);
7629+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
7630+
7631+/* ---------------------------------------------------------------------- */
7632+
7633+static inline struct au_dinfo *au_di(struct dentry *dentry)
7634+{
7635+ return dentry->d_fsdata;
7636+}
7637+
7638+/* ---------------------------------------------------------------------- */
7639+
7640+/* lock subclass for dinfo */
7641+enum {
7642+ AuLsc_DI_CHILD, /* child first */
4a4d8108 7643+ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */
1facf9fc 7644+ AuLsc_DI_CHILD3, /* copyup dirs */
7645+ AuLsc_DI_PARENT,
7646+ AuLsc_DI_PARENT2,
027c5e7a
AM
7647+ AuLsc_DI_PARENT3,
7648+ AuLsc_DI_TMP /* temp for replacing dinfo */
1facf9fc 7649+};
7650+
7651+/*
7652+ * di_read_lock_child, di_write_lock_child,
7653+ * di_read_lock_child2, di_write_lock_child2,
7654+ * di_read_lock_child3, di_write_lock_child3,
7655+ * di_read_lock_parent, di_write_lock_parent,
7656+ * di_read_lock_parent2, di_write_lock_parent2,
7657+ * di_read_lock_parent3, di_write_lock_parent3,
7658+ */
7659+#define AuReadLockFunc(name, lsc) \
7660+static inline void di_read_lock_##name(struct dentry *d, int flags) \
7661+{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
7662+
7663+#define AuWriteLockFunc(name, lsc) \
7664+static inline void di_write_lock_##name(struct dentry *d) \
7665+{ di_write_lock(d, AuLsc_DI_##lsc); }
7666+
7667+#define AuRWLockFuncs(name, lsc) \
7668+ AuReadLockFunc(name, lsc) \
7669+ AuWriteLockFunc(name, lsc)
7670+
7671+AuRWLockFuncs(child, CHILD);
7672+AuRWLockFuncs(child2, CHILD2);
7673+AuRWLockFuncs(child3, CHILD3);
7674+AuRWLockFuncs(parent, PARENT);
7675+AuRWLockFuncs(parent2, PARENT2);
7676+AuRWLockFuncs(parent3, PARENT3);
7677+
7678+#undef AuReadLockFunc
7679+#undef AuWriteLockFunc
7680+#undef AuRWLockFuncs
7681+
7682+#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
dece6358
AM
7683+#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
7684+#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
1facf9fc 7685+
7686+/* ---------------------------------------------------------------------- */
7687+
7688+/* todo: memory barrier? */
7689+static inline unsigned int au_digen(struct dentry *d)
7690+{
7691+ return atomic_read(&au_di(d)->di_generation);
7692+}
7693+
7694+static inline void au_h_dentry_init(struct au_hdentry *hdentry)
7695+{
7696+ hdentry->hd_dentry = NULL;
7697+}
7698+
7699+static inline void au_hdput(struct au_hdentry *hd)
7700+{
4a4d8108
AM
7701+ if (hd)
7702+ dput(hd->hd_dentry);
1facf9fc 7703+}
7704+
7705+static inline aufs_bindex_t au_dbstart(struct dentry *dentry)
7706+{
1308ab2a 7707+ DiMustAnyLock(dentry);
1facf9fc 7708+ return au_di(dentry)->di_bstart;
7709+}
7710+
7711+static inline aufs_bindex_t au_dbend(struct dentry *dentry)
7712+{
1308ab2a 7713+ DiMustAnyLock(dentry);
1facf9fc 7714+ return au_di(dentry)->di_bend;
7715+}
7716+
7717+static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
7718+{
1308ab2a 7719+ DiMustAnyLock(dentry);
1facf9fc 7720+ return au_di(dentry)->di_bwh;
7721+}
7722+
7723+static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
7724+{
1308ab2a 7725+ DiMustAnyLock(dentry);
1facf9fc 7726+ return au_di(dentry)->di_bdiropq;
7727+}
7728+
7729+/* todo: hard/soft set? */
7730+static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex)
7731+{
1308ab2a 7732+ DiMustWriteLock(dentry);
1facf9fc 7733+ au_di(dentry)->di_bstart = bindex;
7734+}
7735+
7736+static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex)
7737+{
1308ab2a 7738+ DiMustWriteLock(dentry);
1facf9fc 7739+ au_di(dentry)->di_bend = bindex;
7740+}
7741+
7742+static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
7743+{
1308ab2a 7744+ DiMustWriteLock(dentry);
1facf9fc 7745+ /* dbwh can be outside of bstart - bend range */
7746+ au_di(dentry)->di_bwh = bindex;
7747+}
7748+
7749+static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
7750+{
1308ab2a 7751+ DiMustWriteLock(dentry);
1facf9fc 7752+ au_di(dentry)->di_bdiropq = bindex;
7753+}
7754+
7755+/* ---------------------------------------------------------------------- */
7756+
4a4d8108 7757+#ifdef CONFIG_AUFS_HNOTIFY
1facf9fc 7758+static inline void au_digen_dec(struct dentry *d)
7759+{
e49829fe 7760+ atomic_dec(&au_di(d)->di_generation);
1facf9fc 7761+}
7762+
4a4d8108 7763+static inline void au_hn_di_reinit(struct dentry *dentry)
1facf9fc 7764+{
7765+ dentry->d_fsdata = NULL;
7766+}
7767+#else
4a4d8108
AM
7768+AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
7769+#endif /* CONFIG_AUFS_HNOTIFY */
1facf9fc 7770+
7771+#endif /* __KERNEL__ */
7772+#endif /* __AUFS_DENTRY_H__ */
7f207e10
AM
7773diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
7774--- /usr/share/empty/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100
392086de 7775+++ linux/fs/aufs/dinfo.c 2013-10-26 16:51:29.579631476 +0200
2cbb1c4b 7776@@ -0,0 +1,543 @@
1facf9fc 7777+/*
7a9e40b8 7778+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 7779+ *
7780+ * This program, aufs is free software; you can redistribute it and/or modify
7781+ * it under the terms of the GNU General Public License as published by
7782+ * the Free Software Foundation; either version 2 of the License, or
7783+ * (at your option) any later version.
dece6358
AM
7784+ *
7785+ * This program is distributed in the hope that it will be useful,
7786+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7787+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7788+ * GNU General Public License for more details.
7789+ *
7790+ * You should have received a copy of the GNU General Public License
7791+ * along with this program; if not, write to the Free Software
7792+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 7793+ */
7794+
7795+/*
7796+ * dentry private data
7797+ */
7798+
7799+#include "aufs.h"
7800+
e49829fe 7801+void au_di_init_once(void *_dinfo)
4a4d8108 7802+{
e49829fe
JR
7803+ struct au_dinfo *dinfo = _dinfo;
7804+ static struct lock_class_key aufs_di;
4a4d8108 7805+
e49829fe
JR
7806+ au_rw_init(&dinfo->di_rwsem);
7807+ au_rw_class(&dinfo->di_rwsem, &aufs_di);
4a4d8108
AM
7808+}
7809+
027c5e7a 7810+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
1facf9fc 7811+{
7812+ struct au_dinfo *dinfo;
027c5e7a 7813+ int nbr, i;
1facf9fc 7814+
7815+ dinfo = au_cache_alloc_dinfo();
7816+ if (unlikely(!dinfo))
7817+ goto out;
7818+
1facf9fc 7819+ nbr = au_sbend(sb) + 1;
7820+ if (nbr <= 0)
7821+ nbr = 1;
7822+ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
027c5e7a
AM
7823+ if (dinfo->di_hdentry) {
7824+ au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
7825+ dinfo->di_bstart = -1;
7826+ dinfo->di_bend = -1;
7827+ dinfo->di_bwh = -1;
7828+ dinfo->di_bdiropq = -1;
7829+ for (i = 0; i < nbr; i++)
7830+ dinfo->di_hdentry[i].hd_id = -1;
7831+ goto out;
7832+ }
1facf9fc 7833+
1facf9fc 7834+ au_cache_free_dinfo(dinfo);
027c5e7a
AM
7835+ dinfo = NULL;
7836+
4f0767ce 7837+out:
027c5e7a 7838+ return dinfo;
1facf9fc 7839+}
7840+
027c5e7a 7841+void au_di_free(struct au_dinfo *dinfo)
4a4d8108 7842+{
4a4d8108
AM
7843+ struct au_hdentry *p;
7844+ aufs_bindex_t bend, bindex;
7845+
7846+ /* dentry may not be revalidated */
027c5e7a 7847+ bindex = dinfo->di_bstart;
4a4d8108 7848+ if (bindex >= 0) {
027c5e7a
AM
7849+ bend = dinfo->di_bend;
7850+ p = dinfo->di_hdentry + bindex;
4a4d8108
AM
7851+ while (bindex++ <= bend)
7852+ au_hdput(p++);
7853+ }
027c5e7a
AM
7854+ kfree(dinfo->di_hdentry);
7855+ au_cache_free_dinfo(dinfo);
7856+}
7857+
7858+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
7859+{
7860+ struct au_hdentry *p;
7861+ aufs_bindex_t bi;
7862+
7863+ AuRwMustWriteLock(&a->di_rwsem);
7864+ AuRwMustWriteLock(&b->di_rwsem);
7865+
7866+#define DiSwap(v, name) \
7867+ do { \
7868+ v = a->di_##name; \
7869+ a->di_##name = b->di_##name; \
7870+ b->di_##name = v; \
7871+ } while (0)
7872+
7873+ DiSwap(p, hdentry);
7874+ DiSwap(bi, bstart);
7875+ DiSwap(bi, bend);
7876+ DiSwap(bi, bwh);
7877+ DiSwap(bi, bdiropq);
7878+ /* smp_mb(); */
7879+
7880+#undef DiSwap
7881+}
7882+
7883+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
7884+{
7885+ AuRwMustWriteLock(&dst->di_rwsem);
7886+ AuRwMustWriteLock(&src->di_rwsem);
7887+
7888+ dst->di_bstart = src->di_bstart;
7889+ dst->di_bend = src->di_bend;
7890+ dst->di_bwh = src->di_bwh;
7891+ dst->di_bdiropq = src->di_bdiropq;
7892+ /* smp_mb(); */
7893+}
7894+
7895+int au_di_init(struct dentry *dentry)
7896+{
7897+ int err;
7898+ struct super_block *sb;
7899+ struct au_dinfo *dinfo;
7900+
7901+ err = 0;
7902+ sb = dentry->d_sb;
7903+ dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
7904+ if (dinfo) {
7905+ atomic_set(&dinfo->di_generation, au_sigen(sb));
7906+ /* smp_mb(); */ /* atomic_set */
7907+ dentry->d_fsdata = dinfo;
7908+ } else
7909+ err = -ENOMEM;
7910+
7911+ return err;
7912+}
7913+
7914+void au_di_fin(struct dentry *dentry)
7915+{
7916+ struct au_dinfo *dinfo;
7917+
7918+ dinfo = au_di(dentry);
7919+ AuRwDestroy(&dinfo->di_rwsem);
7920+ au_di_free(dinfo);
4a4d8108
AM
7921+}
7922+
1facf9fc 7923+int au_di_realloc(struct au_dinfo *dinfo, int nbr)
7924+{
7925+ int err, sz;
7926+ struct au_hdentry *hdp;
7927+
1308ab2a 7928+ AuRwMustWriteLock(&dinfo->di_rwsem);
7929+
1facf9fc 7930+ err = -ENOMEM;
7931+ sz = sizeof(*hdp) * (dinfo->di_bend + 1);
7932+ if (!sz)
7933+ sz = sizeof(*hdp);
7934+ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS);
7935+ if (hdp) {
7936+ dinfo->di_hdentry = hdp;
7937+ err = 0;
7938+ }
7939+
7940+ return err;
7941+}
7942+
7943+/* ---------------------------------------------------------------------- */
7944+
7945+static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
7946+{
7947+ switch (lsc) {
7948+ case AuLsc_DI_CHILD:
7949+ ii_write_lock_child(inode);
7950+ break;
7951+ case AuLsc_DI_CHILD2:
7952+ ii_write_lock_child2(inode);
7953+ break;
7954+ case AuLsc_DI_CHILD3:
7955+ ii_write_lock_child3(inode);
7956+ break;
7957+ case AuLsc_DI_PARENT:
7958+ ii_write_lock_parent(inode);
7959+ break;
7960+ case AuLsc_DI_PARENT2:
7961+ ii_write_lock_parent2(inode);
7962+ break;
7963+ case AuLsc_DI_PARENT3:
7964+ ii_write_lock_parent3(inode);
7965+ break;
7966+ default:
7967+ BUG();
7968+ }
7969+}
7970+
7971+static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
7972+{
7973+ switch (lsc) {
7974+ case AuLsc_DI_CHILD:
7975+ ii_read_lock_child(inode);
7976+ break;
7977+ case AuLsc_DI_CHILD2:
7978+ ii_read_lock_child2(inode);
7979+ break;
7980+ case AuLsc_DI_CHILD3:
7981+ ii_read_lock_child3(inode);
7982+ break;
7983+ case AuLsc_DI_PARENT:
7984+ ii_read_lock_parent(inode);
7985+ break;
7986+ case AuLsc_DI_PARENT2:
7987+ ii_read_lock_parent2(inode);
7988+ break;
7989+ case AuLsc_DI_PARENT3:
7990+ ii_read_lock_parent3(inode);
7991+ break;
7992+ default:
7993+ BUG();
7994+ }
7995+}
7996+
7997+void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
7998+{
dece6358 7999+ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
1facf9fc 8000+ if (d->d_inode) {
8001+ if (au_ftest_lock(flags, IW))
8002+ do_ii_write_lock(d->d_inode, lsc);
8003+ else if (au_ftest_lock(flags, IR))
8004+ do_ii_read_lock(d->d_inode, lsc);
8005+ }
8006+}
8007+
8008+void di_read_unlock(struct dentry *d, int flags)
8009+{
8010+ if (d->d_inode) {
027c5e7a
AM
8011+ if (au_ftest_lock(flags, IW)) {
8012+ au_dbg_verify_dinode(d);
1facf9fc 8013+ ii_write_unlock(d->d_inode);
027c5e7a
AM
8014+ } else if (au_ftest_lock(flags, IR)) {
8015+ au_dbg_verify_dinode(d);
1facf9fc 8016+ ii_read_unlock(d->d_inode);
027c5e7a 8017+ }
1facf9fc 8018+ }
dece6358 8019+ au_rw_read_unlock(&au_di(d)->di_rwsem);
1facf9fc 8020+}
8021+
8022+void di_downgrade_lock(struct dentry *d, int flags)
8023+{
1facf9fc 8024+ if (d->d_inode && au_ftest_lock(flags, IR))
8025+ ii_downgrade_lock(d->d_inode);
dece6358 8026+ au_rw_dgrade_lock(&au_di(d)->di_rwsem);
1facf9fc 8027+}
8028+
8029+void di_write_lock(struct dentry *d, unsigned int lsc)
8030+{
dece6358 8031+ au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
1facf9fc 8032+ if (d->d_inode)
8033+ do_ii_write_lock(d->d_inode, lsc);
8034+}
8035+
8036+void di_write_unlock(struct dentry *d)
8037+{
027c5e7a 8038+ au_dbg_verify_dinode(d);
1facf9fc 8039+ if (d->d_inode)
8040+ ii_write_unlock(d->d_inode);
dece6358 8041+ au_rw_write_unlock(&au_di(d)->di_rwsem);
1facf9fc 8042+}
8043+
8044+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
8045+{
8046+ AuDebugOn(d1 == d2
8047+ || d1->d_inode == d2->d_inode
8048+ || d1->d_sb != d2->d_sb);
8049+
8050+ if (isdir && au_test_subdir(d1, d2)) {
8051+ di_write_lock_child(d1);
8052+ di_write_lock_child2(d2);
8053+ } else {
8054+ /* there should be no races */
8055+ di_write_lock_child(d2);
8056+ di_write_lock_child2(d1);
8057+ }
8058+}
8059+
8060+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
8061+{
8062+ AuDebugOn(d1 == d2
8063+ || d1->d_inode == d2->d_inode
8064+ || d1->d_sb != d2->d_sb);
8065+
8066+ if (isdir && au_test_subdir(d1, d2)) {
8067+ di_write_lock_parent(d1);
8068+ di_write_lock_parent2(d2);
8069+ } else {
8070+ /* there should be no races */
8071+ di_write_lock_parent(d2);
8072+ di_write_lock_parent2(d1);
8073+ }
8074+}
8075+
8076+void di_write_unlock2(struct dentry *d1, struct dentry *d2)
8077+{
8078+ di_write_unlock(d1);
8079+ if (d1->d_inode == d2->d_inode)
dece6358 8080+ au_rw_write_unlock(&au_di(d2)->di_rwsem);
1facf9fc 8081+ else
8082+ di_write_unlock(d2);
8083+}
8084+
8085+/* ---------------------------------------------------------------------- */
8086+
8087+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
8088+{
8089+ struct dentry *d;
8090+
1308ab2a 8091+ DiMustAnyLock(dentry);
8092+
1facf9fc 8093+ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
8094+ return NULL;
8095+ AuDebugOn(bindex < 0);
8096+ d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry;
392086de 8097+ AuDebugOn(d && d_count(d) <= 0);
1facf9fc 8098+ return d;
8099+}
8100+
2cbb1c4b
JR
8101+/*
8102+ * extended version of au_h_dptr().
8103+ * returns a hashed and positive h_dentry in bindex, NULL, or error.
8104+ */
8105+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
8106+{
8107+ struct dentry *h_dentry;
8108+ struct inode *inode, *h_inode;
8109+
8110+ inode = dentry->d_inode;
8111+ AuDebugOn(!inode);
8112+
8113+ h_dentry = NULL;
8114+ if (au_dbstart(dentry) <= bindex
8115+ && bindex <= au_dbend(dentry))
8116+ h_dentry = au_h_dptr(dentry, bindex);
8117+ if (h_dentry && !au_d_hashed_positive(h_dentry)) {
8118+ dget(h_dentry);
8119+ goto out; /* success */
8120+ }
8121+
8122+ AuDebugOn(bindex < au_ibstart(inode));
8123+ AuDebugOn(au_ibend(inode) < bindex);
8124+ h_inode = au_h_iptr(inode, bindex);
8125+ h_dentry = d_find_alias(h_inode);
8126+ if (h_dentry) {
8127+ if (!IS_ERR(h_dentry)) {
8128+ if (!au_d_hashed_positive(h_dentry))
8129+ goto out; /* success */
8130+ dput(h_dentry);
8131+ } else
8132+ goto out;
8133+ }
8134+
8135+ if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
8136+ h_dentry = au_plink_lkup(inode, bindex);
8137+ AuDebugOn(!h_dentry);
8138+ if (!IS_ERR(h_dentry)) {
8139+ if (!au_d_hashed_positive(h_dentry))
8140+ goto out; /* success */
8141+ dput(h_dentry);
8142+ h_dentry = NULL;
8143+ }
8144+ }
8145+
8146+out:
8147+ AuDbgDentry(h_dentry);
8148+ return h_dentry;
8149+}
8150+
1facf9fc 8151+aufs_bindex_t au_dbtail(struct dentry *dentry)
8152+{
8153+ aufs_bindex_t bend, bwh;
8154+
8155+ bend = au_dbend(dentry);
8156+ if (0 <= bend) {
8157+ bwh = au_dbwh(dentry);
8158+ if (!bwh)
8159+ return bwh;
8160+ if (0 < bwh && bwh < bend)
8161+ return bwh - 1;
8162+ }
8163+ return bend;
8164+}
8165+
8166+aufs_bindex_t au_dbtaildir(struct dentry *dentry)
8167+{
8168+ aufs_bindex_t bend, bopq;
8169+
8170+ bend = au_dbtail(dentry);
8171+ if (0 <= bend) {
8172+ bopq = au_dbdiropq(dentry);
8173+ if (0 <= bopq && bopq < bend)
8174+ bend = bopq;
8175+ }
8176+ return bend;
8177+}
8178+
8179+/* ---------------------------------------------------------------------- */
8180+
8181+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
8182+ struct dentry *h_dentry)
8183+{
8184+ struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
027c5e7a 8185+ struct au_branch *br;
1facf9fc 8186+
1308ab2a 8187+ DiMustWriteLock(dentry);
8188+
4a4d8108 8189+ au_hdput(hd);
1facf9fc 8190+ hd->hd_dentry = h_dentry;
027c5e7a
AM
8191+ if (h_dentry) {
8192+ br = au_sbr(dentry->d_sb, bindex);
8193+ hd->hd_id = br->br_id;
8194+ }
8195+}
8196+
8197+int au_dbrange_test(struct dentry *dentry)
8198+{
8199+ int err;
8200+ aufs_bindex_t bstart, bend;
8201+
8202+ err = 0;
8203+ bstart = au_dbstart(dentry);
8204+ bend = au_dbend(dentry);
8205+ if (bstart >= 0)
8206+ AuDebugOn(bend < 0 && bstart > bend);
8207+ else {
8208+ err = -EIO;
8209+ AuDebugOn(bend >= 0);
8210+ }
8211+
8212+ return err;
8213+}
8214+
8215+int au_digen_test(struct dentry *dentry, unsigned int sigen)
8216+{
8217+ int err;
8218+
8219+ err = 0;
8220+ if (unlikely(au_digen(dentry) != sigen
8221+ || au_iigen_test(dentry->d_inode, sigen)))
8222+ err = -EIO;
8223+
8224+ return err;
1facf9fc 8225+}
8226+
8227+void au_update_digen(struct dentry *dentry)
8228+{
8229+ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
8230+ /* smp_mb(); */ /* atomic_set */
8231+}
8232+
8233+void au_update_dbrange(struct dentry *dentry, int do_put_zero)
8234+{
8235+ struct au_dinfo *dinfo;
8236+ struct dentry *h_d;
4a4d8108 8237+ struct au_hdentry *hdp;
1facf9fc 8238+
1308ab2a 8239+ DiMustWriteLock(dentry);
8240+
1facf9fc 8241+ dinfo = au_di(dentry);
8242+ if (!dinfo || dinfo->di_bstart < 0)
8243+ return;
8244+
4a4d8108 8245+ hdp = dinfo->di_hdentry;
1facf9fc 8246+ if (do_put_zero) {
8247+ aufs_bindex_t bindex, bend;
8248+
8249+ bend = dinfo->di_bend;
8250+ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) {
4a4d8108 8251+ h_d = hdp[0 + bindex].hd_dentry;
1facf9fc 8252+ if (h_d && !h_d->d_inode)
8253+ au_set_h_dptr(dentry, bindex, NULL);
8254+ }
8255+ }
8256+
8257+ dinfo->di_bstart = -1;
8258+ while (++dinfo->di_bstart <= dinfo->di_bend)
4a4d8108 8259+ if (hdp[0 + dinfo->di_bstart].hd_dentry)
1facf9fc 8260+ break;
8261+ if (dinfo->di_bstart > dinfo->di_bend) {
8262+ dinfo->di_bstart = -1;
8263+ dinfo->di_bend = -1;
8264+ return;
8265+ }
8266+
8267+ dinfo->di_bend++;
8268+ while (0 <= --dinfo->di_bend)
4a4d8108 8269+ if (hdp[0 + dinfo->di_bend].hd_dentry)
1facf9fc 8270+ break;
8271+ AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0);
8272+}
8273+
8274+void au_update_dbstart(struct dentry *dentry)
8275+{
8276+ aufs_bindex_t bindex, bend;
8277+ struct dentry *h_dentry;
8278+
8279+ bend = au_dbend(dentry);
8280+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
8281+ h_dentry = au_h_dptr(dentry, bindex);
8282+ if (!h_dentry)
8283+ continue;
8284+ if (h_dentry->d_inode) {
8285+ au_set_dbstart(dentry, bindex);
8286+ return;
8287+ }
8288+ au_set_h_dptr(dentry, bindex, NULL);
8289+ }
8290+}
8291+
8292+void au_update_dbend(struct dentry *dentry)
8293+{
8294+ aufs_bindex_t bindex, bstart;
8295+ struct dentry *h_dentry;
8296+
8297+ bstart = au_dbstart(dentry);
7f207e10 8298+ for (bindex = au_dbend(dentry); bindex >= bstart; bindex--) {
1facf9fc 8299+ h_dentry = au_h_dptr(dentry, bindex);
8300+ if (!h_dentry)
8301+ continue;
8302+ if (h_dentry->d_inode) {
8303+ au_set_dbend(dentry, bindex);
8304+ return;
8305+ }
8306+ au_set_h_dptr(dentry, bindex, NULL);
8307+ }
8308+}
8309+
8310+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
8311+{
8312+ aufs_bindex_t bindex, bend;
8313+
8314+ bend = au_dbend(dentry);
8315+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++)
8316+ if (au_h_dptr(dentry, bindex) == h_dentry)
8317+ return bindex;
8318+ return -1;
8319+}
7f207e10
AM
8320diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
8321--- /usr/share/empty/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
8322+++ linux/fs/aufs/dir.c 2013-10-26 16:51:32.273040419 +0200
8323@@ -0,0 +1,645 @@
1facf9fc 8324+/*
7a9e40b8 8325+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 8326+ *
8327+ * This program, aufs is free software; you can redistribute it and/or modify
8328+ * it under the terms of the GNU General Public License as published by
8329+ * the Free Software Foundation; either version 2 of the License, or
8330+ * (at your option) any later version.
dece6358
AM
8331+ *
8332+ * This program is distributed in the hope that it will be useful,
8333+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8334+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8335+ * GNU General Public License for more details.
8336+ *
8337+ * You should have received a copy of the GNU General Public License
8338+ * along with this program; if not, write to the Free Software
8339+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 8340+ */
8341+
8342+/*
8343+ * directory operations
8344+ */
8345+
8346+#include <linux/fs_stack.h>
8347+#include "aufs.h"
8348+
8349+void au_add_nlink(struct inode *dir, struct inode *h_dir)
8350+{
9dbd164d
AM
8351+ unsigned int nlink;
8352+
1facf9fc 8353+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
8354+
9dbd164d
AM
8355+ nlink = dir->i_nlink;
8356+ nlink += h_dir->i_nlink - 2;
1facf9fc 8357+ if (h_dir->i_nlink < 2)
9dbd164d 8358+ nlink += 2;
86dc4139 8359+ smp_mb();
7eafdf33 8360+ /* 0 can happen in revaliding */
92d182d2 8361+ set_nlink(dir, nlink);
1facf9fc 8362+}
8363+
8364+void au_sub_nlink(struct inode *dir, struct inode *h_dir)
8365+{
9dbd164d
AM
8366+ unsigned int nlink;
8367+
1facf9fc 8368+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
8369+
9dbd164d
AM
8370+ nlink = dir->i_nlink;
8371+ nlink -= h_dir->i_nlink - 2;
1facf9fc 8372+ if (h_dir->i_nlink < 2)
9dbd164d 8373+ nlink -= 2;
86dc4139 8374+ smp_mb();
92d182d2 8375+ /* nlink == 0 means the branch-fs is broken */
9dbd164d 8376+ set_nlink(dir, nlink);
1facf9fc 8377+}
8378+
1308ab2a 8379+loff_t au_dir_size(struct file *file, struct dentry *dentry)
8380+{
8381+ loff_t sz;
8382+ aufs_bindex_t bindex, bend;
8383+ struct file *h_file;
8384+ struct dentry *h_dentry;
8385+
8386+ sz = 0;
8387+ if (file) {
c06a8ce3
AM
8388+ AuDebugOn(!file_inode(file));
8389+ AuDebugOn(!S_ISDIR(file_inode(file)->i_mode));
1308ab2a 8390+
4a4d8108 8391+ bend = au_fbend_dir(file);
1308ab2a 8392+ for (bindex = au_fbstart(file);
8393+ bindex <= bend && sz < KMALLOC_MAX_SIZE;
8394+ bindex++) {
4a4d8108 8395+ h_file = au_hf_dir(file, bindex);
c06a8ce3
AM
8396+ if (h_file && file_inode(h_file))
8397+ sz += vfsub_f_size_read(h_file);
1308ab2a 8398+ }
8399+ } else {
8400+ AuDebugOn(!dentry);
8401+ AuDebugOn(!dentry->d_inode);
8402+ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
8403+
8404+ bend = au_dbtaildir(dentry);
8405+ for (bindex = au_dbstart(dentry);
8406+ bindex <= bend && sz < KMALLOC_MAX_SIZE;
8407+ bindex++) {
8408+ h_dentry = au_h_dptr(dentry, bindex);
8409+ if (h_dentry && h_dentry->d_inode)
8410+ sz += i_size_read(h_dentry->d_inode);
8411+ }
8412+ }
8413+ if (sz < KMALLOC_MAX_SIZE)
8414+ sz = roundup_pow_of_two(sz);
8415+ if (sz > KMALLOC_MAX_SIZE)
8416+ sz = KMALLOC_MAX_SIZE;
8417+ else if (sz < NAME_MAX) {
8418+ BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX);
8419+ sz = AUFS_RDBLK_DEF;
8420+ }
8421+ return sz;
8422+}
8423+
1facf9fc 8424+/* ---------------------------------------------------------------------- */
8425+
8426+static int reopen_dir(struct file *file)
8427+{
8428+ int err;
8429+ unsigned int flags;
8430+ aufs_bindex_t bindex, btail, bstart;
8431+ struct dentry *dentry, *h_dentry;
8432+ struct file *h_file;
8433+
8434+ /* open all lower dirs */
8435+ dentry = file->f_dentry;
8436+ bstart = au_dbstart(dentry);
8437+ for (bindex = au_fbstart(file); bindex < bstart; bindex++)
8438+ au_set_h_fptr(file, bindex, NULL);
8439+ au_set_fbstart(file, bstart);
8440+
8441+ btail = au_dbtaildir(dentry);
4a4d8108 8442+ for (bindex = au_fbend_dir(file); btail < bindex; bindex--)
1facf9fc 8443+ au_set_h_fptr(file, bindex, NULL);
4a4d8108 8444+ au_set_fbend_dir(file, btail);
1facf9fc 8445+
4a4d8108 8446+ flags = vfsub_file_flags(file);
1facf9fc 8447+ for (bindex = bstart; bindex <= btail; bindex++) {
8448+ h_dentry = au_h_dptr(dentry, bindex);
8449+ if (!h_dentry)
8450+ continue;
4a4d8108 8451+ h_file = au_hf_dir(file, bindex);
1facf9fc 8452+ if (h_file)
8453+ continue;
8454+
392086de 8455+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 8456+ err = PTR_ERR(h_file);
8457+ if (IS_ERR(h_file))
8458+ goto out; /* close all? */
8459+ au_set_h_fptr(file, bindex, h_file);
8460+ }
8461+ au_update_figen(file);
8462+ /* todo: necessary? */
8463+ /* file->f_ra = h_file->f_ra; */
8464+ err = 0;
8465+
4f0767ce 8466+out:
1facf9fc 8467+ return err;
8468+}
8469+
8470+static int do_open_dir(struct file *file, int flags)
8471+{
8472+ int err;
8473+ aufs_bindex_t bindex, btail;
8474+ struct dentry *dentry, *h_dentry;
8475+ struct file *h_file;
8476+
1308ab2a 8477+ FiMustWriteLock(file);
8478+
1facf9fc 8479+ dentry = file->f_dentry;
027c5e7a
AM
8480+ err = au_alive_dir(dentry);
8481+ if (unlikely(err))
8482+ goto out;
8483+
1facf9fc 8484+ file->f_version = dentry->d_inode->i_version;
8485+ bindex = au_dbstart(dentry);
8486+ au_set_fbstart(file, bindex);
8487+ btail = au_dbtaildir(dentry);
4a4d8108 8488+ au_set_fbend_dir(file, btail);
1facf9fc 8489+ for (; !err && bindex <= btail; bindex++) {
8490+ h_dentry = au_h_dptr(dentry, bindex);
8491+ if (!h_dentry)
8492+ continue;
8493+
392086de 8494+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 8495+ if (IS_ERR(h_file)) {
8496+ err = PTR_ERR(h_file);
8497+ break;
8498+ }
8499+ au_set_h_fptr(file, bindex, h_file);
8500+ }
8501+ au_update_figen(file);
8502+ /* todo: necessary? */
8503+ /* file->f_ra = h_file->f_ra; */
8504+ if (!err)
8505+ return 0; /* success */
8506+
8507+ /* close all */
8508+ for (bindex = au_fbstart(file); bindex <= btail; bindex++)
8509+ au_set_h_fptr(file, bindex, NULL);
8510+ au_set_fbstart(file, -1);
4a4d8108
AM
8511+ au_set_fbend_dir(file, -1);
8512+
027c5e7a 8513+out:
1facf9fc 8514+ return err;
8515+}
8516+
8517+static int aufs_open_dir(struct inode *inode __maybe_unused,
8518+ struct file *file)
8519+{
4a4d8108
AM
8520+ int err;
8521+ struct super_block *sb;
8522+ struct au_fidir *fidir;
8523+
8524+ err = -ENOMEM;
8525+ sb = file->f_dentry->d_sb;
8526+ si_read_lock(sb, AuLock_FLUSH);
e49829fe 8527+ fidir = au_fidir_alloc(sb);
4a4d8108
AM
8528+ if (fidir) {
8529+ err = au_do_open(file, do_open_dir, fidir);
8530+ if (unlikely(err))
8531+ kfree(fidir);
8532+ }
8533+ si_read_unlock(sb);
8534+ return err;
1facf9fc 8535+}
8536+
8537+static int aufs_release_dir(struct inode *inode __maybe_unused,
8538+ struct file *file)
8539+{
8540+ struct au_vdir *vdir_cache;
4a4d8108
AM
8541+ struct au_finfo *finfo;
8542+ struct au_fidir *fidir;
8543+ aufs_bindex_t bindex, bend;
1facf9fc 8544+
4a4d8108
AM
8545+ finfo = au_fi(file);
8546+ fidir = finfo->fi_hdir;
8547+ if (fidir) {
8548+ vdir_cache = fidir->fd_vdir_cache; /* lock-free */
8549+ if (vdir_cache)
8550+ au_vdir_free(vdir_cache);
8551+
8552+ bindex = finfo->fi_btop;
8553+ if (bindex >= 0) {
8554+ /*
8555+ * calls fput() instead of filp_close(),
8556+ * since no dnotify or lock for the lower file.
8557+ */
8558+ bend = fidir->fd_bbot;
8559+ for (; bindex <= bend; bindex++)
8560+ au_set_h_fptr(file, bindex, NULL);
8561+ }
8562+ kfree(fidir);
8563+ finfo->fi_hdir = NULL;
1facf9fc 8564+ }
1facf9fc 8565+ au_finfo_fin(file);
1facf9fc 8566+ return 0;
8567+}
8568+
8569+/* ---------------------------------------------------------------------- */
8570+
4a4d8108
AM
8571+static int au_do_flush_dir(struct file *file, fl_owner_t id)
8572+{
8573+ int err;
8574+ aufs_bindex_t bindex, bend;
8575+ struct file *h_file;
8576+
8577+ err = 0;
8578+ bend = au_fbend_dir(file);
8579+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
8580+ h_file = au_hf_dir(file, bindex);
8581+ if (h_file)
8582+ err = vfsub_flush(h_file, id);
8583+ }
8584+ return err;
8585+}
8586+
8587+static int aufs_flush_dir(struct file *file, fl_owner_t id)
8588+{
8589+ return au_do_flush(file, id, au_do_flush_dir);
8590+}
8591+
8592+/* ---------------------------------------------------------------------- */
8593+
1facf9fc 8594+static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
8595+{
8596+ int err;
8597+ aufs_bindex_t bend, bindex;
8598+ struct inode *inode;
8599+ struct super_block *sb;
8600+
8601+ err = 0;
8602+ sb = dentry->d_sb;
8603+ inode = dentry->d_inode;
8604+ IMustLock(inode);
8605+ bend = au_dbend(dentry);
8606+ for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) {
8607+ struct path h_path;
1facf9fc 8608+
8609+ if (au_test_ro(sb, bindex, inode))
8610+ continue;
8611+ h_path.dentry = au_h_dptr(dentry, bindex);
8612+ if (!h_path.dentry)
8613+ continue;
1facf9fc 8614+
1facf9fc 8615+ h_path.mnt = au_sbr_mnt(sb, bindex);
53392da6 8616+ err = vfsub_fsync(NULL, &h_path, datasync);
1facf9fc 8617+ }
8618+
8619+ return err;
8620+}
8621+
8622+static int au_do_fsync_dir(struct file *file, int datasync)
8623+{
8624+ int err;
8625+ aufs_bindex_t bend, bindex;
8626+ struct file *h_file;
8627+ struct super_block *sb;
8628+ struct inode *inode;
1facf9fc 8629+
8630+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
8631+ if (unlikely(err))
8632+ goto out;
8633+
8634+ sb = file->f_dentry->d_sb;
c06a8ce3 8635+ inode = file_inode(file);
4a4d8108 8636+ bend = au_fbend_dir(file);
1facf9fc 8637+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
4a4d8108 8638+ h_file = au_hf_dir(file, bindex);
1facf9fc 8639+ if (!h_file || au_test_ro(sb, bindex, inode))
8640+ continue;
8641+
53392da6 8642+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
1facf9fc 8643+ }
8644+
4f0767ce 8645+out:
1facf9fc 8646+ return err;
8647+}
8648+
8649+/*
8650+ * @file may be NULL
8651+ */
1e00d052
AM
8652+static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end,
8653+ int datasync)
1facf9fc 8654+{
8655+ int err;
b752ccd1 8656+ struct dentry *dentry;
1facf9fc 8657+ struct super_block *sb;
1e00d052 8658+ struct mutex *mtx;
1facf9fc 8659+
8660+ err = 0;
1e00d052
AM
8661+ dentry = file->f_dentry;
8662+ mtx = &dentry->d_inode->i_mutex;
8663+ mutex_lock(mtx);
1facf9fc 8664+ sb = dentry->d_sb;
8665+ si_noflush_read_lock(sb);
8666+ if (file)
8667+ err = au_do_fsync_dir(file, datasync);
8668+ else {
8669+ di_write_lock_child(dentry);
8670+ err = au_do_fsync_dir_no_file(dentry, datasync);
8671+ }
8672+ au_cpup_attr_timesizes(dentry->d_inode);
8673+ di_write_unlock(dentry);
8674+ if (file)
8675+ fi_write_unlock(file);
8676+
8677+ si_read_unlock(sb);
1e00d052 8678+ mutex_unlock(mtx);
1facf9fc 8679+ return err;
8680+}
8681+
8682+/* ---------------------------------------------------------------------- */
8683+
392086de 8684+static int aufs_iterate(struct file *file, struct dir_context *ctx)
1facf9fc 8685+{
8686+ int err;
8687+ struct dentry *dentry;
9dbd164d 8688+ struct inode *inode, *h_inode;
1facf9fc 8689+ struct super_block *sb;
8690+
392086de
AM
8691+ AuDbg("%.*s, ctx{%pf, %llu}\n",
8692+ AuDLNPair(file->f_dentry), ctx->actor, ctx->pos);
8693+
1facf9fc 8694+ dentry = file->f_dentry;
8695+ inode = dentry->d_inode;
8696+ IMustLock(inode);
8697+
8698+ sb = dentry->d_sb;
8699+ si_read_lock(sb, AuLock_FLUSH);
8700+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
8701+ if (unlikely(err))
8702+ goto out;
027c5e7a
AM
8703+ err = au_alive_dir(dentry);
8704+ if (!err)
8705+ err = au_vdir_init(file);
1facf9fc 8706+ di_downgrade_lock(dentry, AuLock_IR);
8707+ if (unlikely(err))
8708+ goto out_unlock;
8709+
9dbd164d 8710+ h_inode = au_h_iptr(inode, au_ibstart(inode));
b752ccd1 8711+ if (!au_test_nfsd()) {
392086de 8712+ err = au_vdir_fill_de(file, ctx);
9dbd164d 8713+ fsstack_copy_attr_atime(inode, h_inode);
1facf9fc 8714+ } else {
8715+ /*
8716+ * nfsd filldir may call lookup_one_len(), vfs_getattr(),
8717+ * encode_fh() and others.
8718+ */
9dbd164d 8719+ atomic_inc(&h_inode->i_count);
1facf9fc 8720+ di_read_unlock(dentry, AuLock_IR);
8721+ si_read_unlock(sb);
392086de 8722+ err = au_vdir_fill_de(file, ctx);
1facf9fc 8723+ fsstack_copy_attr_atime(inode, h_inode);
8724+ fi_write_unlock(file);
9dbd164d 8725+ iput(h_inode);
1facf9fc 8726+
8727+ AuTraceErr(err);
8728+ return err;
8729+ }
8730+
4f0767ce 8731+out_unlock:
1facf9fc 8732+ di_read_unlock(dentry, AuLock_IR);
8733+ fi_write_unlock(file);
4f0767ce 8734+out:
1facf9fc 8735+ si_read_unlock(sb);
8736+ return err;
8737+}
8738+
8739+/* ---------------------------------------------------------------------- */
8740+
8741+#define AuTestEmpty_WHONLY 1
dece6358
AM
8742+#define AuTestEmpty_CALLED (1 << 1)
8743+#define AuTestEmpty_SHWH (1 << 2)
1facf9fc 8744+#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
7f207e10
AM
8745+#define au_fset_testempty(flags, name) \
8746+ do { (flags) |= AuTestEmpty_##name; } while (0)
8747+#define au_fclr_testempty(flags, name) \
8748+ do { (flags) &= ~AuTestEmpty_##name; } while (0)
1facf9fc 8749+
dece6358
AM
8750+#ifndef CONFIG_AUFS_SHWH
8751+#undef AuTestEmpty_SHWH
8752+#define AuTestEmpty_SHWH 0
8753+#endif
8754+
1facf9fc 8755+struct test_empty_arg {
392086de 8756+ struct dir_context ctx;
1308ab2a 8757+ struct au_nhash *whlist;
1facf9fc 8758+ unsigned int flags;
8759+ int err;
8760+ aufs_bindex_t bindex;
8761+};
8762+
392086de
AM
8763+static int test_empty_cb(struct dir_context *ctx, const char *__name,
8764+ int namelen, loff_t offset __maybe_unused, u64 ino,
dece6358 8765+ unsigned int d_type)
1facf9fc 8766+{
392086de
AM
8767+ struct test_empty_arg *arg = container_of(ctx, struct test_empty_arg,
8768+ ctx);
1facf9fc 8769+ char *name = (void *)__name;
8770+
8771+ arg->err = 0;
8772+ au_fset_testempty(arg->flags, CALLED);
8773+ /* smp_mb(); */
8774+ if (name[0] == '.'
8775+ && (namelen == 1 || (name[1] == '.' && namelen == 2)))
8776+ goto out; /* success */
8777+
8778+ if (namelen <= AUFS_WH_PFX_LEN
8779+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
8780+ if (au_ftest_testempty(arg->flags, WHONLY)
1308ab2a 8781+ && !au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 8782+ arg->err = -ENOTEMPTY;
8783+ goto out;
8784+ }
8785+
8786+ name += AUFS_WH_PFX_LEN;
8787+ namelen -= AUFS_WH_PFX_LEN;
1308ab2a 8788+ if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 8789+ arg->err = au_nhash_append_wh
1308ab2a 8790+ (arg->whlist, name, namelen, ino, d_type, arg->bindex,
dece6358 8791+ au_ftest_testempty(arg->flags, SHWH));
1facf9fc 8792+
4f0767ce 8793+out:
1facf9fc 8794+ /* smp_mb(); */
8795+ AuTraceErr(arg->err);
8796+ return arg->err;
8797+}
8798+
8799+static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
8800+{
8801+ int err;
8802+ struct file *h_file;
8803+
8804+ h_file = au_h_open(dentry, arg->bindex,
8805+ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
392086de 8806+ /*file*/NULL, /*force_wr*/0);
1facf9fc 8807+ err = PTR_ERR(h_file);
8808+ if (IS_ERR(h_file))
8809+ goto out;
8810+
8811+ err = 0;
8812+ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
c06a8ce3 8813+ && !file_inode(h_file)->i_nlink)
1facf9fc 8814+ goto out_put;
8815+
8816+ do {
8817+ arg->err = 0;
8818+ au_fclr_testempty(arg->flags, CALLED);
8819+ /* smp_mb(); */
392086de 8820+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1facf9fc 8821+ if (err >= 0)
8822+ err = arg->err;
8823+ } while (!err && au_ftest_testempty(arg->flags, CALLED));
8824+
4f0767ce 8825+out_put:
1facf9fc 8826+ fput(h_file);
8827+ au_sbr_put(dentry->d_sb, arg->bindex);
4f0767ce 8828+out:
1facf9fc 8829+ return err;
8830+}
8831+
8832+struct do_test_empty_args {
8833+ int *errp;
8834+ struct dentry *dentry;
8835+ struct test_empty_arg *arg;
8836+};
8837+
8838+static void call_do_test_empty(void *args)
8839+{
8840+ struct do_test_empty_args *a = args;
8841+ *a->errp = do_test_empty(a->dentry, a->arg);
8842+}
8843+
8844+static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
8845+{
8846+ int err, wkq_err;
8847+ struct dentry *h_dentry;
8848+ struct inode *h_inode;
8849+
8850+ h_dentry = au_h_dptr(dentry, arg->bindex);
8851+ h_inode = h_dentry->d_inode;
53392da6 8852+ /* todo: i_mode changes anytime? */
1facf9fc 8853+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
8854+ err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
8855+ mutex_unlock(&h_inode->i_mutex);
8856+ if (!err)
8857+ err = do_test_empty(dentry, arg);
8858+ else {
8859+ struct do_test_empty_args args = {
8860+ .errp = &err,
8861+ .dentry = dentry,
8862+ .arg = arg
8863+ };
8864+ unsigned int flags = arg->flags;
8865+
8866+ wkq_err = au_wkq_wait(call_do_test_empty, &args);
8867+ if (unlikely(wkq_err))
8868+ err = wkq_err;
8869+ arg->flags = flags;
8870+ }
8871+
8872+ return err;
8873+}
8874+
8875+int au_test_empty_lower(struct dentry *dentry)
8876+{
8877+ int err;
1308ab2a 8878+ unsigned int rdhash;
1facf9fc 8879+ aufs_bindex_t bindex, bstart, btail;
1308ab2a 8880+ struct au_nhash whlist;
392086de
AM
8881+ struct test_empty_arg arg = {
8882+ .ctx = {
8883+ .actor = au_diractor(test_empty_cb)
8884+ }
8885+ };
1facf9fc 8886+
dece6358
AM
8887+ SiMustAnyLock(dentry->d_sb);
8888+
1308ab2a 8889+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
8890+ if (!rdhash)
8891+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry));
8892+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
dece6358 8893+ if (unlikely(err))
1facf9fc 8894+ goto out;
8895+
1facf9fc 8896+ arg.flags = 0;
1308ab2a 8897+ arg.whlist = &whlist;
8898+ bstart = au_dbstart(dentry);
dece6358
AM
8899+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
8900+ au_fset_testempty(arg.flags, SHWH);
1facf9fc 8901+ arg.bindex = bstart;
8902+ err = do_test_empty(dentry, &arg);
8903+ if (unlikely(err))
8904+ goto out_whlist;
8905+
8906+ au_fset_testempty(arg.flags, WHONLY);
8907+ btail = au_dbtaildir(dentry);
8908+ for (bindex = bstart + 1; !err && bindex <= btail; bindex++) {
8909+ struct dentry *h_dentry;
8910+
8911+ h_dentry = au_h_dptr(dentry, bindex);
8912+ if (h_dentry && h_dentry->d_inode) {
8913+ arg.bindex = bindex;
8914+ err = do_test_empty(dentry, &arg);
8915+ }
8916+ }
8917+
4f0767ce 8918+out_whlist:
1308ab2a 8919+ au_nhash_wh_free(&whlist);
4f0767ce 8920+out:
1facf9fc 8921+ return err;
8922+}
8923+
8924+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
8925+{
8926+ int err;
392086de
AM
8927+ struct test_empty_arg arg = {
8928+ .ctx = {
8929+ .actor = au_diractor(test_empty_cb)
8930+ }
8931+ };
1facf9fc 8932+ aufs_bindex_t bindex, btail;
8933+
8934+ err = 0;
1308ab2a 8935+ arg.whlist = whlist;
1facf9fc 8936+ arg.flags = AuTestEmpty_WHONLY;
dece6358
AM
8937+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
8938+ au_fset_testempty(arg.flags, SHWH);
1facf9fc 8939+ btail = au_dbtaildir(dentry);
8940+ for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) {
8941+ struct dentry *h_dentry;
8942+
8943+ h_dentry = au_h_dptr(dentry, bindex);
8944+ if (h_dentry && h_dentry->d_inode) {
8945+ arg.bindex = bindex;
8946+ err = sio_test_empty(dentry, &arg);
8947+ }
8948+ }
8949+
8950+ return err;
8951+}
8952+
8953+/* ---------------------------------------------------------------------- */
8954+
8955+const struct file_operations aufs_dir_fop = {
4a4d8108 8956+ .owner = THIS_MODULE,
027c5e7a 8957+ .llseek = default_llseek,
1facf9fc 8958+ .read = generic_read_dir,
392086de 8959+ .iterate = aufs_iterate,
1facf9fc 8960+ .unlocked_ioctl = aufs_ioctl_dir,
b752ccd1
AM
8961+#ifdef CONFIG_COMPAT
8962+ .compat_ioctl = aufs_compat_ioctl_dir,
8963+#endif
1facf9fc 8964+ .open = aufs_open_dir,
8965+ .release = aufs_release_dir,
4a4d8108 8966+ .flush = aufs_flush_dir,
1facf9fc 8967+ .fsync = aufs_fsync_dir
8968+};
7f207e10
AM
8969diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
8970--- /usr/share/empty/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100
392086de 8971+++ linux/fs/aufs/dir.h 2013-10-26 16:51:29.582964925 +0200
f6c5ef8b 8972@@ -0,0 +1,137 @@
1facf9fc 8973+/*
7a9e40b8 8974+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 8975+ *
8976+ * This program, aufs is free software; you can redistribute it and/or modify
8977+ * it under the terms of the GNU General Public License as published by
8978+ * the Free Software Foundation; either version 2 of the License, or
8979+ * (at your option) any later version.
dece6358
AM
8980+ *
8981+ * This program is distributed in the hope that it will be useful,
8982+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8983+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8984+ * GNU General Public License for more details.
8985+ *
8986+ * You should have received a copy of the GNU General Public License
8987+ * along with this program; if not, write to the Free Software
8988+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 8989+ */
8990+
8991+/*
8992+ * directory operations
8993+ */
8994+
8995+#ifndef __AUFS_DIR_H__
8996+#define __AUFS_DIR_H__
8997+
8998+#ifdef __KERNEL__
8999+
9000+#include <linux/fs.h>
1facf9fc 9001+
9002+/* ---------------------------------------------------------------------- */
9003+
9004+/* need to be faster and smaller */
9005+
9006+struct au_nhash {
dece6358
AM
9007+ unsigned int nh_num;
9008+ struct hlist_head *nh_head;
1facf9fc 9009+};
9010+
9011+struct au_vdir_destr {
9012+ unsigned char len;
9013+ unsigned char name[0];
9014+} __packed;
9015+
9016+struct au_vdir_dehstr {
9017+ struct hlist_node hash;
9018+ struct au_vdir_destr *str;
4a4d8108 9019+} ____cacheline_aligned_in_smp;
1facf9fc 9020+
9021+struct au_vdir_de {
9022+ ino_t de_ino;
9023+ unsigned char de_type;
9024+ /* caution: packed */
9025+ struct au_vdir_destr de_str;
9026+} __packed;
9027+
9028+struct au_vdir_wh {
9029+ struct hlist_node wh_hash;
dece6358
AM
9030+#ifdef CONFIG_AUFS_SHWH
9031+ ino_t wh_ino;
1facf9fc 9032+ aufs_bindex_t wh_bindex;
dece6358
AM
9033+ unsigned char wh_type;
9034+#else
9035+ aufs_bindex_t wh_bindex;
9036+#endif
9037+ /* caution: packed */
1facf9fc 9038+ struct au_vdir_destr wh_str;
9039+} __packed;
9040+
9041+union au_vdir_deblk_p {
9042+ unsigned char *deblk;
9043+ struct au_vdir_de *de;
9044+};
9045+
9046+struct au_vdir {
9047+ unsigned char **vd_deblk;
9048+ unsigned long vd_nblk;
1facf9fc 9049+ struct {
9050+ unsigned long ul;
9051+ union au_vdir_deblk_p p;
9052+ } vd_last;
9053+
9054+ unsigned long vd_version;
dece6358 9055+ unsigned int vd_deblk_sz;
1facf9fc 9056+ unsigned long vd_jiffy;
4a4d8108 9057+} ____cacheline_aligned_in_smp;
1facf9fc 9058+
9059+/* ---------------------------------------------------------------------- */
9060+
9061+/* dir.c */
9062+extern const struct file_operations aufs_dir_fop;
9063+void au_add_nlink(struct inode *dir, struct inode *h_dir);
9064+void au_sub_nlink(struct inode *dir, struct inode *h_dir);
1308ab2a 9065+loff_t au_dir_size(struct file *file, struct dentry *dentry);
1facf9fc 9066+int au_test_empty_lower(struct dentry *dentry);
9067+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
9068+
9069+/* vdir.c */
1308ab2a 9070+unsigned int au_rdhash_est(loff_t sz);
dece6358
AM
9071+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
9072+void au_nhash_wh_free(struct au_nhash *whlist);
1facf9fc 9073+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
9074+ int limit);
dece6358
AM
9075+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
9076+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
9077+ unsigned int d_type, aufs_bindex_t bindex,
9078+ unsigned char shwh);
1facf9fc 9079+void au_vdir_free(struct au_vdir *vdir);
9080+int au_vdir_init(struct file *file);
392086de 9081+int au_vdir_fill_de(struct file *file, struct dir_context *ctx);
1facf9fc 9082+
9083+/* ioctl.c */
9084+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
9085+
1308ab2a 9086+#ifdef CONFIG_AUFS_RDU
9087+/* rdu.c */
9088+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
9089+#ifdef CONFIG_COMPAT
9090+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
9091+ unsigned long arg);
9092+#endif
1308ab2a 9093+#else
9094+static inline long au_rdu_ioctl(struct file *file, unsigned int cmd,
9095+ unsigned long arg)
9096+{
9097+ return -EINVAL;
9098+}
b752ccd1
AM
9099+#ifdef CONFIG_COMPAT
9100+static inline long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
9101+ unsigned long arg)
9102+{
9103+ return -EINVAL;
9104+}
9105+#endif
1308ab2a 9106+#endif
9107+
1facf9fc 9108+#endif /* __KERNEL__ */
9109+#endif /* __AUFS_DIR_H__ */
7f207e10
AM
9110diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
9111--- /usr/share/empty/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
9112+++ linux/fs/aufs/dynop.c 2013-10-26 16:51:29.582964925 +0200
9113@@ -0,0 +1,380 @@
1facf9fc 9114+/*
7a9e40b8 9115+ * Copyright (C) 2010-2013 Junjiro R. Okajima
1facf9fc 9116+ *
9117+ * This program, aufs is free software; you can redistribute it and/or modify
9118+ * it under the terms of the GNU General Public License as published by
9119+ * the Free Software Foundation; either version 2 of the License, or
9120+ * (at your option) any later version.
dece6358
AM
9121+ *
9122+ * This program is distributed in the hope that it will be useful,
9123+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9124+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9125+ * GNU General Public License for more details.
9126+ *
9127+ * You should have received a copy of the GNU General Public License
9128+ * along with this program; if not, write to the Free Software
9129+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 9130+ */
9131+
9132+/*
4a4d8108 9133+ * dynamically customizable operations for regular files
1facf9fc 9134+ */
9135+
1facf9fc 9136+#include "aufs.h"
9137+
4a4d8108 9138+#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop)
1facf9fc 9139+
4a4d8108
AM
9140+/*
9141+ * How large will these lists be?
9142+ * Usually just a few elements, 20-30 at most for each, I guess.
9143+ */
9144+static struct au_splhead dynop[AuDyLast];
9145+
9146+static struct au_dykey *dy_gfind_get(struct au_splhead *spl, const void *h_op)
1facf9fc 9147+{
4a4d8108
AM
9148+ struct au_dykey *key, *tmp;
9149+ struct list_head *head;
1facf9fc 9150+
4a4d8108
AM
9151+ key = NULL;
9152+ head = &spl->head;
9153+ rcu_read_lock();
9154+ list_for_each_entry_rcu(tmp, head, dk_list)
9155+ if (tmp->dk_op.dy_hop == h_op) {
9156+ key = tmp;
9157+ kref_get(&key->dk_kref);
9158+ break;
9159+ }
9160+ rcu_read_unlock();
9161+
9162+ return key;
1facf9fc 9163+}
9164+
4a4d8108 9165+static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
1facf9fc 9166+{
4a4d8108
AM
9167+ struct au_dykey **k, *found;
9168+ const void *h_op = key->dk_op.dy_hop;
9169+ int i;
1facf9fc 9170+
4a4d8108
AM
9171+ found = NULL;
9172+ k = br->br_dykey;
9173+ for (i = 0; i < AuBrDynOp; i++)
9174+ if (k[i]) {
9175+ if (k[i]->dk_op.dy_hop == h_op) {
9176+ found = k[i];
9177+ break;
9178+ }
9179+ } else
9180+ break;
9181+ if (!found) {
9182+ spin_lock(&br->br_dykey_lock);
9183+ for (; i < AuBrDynOp; i++)
9184+ if (k[i]) {
9185+ if (k[i]->dk_op.dy_hop == h_op) {
9186+ found = k[i];
9187+ break;
9188+ }
9189+ } else {
9190+ k[i] = key;
9191+ break;
9192+ }
9193+ spin_unlock(&br->br_dykey_lock);
9194+ BUG_ON(i == AuBrDynOp); /* expand the array */
9195+ }
9196+
9197+ return found;
1facf9fc 9198+}
9199+
4a4d8108
AM
9200+/* kref_get() if @key is already added */
9201+static struct au_dykey *dy_gadd(struct au_splhead *spl, struct au_dykey *key)
9202+{
9203+ struct au_dykey *tmp, *found;
9204+ struct list_head *head;
9205+ const void *h_op = key->dk_op.dy_hop;
1facf9fc 9206+
4a4d8108
AM
9207+ found = NULL;
9208+ head = &spl->head;
9209+ spin_lock(&spl->spin);
9210+ list_for_each_entry(tmp, head, dk_list)
9211+ if (tmp->dk_op.dy_hop == h_op) {
9212+ kref_get(&tmp->dk_kref);
9213+ found = tmp;
9214+ break;
9215+ }
9216+ if (!found)
9217+ list_add_rcu(&key->dk_list, head);
9218+ spin_unlock(&spl->spin);
1facf9fc 9219+
4a4d8108
AM
9220+ if (!found)
9221+ DyPrSym(key);
9222+ return found;
9223+}
9224+
9225+static void dy_free_rcu(struct rcu_head *rcu)
1facf9fc 9226+{
4a4d8108
AM
9227+ struct au_dykey *key;
9228+
9229+ key = container_of(rcu, struct au_dykey, dk_rcu);
9230+ DyPrSym(key);
9231+ kfree(key);
1facf9fc 9232+}
9233+
4a4d8108
AM
9234+static void dy_free(struct kref *kref)
9235+{
9236+ struct au_dykey *key;
9237+ struct au_splhead *spl;
1facf9fc 9238+
4a4d8108
AM
9239+ key = container_of(kref, struct au_dykey, dk_kref);
9240+ spl = dynop + key->dk_op.dy_type;
9241+ au_spl_del_rcu(&key->dk_list, spl);
9242+ call_rcu(&key->dk_rcu, dy_free_rcu);
9243+}
9244+
9245+void au_dy_put(struct au_dykey *key)
1facf9fc 9246+{
4a4d8108
AM
9247+ kref_put(&key->dk_kref, dy_free);
9248+}
1facf9fc 9249+
4a4d8108
AM
9250+/* ---------------------------------------------------------------------- */
9251+
9252+#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *))
9253+
9254+#ifdef CONFIG_AUFS_DEBUG
9255+#define DyDbgDeclare(cnt) unsigned int cnt = 0
4f0767ce 9256+#define DyDbgInc(cnt) do { cnt++; } while (0)
4a4d8108
AM
9257+#else
9258+#define DyDbgDeclare(cnt) do {} while (0)
9259+#define DyDbgInc(cnt) do {} while (0)
9260+#endif
9261+
9262+#define DySet(func, dst, src, h_op, h_sb) do { \
9263+ DyDbgInc(cnt); \
9264+ if (h_op->func) { \
9265+ if (src.func) \
9266+ dst.func = src.func; \
9267+ else \
9268+ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \
9269+ } \
9270+} while (0)
9271+
9272+#define DySetForce(func, dst, src) do { \
9273+ AuDebugOn(!src.func); \
9274+ DyDbgInc(cnt); \
9275+ dst.func = src.func; \
9276+} while (0)
9277+
9278+#define DySetAop(func) \
9279+ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
9280+#define DySetAopForce(func) \
9281+ DySetForce(func, dyaop->da_op, aufs_aop)
9282+
9283+static void dy_aop(struct au_dykey *key, const void *h_op,
9284+ struct super_block *h_sb __maybe_unused)
9285+{
9286+ struct au_dyaop *dyaop = (void *)key;
9287+ const struct address_space_operations *h_aop = h_op;
9288+ DyDbgDeclare(cnt);
9289+
9290+ AuDbg("%s\n", au_sbtype(h_sb));
9291+
9292+ DySetAop(writepage);
9293+ DySetAopForce(readpage); /* force */
4a4d8108
AM
9294+ DySetAop(writepages);
9295+ DySetAop(set_page_dirty);
9296+ DySetAop(readpages);
9297+ DySetAop(write_begin);
9298+ DySetAop(write_end);
9299+ DySetAop(bmap);
9300+ DySetAop(invalidatepage);
9301+ DySetAop(releasepage);
027c5e7a 9302+ DySetAop(freepage);
4a4d8108
AM
9303+ /* these two will be changed according to an aufs mount option */
9304+ DySetAop(direct_IO);
9305+ DySetAop(get_xip_mem);
9306+ DySetAop(migratepage);
9307+ DySetAop(launder_page);
9308+ DySetAop(is_partially_uptodate);
392086de 9309+ DySetAop(is_dirty_writeback);
4a4d8108 9310+ DySetAop(error_remove_page);
b4510431
AM
9311+ DySetAop(swap_activate);
9312+ DySetAop(swap_deactivate);
4a4d8108
AM
9313+
9314+ DyDbgSize(cnt, *h_aop);
9315+ dyaop->da_get_xip_mem = h_aop->get_xip_mem;
9316+}
9317+
4a4d8108
AM
9318+/* ---------------------------------------------------------------------- */
9319+
9320+static void dy_bug(struct kref *kref)
9321+{
9322+ BUG();
9323+}
9324+
9325+static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
9326+{
9327+ struct au_dykey *key, *old;
9328+ struct au_splhead *spl;
b752ccd1 9329+ struct op {
4a4d8108 9330+ unsigned int sz;
b752ccd1
AM
9331+ void (*set)(struct au_dykey *key, const void *h_op,
9332+ struct super_block *h_sb __maybe_unused);
9333+ };
9334+ static const struct op a[] = {
4a4d8108
AM
9335+ [AuDy_AOP] = {
9336+ .sz = sizeof(struct au_dyaop),
b752ccd1 9337+ .set = dy_aop
4a4d8108 9338+ }
b752ccd1
AM
9339+ };
9340+ const struct op *p;
4a4d8108
AM
9341+
9342+ spl = dynop + op->dy_type;
9343+ key = dy_gfind_get(spl, op->dy_hop);
9344+ if (key)
9345+ goto out_add; /* success */
9346+
9347+ p = a + op->dy_type;
9348+ key = kzalloc(p->sz, GFP_NOFS);
9349+ if (unlikely(!key)) {
9350+ key = ERR_PTR(-ENOMEM);
9351+ goto out;
9352+ }
9353+
9354+ key->dk_op.dy_hop = op->dy_hop;
9355+ kref_init(&key->dk_kref);
86dc4139 9356+ p->set(key, op->dy_hop, au_br_sb(br));
4a4d8108
AM
9357+ old = dy_gadd(spl, key);
9358+ if (old) {
9359+ kfree(key);
9360+ key = old;
9361+ }
9362+
9363+out_add:
9364+ old = dy_bradd(br, key);
9365+ if (old)
9366+ /* its ref-count should never be zero here */
9367+ kref_put(&key->dk_kref, dy_bug);
9368+out:
9369+ return key;
9370+}
9371+
9372+/* ---------------------------------------------------------------------- */
9373+/*
9374+ * Aufs prohibits O_DIRECT by defaut even if the branch supports it.
9375+ * This behaviour is neccessary to return an error from open(O_DIRECT) instead
9376+ * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
9377+ * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
9378+ * See the aufs manual in detail.
9379+ *
9380+ * To keep this behaviour, aufs has to set NULL to ->get_xip_mem too, and the
9381+ * performance of fadvise() and madvise() may be affected.
9382+ */
9383+static void dy_adx(struct au_dyaop *dyaop, int do_dx)
9384+{
9385+ if (!do_dx) {
9386+ dyaop->da_op.direct_IO = NULL;
9387+ dyaop->da_op.get_xip_mem = NULL;
9388+ } else {
9389+ dyaop->da_op.direct_IO = aufs_aop.direct_IO;
9390+ dyaop->da_op.get_xip_mem = aufs_aop.get_xip_mem;
9391+ if (!dyaop->da_get_xip_mem)
9392+ dyaop->da_op.get_xip_mem = NULL;
9393+ }
9394+}
9395+
9396+static struct au_dyaop *dy_aget(struct au_branch *br,
9397+ const struct address_space_operations *h_aop,
9398+ int do_dx)
9399+{
9400+ struct au_dyaop *dyaop;
9401+ struct au_dynop op;
9402+
9403+ op.dy_type = AuDy_AOP;
9404+ op.dy_haop = h_aop;
9405+ dyaop = (void *)dy_get(&op, br);
9406+ if (IS_ERR(dyaop))
9407+ goto out;
9408+ dy_adx(dyaop, do_dx);
9409+
9410+out:
9411+ return dyaop;
9412+}
9413+
9414+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
9415+ struct inode *h_inode)
9416+{
9417+ int err, do_dx;
9418+ struct super_block *sb;
9419+ struct au_branch *br;
9420+ struct au_dyaop *dyaop;
9421+
9422+ AuDebugOn(!S_ISREG(h_inode->i_mode));
9423+ IiMustWriteLock(inode);
9424+
9425+ sb = inode->i_sb;
9426+ br = au_sbr(sb, bindex);
9427+ do_dx = !!au_opt_test(au_mntflags(sb), DIO);
9428+ dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
9429+ err = PTR_ERR(dyaop);
9430+ if (IS_ERR(dyaop))
9431+ /* unnecessary to call dy_fput() */
9432+ goto out;
9433+
9434+ err = 0;
9435+ inode->i_mapping->a_ops = &dyaop->da_op;
9436+
9437+out:
9438+ return err;
9439+}
9440+
b752ccd1
AM
9441+/*
9442+ * Is it safe to replace a_ops during the inode/file is in operation?
9443+ * Yes, I hope so.
9444+ */
9445+int au_dy_irefresh(struct inode *inode)
9446+{
9447+ int err;
9448+ aufs_bindex_t bstart;
9449+ struct inode *h_inode;
9450+
9451+ err = 0;
9452+ if (S_ISREG(inode->i_mode)) {
9453+ bstart = au_ibstart(inode);
9454+ h_inode = au_h_iptr(inode, bstart);
9455+ err = au_dy_iaop(inode, bstart, h_inode);
9456+ }
9457+ return err;
9458+}
9459+
4a4d8108
AM
9460+void au_dy_arefresh(int do_dx)
9461+{
9462+ struct au_splhead *spl;
9463+ struct list_head *head;
9464+ struct au_dykey *key;
9465+
9466+ spl = dynop + AuDy_AOP;
9467+ head = &spl->head;
9468+ spin_lock(&spl->spin);
9469+ list_for_each_entry(key, head, dk_list)
9470+ dy_adx((void *)key, do_dx);
9471+ spin_unlock(&spl->spin);
9472+}
9473+
4a4d8108
AM
9474+/* ---------------------------------------------------------------------- */
9475+
9476+void __init au_dy_init(void)
9477+{
9478+ int i;
9479+
9480+ /* make sure that 'struct au_dykey *' can be any type */
9481+ BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
4a4d8108
AM
9482+
9483+ for (i = 0; i < AuDyLast; i++)
9484+ au_spl_init(dynop + i);
9485+}
9486+
9487+void au_dy_fin(void)
9488+{
9489+ int i;
9490+
9491+ for (i = 0; i < AuDyLast; i++)
9492+ WARN_ON(!list_empty(&dynop[i].head));
9493+}
7f207e10
AM
9494diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
9495--- /usr/share/empty/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100
86dc4139 9496+++ linux/fs/aufs/dynop.h 2013-07-06 13:20:47.740198107 +0200
f6c5ef8b 9497@@ -0,0 +1,76 @@
4a4d8108 9498+/*
7a9e40b8 9499+ * Copyright (C) 2010-2013 Junjiro R. Okajima
4a4d8108
AM
9500+ *
9501+ * This program, aufs is free software; you can redistribute it and/or modify
9502+ * it under the terms of the GNU General Public License as published by
9503+ * the Free Software Foundation; either version 2 of the License, or
9504+ * (at your option) any later version.
9505+ *
9506+ * This program is distributed in the hope that it will be useful,
9507+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9508+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9509+ * GNU General Public License for more details.
9510+ *
9511+ * You should have received a copy of the GNU General Public License
9512+ * along with this program; if not, write to the Free Software
9513+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9514+ */
9515+
9516+/*
9517+ * dynamically customizable operations (for regular files only)
9518+ */
9519+
9520+#ifndef __AUFS_DYNOP_H__
9521+#define __AUFS_DYNOP_H__
9522+
9523+#ifdef __KERNEL__
9524+
4a4d8108
AM
9525+#include "inode.h"
9526+
2cbb1c4b 9527+enum {AuDy_AOP, AuDyLast};
4a4d8108
AM
9528+
9529+struct au_dynop {
9530+ int dy_type;
9531+ union {
9532+ const void *dy_hop;
9533+ const struct address_space_operations *dy_haop;
4a4d8108
AM
9534+ };
9535+};
9536+
9537+struct au_dykey {
9538+ union {
9539+ struct list_head dk_list;
9540+ struct rcu_head dk_rcu;
9541+ };
9542+ struct au_dynop dk_op;
9543+
9544+ /*
9545+ * during I am in the branch local array, kref is gotten. when the
9546+ * branch is removed, kref is put.
9547+ */
9548+ struct kref dk_kref;
9549+};
9550+
9551+/* stop unioning since their sizes are very different from each other */
9552+struct au_dyaop {
9553+ struct au_dykey da_key;
9554+ struct address_space_operations da_op; /* not const */
9555+ int (*da_get_xip_mem)(struct address_space *, pgoff_t, int,
9556+ void **, unsigned long *);
9557+};
9558+
4a4d8108
AM
9559+/* ---------------------------------------------------------------------- */
9560+
9561+/* dynop.c */
9562+struct au_branch;
9563+void au_dy_put(struct au_dykey *key);
9564+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
9565+ struct inode *h_inode);
b752ccd1 9566+int au_dy_irefresh(struct inode *inode);
4a4d8108 9567+void au_dy_arefresh(int do_dio);
4a4d8108
AM
9568+
9569+void __init au_dy_init(void);
9570+void au_dy_fin(void);
9571+
4a4d8108
AM
9572+#endif /* __KERNEL__ */
9573+#endif /* __AUFS_DYNOP_H__ */
7f207e10
AM
9574diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
9575--- /usr/share/empty/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
9576+++ linux/fs/aufs/export.c 2013-10-26 16:51:29.582964925 +0200
9577@@ -0,0 +1,832 @@
4a4d8108 9578+/*
7a9e40b8 9579+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
9580+ *
9581+ * This program, aufs is free software; you can redistribute it and/or modify
9582+ * it under the terms of the GNU General Public License as published by
9583+ * the Free Software Foundation; either version 2 of the License, or
9584+ * (at your option) any later version.
9585+ *
9586+ * This program is distributed in the hope that it will be useful,
9587+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9588+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9589+ * GNU General Public License for more details.
9590+ *
9591+ * You should have received a copy of the GNU General Public License
9592+ * along with this program; if not, write to the Free Software
9593+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9594+ */
9595+
9596+/*
9597+ * export via nfs
9598+ */
9599+
9600+#include <linux/exportfs.h>
7eafdf33 9601+#include <linux/fs_struct.h>
4a4d8108
AM
9602+#include <linux/namei.h>
9603+#include <linux/nsproxy.h>
9604+#include <linux/random.h>
9605+#include <linux/writeback.h>
7eafdf33 9606+#include "../fs/mount.h"
4a4d8108
AM
9607+#include "aufs.h"
9608+
9609+union conv {
9610+#ifdef CONFIG_AUFS_INO_T_64
9611+ __u32 a[2];
9612+#else
9613+ __u32 a[1];
9614+#endif
9615+ ino_t ino;
9616+};
9617+
9618+static ino_t decode_ino(__u32 *a)
9619+{
9620+ union conv u;
9621+
9622+ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
9623+ u.a[0] = a[0];
9624+#ifdef CONFIG_AUFS_INO_T_64
9625+ u.a[1] = a[1];
9626+#endif
9627+ return u.ino;
9628+}
9629+
9630+static void encode_ino(__u32 *a, ino_t ino)
9631+{
9632+ union conv u;
9633+
9634+ u.ino = ino;
9635+ a[0] = u.a[0];
9636+#ifdef CONFIG_AUFS_INO_T_64
9637+ a[1] = u.a[1];
9638+#endif
9639+}
9640+
9641+/* NFS file handle */
9642+enum {
9643+ Fh_br_id,
9644+ Fh_sigen,
9645+#ifdef CONFIG_AUFS_INO_T_64
9646+ /* support 64bit inode number */
9647+ Fh_ino1,
9648+ Fh_ino2,
9649+ Fh_dir_ino1,
9650+ Fh_dir_ino2,
9651+#else
9652+ Fh_ino1,
9653+ Fh_dir_ino1,
9654+#endif
9655+ Fh_igen,
9656+ Fh_h_type,
9657+ Fh_tail,
9658+
9659+ Fh_ino = Fh_ino1,
9660+ Fh_dir_ino = Fh_dir_ino1
9661+};
9662+
9663+static int au_test_anon(struct dentry *dentry)
9664+{
027c5e7a 9665+ /* note: read d_flags without d_lock */
4a4d8108
AM
9666+ return !!(dentry->d_flags & DCACHE_DISCONNECTED);
9667+}
9668+
a2a7ad62
AM
9669+int au_test_nfsd(void)
9670+{
9671+ int ret;
9672+ struct task_struct *tsk = current;
9673+ char comm[sizeof(tsk->comm)];
9674+
9675+ ret = 0;
9676+ if (tsk->flags & PF_KTHREAD) {
9677+ get_task_comm(comm, tsk);
9678+ ret = !strcmp(comm, "nfsd");
9679+ }
9680+
9681+ return ret;
9682+}
9683+
4a4d8108
AM
9684+/* ---------------------------------------------------------------------- */
9685+/* inode generation external table */
9686+
b752ccd1 9687+void au_xigen_inc(struct inode *inode)
4a4d8108 9688+{
4a4d8108
AM
9689+ loff_t pos;
9690+ ssize_t sz;
9691+ __u32 igen;
9692+ struct super_block *sb;
9693+ struct au_sbinfo *sbinfo;
9694+
4a4d8108 9695+ sb = inode->i_sb;
b752ccd1 9696+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
1facf9fc 9697+
b752ccd1 9698+ sbinfo = au_sbi(sb);
1facf9fc 9699+ pos = inode->i_ino;
9700+ pos *= sizeof(igen);
9701+ igen = inode->i_generation + 1;
1facf9fc 9702+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
9703+ sizeof(igen), &pos);
9704+ if (sz == sizeof(igen))
b752ccd1 9705+ return; /* success */
1facf9fc 9706+
b752ccd1 9707+ if (unlikely(sz >= 0))
1facf9fc 9708+ AuIOErr("xigen error (%zd)\n", sz);
1facf9fc 9709+}
9710+
9711+int au_xigen_new(struct inode *inode)
9712+{
9713+ int err;
9714+ loff_t pos;
9715+ ssize_t sz;
9716+ struct super_block *sb;
9717+ struct au_sbinfo *sbinfo;
9718+ struct file *file;
9719+
9720+ err = 0;
9721+ /* todo: dirty, at mount time */
9722+ if (inode->i_ino == AUFS_ROOT_INO)
9723+ goto out;
9724+ sb = inode->i_sb;
dece6358 9725+ SiMustAnyLock(sb);
1facf9fc 9726+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
9727+ goto out;
9728+
9729+ err = -EFBIG;
9730+ pos = inode->i_ino;
9731+ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
9732+ AuIOErr1("too large i%lld\n", pos);
9733+ goto out;
9734+ }
9735+ pos *= sizeof(inode->i_generation);
9736+
9737+ err = 0;
9738+ sbinfo = au_sbi(sb);
9739+ file = sbinfo->si_xigen;
9740+ BUG_ON(!file);
9741+
c06a8ce3 9742+ if (vfsub_f_size_read(file)
1facf9fc 9743+ < pos + sizeof(inode->i_generation)) {
9744+ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
9745+ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
9746+ sizeof(inode->i_generation), &pos);
9747+ } else
9748+ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
9749+ sizeof(inode->i_generation), &pos);
9750+ if (sz == sizeof(inode->i_generation))
9751+ goto out; /* success */
9752+
9753+ err = sz;
9754+ if (unlikely(sz >= 0)) {
9755+ err = -EIO;
9756+ AuIOErr("xigen error (%zd)\n", sz);
9757+ }
9758+
4f0767ce 9759+out:
1facf9fc 9760+ return err;
9761+}
9762+
9763+int au_xigen_set(struct super_block *sb, struct file *base)
9764+{
9765+ int err;
9766+ struct au_sbinfo *sbinfo;
9767+ struct file *file;
9768+
dece6358
AM
9769+ SiMustWriteLock(sb);
9770+
1facf9fc 9771+ sbinfo = au_sbi(sb);
9772+ file = au_xino_create2(base, sbinfo->si_xigen);
9773+ err = PTR_ERR(file);
9774+ if (IS_ERR(file))
9775+ goto out;
9776+ err = 0;
9777+ if (sbinfo->si_xigen)
9778+ fput(sbinfo->si_xigen);
9779+ sbinfo->si_xigen = file;
9780+
4f0767ce 9781+out:
1facf9fc 9782+ return err;
9783+}
9784+
9785+void au_xigen_clr(struct super_block *sb)
9786+{
9787+ struct au_sbinfo *sbinfo;
9788+
dece6358
AM
9789+ SiMustWriteLock(sb);
9790+
1facf9fc 9791+ sbinfo = au_sbi(sb);
9792+ if (sbinfo->si_xigen) {
9793+ fput(sbinfo->si_xigen);
9794+ sbinfo->si_xigen = NULL;
9795+ }
9796+}
9797+
9798+/* ---------------------------------------------------------------------- */
9799+
9800+static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
9801+ ino_t dir_ino)
9802+{
9803+ struct dentry *dentry, *d;
9804+ struct inode *inode;
9805+ unsigned int sigen;
9806+
9807+ dentry = NULL;
9808+ inode = ilookup(sb, ino);
9809+ if (!inode)
9810+ goto out;
9811+
9812+ dentry = ERR_PTR(-ESTALE);
9813+ sigen = au_sigen(sb);
9814+ if (unlikely(is_bad_inode(inode)
9815+ || IS_DEADDIR(inode)
537831f9 9816+ || sigen != au_iigen(inode, NULL)))
1facf9fc 9817+ goto out_iput;
9818+
9819+ dentry = NULL;
9820+ if (!dir_ino || S_ISDIR(inode->i_mode))
9821+ dentry = d_find_alias(inode);
9822+ else {
027c5e7a 9823+ spin_lock(&inode->i_lock);
c06a8ce3 9824+ hlist_for_each_entry(d, &inode->i_dentry, d_alias) {
027c5e7a 9825+ spin_lock(&d->d_lock);
1facf9fc 9826+ if (!au_test_anon(d)
9827+ && d->d_parent->d_inode->i_ino == dir_ino) {
027c5e7a
AM
9828+ dentry = dget_dlock(d);
9829+ spin_unlock(&d->d_lock);
1facf9fc 9830+ break;
9831+ }
027c5e7a
AM
9832+ spin_unlock(&d->d_lock);
9833+ }
9834+ spin_unlock(&inode->i_lock);
1facf9fc 9835+ }
027c5e7a 9836+ if (unlikely(dentry && au_digen_test(dentry, sigen))) {
2cbb1c4b 9837+ /* need to refresh */
1facf9fc 9838+ dput(dentry);
2cbb1c4b 9839+ dentry = NULL;
1facf9fc 9840+ }
9841+
4f0767ce 9842+out_iput:
1facf9fc 9843+ iput(inode);
4f0767ce 9844+out:
2cbb1c4b 9845+ AuTraceErrPtr(dentry);
1facf9fc 9846+ return dentry;
9847+}
9848+
9849+/* ---------------------------------------------------------------------- */
9850+
9851+/* todo: dirty? */
9852+/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
4a4d8108
AM
9853+
9854+struct au_compare_mnt_args {
9855+ /* input */
9856+ struct super_block *sb;
9857+
9858+ /* output */
9859+ struct vfsmount *mnt;
9860+};
9861+
9862+static int au_compare_mnt(struct vfsmount *mnt, void *arg)
9863+{
9864+ struct au_compare_mnt_args *a = arg;
9865+
9866+ if (mnt->mnt_sb != a->sb)
9867+ return 0;
9868+ a->mnt = mntget(mnt);
9869+ return 1;
9870+}
9871+
1facf9fc 9872+static struct vfsmount *au_mnt_get(struct super_block *sb)
9873+{
4a4d8108 9874+ int err;
7eafdf33 9875+ struct path root;
4a4d8108
AM
9876+ struct au_compare_mnt_args args = {
9877+ .sb = sb
9878+ };
1facf9fc 9879+
7eafdf33 9880+ get_fs_root(current->fs, &root);
0c3ec466 9881+ br_read_lock(&vfsmount_lock);
7eafdf33 9882+ err = iterate_mounts(au_compare_mnt, &args, root.mnt);
0c3ec466 9883+ br_read_unlock(&vfsmount_lock);
7eafdf33 9884+ path_put(&root);
4a4d8108
AM
9885+ AuDebugOn(!err);
9886+ AuDebugOn(!args.mnt);
9887+ return args.mnt;
1facf9fc 9888+}
9889+
9890+struct au_nfsd_si_lock {
4a4d8108 9891+ unsigned int sigen;
027c5e7a 9892+ aufs_bindex_t bindex, br_id;
1facf9fc 9893+ unsigned char force_lock;
9894+};
9895+
027c5e7a
AM
9896+static int si_nfsd_read_lock(struct super_block *sb,
9897+ struct au_nfsd_si_lock *nsi_lock)
1facf9fc 9898+{
027c5e7a 9899+ int err;
1facf9fc 9900+ aufs_bindex_t bindex;
9901+
9902+ si_read_lock(sb, AuLock_FLUSH);
9903+
9904+ /* branch id may be wrapped around */
027c5e7a 9905+ err = 0;
1facf9fc 9906+ bindex = au_br_index(sb, nsi_lock->br_id);
9907+ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
9908+ goto out; /* success */
9909+
027c5e7a
AM
9910+ err = -ESTALE;
9911+ bindex = -1;
1facf9fc 9912+ if (!nsi_lock->force_lock)
9913+ si_read_unlock(sb);
1facf9fc 9914+
4f0767ce 9915+out:
027c5e7a
AM
9916+ nsi_lock->bindex = bindex;
9917+ return err;
1facf9fc 9918+}
9919+
9920+struct find_name_by_ino {
392086de 9921+ struct dir_context ctx;
1facf9fc 9922+ int called, found;
9923+ ino_t ino;
9924+ char *name;
9925+ int namelen;
9926+};
9927+
9928+static int
392086de
AM
9929+find_name_by_ino(struct dir_context *ctx, const char *name, int namelen,
9930+ loff_t offset, u64 ino, unsigned int d_type)
1facf9fc 9931+{
392086de
AM
9932+ struct find_name_by_ino *a = container_of(ctx, struct find_name_by_ino,
9933+ ctx);
1facf9fc 9934+
9935+ a->called++;
9936+ if (a->ino != ino)
9937+ return 0;
9938+
9939+ memcpy(a->name, name, namelen);
9940+ a->namelen = namelen;
9941+ a->found = 1;
9942+ return 1;
9943+}
9944+
9945+static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
9946+ struct au_nfsd_si_lock *nsi_lock)
9947+{
9948+ struct dentry *dentry, *parent;
9949+ struct file *file;
9950+ struct inode *dir;
392086de
AM
9951+ struct find_name_by_ino arg = {
9952+ .ctx = {
9953+ .actor = au_diractor(find_name_by_ino)
9954+ }
9955+ };
1facf9fc 9956+ int err;
9957+
9958+ parent = path->dentry;
9959+ if (nsi_lock)
9960+ si_read_unlock(parent->d_sb);
4a4d8108 9961+ file = vfsub_dentry_open(path, au_dir_roflags);
1facf9fc 9962+ dentry = (void *)file;
9963+ if (IS_ERR(file))
9964+ goto out;
9965+
9966+ dentry = ERR_PTR(-ENOMEM);
537831f9 9967+ arg.name = (void *)__get_free_page(GFP_NOFS);
1facf9fc 9968+ if (unlikely(!arg.name))
9969+ goto out_file;
9970+ arg.ino = ino;
9971+ arg.found = 0;
9972+ do {
9973+ arg.called = 0;
9974+ /* smp_mb(); */
392086de 9975+ err = vfsub_iterate_dir(file, &arg.ctx);
1facf9fc 9976+ } while (!err && !arg.found && arg.called);
9977+ dentry = ERR_PTR(err);
9978+ if (unlikely(err))
9979+ goto out_name;
1716fcea
AM
9980+ /* instead of ENOENT */
9981+ dentry = ERR_PTR(-ESTALE);
1facf9fc 9982+ if (!arg.found)
9983+ goto out_name;
9984+
b4510431 9985+ /* do not call vfsub_lkup_one() */
1facf9fc 9986+ dir = parent->d_inode;
9987+ mutex_lock(&dir->i_mutex);
9988+ dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
9989+ mutex_unlock(&dir->i_mutex);
9990+ AuTraceErrPtr(dentry);
9991+ if (IS_ERR(dentry))
9992+ goto out_name;
9993+ AuDebugOn(au_test_anon(dentry));
9994+ if (unlikely(!dentry->d_inode)) {
9995+ dput(dentry);
9996+ dentry = ERR_PTR(-ENOENT);
9997+ }
9998+
4f0767ce 9999+out_name:
537831f9 10000+ free_page((unsigned long)arg.name);
4f0767ce 10001+out_file:
1facf9fc 10002+ fput(file);
4f0767ce 10003+out:
1facf9fc 10004+ if (unlikely(nsi_lock
10005+ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
10006+ if (!IS_ERR(dentry)) {
10007+ dput(dentry);
10008+ dentry = ERR_PTR(-ESTALE);
10009+ }
10010+ AuTraceErrPtr(dentry);
10011+ return dentry;
10012+}
10013+
10014+static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
10015+ ino_t dir_ino,
10016+ struct au_nfsd_si_lock *nsi_lock)
10017+{
10018+ struct dentry *dentry;
10019+ struct path path;
10020+
10021+ if (dir_ino != AUFS_ROOT_INO) {
10022+ path.dentry = decode_by_ino(sb, dir_ino, 0);
10023+ dentry = path.dentry;
10024+ if (!path.dentry || IS_ERR(path.dentry))
10025+ goto out;
10026+ AuDebugOn(au_test_anon(path.dentry));
10027+ } else
10028+ path.dentry = dget(sb->s_root);
10029+
10030+ path.mnt = au_mnt_get(sb);
10031+ dentry = au_lkup_by_ino(&path, ino, nsi_lock);
10032+ path_put(&path);
10033+
4f0767ce 10034+out:
1facf9fc 10035+ AuTraceErrPtr(dentry);
10036+ return dentry;
10037+}
10038+
10039+/* ---------------------------------------------------------------------- */
10040+
10041+static int h_acceptable(void *expv, struct dentry *dentry)
10042+{
10043+ return 1;
10044+}
10045+
10046+static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
10047+ char *buf, int len, struct super_block *sb)
10048+{
10049+ char *p;
10050+ int n;
10051+ struct path path;
10052+
10053+ p = d_path(h_rootpath, buf, len);
10054+ if (IS_ERR(p))
10055+ goto out;
10056+ n = strlen(p);
10057+
10058+ path.mnt = h_rootpath->mnt;
10059+ path.dentry = h_parent;
10060+ p = d_path(&path, buf, len);
10061+ if (IS_ERR(p))
10062+ goto out;
10063+ if (n != 1)
10064+ p += n;
10065+
10066+ path.mnt = au_mnt_get(sb);
10067+ path.dentry = sb->s_root;
10068+ p = d_path(&path, buf, len - strlen(p));
10069+ mntput(path.mnt);
10070+ if (IS_ERR(p))
10071+ goto out;
10072+ if (n != 1)
10073+ p[strlen(p)] = '/';
10074+
4f0767ce 10075+out:
1facf9fc 10076+ AuTraceErrPtr(p);
10077+ return p;
10078+}
10079+
10080+static
027c5e7a
AM
10081+struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
10082+ int fh_len, struct au_nfsd_si_lock *nsi_lock)
1facf9fc 10083+{
10084+ struct dentry *dentry, *h_parent, *root;
10085+ struct super_block *h_sb;
10086+ char *pathname, *p;
10087+ struct vfsmount *h_mnt;
10088+ struct au_branch *br;
10089+ int err;
10090+ struct path path;
10091+
027c5e7a 10092+ br = au_sbr(sb, nsi_lock->bindex);
86dc4139 10093+ h_mnt = au_br_mnt(br);
1facf9fc 10094+ h_sb = h_mnt->mnt_sb;
10095+ /* todo: call lower fh_to_dentry()? fh_to_parent()? */
10096+ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
10097+ fh_len - Fh_tail, fh[Fh_h_type],
10098+ h_acceptable, /*context*/NULL);
10099+ dentry = h_parent;
10100+ if (unlikely(!h_parent || IS_ERR(h_parent))) {
10101+ AuWarn1("%s decode_fh failed, %ld\n",
10102+ au_sbtype(h_sb), PTR_ERR(h_parent));
10103+ goto out;
10104+ }
10105+ dentry = NULL;
10106+ if (unlikely(au_test_anon(h_parent))) {
10107+ AuWarn1("%s decode_fh returned a disconnected dentry\n",
10108+ au_sbtype(h_sb));
10109+ goto out_h_parent;
10110+ }
10111+
10112+ dentry = ERR_PTR(-ENOMEM);
10113+ pathname = (void *)__get_free_page(GFP_NOFS);
10114+ if (unlikely(!pathname))
10115+ goto out_h_parent;
10116+
10117+ root = sb->s_root;
10118+ path.mnt = h_mnt;
10119+ di_read_lock_parent(root, !AuLock_IR);
027c5e7a 10120+ path.dentry = au_h_dptr(root, nsi_lock->bindex);
1facf9fc 10121+ di_read_unlock(root, !AuLock_IR);
10122+ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
10123+ dentry = (void *)p;
10124+ if (IS_ERR(p))
10125+ goto out_pathname;
10126+
10127+ si_read_unlock(sb);
10128+ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
10129+ dentry = ERR_PTR(err);
10130+ if (unlikely(err))
10131+ goto out_relock;
10132+
10133+ dentry = ERR_PTR(-ENOENT);
10134+ AuDebugOn(au_test_anon(path.dentry));
10135+ if (unlikely(!path.dentry->d_inode))
10136+ goto out_path;
10137+
10138+ if (ino != path.dentry->d_inode->i_ino)
10139+ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
10140+ else
10141+ dentry = dget(path.dentry);
10142+
4f0767ce 10143+out_path:
1facf9fc 10144+ path_put(&path);
4f0767ce 10145+out_relock:
1facf9fc 10146+ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
10147+ if (!IS_ERR(dentry)) {
10148+ dput(dentry);
10149+ dentry = ERR_PTR(-ESTALE);
10150+ }
4f0767ce 10151+out_pathname:
1facf9fc 10152+ free_page((unsigned long)pathname);
4f0767ce 10153+out_h_parent:
1facf9fc 10154+ dput(h_parent);
4f0767ce 10155+out:
1facf9fc 10156+ AuTraceErrPtr(dentry);
10157+ return dentry;
10158+}
10159+
10160+/* ---------------------------------------------------------------------- */
10161+
10162+static struct dentry *
10163+aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
10164+ int fh_type)
10165+{
10166+ struct dentry *dentry;
10167+ __u32 *fh = fid->raw;
027c5e7a 10168+ struct au_branch *br;
1facf9fc 10169+ ino_t ino, dir_ino;
1facf9fc 10170+ struct au_nfsd_si_lock nsi_lock = {
1facf9fc 10171+ .force_lock = 0
10172+ };
10173+
1facf9fc 10174+ dentry = ERR_PTR(-ESTALE);
4a4d8108
AM
10175+ /* it should never happen, but the file handle is unreliable */
10176+ if (unlikely(fh_len < Fh_tail))
10177+ goto out;
10178+ nsi_lock.sigen = fh[Fh_sigen];
10179+ nsi_lock.br_id = fh[Fh_br_id];
10180+
1facf9fc 10181+ /* branch id may be wrapped around */
027c5e7a
AM
10182+ br = NULL;
10183+ if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
1facf9fc 10184+ goto out;
10185+ nsi_lock.force_lock = 1;
10186+
10187+ /* is this inode still cached? */
10188+ ino = decode_ino(fh + Fh_ino);
4a4d8108
AM
10189+ /* it should never happen */
10190+ if (unlikely(ino == AUFS_ROOT_INO))
10191+ goto out;
10192+
1facf9fc 10193+ dir_ino = decode_ino(fh + Fh_dir_ino);
10194+ dentry = decode_by_ino(sb, ino, dir_ino);
10195+ if (IS_ERR(dentry))
10196+ goto out_unlock;
10197+ if (dentry)
10198+ goto accept;
10199+
10200+ /* is the parent dir cached? */
027c5e7a
AM
10201+ br = au_sbr(sb, nsi_lock.bindex);
10202+ atomic_inc(&br->br_count);
1facf9fc 10203+ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
10204+ if (IS_ERR(dentry))
10205+ goto out_unlock;
10206+ if (dentry)
10207+ goto accept;
10208+
10209+ /* lookup path */
027c5e7a 10210+ dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
1facf9fc 10211+ if (IS_ERR(dentry))
10212+ goto out_unlock;
10213+ if (unlikely(!dentry))
10214+ /* todo?: make it ESTALE */
10215+ goto out_unlock;
10216+
4f0767ce 10217+accept:
027c5e7a
AM
10218+ if (!au_digen_test(dentry, au_sigen(sb))
10219+ && dentry->d_inode->i_generation == fh[Fh_igen])
1facf9fc 10220+ goto out_unlock; /* success */
10221+
10222+ dput(dentry);
10223+ dentry = ERR_PTR(-ESTALE);
4f0767ce 10224+out_unlock:
027c5e7a
AM
10225+ if (br)
10226+ atomic_dec(&br->br_count);
1facf9fc 10227+ si_read_unlock(sb);
4f0767ce 10228+out:
1facf9fc 10229+ AuTraceErrPtr(dentry);
10230+ return dentry;
10231+}
10232+
10233+#if 0 /* reserved for future use */
10234+/* support subtreecheck option */
10235+static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
10236+ int fh_len, int fh_type)
10237+{
10238+ struct dentry *parent;
10239+ __u32 *fh = fid->raw;
10240+ ino_t dir_ino;
10241+
10242+ dir_ino = decode_ino(fh + Fh_dir_ino);
10243+ parent = decode_by_ino(sb, dir_ino, 0);
10244+ if (IS_ERR(parent))
10245+ goto out;
10246+ if (!parent)
10247+ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
10248+ dir_ino, fh, fh_len);
10249+
4f0767ce 10250+out:
1facf9fc 10251+ AuTraceErrPtr(parent);
10252+ return parent;
10253+}
10254+#endif
10255+
10256+/* ---------------------------------------------------------------------- */
10257+
0c3ec466
AM
10258+static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
10259+ struct inode *dir)
1facf9fc 10260+{
10261+ int err;
0c3ec466 10262+ aufs_bindex_t bindex;
1facf9fc 10263+ struct super_block *sb, *h_sb;
0c3ec466
AM
10264+ struct dentry *dentry, *parent, *h_parent;
10265+ struct inode *h_dir;
1facf9fc 10266+ struct au_branch *br;
10267+
1facf9fc 10268+ err = -ENOSPC;
10269+ if (unlikely(*max_len <= Fh_tail)) {
10270+ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
10271+ goto out;
10272+ }
10273+
10274+ err = FILEID_ROOT;
0c3ec466
AM
10275+ if (inode->i_ino == AUFS_ROOT_INO) {
10276+ AuDebugOn(inode->i_ino != AUFS_ROOT_INO);
1facf9fc 10277+ goto out;
10278+ }
10279+
1facf9fc 10280+ h_parent = NULL;
0c3ec466
AM
10281+ sb = inode->i_sb;
10282+ err = si_read_lock(sb, AuLock_FLUSH);
027c5e7a
AM
10283+ if (unlikely(err))
10284+ goto out;
10285+
1facf9fc 10286+#ifdef CONFIG_AUFS_DEBUG
10287+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
10288+ AuWarn1("NFS-exporting requires xino\n");
10289+#endif
027c5e7a 10290+ err = -EIO;
0c3ec466
AM
10291+ parent = NULL;
10292+ ii_read_lock_child(inode);
10293+ bindex = au_ibstart(inode);
10294+ if (!dir) {
10295+ dentry = d_find_alias(inode);
10296+ if (unlikely(!dentry))
10297+ goto out_unlock;
10298+ AuDebugOn(au_test_anon(dentry));
10299+ parent = dget_parent(dentry);
10300+ dput(dentry);
10301+ if (unlikely(!parent))
10302+ goto out_unlock;
10303+ dir = parent->d_inode;
1facf9fc 10304+ }
0c3ec466
AM
10305+
10306+ ii_read_lock_parent(dir);
10307+ h_dir = au_h_iptr(dir, bindex);
10308+ ii_read_unlock(dir);
10309+ if (unlikely(!h_dir))
10310+ goto out_parent;
10311+ h_parent = d_find_alias(h_dir);
1facf9fc 10312+ if (unlikely(!h_parent))
0c3ec466 10313+ goto out_hparent;
1facf9fc 10314+
10315+ err = -EPERM;
10316+ br = au_sbr(sb, bindex);
86dc4139 10317+ h_sb = au_br_sb(br);
1facf9fc 10318+ if (unlikely(!h_sb->s_export_op)) {
10319+ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
0c3ec466 10320+ goto out_hparent;
1facf9fc 10321+ }
10322+
10323+ fh[Fh_br_id] = br->br_id;
10324+ fh[Fh_sigen] = au_sigen(sb);
10325+ encode_ino(fh + Fh_ino, inode->i_ino);
0c3ec466 10326+ encode_ino(fh + Fh_dir_ino, dir->i_ino);
1facf9fc 10327+ fh[Fh_igen] = inode->i_generation;
10328+
10329+ *max_len -= Fh_tail;
10330+ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
10331+ max_len,
10332+ /*connectable or subtreecheck*/0);
10333+ err = fh[Fh_h_type];
10334+ *max_len += Fh_tail;
10335+ /* todo: macros? */
1716fcea 10336+ if (err != FILEID_INVALID)
1facf9fc 10337+ err = 99;
10338+ else
10339+ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
10340+
0c3ec466 10341+out_hparent:
1facf9fc 10342+ dput(h_parent);
0c3ec466 10343+out_parent:
1facf9fc 10344+ dput(parent);
0c3ec466
AM
10345+out_unlock:
10346+ ii_read_unlock(inode);
10347+ si_read_unlock(sb);
4f0767ce 10348+out:
1facf9fc 10349+ if (unlikely(err < 0))
1716fcea 10350+ err = FILEID_INVALID;
1facf9fc 10351+ return err;
10352+}
10353+
10354+/* ---------------------------------------------------------------------- */
10355+
4a4d8108
AM
10356+static int aufs_commit_metadata(struct inode *inode)
10357+{
10358+ int err;
10359+ aufs_bindex_t bindex;
10360+ struct super_block *sb;
10361+ struct inode *h_inode;
10362+ int (*f)(struct inode *inode);
10363+
10364+ sb = inode->i_sb;
e49829fe 10365+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
10366+ ii_write_lock_child(inode);
10367+ bindex = au_ibstart(inode);
10368+ AuDebugOn(bindex < 0);
10369+ h_inode = au_h_iptr(inode, bindex);
10370+
10371+ f = h_inode->i_sb->s_export_op->commit_metadata;
10372+ if (f)
10373+ err = f(h_inode);
10374+ else {
10375+ struct writeback_control wbc = {
10376+ .sync_mode = WB_SYNC_ALL,
10377+ .nr_to_write = 0 /* metadata only */
10378+ };
10379+
10380+ err = sync_inode(h_inode, &wbc);
10381+ }
10382+
10383+ au_cpup_attr_timesizes(inode);
10384+ ii_write_unlock(inode);
10385+ si_read_unlock(sb);
10386+ return err;
10387+}
10388+
10389+/* ---------------------------------------------------------------------- */
10390+
1facf9fc 10391+static struct export_operations aufs_export_op = {
4a4d8108 10392+ .fh_to_dentry = aufs_fh_to_dentry,
1facf9fc 10393+ /* .fh_to_parent = aufs_fh_to_parent, */
4a4d8108
AM
10394+ .encode_fh = aufs_encode_fh,
10395+ .commit_metadata = aufs_commit_metadata
1facf9fc 10396+};
10397+
10398+void au_export_init(struct super_block *sb)
10399+{
10400+ struct au_sbinfo *sbinfo;
10401+ __u32 u;
10402+
10403+ sb->s_export_op = &aufs_export_op;
10404+ sbinfo = au_sbi(sb);
10405+ sbinfo->si_xigen = NULL;
10406+ get_random_bytes(&u, sizeof(u));
10407+ BUILD_BUG_ON(sizeof(u) != sizeof(int));
10408+ atomic_set(&sbinfo->si_xigen_next, u);
10409+}
7f207e10
AM
10410diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
10411--- /usr/share/empty/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
10412+++ linux/fs/aufs/file.c 2013-10-26 16:51:32.273040419 +0200
10413@@ -0,0 +1,725 @@
1facf9fc 10414+/*
7a9e40b8 10415+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 10416+ *
10417+ * This program, aufs is free software; you can redistribute it and/or modify
10418+ * it under the terms of the GNU General Public License as published by
10419+ * the Free Software Foundation; either version 2 of the License, or
10420+ * (at your option) any later version.
dece6358
AM
10421+ *
10422+ * This program is distributed in the hope that it will be useful,
10423+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10424+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10425+ * GNU General Public License for more details.
10426+ *
10427+ * You should have received a copy of the GNU General Public License
10428+ * along with this program; if not, write to the Free Software
10429+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 10430+ */
10431+
10432+/*
4a4d8108 10433+ * handling file/dir, and address_space operation
1facf9fc 10434+ */
10435+
7eafdf33
AM
10436+#ifdef CONFIG_AUFS_DEBUG
10437+#include <linux/migrate.h>
10438+#endif
4a4d8108 10439+#include <linux/pagemap.h>
1facf9fc 10440+#include "aufs.h"
10441+
4a4d8108
AM
10442+/* drop flags for writing */
10443+unsigned int au_file_roflags(unsigned int flags)
10444+{
10445+ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
10446+ flags |= O_RDONLY | O_NOATIME;
10447+ return flags;
10448+}
10449+
10450+/* common functions to regular file and dir */
10451+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 10452+ struct file *file, int force_wr)
1facf9fc 10453+{
1308ab2a 10454+ struct file *h_file;
4a4d8108
AM
10455+ struct dentry *h_dentry;
10456+ struct inode *h_inode;
10457+ struct super_block *sb;
10458+ struct au_branch *br;
10459+ struct path h_path;
10460+ int err, exec_flag;
1facf9fc 10461+
4a4d8108
AM
10462+ /* a race condition can happen between open and unlink/rmdir */
10463+ h_file = ERR_PTR(-ENOENT);
10464+ h_dentry = au_h_dptr(dentry, bindex);
b752ccd1 10465+ if (au_test_nfsd() && !h_dentry)
4a4d8108
AM
10466+ goto out;
10467+ h_inode = h_dentry->d_inode;
b752ccd1 10468+ if (au_test_nfsd() && !h_inode)
4a4d8108 10469+ goto out;
027c5e7a
AM
10470+ spin_lock(&h_dentry->d_lock);
10471+ err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
10472+ || !h_inode
10473+ /* || !dentry->d_inode->i_nlink */
10474+ ;
10475+ spin_unlock(&h_dentry->d_lock);
10476+ if (unlikely(err))
4a4d8108 10477+ goto out;
1facf9fc 10478+
4a4d8108
AM
10479+ sb = dentry->d_sb;
10480+ br = au_sbr(sb, bindex);
10481+ h_file = ERR_PTR(-EACCES);
2cbb1c4b 10482+ exec_flag = flags & __FMODE_EXEC;
86dc4139 10483+ if (exec_flag && (au_br_mnt(br)->mnt_flags & MNT_NOEXEC))
027c5e7a 10484+ goto out;
1facf9fc 10485+
4a4d8108 10486+ /* drop flags for writing */
392086de
AM
10487+ if (au_test_ro(sb, bindex, dentry->d_inode)) {
10488+ if (force_wr && !(flags & O_WRONLY))
10489+ force_wr = 0;
4a4d8108 10490+ flags = au_file_roflags(flags);
392086de
AM
10491+ if (force_wr) {
10492+ h_file = ERR_PTR(-EROFS);
10493+ flags = au_file_roflags(flags);
10494+ if (unlikely(vfsub_native_ro(h_inode)
10495+ || IS_APPEND(h_inode)))
10496+ goto out;
10497+ flags &= ~O_ACCMODE;
10498+ flags |= O_WRONLY;
10499+ }
10500+ }
4a4d8108
AM
10501+ flags &= ~O_CREAT;
10502+ atomic_inc(&br->br_count);
10503+ h_path.dentry = h_dentry;
86dc4139 10504+ h_path.mnt = au_br_mnt(br);
4a4d8108
AM
10505+ if (!au_special_file(h_inode->i_mode))
10506+ h_file = vfsub_dentry_open(&h_path, flags);
10507+ else {
10508+ /* this block depends upon the configuration */
10509+ di_read_unlock(dentry, AuLock_IR);
10510+ fi_write_unlock(file);
10511+ si_read_unlock(sb);
10512+ h_file = vfsub_dentry_open(&h_path, flags);
10513+ si_noflush_read_lock(sb);
10514+ fi_write_lock(file);
10515+ di_read_lock_child(dentry, AuLock_IR);
dece6358 10516+ }
4a4d8108
AM
10517+ if (IS_ERR(h_file))
10518+ goto out_br;
dece6358 10519+
4a4d8108
AM
10520+ if (exec_flag) {
10521+ err = deny_write_access(h_file);
10522+ if (unlikely(err)) {
10523+ fput(h_file);
10524+ h_file = ERR_PTR(err);
10525+ goto out_br;
10526+ }
10527+ }
953406b4 10528+ fsnotify_open(h_file);
4a4d8108 10529+ goto out; /* success */
1facf9fc 10530+
4f0767ce 10531+out_br:
4a4d8108 10532+ atomic_dec(&br->br_count);
4f0767ce 10533+out:
4a4d8108
AM
10534+ return h_file;
10535+}
1308ab2a 10536+
4a4d8108
AM
10537+int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
10538+ struct au_fidir *fidir)
1facf9fc 10539+{
dece6358 10540+ int err;
1facf9fc 10541+ struct dentry *dentry;
1308ab2a 10542+
4a4d8108
AM
10543+ err = au_finfo_init(file, fidir);
10544+ if (unlikely(err))
10545+ goto out;
1facf9fc 10546+
10547+ dentry = file->f_dentry;
4a4d8108
AM
10548+ di_read_lock_child(dentry, AuLock_IR);
10549+ err = open(file, vfsub_file_flags(file));
10550+ di_read_unlock(dentry, AuLock_IR);
1facf9fc 10551+
4a4d8108
AM
10552+ fi_write_unlock(file);
10553+ if (unlikely(err)) {
10554+ au_fi(file)->fi_hdir = NULL;
10555+ au_finfo_fin(file);
1308ab2a 10556+ }
4a4d8108 10557+
4f0767ce 10558+out:
1308ab2a 10559+ return err;
10560+}
dece6358 10561+
4a4d8108 10562+int au_reopen_nondir(struct file *file)
1308ab2a 10563+{
4a4d8108
AM
10564+ int err;
10565+ aufs_bindex_t bstart;
10566+ struct dentry *dentry;
10567+ struct file *h_file, *h_file_tmp;
1308ab2a 10568+
4a4d8108
AM
10569+ dentry = file->f_dentry;
10570+ AuDebugOn(au_special_file(dentry->d_inode->i_mode));
10571+ bstart = au_dbstart(dentry);
10572+ h_file_tmp = NULL;
10573+ if (au_fbstart(file) == bstart) {
10574+ h_file = au_hf_top(file);
10575+ if (file->f_mode == h_file->f_mode)
10576+ return 0; /* success */
10577+ h_file_tmp = h_file;
10578+ get_file(h_file_tmp);
10579+ au_set_h_fptr(file, bstart, NULL);
10580+ }
10581+ AuDebugOn(au_fi(file)->fi_hdir);
86dc4139
AM
10582+ /*
10583+ * it can happen
10584+ * file exists on both of rw and ro
10585+ * open --> dbstart and fbstart are both 0
10586+ * prepend a branch as rw, "rw" become ro
10587+ * remove rw/file
10588+ * delete the top branch, "rw" becomes rw again
10589+ * --> dbstart is 1, fbstart is still 0
10590+ * write --> fbstart is 0 but dbstart is 1
10591+ */
10592+ /* AuDebugOn(au_fbstart(file) < bstart); */
1308ab2a 10593+
4a4d8108 10594+ h_file = au_h_open(dentry, bstart, vfsub_file_flags(file) & ~O_TRUNC,
392086de 10595+ file, /*force_wr*/0);
4a4d8108 10596+ err = PTR_ERR(h_file);
86dc4139
AM
10597+ if (IS_ERR(h_file)) {
10598+ if (h_file_tmp) {
10599+ atomic_inc(&au_sbr(dentry->d_sb, bstart)->br_count);
10600+ au_set_h_fptr(file, bstart, h_file_tmp);
10601+ h_file_tmp = NULL;
10602+ }
4a4d8108 10603+ goto out; /* todo: close all? */
86dc4139 10604+ }
4a4d8108
AM
10605+
10606+ err = 0;
10607+ au_set_fbstart(file, bstart);
10608+ au_set_h_fptr(file, bstart, h_file);
10609+ au_update_figen(file);
10610+ /* todo: necessary? */
10611+ /* file->f_ra = h_file->f_ra; */
10612+
4f0767ce 10613+out:
4a4d8108
AM
10614+ if (h_file_tmp)
10615+ fput(h_file_tmp);
10616+ return err;
1facf9fc 10617+}
10618+
1308ab2a 10619+/* ---------------------------------------------------------------------- */
10620+
4a4d8108
AM
10621+static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
10622+ struct dentry *hi_wh)
1facf9fc 10623+{
4a4d8108
AM
10624+ int err;
10625+ aufs_bindex_t bstart;
10626+ struct au_dinfo *dinfo;
10627+ struct dentry *h_dentry;
10628+ struct au_hdentry *hdp;
1facf9fc 10629+
4a4d8108
AM
10630+ dinfo = au_di(file->f_dentry);
10631+ AuRwMustWriteLock(&dinfo->di_rwsem);
dece6358 10632+
4a4d8108
AM
10633+ bstart = dinfo->di_bstart;
10634+ dinfo->di_bstart = btgt;
10635+ hdp = dinfo->di_hdentry;
10636+ h_dentry = hdp[0 + btgt].hd_dentry;
10637+ hdp[0 + btgt].hd_dentry = hi_wh;
10638+ err = au_reopen_nondir(file);
10639+ hdp[0 + btgt].hd_dentry = h_dentry;
10640+ dinfo->di_bstart = bstart;
1facf9fc 10641+
1facf9fc 10642+ return err;
10643+}
10644+
4a4d8108 10645+static int au_ready_to_write_wh(struct file *file, loff_t len,
86dc4139 10646+ aufs_bindex_t bcpup, struct au_pin *pin)
1facf9fc 10647+{
4a4d8108 10648+ int err;
027c5e7a 10649+ struct inode *inode, *h_inode;
c2b27bf2
AM
10650+ struct dentry *h_dentry, *hi_wh;
10651+ struct au_cp_generic cpg = {
10652+ .dentry = file->f_dentry,
10653+ .bdst = bcpup,
10654+ .bsrc = -1,
10655+ .len = len,
10656+ .pin = pin
10657+ };
1facf9fc 10658+
c2b27bf2
AM
10659+ au_update_dbstart(cpg.dentry);
10660+ inode = cpg.dentry->d_inode;
027c5e7a 10661+ h_inode = NULL;
c2b27bf2
AM
10662+ if (au_dbstart(cpg.dentry) <= bcpup
10663+ && au_dbend(cpg.dentry) >= bcpup) {
10664+ h_dentry = au_h_dptr(cpg.dentry, bcpup);
027c5e7a
AM
10665+ if (h_dentry)
10666+ h_inode = h_dentry->d_inode;
10667+ }
4a4d8108 10668+ hi_wh = au_hi_wh(inode, bcpup);
027c5e7a 10669+ if (!hi_wh && !h_inode)
c2b27bf2 10670+ err = au_sio_cpup_wh(&cpg, file);
4a4d8108
AM
10671+ else
10672+ /* already copied-up after unlink */
10673+ err = au_reopen_wh(file, bcpup, hi_wh);
1facf9fc 10674+
4a4d8108
AM
10675+ if (!err
10676+ && inode->i_nlink > 1
c2b27bf2
AM
10677+ && au_opt_test(au_mntflags(cpg.dentry->d_sb), PLINK))
10678+ au_plink_append(inode, bcpup, au_h_dptr(cpg.dentry, bcpup));
1308ab2a 10679+
dece6358 10680+ return err;
1facf9fc 10681+}
10682+
4a4d8108
AM
10683+/*
10684+ * prepare the @file for writing.
10685+ */
10686+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
1facf9fc 10687+{
4a4d8108 10688+ int err;
c2b27bf2
AM
10689+ aufs_bindex_t dbstart;
10690+ struct dentry *parent, *h_dentry;
86dc4139 10691+ struct inode *inode;
1facf9fc 10692+ struct super_block *sb;
4a4d8108 10693+ struct file *h_file;
c2b27bf2
AM
10694+ struct au_cp_generic cpg = {
10695+ .dentry = file->f_dentry,
10696+ .bdst = -1,
10697+ .bsrc = -1,
10698+ .len = len,
10699+ .pin = pin,
10700+ .flags = AuCpup_DTIME
10701+ };
1facf9fc 10702+
c2b27bf2
AM
10703+ sb = cpg.dentry->d_sb;
10704+ inode = cpg.dentry->d_inode;
4a4d8108 10705+ AuDebugOn(au_special_file(inode->i_mode));
c2b27bf2
AM
10706+ cpg.bsrc = au_fbstart(file);
10707+ err = au_test_ro(sb, cpg.bsrc, inode);
4a4d8108 10708+ if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
c2b27bf2
AM
10709+ err = au_pin(pin, cpg.dentry, cpg.bsrc, AuOpt_UDBA_NONE,
10710+ /*flags*/0);
1facf9fc 10711+ goto out;
4a4d8108 10712+ }
1facf9fc 10713+
027c5e7a 10714+ /* need to cpup or reopen */
c2b27bf2 10715+ parent = dget_parent(cpg.dentry);
4a4d8108 10716+ di_write_lock_parent(parent);
c2b27bf2
AM
10717+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
10718+ cpg.bdst = err;
4a4d8108
AM
10719+ if (unlikely(err < 0))
10720+ goto out_dgrade;
10721+ err = 0;
10722+
c2b27bf2
AM
10723+ if (!d_unhashed(cpg.dentry) && !au_h_dptr(parent, cpg.bdst)) {
10724+ err = au_cpup_dirs(cpg.dentry, cpg.bdst);
1facf9fc 10725+ if (unlikely(err))
4a4d8108
AM
10726+ goto out_dgrade;
10727+ }
10728+
c2b27bf2 10729+ err = au_pin(pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108
AM
10730+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
10731+ if (unlikely(err))
10732+ goto out_dgrade;
10733+
10734+ h_dentry = au_hf_top(file)->f_dentry;
c2b27bf2
AM
10735+ dbstart = au_dbstart(cpg.dentry);
10736+ if (dbstart <= cpg.bdst) {
10737+ h_dentry = au_h_dptr(cpg.dentry, cpg.bdst);
027c5e7a 10738+ AuDebugOn(!h_dentry);
c2b27bf2 10739+ cpg.bsrc = cpg.bdst;
027c5e7a
AM
10740+ }
10741+
c2b27bf2
AM
10742+ if (dbstart <= cpg.bdst /* just reopen */
10743+ || !d_unhashed(cpg.dentry) /* copyup and reopen */
027c5e7a 10744+ ) {
392086de 10745+ h_file = au_h_open_pre(cpg.dentry, cpg.bsrc, /*force_wr*/0);
86dc4139 10746+ if (IS_ERR(h_file))
027c5e7a 10747+ err = PTR_ERR(h_file);
86dc4139 10748+ else {
027c5e7a 10749+ di_downgrade_lock(parent, AuLock_IR);
c2b27bf2
AM
10750+ if (dbstart > cpg.bdst)
10751+ err = au_sio_cpup_simple(&cpg);
027c5e7a
AM
10752+ if (!err)
10753+ err = au_reopen_nondir(file);
c2b27bf2 10754+ au_h_open_post(cpg.dentry, cpg.bsrc, h_file);
027c5e7a 10755+ }
027c5e7a
AM
10756+ } else { /* copyup as wh and reopen */
10757+ /*
10758+ * since writable hfsplus branch is not supported,
10759+ * h_open_pre/post() are unnecessary.
10760+ */
c2b27bf2 10761+ err = au_ready_to_write_wh(file, len, cpg.bdst, pin);
4a4d8108 10762+ di_downgrade_lock(parent, AuLock_IR);
4a4d8108 10763+ }
4a4d8108
AM
10764+
10765+ if (!err) {
10766+ au_pin_set_parent_lflag(pin, /*lflag*/0);
10767+ goto out_dput; /* success */
10768+ }
10769+ au_unpin(pin);
10770+ goto out_unlock;
1facf9fc 10771+
4f0767ce 10772+out_dgrade:
4a4d8108 10773+ di_downgrade_lock(parent, AuLock_IR);
4f0767ce 10774+out_unlock:
4a4d8108 10775+ di_read_unlock(parent, AuLock_IR);
4f0767ce 10776+out_dput:
4a4d8108 10777+ dput(parent);
4f0767ce 10778+out:
1facf9fc 10779+ return err;
10780+}
10781+
4a4d8108
AM
10782+/* ---------------------------------------------------------------------- */
10783+
10784+int au_do_flush(struct file *file, fl_owner_t id,
10785+ int (*flush)(struct file *file, fl_owner_t id))
1facf9fc 10786+{
4a4d8108 10787+ int err;
1facf9fc 10788+ struct super_block *sb;
4a4d8108 10789+ struct inode *inode;
1facf9fc 10790+
c06a8ce3
AM
10791+ inode = file_inode(file);
10792+ sb = inode->i_sb;
4a4d8108
AM
10793+ si_noflush_read_lock(sb);
10794+ fi_read_lock(file);
b752ccd1 10795+ ii_read_lock_child(inode);
1facf9fc 10796+
4a4d8108
AM
10797+ err = flush(file, id);
10798+ au_cpup_attr_timesizes(inode);
1facf9fc 10799+
b752ccd1 10800+ ii_read_unlock(inode);
4a4d8108 10801+ fi_read_unlock(file);
1308ab2a 10802+ si_read_unlock(sb);
dece6358 10803+ return err;
1facf9fc 10804+}
10805+
4a4d8108
AM
10806+/* ---------------------------------------------------------------------- */
10807+
10808+static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
1facf9fc 10809+{
4a4d8108 10810+ int err;
4a4d8108
AM
10811+ struct au_pin pin;
10812+ struct au_finfo *finfo;
c2b27bf2 10813+ struct dentry *parent, *hi_wh;
4a4d8108 10814+ struct inode *inode;
1facf9fc 10815+ struct super_block *sb;
c2b27bf2
AM
10816+ struct au_cp_generic cpg = {
10817+ .dentry = file->f_dentry,
10818+ .bdst = -1,
10819+ .bsrc = -1,
10820+ .len = -1,
10821+ .pin = &pin,
10822+ .flags = AuCpup_DTIME
10823+ };
1facf9fc 10824+
4a4d8108
AM
10825+ FiMustWriteLock(file);
10826+
10827+ err = 0;
10828+ finfo = au_fi(file);
c2b27bf2
AM
10829+ sb = cpg.dentry->d_sb;
10830+ inode = cpg.dentry->d_inode;
10831+ cpg.bdst = au_ibstart(inode);
10832+ if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry))
1308ab2a 10833+ goto out;
dece6358 10834+
c2b27bf2
AM
10835+ parent = dget_parent(cpg.dentry);
10836+ if (au_test_ro(sb, cpg.bdst, inode)) {
4a4d8108 10837+ di_read_lock_parent(parent, !AuLock_IR);
c2b27bf2
AM
10838+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
10839+ cpg.bdst = err;
4a4d8108
AM
10840+ di_read_unlock(parent, !AuLock_IR);
10841+ if (unlikely(err < 0))
10842+ goto out_parent;
10843+ err = 0;
1facf9fc 10844+ }
1facf9fc 10845+
4a4d8108 10846+ di_read_lock_parent(parent, AuLock_IR);
c2b27bf2 10847+ hi_wh = au_hi_wh(inode, cpg.bdst);
7f207e10
AM
10848+ if (!S_ISDIR(inode->i_mode)
10849+ && au_opt_test(au_mntflags(sb), PLINK)
4a4d8108 10850+ && au_plink_test(inode)
c2b27bf2
AM
10851+ && !d_unhashed(cpg.dentry)
10852+ && cpg.bdst < au_dbstart(cpg.dentry)) {
10853+ err = au_test_and_cpup_dirs(cpg.dentry, cpg.bdst);
4a4d8108
AM
10854+ if (unlikely(err))
10855+ goto out_unlock;
10856+
10857+ /* always superio. */
c2b27bf2 10858+ err = au_pin(&pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108 10859+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 10860+ if (!err) {
c2b27bf2 10861+ err = au_sio_cpup_simple(&cpg);
367653fa
AM
10862+ au_unpin(&pin);
10863+ }
4a4d8108
AM
10864+ } else if (hi_wh) {
10865+ /* already copied-up after unlink */
c2b27bf2 10866+ err = au_reopen_wh(file, cpg.bdst, hi_wh);
4a4d8108
AM
10867+ *need_reopen = 0;
10868+ }
1facf9fc 10869+
4f0767ce 10870+out_unlock:
4a4d8108 10871+ di_read_unlock(parent, AuLock_IR);
4f0767ce 10872+out_parent:
4a4d8108 10873+ dput(parent);
4f0767ce 10874+out:
1308ab2a 10875+ return err;
dece6358 10876+}
1facf9fc 10877+
4a4d8108 10878+static void au_do_refresh_dir(struct file *file)
dece6358 10879+{
4a4d8108
AM
10880+ aufs_bindex_t bindex, bend, new_bindex, brid;
10881+ struct au_hfile *p, tmp, *q;
10882+ struct au_finfo *finfo;
1308ab2a 10883+ struct super_block *sb;
4a4d8108 10884+ struct au_fidir *fidir;
1facf9fc 10885+
4a4d8108 10886+ FiMustWriteLock(file);
1facf9fc 10887+
4a4d8108
AM
10888+ sb = file->f_dentry->d_sb;
10889+ finfo = au_fi(file);
10890+ fidir = finfo->fi_hdir;
10891+ AuDebugOn(!fidir);
10892+ p = fidir->fd_hfile + finfo->fi_btop;
10893+ brid = p->hf_br->br_id;
10894+ bend = fidir->fd_bbot;
10895+ for (bindex = finfo->fi_btop; bindex <= bend; bindex++, p++) {
10896+ if (!p->hf_file)
10897+ continue;
1308ab2a 10898+
4a4d8108
AM
10899+ new_bindex = au_br_index(sb, p->hf_br->br_id);
10900+ if (new_bindex == bindex)
10901+ continue;
10902+ if (new_bindex < 0) {
10903+ au_set_h_fptr(file, bindex, NULL);
10904+ continue;
10905+ }
1308ab2a 10906+
4a4d8108
AM
10907+ /* swap two lower inode, and loop again */
10908+ q = fidir->fd_hfile + new_bindex;
10909+ tmp = *q;
10910+ *q = *p;
10911+ *p = tmp;
10912+ if (tmp.hf_file) {
10913+ bindex--;
10914+ p--;
10915+ }
10916+ }
1308ab2a 10917+
4a4d8108 10918+ p = fidir->fd_hfile;
027c5e7a 10919+ if (!au_test_mmapped(file) && !d_unlinked(file->f_dentry)) {
4a4d8108
AM
10920+ bend = au_sbend(sb);
10921+ for (finfo->fi_btop = 0; finfo->fi_btop <= bend;
10922+ finfo->fi_btop++, p++)
10923+ if (p->hf_file) {
c06a8ce3 10924+ if (file_inode(p->hf_file))
4a4d8108
AM
10925+ break;
10926+ else
10927+ au_hfput(p, file);
10928+ }
10929+ } else {
10930+ bend = au_br_index(sb, brid);
10931+ for (finfo->fi_btop = 0; finfo->fi_btop < bend;
10932+ finfo->fi_btop++, p++)
10933+ if (p->hf_file)
10934+ au_hfput(p, file);
10935+ bend = au_sbend(sb);
10936+ }
1308ab2a 10937+
4a4d8108
AM
10938+ p = fidir->fd_hfile + bend;
10939+ for (fidir->fd_bbot = bend; fidir->fd_bbot >= finfo->fi_btop;
10940+ fidir->fd_bbot--, p--)
10941+ if (p->hf_file) {
c06a8ce3 10942+ if (file_inode(p->hf_file))
4a4d8108
AM
10943+ break;
10944+ else
10945+ au_hfput(p, file);
10946+ }
10947+ AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
1308ab2a 10948+}
10949+
4a4d8108
AM
10950+/*
10951+ * after branch manipulating, refresh the file.
10952+ */
10953+static int refresh_file(struct file *file, int (*reopen)(struct file *file))
1facf9fc 10954+{
4a4d8108
AM
10955+ int err, need_reopen;
10956+ aufs_bindex_t bend, bindex;
10957+ struct dentry *dentry;
1308ab2a 10958+ struct au_finfo *finfo;
4a4d8108 10959+ struct au_hfile *hfile;
1facf9fc 10960+
4a4d8108 10961+ dentry = file->f_dentry;
1308ab2a 10962+ finfo = au_fi(file);
4a4d8108
AM
10963+ if (!finfo->fi_hdir) {
10964+ hfile = &finfo->fi_htop;
10965+ AuDebugOn(!hfile->hf_file);
10966+ bindex = au_br_index(dentry->d_sb, hfile->hf_br->br_id);
10967+ AuDebugOn(bindex < 0);
10968+ if (bindex != finfo->fi_btop)
10969+ au_set_fbstart(file, bindex);
10970+ } else {
10971+ err = au_fidir_realloc(finfo, au_sbend(dentry->d_sb) + 1);
10972+ if (unlikely(err))
10973+ goto out;
10974+ au_do_refresh_dir(file);
10975+ }
1facf9fc 10976+
4a4d8108
AM
10977+ err = 0;
10978+ need_reopen = 1;
10979+ if (!au_test_mmapped(file))
10980+ err = au_file_refresh_by_inode(file, &need_reopen);
027c5e7a 10981+ if (!err && need_reopen && !d_unlinked(dentry))
4a4d8108
AM
10982+ err = reopen(file);
10983+ if (!err) {
10984+ au_update_figen(file);
10985+ goto out; /* success */
10986+ }
10987+
10988+ /* error, close all lower files */
10989+ if (finfo->fi_hdir) {
10990+ bend = au_fbend_dir(file);
10991+ for (bindex = au_fbstart(file); bindex <= bend; bindex++)
10992+ au_set_h_fptr(file, bindex, NULL);
10993+ }
1facf9fc 10994+
4f0767ce 10995+out:
1facf9fc 10996+ return err;
10997+}
10998+
4a4d8108
AM
10999+/* common function to regular file and dir */
11000+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
11001+ int wlock)
dece6358 11002+{
1308ab2a 11003+ int err;
4a4d8108
AM
11004+ unsigned int sigen, figen;
11005+ aufs_bindex_t bstart;
11006+ unsigned char pseudo_link;
11007+ struct dentry *dentry;
11008+ struct inode *inode;
1facf9fc 11009+
4a4d8108
AM
11010+ err = 0;
11011+ dentry = file->f_dentry;
11012+ inode = dentry->d_inode;
11013+ AuDebugOn(au_special_file(inode->i_mode));
11014+ sigen = au_sigen(dentry->d_sb);
11015+ fi_write_lock(file);
11016+ figen = au_figen(file);
11017+ di_write_lock_child(dentry);
11018+ bstart = au_dbstart(dentry);
11019+ pseudo_link = (bstart != au_ibstart(inode));
11020+ if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) {
11021+ if (!wlock) {
11022+ di_downgrade_lock(dentry, AuLock_IR);
11023+ fi_downgrade_lock(file);
11024+ }
11025+ goto out; /* success */
11026+ }
dece6358 11027+
4a4d8108 11028+ AuDbg("sigen %d, figen %d\n", sigen, figen);
027c5e7a 11029+ if (au_digen_test(dentry, sigen)) {
4a4d8108 11030+ err = au_reval_dpath(dentry, sigen);
027c5e7a 11031+ AuDebugOn(!err && au_digen_test(dentry, sigen));
4a4d8108 11032+ }
dece6358 11033+
027c5e7a
AM
11034+ if (!err)
11035+ err = refresh_file(file, reopen);
4a4d8108
AM
11036+ if (!err) {
11037+ if (!wlock) {
11038+ di_downgrade_lock(dentry, AuLock_IR);
11039+ fi_downgrade_lock(file);
11040+ }
11041+ } else {
11042+ di_write_unlock(dentry);
11043+ fi_write_unlock(file);
11044+ }
1facf9fc 11045+
4f0767ce 11046+out:
1308ab2a 11047+ return err;
11048+}
1facf9fc 11049+
4a4d8108
AM
11050+/* ---------------------------------------------------------------------- */
11051+
11052+/* cf. aufs_nopage() */
11053+/* for madvise(2) */
11054+static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
1308ab2a 11055+{
4a4d8108
AM
11056+ unlock_page(page);
11057+ return 0;
11058+}
1facf9fc 11059+
4a4d8108
AM
11060+/* it will never be called, but necessary to support O_DIRECT */
11061+static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb,
11062+ const struct iovec *iov, loff_t offset,
11063+ unsigned long nr_segs)
11064+{ BUG(); return 0; }
1facf9fc 11065+
4a4d8108
AM
11066+/*
11067+ * it will never be called, but madvise and fadvise behaves differently
11068+ * when get_xip_mem is defined
11069+ */
11070+static int aufs_get_xip_mem(struct address_space *mapping, pgoff_t pgoff,
11071+ int create, void **kmem, unsigned long *pfn)
11072+{ BUG(); return 0; }
1facf9fc 11073+
4a4d8108
AM
11074+/* they will never be called. */
11075+#ifdef CONFIG_AUFS_DEBUG
11076+static int aufs_write_begin(struct file *file, struct address_space *mapping,
11077+ loff_t pos, unsigned len, unsigned flags,
11078+ struct page **pagep, void **fsdata)
11079+{ AuUnsupport(); return 0; }
11080+static int aufs_write_end(struct file *file, struct address_space *mapping,
11081+ loff_t pos, unsigned len, unsigned copied,
11082+ struct page *page, void *fsdata)
11083+{ AuUnsupport(); return 0; }
11084+static int aufs_writepage(struct page *page, struct writeback_control *wbc)
11085+{ AuUnsupport(); return 0; }
1308ab2a 11086+
4a4d8108
AM
11087+static int aufs_set_page_dirty(struct page *page)
11088+{ AuUnsupport(); return 0; }
392086de
AM
11089+static void aufs_invalidatepage(struct page *page, unsigned int offset,
11090+ unsigned int length)
4a4d8108
AM
11091+{ AuUnsupport(); }
11092+static int aufs_releasepage(struct page *page, gfp_t gfp)
11093+{ AuUnsupport(); return 0; }
11094+static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
7eafdf33 11095+ struct page *page, enum migrate_mode mode)
4a4d8108
AM
11096+{ AuUnsupport(); return 0; }
11097+static int aufs_launder_page(struct page *page)
11098+{ AuUnsupport(); return 0; }
11099+static int aufs_is_partially_uptodate(struct page *page,
11100+ read_descriptor_t *desc,
11101+ unsigned long from)
11102+{ AuUnsupport(); return 0; }
392086de
AM
11103+static void aufs_is_dirty_writeback(struct page *page, bool *dirty,
11104+ bool *writeback)
11105+{ AuUnsupport(); }
4a4d8108
AM
11106+static int aufs_error_remove_page(struct address_space *mapping,
11107+ struct page *page)
11108+{ AuUnsupport(); return 0; }
b4510431
AM
11109+static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file,
11110+ sector_t *span)
11111+{ AuUnsupport(); return 0; }
11112+static void aufs_swap_deactivate(struct file *file)
11113+{ AuUnsupport(); }
4a4d8108
AM
11114+#endif /* CONFIG_AUFS_DEBUG */
11115+
11116+const struct address_space_operations aufs_aop = {
11117+ .readpage = aufs_readpage,
11118+ .direct_IO = aufs_direct_IO,
11119+ .get_xip_mem = aufs_get_xip_mem,
11120+#ifdef CONFIG_AUFS_DEBUG
11121+ .writepage = aufs_writepage,
4a4d8108
AM
11122+ /* no writepages, because of writepage */
11123+ .set_page_dirty = aufs_set_page_dirty,
11124+ /* no readpages, because of readpage */
11125+ .write_begin = aufs_write_begin,
11126+ .write_end = aufs_write_end,
11127+ /* no bmap, no block device */
11128+ .invalidatepage = aufs_invalidatepage,
11129+ .releasepage = aufs_releasepage,
11130+ .migratepage = aufs_migratepage,
11131+ .launder_page = aufs_launder_page,
11132+ .is_partially_uptodate = aufs_is_partially_uptodate,
392086de 11133+ .is_dirty_writeback = aufs_is_dirty_writeback,
b4510431
AM
11134+ .error_remove_page = aufs_error_remove_page,
11135+ .swap_activate = aufs_swap_activate,
11136+ .swap_deactivate = aufs_swap_deactivate
4a4d8108 11137+#endif /* CONFIG_AUFS_DEBUG */
dece6358 11138+};
7f207e10
AM
11139diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
11140--- /usr/share/empty/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100
392086de
AM
11141+++ linux/fs/aufs/file.h 2013-10-26 16:51:32.273040419 +0200
11142@@ -0,0 +1,312 @@
4a4d8108 11143+/*
7a9e40b8 11144+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
11145+ *
11146+ * This program, aufs is free software; you can redistribute it and/or modify
11147+ * it under the terms of the GNU General Public License as published by
11148+ * the Free Software Foundation; either version 2 of the License, or
11149+ * (at your option) any later version.
11150+ *
11151+ * This program is distributed in the hope that it will be useful,
11152+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11153+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11154+ * GNU General Public License for more details.
11155+ *
11156+ * You should have received a copy of the GNU General Public License
11157+ * along with this program; if not, write to the Free Software
11158+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11159+ */
1facf9fc 11160+
4a4d8108
AM
11161+/*
11162+ * file operations
11163+ */
1facf9fc 11164+
4a4d8108
AM
11165+#ifndef __AUFS_FILE_H__
11166+#define __AUFS_FILE_H__
1facf9fc 11167+
4a4d8108 11168+#ifdef __KERNEL__
1facf9fc 11169+
2cbb1c4b 11170+#include <linux/file.h>
4a4d8108
AM
11171+#include <linux/fs.h>
11172+#include <linux/poll.h>
4a4d8108 11173+#include "rwsem.h"
1facf9fc 11174+
4a4d8108
AM
11175+struct au_branch;
11176+struct au_hfile {
11177+ struct file *hf_file;
11178+ struct au_branch *hf_br;
11179+};
1facf9fc 11180+
4a4d8108
AM
11181+struct au_vdir;
11182+struct au_fidir {
11183+ aufs_bindex_t fd_bbot;
11184+ aufs_bindex_t fd_nent;
11185+ struct au_vdir *fd_vdir_cache;
11186+ struct au_hfile fd_hfile[];
11187+};
1facf9fc 11188+
4a4d8108 11189+static inline int au_fidir_sz(int nent)
dece6358 11190+{
4f0767ce
JR
11191+ AuDebugOn(nent < 0);
11192+ return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
4a4d8108 11193+}
1facf9fc 11194+
4a4d8108
AM
11195+struct au_finfo {
11196+ atomic_t fi_generation;
dece6358 11197+
4a4d8108
AM
11198+ struct au_rwsem fi_rwsem;
11199+ aufs_bindex_t fi_btop;
11200+
11201+ /* do not union them */
11202+ struct { /* for non-dir */
11203+ struct au_hfile fi_htop;
2cbb1c4b 11204+ atomic_t fi_mmapped;
4a4d8108
AM
11205+ };
11206+ struct au_fidir *fi_hdir; /* for dir only */
11207+} ____cacheline_aligned_in_smp;
1facf9fc 11208+
4a4d8108 11209+/* ---------------------------------------------------------------------- */
1facf9fc 11210+
4a4d8108
AM
11211+/* file.c */
11212+extern const struct address_space_operations aufs_aop;
11213+unsigned int au_file_roflags(unsigned int flags);
11214+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 11215+ struct file *file, int force_wr);
4a4d8108
AM
11216+int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
11217+ struct au_fidir *fidir);
11218+int au_reopen_nondir(struct file *file);
11219+struct au_pin;
11220+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
11221+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
11222+ int wlock);
11223+int au_do_flush(struct file *file, fl_owner_t id,
11224+ int (*flush)(struct file *file, fl_owner_t id));
1facf9fc 11225+
4a4d8108
AM
11226+/* poll.c */
11227+#ifdef CONFIG_AUFS_POLL
11228+unsigned int aufs_poll(struct file *file, poll_table *wait);
11229+#endif
1facf9fc 11230+
4a4d8108
AM
11231+#ifdef CONFIG_AUFS_BR_HFSPLUS
11232+/* hfsplus.c */
392086de
AM
11233+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
11234+ int force_wr);
4a4d8108
AM
11235+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
11236+ struct file *h_file);
11237+#else
11238+static inline
392086de
AM
11239+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
11240+ int force_wr)
dece6358 11241+{
4a4d8108
AM
11242+ return NULL;
11243+}
1facf9fc 11244+
4a4d8108
AM
11245+AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
11246+ struct file *h_file);
11247+#endif
1facf9fc 11248+
4a4d8108
AM
11249+/* f_op.c */
11250+extern const struct file_operations aufs_file_fop;
4a4d8108
AM
11251+int au_do_open_nondir(struct file *file, int flags);
11252+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
11253+
11254+#ifdef CONFIG_AUFS_SP_IATTR
11255+/* f_op_sp.c */
86dc4139 11256+struct au_finfo *au_fi_sp(struct file *file);
4a4d8108
AM
11257+int au_special_file(umode_t mode);
11258+void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev);
11259+#else
86dc4139
AM
11260+static inline struct au_finfo *au_fi_sp(struct file *file)
11261+{
11262+ return NULL;
11263+}
4a4d8108
AM
11264+AuStubInt0(au_special_file, umode_t mode)
11265+static inline void au_init_special_fop(struct inode *inode, umode_t mode,
11266+ dev_t rdev)
11267+{
11268+ init_special_inode(inode, mode, rdev);
11269+}
11270+#endif
1facf9fc 11271+
4a4d8108
AM
11272+/* finfo.c */
11273+void au_hfput(struct au_hfile *hf, struct file *file);
11274+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
11275+ struct file *h_file);
1facf9fc 11276+
4a4d8108 11277+void au_update_figen(struct file *file);
4a4d8108
AM
11278+struct au_fidir *au_fidir_alloc(struct super_block *sb);
11279+int au_fidir_realloc(struct au_finfo *finfo, int nbr);
1facf9fc 11280+
4a4d8108
AM
11281+void au_fi_init_once(void *_fi);
11282+void au_finfo_fin(struct file *file);
11283+int au_finfo_init(struct file *file, struct au_fidir *fidir);
1facf9fc 11284+
4a4d8108
AM
11285+/* ioctl.c */
11286+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
11287+#ifdef CONFIG_COMPAT
11288+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
11289+ unsigned long arg);
c2b27bf2
AM
11290+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
11291+ unsigned long arg);
b752ccd1 11292+#endif
1facf9fc 11293+
4a4d8108 11294+/* ---------------------------------------------------------------------- */
1facf9fc 11295+
4a4d8108
AM
11296+static inline struct au_finfo *au_fi(struct file *file)
11297+{
86dc4139
AM
11298+ struct au_finfo *finfo;
11299+
11300+ finfo = au_fi_sp(file);
11301+ if (!finfo)
11302+ finfo = file->private_data;
11303+ return finfo;
4a4d8108 11304+}
1facf9fc 11305+
4a4d8108 11306+/* ---------------------------------------------------------------------- */
1facf9fc 11307+
4a4d8108
AM
11308+/*
11309+ * fi_read_lock, fi_write_lock,
11310+ * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
11311+ */
11312+AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
1308ab2a 11313+
4a4d8108
AM
11314+#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
11315+#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
11316+#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
1facf9fc 11317+
1308ab2a 11318+/* ---------------------------------------------------------------------- */
11319+
4a4d8108
AM
11320+/* todo: hard/soft set? */
11321+static inline aufs_bindex_t au_fbstart(struct file *file)
dece6358 11322+{
4a4d8108
AM
11323+ FiMustAnyLock(file);
11324+ return au_fi(file)->fi_btop;
11325+}
dece6358 11326+
4a4d8108
AM
11327+static inline aufs_bindex_t au_fbend_dir(struct file *file)
11328+{
11329+ FiMustAnyLock(file);
11330+ AuDebugOn(!au_fi(file)->fi_hdir);
11331+ return au_fi(file)->fi_hdir->fd_bbot;
11332+}
1facf9fc 11333+
4a4d8108
AM
11334+static inline struct au_vdir *au_fvdir_cache(struct file *file)
11335+{
11336+ FiMustAnyLock(file);
11337+ AuDebugOn(!au_fi(file)->fi_hdir);
11338+ return au_fi(file)->fi_hdir->fd_vdir_cache;
11339+}
1facf9fc 11340+
4a4d8108
AM
11341+static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex)
11342+{
11343+ FiMustWriteLock(file);
11344+ au_fi(file)->fi_btop = bindex;
11345+}
1facf9fc 11346+
4a4d8108
AM
11347+static inline void au_set_fbend_dir(struct file *file, aufs_bindex_t bindex)
11348+{
11349+ FiMustWriteLock(file);
11350+ AuDebugOn(!au_fi(file)->fi_hdir);
11351+ au_fi(file)->fi_hdir->fd_bbot = bindex;
11352+}
1308ab2a 11353+
4a4d8108
AM
11354+static inline void au_set_fvdir_cache(struct file *file,
11355+ struct au_vdir *vdir_cache)
11356+{
11357+ FiMustWriteLock(file);
11358+ AuDebugOn(!au_fi(file)->fi_hdir);
11359+ au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
11360+}
dece6358 11361+
4a4d8108
AM
11362+static inline struct file *au_hf_top(struct file *file)
11363+{
11364+ FiMustAnyLock(file);
11365+ AuDebugOn(au_fi(file)->fi_hdir);
11366+ return au_fi(file)->fi_htop.hf_file;
11367+}
1facf9fc 11368+
4a4d8108
AM
11369+static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
11370+{
11371+ FiMustAnyLock(file);
11372+ AuDebugOn(!au_fi(file)->fi_hdir);
11373+ return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
dece6358
AM
11374+}
11375+
4a4d8108
AM
11376+/* todo: memory barrier? */
11377+static inline unsigned int au_figen(struct file *f)
dece6358 11378+{
4a4d8108
AM
11379+ return atomic_read(&au_fi(f)->fi_generation);
11380+}
dece6358 11381+
2cbb1c4b
JR
11382+static inline void au_set_mmapped(struct file *f)
11383+{
11384+ if (atomic_inc_return(&au_fi(f)->fi_mmapped))
11385+ return;
0c3ec466 11386+ pr_warn("fi_mmapped wrapped around\n");
2cbb1c4b
JR
11387+ while (!atomic_inc_return(&au_fi(f)->fi_mmapped))
11388+ ;
11389+}
11390+
11391+static inline void au_unset_mmapped(struct file *f)
11392+{
11393+ atomic_dec(&au_fi(f)->fi_mmapped);
11394+}
11395+
4a4d8108
AM
11396+static inline int au_test_mmapped(struct file *f)
11397+{
2cbb1c4b
JR
11398+ return atomic_read(&au_fi(f)->fi_mmapped);
11399+}
11400+
11401+/* customize vma->vm_file */
11402+
11403+static inline void au_do_vm_file_reset(struct vm_area_struct *vma,
11404+ struct file *file)
11405+{
53392da6
AM
11406+ struct file *f;
11407+
11408+ f = vma->vm_file;
2cbb1c4b
JR
11409+ get_file(file);
11410+ vma->vm_file = file;
53392da6 11411+ fput(f);
2cbb1c4b
JR
11412+}
11413+
11414+#ifdef CONFIG_MMU
11415+#define AuDbgVmRegion(file, vma) do {} while (0)
11416+
11417+static inline void au_vm_file_reset(struct vm_area_struct *vma,
11418+ struct file *file)
11419+{
11420+ au_do_vm_file_reset(vma, file);
11421+}
11422+#else
11423+#define AuDbgVmRegion(file, vma) \
11424+ AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
11425+
11426+static inline void au_vm_file_reset(struct vm_area_struct *vma,
11427+ struct file *file)
11428+{
53392da6
AM
11429+ struct file *f;
11430+
2cbb1c4b 11431+ au_do_vm_file_reset(vma, file);
53392da6 11432+ f = vma->vm_region->vm_file;
2cbb1c4b
JR
11433+ get_file(file);
11434+ vma->vm_region->vm_file = file;
53392da6 11435+ fput(f);
2cbb1c4b
JR
11436+}
11437+#endif /* CONFIG_MMU */
11438+
11439+/* handle vma->vm_prfile */
11440+static inline void au_vm_prfile_set(struct vm_area_struct *vma,
11441+ struct file *file)
11442+{
11443+#ifdef CONFIG_AUFS_PROC_MAP
11444+ get_file(file);
11445+ vma->vm_prfile = file;
11446+#ifndef CONFIG_MMU
11447+ get_file(file);
11448+ vma->vm_region->vm_prfile = file;
11449+#endif
11450+#endif
4a4d8108 11451+}
1308ab2a 11452+
4a4d8108
AM
11453+#endif /* __KERNEL__ */
11454+#endif /* __AUFS_FILE_H__ */
7f207e10
AM
11455diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
11456--- /usr/share/empty/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100
86dc4139 11457+++ linux/fs/aufs/finfo.c 2013-07-06 13:20:47.750198454 +0200
1716fcea 11458@@ -0,0 +1,157 @@
4a4d8108 11459+/*
7a9e40b8 11460+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
11461+ *
11462+ * This program, aufs is free software; you can redistribute it and/or modify
11463+ * it under the terms of the GNU General Public License as published by
11464+ * the Free Software Foundation; either version 2 of the License, or
11465+ * (at your option) any later version.
11466+ *
11467+ * This program is distributed in the hope that it will be useful,
11468+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11469+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11470+ * GNU General Public License for more details.
11471+ *
11472+ * You should have received a copy of the GNU General Public License
11473+ * along with this program; if not, write to the Free Software
11474+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11475+ */
1308ab2a 11476+
4a4d8108
AM
11477+/*
11478+ * file private data
11479+ */
1facf9fc 11480+
4a4d8108 11481+#include "aufs.h"
1facf9fc 11482+
4a4d8108
AM
11483+void au_hfput(struct au_hfile *hf, struct file *file)
11484+{
11485+ /* todo: direct access f_flags */
2cbb1c4b 11486+ if (vfsub_file_flags(file) & __FMODE_EXEC)
4a4d8108
AM
11487+ allow_write_access(hf->hf_file);
11488+ fput(hf->hf_file);
11489+ hf->hf_file = NULL;
e49829fe 11490+ atomic_dec(&hf->hf_br->br_count);
4a4d8108
AM
11491+ hf->hf_br = NULL;
11492+}
1facf9fc 11493+
4a4d8108
AM
11494+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
11495+{
11496+ struct au_finfo *finfo = au_fi(file);
11497+ struct au_hfile *hf;
11498+ struct au_fidir *fidir;
11499+
11500+ fidir = finfo->fi_hdir;
11501+ if (!fidir) {
11502+ AuDebugOn(finfo->fi_btop != bindex);
11503+ hf = &finfo->fi_htop;
11504+ } else
11505+ hf = fidir->fd_hfile + bindex;
11506+
11507+ if (hf && hf->hf_file)
11508+ au_hfput(hf, file);
11509+ if (val) {
11510+ FiMustWriteLock(file);
11511+ hf->hf_file = val;
11512+ hf->hf_br = au_sbr(file->f_dentry->d_sb, bindex);
1308ab2a 11513+ }
4a4d8108 11514+}
1facf9fc 11515+
4a4d8108
AM
11516+void au_update_figen(struct file *file)
11517+{
11518+ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_dentry));
11519+ /* smp_mb(); */ /* atomic_set */
1facf9fc 11520+}
11521+
4a4d8108
AM
11522+/* ---------------------------------------------------------------------- */
11523+
4a4d8108
AM
11524+struct au_fidir *au_fidir_alloc(struct super_block *sb)
11525+{
11526+ struct au_fidir *fidir;
11527+ int nbr;
11528+
11529+ nbr = au_sbend(sb) + 1;
11530+ if (nbr < 2)
11531+ nbr = 2; /* initial allocate for 2 branches */
11532+ fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS);
11533+ if (fidir) {
11534+ fidir->fd_bbot = -1;
11535+ fidir->fd_nent = nbr;
11536+ fidir->fd_vdir_cache = NULL;
11537+ }
11538+
11539+ return fidir;
11540+}
11541+
11542+int au_fidir_realloc(struct au_finfo *finfo, int nbr)
11543+{
11544+ int err;
11545+ struct au_fidir *fidir, *p;
11546+
11547+ AuRwMustWriteLock(&finfo->fi_rwsem);
11548+ fidir = finfo->fi_hdir;
11549+ AuDebugOn(!fidir);
11550+
11551+ err = -ENOMEM;
11552+ p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr),
11553+ GFP_NOFS);
11554+ if (p) {
11555+ p->fd_nent = nbr;
11556+ finfo->fi_hdir = p;
11557+ err = 0;
11558+ }
1facf9fc 11559+
dece6358 11560+ return err;
1facf9fc 11561+}
1308ab2a 11562+
11563+/* ---------------------------------------------------------------------- */
11564+
4a4d8108 11565+void au_finfo_fin(struct file *file)
1308ab2a 11566+{
4a4d8108
AM
11567+ struct au_finfo *finfo;
11568+
7f207e10
AM
11569+ au_nfiles_dec(file->f_dentry->d_sb);
11570+
4a4d8108
AM
11571+ finfo = au_fi(file);
11572+ AuDebugOn(finfo->fi_hdir);
11573+ AuRwDestroy(&finfo->fi_rwsem);
11574+ au_cache_free_finfo(finfo);
1308ab2a 11575+}
1308ab2a 11576+
e49829fe 11577+void au_fi_init_once(void *_finfo)
4a4d8108 11578+{
e49829fe 11579+ struct au_finfo *finfo = _finfo;
2cbb1c4b 11580+ static struct lock_class_key aufs_fi;
1308ab2a 11581+
e49829fe
JR
11582+ au_rw_init(&finfo->fi_rwsem);
11583+ au_rw_class(&finfo->fi_rwsem, &aufs_fi);
4a4d8108 11584+}
1308ab2a 11585+
4a4d8108
AM
11586+int au_finfo_init(struct file *file, struct au_fidir *fidir)
11587+{
1716fcea 11588+ int err;
4a4d8108
AM
11589+ struct au_finfo *finfo;
11590+ struct dentry *dentry;
11591+
11592+ err = -ENOMEM;
11593+ dentry = file->f_dentry;
11594+ finfo = au_cache_alloc_finfo();
11595+ if (unlikely(!finfo))
11596+ goto out;
11597+
11598+ err = 0;
7f207e10 11599+ au_nfiles_inc(dentry->d_sb);
1716fcea
AM
11600+ /* verbose coding for lock class name */
11601+ if (!fidir)
11602+ au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcNonDir_FIINFO);
11603+ else
11604+ au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcDir_FIINFO);
4a4d8108
AM
11605+ au_rw_write_lock(&finfo->fi_rwsem);
11606+ finfo->fi_btop = -1;
11607+ finfo->fi_hdir = fidir;
11608+ atomic_set(&finfo->fi_generation, au_digen(dentry));
11609+ /* smp_mb(); */ /* atomic_set */
11610+
11611+ file->private_data = finfo;
11612+
11613+out:
11614+ return err;
11615+}
7f207e10
AM
11616diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
11617--- /usr/share/empty/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
11618+++ linux/fs/aufs/f_op.c 2013-10-26 16:51:32.273040419 +0200
11619@@ -0,0 +1,726 @@
dece6358 11620+/*
7a9e40b8 11621+ * Copyright (C) 2005-2013 Junjiro R. Okajima
dece6358
AM
11622+ *
11623+ * This program, aufs is free software; you can redistribute it and/or modify
11624+ * it under the terms of the GNU General Public License as published by
11625+ * the Free Software Foundation; either version 2 of the License, or
11626+ * (at your option) any later version.
11627+ *
11628+ * This program is distributed in the hope that it will be useful,
11629+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11630+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11631+ * GNU General Public License for more details.
11632+ *
11633+ * You should have received a copy of the GNU General Public License
11634+ * along with this program; if not, write to the Free Software
11635+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11636+ */
1facf9fc 11637+
11638+/*
4a4d8108 11639+ * file and vm operations
1facf9fc 11640+ */
dece6358 11641+
86dc4139 11642+#include <linux/aio.h>
4a4d8108
AM
11643+#include <linux/fs_stack.h>
11644+#include <linux/mman.h>
4a4d8108 11645+#include <linux/security.h>
dece6358
AM
11646+#include "aufs.h"
11647+
4a4d8108 11648+int au_do_open_nondir(struct file *file, int flags)
1facf9fc 11649+{
4a4d8108
AM
11650+ int err;
11651+ aufs_bindex_t bindex;
11652+ struct file *h_file;
11653+ struct dentry *dentry;
11654+ struct au_finfo *finfo;
11655+
11656+ FiMustWriteLock(file);
11657+
4a4d8108 11658+ dentry = file->f_dentry;
027c5e7a
AM
11659+ err = au_d_alive(dentry);
11660+ if (unlikely(err))
11661+ goto out;
11662+
4a4d8108
AM
11663+ finfo = au_fi(file);
11664+ memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
2cbb1c4b 11665+ atomic_set(&finfo->fi_mmapped, 0);
4a4d8108 11666+ bindex = au_dbstart(dentry);
392086de 11667+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
4a4d8108
AM
11668+ if (IS_ERR(h_file))
11669+ err = PTR_ERR(h_file);
11670+ else {
11671+ au_set_fbstart(file, bindex);
11672+ au_set_h_fptr(file, bindex, h_file);
11673+ au_update_figen(file);
392086de
AM
11674+ if (!(file->f_mode & FMODE_WRITE)) {
11675+ lg_local_lock(&files_lglock);
11676+ __file_sb_list_add(file, dentry->d_sb);
11677+ lg_local_unlock(&files_lglock);
11678+ }
4a4d8108
AM
11679+ /* todo: necessary? */
11680+ /* file->f_ra = h_file->f_ra; */
11681+ }
027c5e7a
AM
11682+
11683+out:
4a4d8108 11684+ return err;
1facf9fc 11685+}
11686+
4a4d8108
AM
11687+static int aufs_open_nondir(struct inode *inode __maybe_unused,
11688+ struct file *file)
1facf9fc 11689+{
4a4d8108 11690+ int err;
1308ab2a 11691+ struct super_block *sb;
1facf9fc 11692+
2cbb1c4b 11693+ AuDbg("%.*s, f_flags 0x%x, f_mode 0x%x\n",
4a4d8108
AM
11694+ AuDLNPair(file->f_dentry), vfsub_file_flags(file),
11695+ file->f_mode);
1facf9fc 11696+
4a4d8108
AM
11697+ sb = file->f_dentry->d_sb;
11698+ si_read_lock(sb, AuLock_FLUSH);
11699+ err = au_do_open(file, au_do_open_nondir, /*fidir*/NULL);
11700+ si_read_unlock(sb);
11701+ return err;
11702+}
1facf9fc 11703+
4a4d8108
AM
11704+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
11705+{
11706+ struct au_finfo *finfo;
11707+ aufs_bindex_t bindex;
1facf9fc 11708+
4a4d8108
AM
11709+ finfo = au_fi(file);
11710+ bindex = finfo->fi_btop;
b4510431 11711+ if (bindex >= 0)
4a4d8108 11712+ au_set_h_fptr(file, bindex, NULL);
7f207e10 11713+
4a4d8108
AM
11714+ au_finfo_fin(file);
11715+ return 0;
1facf9fc 11716+}
11717+
4a4d8108
AM
11718+/* ---------------------------------------------------------------------- */
11719+
11720+static int au_do_flush_nondir(struct file *file, fl_owner_t id)
dece6358 11721+{
1308ab2a 11722+ int err;
4a4d8108
AM
11723+ struct file *h_file;
11724+
11725+ err = 0;
11726+ h_file = au_hf_top(file);
11727+ if (h_file)
11728+ err = vfsub_flush(h_file, id);
11729+ return err;
11730+}
11731+
11732+static int aufs_flush_nondir(struct file *file, fl_owner_t id)
11733+{
11734+ return au_do_flush(file, id, au_do_flush_nondir);
11735+}
11736+
11737+/* ---------------------------------------------------------------------- */
9dbd164d
AM
11738+/*
11739+ * read and write functions acquire [fdi]_rwsem once, but release before
11740+ * mmap_sem. This is because to stop a race condition between mmap(2).
11741+ * Releasing these aufs-rwsem should be safe, no branch-mamagement (by keeping
11742+ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in
11743+ * read functions after [fdi]_rwsem are released, but it should be harmless.
11744+ */
4a4d8108
AM
11745+
11746+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
11747+ loff_t *ppos)
11748+{
11749+ ssize_t err;
dece6358 11750+ struct dentry *dentry;
4a4d8108 11751+ struct file *h_file;
dece6358 11752+ struct super_block *sb;
1facf9fc 11753+
dece6358
AM
11754+ dentry = file->f_dentry;
11755+ sb = dentry->d_sb;
e49829fe 11756+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108 11757+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
dece6358
AM
11758+ if (unlikely(err))
11759+ goto out;
1facf9fc 11760+
4a4d8108 11761+ h_file = au_hf_top(file);
9dbd164d
AM
11762+ get_file(h_file);
11763+ di_read_unlock(dentry, AuLock_IR);
11764+ fi_read_unlock(file);
11765+
11766+ /* filedata may be obsoleted by concurrent copyup, but no problem */
4a4d8108
AM
11767+ err = vfsub_read_u(h_file, buf, count, ppos);
11768+ /* todo: necessary? */
11769+ /* file->f_ra = h_file->f_ra; */
9dbd164d 11770+ /* update without lock, I don't think it a problem */
c06a8ce3 11771+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 11772+ fput(h_file);
1308ab2a 11773+
4f0767ce 11774+out:
dece6358
AM
11775+ si_read_unlock(sb);
11776+ return err;
11777+}
1facf9fc 11778+
e49829fe
JR
11779+/*
11780+ * todo: very ugly
11781+ * it locks both of i_mutex and si_rwsem for read in safe.
11782+ * if the plink maintenance mode continues forever (that is the problem),
11783+ * may loop forever.
11784+ */
11785+static void au_mtx_and_read_lock(struct inode *inode)
11786+{
11787+ int err;
11788+ struct super_block *sb = inode->i_sb;
11789+
11790+ while (1) {
11791+ mutex_lock(&inode->i_mutex);
11792+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
11793+ if (!err)
11794+ break;
11795+ mutex_unlock(&inode->i_mutex);
11796+ si_read_lock(sb, AuLock_NOPLMW);
11797+ si_read_unlock(sb);
11798+ }
11799+}
11800+
4a4d8108
AM
11801+static ssize_t aufs_write(struct file *file, const char __user *ubuf,
11802+ size_t count, loff_t *ppos)
dece6358 11803+{
4a4d8108
AM
11804+ ssize_t err;
11805+ struct au_pin pin;
dece6358 11806+ struct dentry *dentry;
9dbd164d 11807+ struct super_block *sb;
4a4d8108 11808+ struct inode *inode;
4a4d8108
AM
11809+ struct file *h_file;
11810+ char __user *buf = (char __user *)ubuf;
1facf9fc 11811+
dece6358 11812+ dentry = file->f_dentry;
9dbd164d 11813+ sb = dentry->d_sb;
4a4d8108 11814+ inode = dentry->d_inode;
e49829fe 11815+ au_mtx_and_read_lock(inode);
1facf9fc 11816+
4a4d8108
AM
11817+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11818+ if (unlikely(err))
11819+ goto out;
1facf9fc 11820+
4a4d8108
AM
11821+ err = au_ready_to_write(file, -1, &pin);
11822+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
11823+ if (unlikely(err)) {
11824+ di_read_unlock(dentry, AuLock_IR);
11825+ fi_write_unlock(file);
11826+ goto out;
11827+ }
1facf9fc 11828+
4a4d8108 11829+ h_file = au_hf_top(file);
9dbd164d 11830+ get_file(h_file);
4a4d8108 11831+ au_unpin(&pin);
9dbd164d
AM
11832+ di_read_unlock(dentry, AuLock_IR);
11833+ fi_write_unlock(file);
11834+
4a4d8108 11835+ err = vfsub_write_u(h_file, buf, count, ppos);
9dbd164d 11836+ ii_write_lock_child(inode);
4a4d8108 11837+ au_cpup_attr_timesizes(inode);
c06a8ce3 11838+ inode->i_mode = file_inode(h_file)->i_mode;
9dbd164d
AM
11839+ ii_write_unlock(inode);
11840+ fput(h_file);
1facf9fc 11841+
4f0767ce 11842+out:
9dbd164d 11843+ si_read_unlock(sb);
4a4d8108 11844+ mutex_unlock(&inode->i_mutex);
dece6358
AM
11845+ return err;
11846+}
1facf9fc 11847+
4a4d8108
AM
11848+static ssize_t au_do_aio(struct file *h_file, int rw, struct kiocb *kio,
11849+ const struct iovec *iov, unsigned long nv, loff_t pos)
dece6358 11850+{
4a4d8108
AM
11851+ ssize_t err;
11852+ struct file *file;
11853+ ssize_t (*func)(struct kiocb *, const struct iovec *, unsigned long,
11854+ loff_t);
1facf9fc 11855+
4a4d8108
AM
11856+ err = security_file_permission(h_file, rw);
11857+ if (unlikely(err))
11858+ goto out;
1facf9fc 11859+
4a4d8108
AM
11860+ err = -ENOSYS;
11861+ func = NULL;
11862+ if (rw == MAY_READ)
11863+ func = h_file->f_op->aio_read;
11864+ else if (rw == MAY_WRITE)
11865+ func = h_file->f_op->aio_write;
11866+ if (func) {
11867+ file = kio->ki_filp;
11868+ kio->ki_filp = h_file;
2cbb1c4b 11869+ lockdep_off();
4a4d8108 11870+ err = func(kio, iov, nv, pos);
2cbb1c4b 11871+ lockdep_on();
4a4d8108
AM
11872+ kio->ki_filp = file;
11873+ } else
11874+ /* currently there is no such fs */
11875+ WARN_ON_ONCE(1);
1facf9fc 11876+
4f0767ce 11877+out:
dece6358
AM
11878+ return err;
11879+}
1facf9fc 11880+
4a4d8108
AM
11881+static ssize_t aufs_aio_read(struct kiocb *kio, const struct iovec *iov,
11882+ unsigned long nv, loff_t pos)
1facf9fc 11883+{
4a4d8108
AM
11884+ ssize_t err;
11885+ struct file *file, *h_file;
11886+ struct dentry *dentry;
dece6358 11887+ struct super_block *sb;
1facf9fc 11888+
4a4d8108 11889+ file = kio->ki_filp;
dece6358 11890+ dentry = file->f_dentry;
1308ab2a 11891+ sb = dentry->d_sb;
e49829fe 11892+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
11893+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
11894+ if (unlikely(err))
11895+ goto out;
11896+
11897+ h_file = au_hf_top(file);
9dbd164d
AM
11898+ get_file(h_file);
11899+ di_read_unlock(dentry, AuLock_IR);
11900+ fi_read_unlock(file);
11901+
4a4d8108
AM
11902+ err = au_do_aio(h_file, MAY_READ, kio, iov, nv, pos);
11903+ /* todo: necessary? */
11904+ /* file->f_ra = h_file->f_ra; */
9dbd164d 11905+ /* update without lock, I don't think it a problem */
c06a8ce3 11906+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 11907+ fput(h_file);
1facf9fc 11908+
4f0767ce 11909+out:
4a4d8108 11910+ si_read_unlock(sb);
1308ab2a 11911+ return err;
11912+}
1facf9fc 11913+
4a4d8108
AM
11914+static ssize_t aufs_aio_write(struct kiocb *kio, const struct iovec *iov,
11915+ unsigned long nv, loff_t pos)
1308ab2a 11916+{
4a4d8108
AM
11917+ ssize_t err;
11918+ struct au_pin pin;
11919+ struct dentry *dentry;
11920+ struct inode *inode;
4a4d8108 11921+ struct file *file, *h_file;
9dbd164d 11922+ struct super_block *sb;
1308ab2a 11923+
4a4d8108 11924+ file = kio->ki_filp;
1308ab2a 11925+ dentry = file->f_dentry;
9dbd164d 11926+ sb = dentry->d_sb;
1308ab2a 11927+ inode = dentry->d_inode;
e49829fe
JR
11928+ au_mtx_and_read_lock(inode);
11929+
4a4d8108
AM
11930+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11931+ if (unlikely(err))
1308ab2a 11932+ goto out;
1facf9fc 11933+
4a4d8108
AM
11934+ err = au_ready_to_write(file, -1, &pin);
11935+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
11936+ if (unlikely(err)) {
11937+ di_read_unlock(dentry, AuLock_IR);
11938+ fi_write_unlock(file);
11939+ goto out;
11940+ }
1facf9fc 11941+
4a4d8108 11942+ h_file = au_hf_top(file);
9dbd164d
AM
11943+ get_file(h_file);
11944+ au_unpin(&pin);
11945+ di_read_unlock(dentry, AuLock_IR);
11946+ fi_write_unlock(file);
11947+
4a4d8108 11948+ err = au_do_aio(h_file, MAY_WRITE, kio, iov, nv, pos);
9dbd164d 11949+ ii_write_lock_child(inode);
4a4d8108 11950+ au_cpup_attr_timesizes(inode);
c06a8ce3 11951+ inode->i_mode = file_inode(h_file)->i_mode;
9dbd164d
AM
11952+ ii_write_unlock(inode);
11953+ fput(h_file);
1facf9fc 11954+
4f0767ce 11955+out:
9dbd164d 11956+ si_read_unlock(sb);
4a4d8108 11957+ mutex_unlock(&inode->i_mutex);
dece6358 11958+ return err;
1facf9fc 11959+}
11960+
4a4d8108
AM
11961+static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
11962+ struct pipe_inode_info *pipe, size_t len,
11963+ unsigned int flags)
1facf9fc 11964+{
4a4d8108
AM
11965+ ssize_t err;
11966+ struct file *h_file;
11967+ struct dentry *dentry;
dece6358 11968+ struct super_block *sb;
1facf9fc 11969+
dece6358 11970+ dentry = file->f_dentry;
dece6358 11971+ sb = dentry->d_sb;
e49829fe 11972+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
11973+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
11974+ if (unlikely(err))
dece6358 11975+ goto out;
1facf9fc 11976+
4a4d8108
AM
11977+ err = -EINVAL;
11978+ h_file = au_hf_top(file);
9dbd164d 11979+ get_file(h_file);
4a4d8108 11980+ if (au_test_loopback_kthread()) {
87a755f4
AM
11981+ au_warn_loopback(h_file->f_dentry->d_sb);
11982+ if (file->f_mapping != h_file->f_mapping) {
11983+ file->f_mapping = h_file->f_mapping;
11984+ smp_mb(); /* unnecessary? */
11985+ }
1308ab2a 11986+ }
9dbd164d
AM
11987+ di_read_unlock(dentry, AuLock_IR);
11988+ fi_read_unlock(file);
11989+
4a4d8108
AM
11990+ err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
11991+ /* todo: necessasry? */
11992+ /* file->f_ra = h_file->f_ra; */
9dbd164d 11993+ /* update without lock, I don't think it a problem */
c06a8ce3 11994+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 11995+ fput(h_file);
1facf9fc 11996+
4f0767ce 11997+out:
4a4d8108 11998+ si_read_unlock(sb);
dece6358 11999+ return err;
1facf9fc 12000+}
12001+
4a4d8108
AM
12002+static ssize_t
12003+aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
12004+ size_t len, unsigned int flags)
1facf9fc 12005+{
4a4d8108
AM
12006+ ssize_t err;
12007+ struct au_pin pin;
12008+ struct dentry *dentry;
12009+ struct inode *inode;
4a4d8108 12010+ struct file *h_file;
9dbd164d 12011+ struct super_block *sb;
1facf9fc 12012+
4a4d8108 12013+ dentry = file->f_dentry;
9dbd164d 12014+ sb = dentry->d_sb;
4a4d8108 12015+ inode = dentry->d_inode;
e49829fe 12016+ au_mtx_and_read_lock(inode);
9dbd164d 12017+
4a4d8108
AM
12018+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
12019+ if (unlikely(err))
12020+ goto out;
1facf9fc 12021+
4a4d8108
AM
12022+ err = au_ready_to_write(file, -1, &pin);
12023+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
12024+ if (unlikely(err)) {
12025+ di_read_unlock(dentry, AuLock_IR);
12026+ fi_write_unlock(file);
12027+ goto out;
12028+ }
1facf9fc 12029+
4a4d8108 12030+ h_file = au_hf_top(file);
9dbd164d 12031+ get_file(h_file);
4a4d8108 12032+ au_unpin(&pin);
9dbd164d
AM
12033+ di_read_unlock(dentry, AuLock_IR);
12034+ fi_write_unlock(file);
12035+
4a4d8108 12036+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
9dbd164d 12037+ ii_write_lock_child(inode);
4a4d8108 12038+ au_cpup_attr_timesizes(inode);
c06a8ce3 12039+ inode->i_mode = file_inode(h_file)->i_mode;
9dbd164d
AM
12040+ ii_write_unlock(inode);
12041+ fput(h_file);
1facf9fc 12042+
4f0767ce 12043+out:
9dbd164d 12044+ si_read_unlock(sb);
4a4d8108
AM
12045+ mutex_unlock(&inode->i_mutex);
12046+ return err;
12047+}
1facf9fc 12048+
4a4d8108
AM
12049+/* ---------------------------------------------------------------------- */
12050+
9dbd164d
AM
12051+/*
12052+ * The locking order around current->mmap_sem.
12053+ * - in most and regular cases
12054+ * file I/O syscall -- aufs_read() or something
12055+ * -- si_rwsem for read -- mmap_sem
12056+ * (Note that [fdi]i_rwsem are released before mmap_sem).
12057+ * - in mmap case
12058+ * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem
12059+ * This AB-BA order is definitly bad, but is not a problem since "si_rwsem for
12060+ * read" allows muliple processes to acquire it and [fdi]i_rwsem are not held in
12061+ * file I/O. Aufs needs to stop lockdep in aufs_mmap() though.
12062+ * It means that when aufs acquires si_rwsem for write, the process should never
12063+ * acquire mmap_sem.
12064+ *
392086de 12065+ * Actually aufs_iterate() holds [fdi]i_rwsem before mmap_sem, but this is not a
9dbd164d
AM
12066+ * problem either since any directory is not able to be mmap-ed.
12067+ * The similar scenario is applied to aufs_readlink() too.
12068+ */
12069+
2dfbb274
AM
12070+/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
12071+#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b)
12072+
12073+static unsigned long au_arch_prot_conv(unsigned long flags)
12074+{
12075+ /* currently ppc64 only */
12076+#ifdef CONFIG_PPC64
12077+ /* cf. linux/arch/powerpc/include/asm/mman.h */
12078+ AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO);
12079+ return AuConv_VM_PROT(flags, SAO);
12080+#else
12081+ AuDebugOn(arch_calc_vm_prot_bits(-1));
12082+ return 0;
12083+#endif
12084+}
12085+
12086+static unsigned long au_prot_conv(unsigned long flags)
12087+{
12088+ return AuConv_VM_PROT(flags, READ)
12089+ | AuConv_VM_PROT(flags, WRITE)
12090+ | AuConv_VM_PROT(flags, EXEC)
12091+ | au_arch_prot_conv(flags);
12092+}
12093+
12094+/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */
12095+#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b)
12096+
12097+static unsigned long au_flag_conv(unsigned long flags)
12098+{
12099+ return AuConv_VM_MAP(flags, GROWSDOWN)
12100+ | AuConv_VM_MAP(flags, DENYWRITE)
2dfbb274
AM
12101+ | AuConv_VM_MAP(flags, LOCKED);
12102+}
12103+
9dbd164d 12104+static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
dece6358 12105+{
4a4d8108
AM
12106+ int err;
12107+ aufs_bindex_t bstart;
12108+ const unsigned char wlock
9dbd164d 12109+ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
4a4d8108
AM
12110+ struct dentry *dentry;
12111+ struct super_block *sb;
9dbd164d
AM
12112+ struct file *h_file;
12113+ struct au_branch *br;
12114+ struct au_pin pin;
12115+
12116+ AuDbgVmRegion(file, vma);
1308ab2a 12117+
4a4d8108
AM
12118+ dentry = file->f_dentry;
12119+ sb = dentry->d_sb;
9dbd164d 12120+ lockdep_off();
e49829fe 12121+ si_read_lock(sb, AuLock_NOPLMW);
4a4d8108
AM
12122+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
12123+ if (unlikely(err))
12124+ goto out;
12125+
4a4d8108 12126+ if (wlock) {
4a4d8108
AM
12127+ err = au_ready_to_write(file, -1, &pin);
12128+ di_write_unlock(dentry);
9dbd164d
AM
12129+ if (unlikely(err)) {
12130+ fi_write_unlock(file);
12131+ goto out;
12132+ }
4a4d8108
AM
12133+ au_unpin(&pin);
12134+ } else
12135+ di_write_unlock(dentry);
9dbd164d 12136+
4a4d8108 12137+ bstart = au_fbstart(file);
9dbd164d
AM
12138+ br = au_sbr(sb, bstart);
12139+ h_file = au_hf_top(file);
12140+ get_file(h_file);
2cbb1c4b 12141+ au_set_mmapped(file);
4a4d8108 12142+ fi_write_unlock(file);
9dbd164d 12143+ lockdep_on();
1308ab2a 12144+
9dbd164d 12145+ au_vm_file_reset(vma, h_file);
2dfbb274
AM
12146+ err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
12147+ au_flag_conv(vma->vm_flags));
9dbd164d
AM
12148+ if (!err)
12149+ err = h_file->f_op->mmap(h_file, vma);
2cbb1c4b
JR
12150+ if (unlikely(err))
12151+ goto out_reset;
4a4d8108 12152+
2cbb1c4b 12153+ au_vm_prfile_set(vma, file);
4a4d8108 12154+ /* update without lock, I don't think it a problem */
c06a8ce3 12155+ fsstack_copy_attr_atime(file_inode(file), file_inode(h_file));
2cbb1c4b 12156+ goto out_fput; /* success */
4a4d8108 12157+
2cbb1c4b
JR
12158+out_reset:
12159+ au_unset_mmapped(file);
12160+ au_vm_file_reset(vma, file);
12161+out_fput:
9dbd164d
AM
12162+ fput(h_file);
12163+ lockdep_off();
4f0767ce 12164+out:
9dbd164d
AM
12165+ si_read_unlock(sb);
12166+ lockdep_on();
12167+ AuTraceErr(err);
4a4d8108
AM
12168+ return err;
12169+}
12170+
12171+/* ---------------------------------------------------------------------- */
12172+
1e00d052
AM
12173+static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end,
12174+ int datasync)
4a4d8108
AM
12175+{
12176+ int err;
12177+ struct au_pin pin;
b752ccd1 12178+ struct dentry *dentry;
4a4d8108
AM
12179+ struct inode *inode;
12180+ struct file *h_file;
12181+ struct super_block *sb;
12182+
b752ccd1 12183+ dentry = file->f_dentry;
4a4d8108 12184+ inode = dentry->d_inode;
4a4d8108 12185+ sb = dentry->d_sb;
1e00d052 12186+ mutex_lock(&inode->i_mutex);
e49829fe
JR
12187+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
12188+ if (unlikely(err))
12189+ goto out;
4a4d8108
AM
12190+
12191+ err = 0; /* -EBADF; */ /* posix? */
12192+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
e49829fe 12193+ goto out_si;
4a4d8108
AM
12194+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
12195+ if (unlikely(err))
e49829fe 12196+ goto out_si;
4a4d8108
AM
12197+
12198+ err = au_ready_to_write(file, -1, &pin);
12199+ di_downgrade_lock(dentry, AuLock_IR);
12200+ if (unlikely(err))
12201+ goto out_unlock;
12202+ au_unpin(&pin);
12203+
12204+ err = -EINVAL;
12205+ h_file = au_hf_top(file);
53392da6
AM
12206+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
12207+ au_cpup_attr_timesizes(inode);
4a4d8108 12208+
4f0767ce 12209+out_unlock:
4a4d8108 12210+ di_read_unlock(dentry, AuLock_IR);
1308ab2a 12211+ fi_write_unlock(file);
e49829fe 12212+out_si:
953406b4 12213+ si_read_unlock(sb);
e49829fe 12214+out:
1e00d052 12215+ mutex_unlock(&inode->i_mutex);
4a4d8108 12216+ return err;
dece6358
AM
12217+}
12218+
4a4d8108
AM
12219+/* no one supports this operation, currently */
12220+#if 0
12221+static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync)
dece6358 12222+{
4a4d8108
AM
12223+ int err;
12224+ struct au_pin pin;
1308ab2a 12225+ struct dentry *dentry;
4a4d8108
AM
12226+ struct inode *inode;
12227+ struct file *file, *h_file;
1308ab2a 12228+
4a4d8108 12229+ file = kio->ki_filp;
1308ab2a 12230+ dentry = file->f_dentry;
4a4d8108 12231+ inode = dentry->d_inode;
e49829fe 12232+ au_mtx_and_read_lock(inode);
4a4d8108
AM
12233+
12234+ err = 0; /* -EBADF; */ /* posix? */
12235+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
12236+ goto out;
12237+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
12238+ if (unlikely(err))
1308ab2a 12239+ goto out;
12240+
4a4d8108
AM
12241+ err = au_ready_to_write(file, -1, &pin);
12242+ di_downgrade_lock(dentry, AuLock_IR);
12243+ if (unlikely(err))
12244+ goto out_unlock;
12245+ au_unpin(&pin);
1308ab2a 12246+
4a4d8108
AM
12247+ err = -ENOSYS;
12248+ h_file = au_hf_top(file);
12249+ if (h_file->f_op && h_file->f_op->aio_fsync) {
4a4d8108 12250+ struct mutex *h_mtx;
1308ab2a 12251+
c06a8ce3 12252+ h_mtx = &file_inode(h_file)->i_mutex;
4a4d8108
AM
12253+ if (!is_sync_kiocb(kio)) {
12254+ get_file(h_file);
12255+ fput(file);
12256+ }
12257+ kio->ki_filp = h_file;
12258+ err = h_file->f_op->aio_fsync(kio, datasync);
12259+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
12260+ if (!err)
12261+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
12262+ /*ignore*/
12263+ au_cpup_attr_timesizes(inode);
12264+ mutex_unlock(h_mtx);
12265+ }
1308ab2a 12266+
4f0767ce 12267+out_unlock:
4a4d8108
AM
12268+ di_read_unlock(dentry, AuLock_IR);
12269+ fi_write_unlock(file);
4f0767ce 12270+out:
e49829fe 12271+ si_read_unlock(inode->sb);
4a4d8108
AM
12272+ mutex_unlock(&inode->i_mutex);
12273+ return err;
dece6358 12274+}
4a4d8108 12275+#endif
dece6358 12276+
4a4d8108 12277+static int aufs_fasync(int fd, struct file *file, int flag)
dece6358 12278+{
4a4d8108
AM
12279+ int err;
12280+ struct file *h_file;
12281+ struct dentry *dentry;
12282+ struct super_block *sb;
1308ab2a 12283+
4a4d8108
AM
12284+ dentry = file->f_dentry;
12285+ sb = dentry->d_sb;
e49829fe 12286+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
12287+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
12288+ if (unlikely(err))
12289+ goto out;
12290+
12291+ h_file = au_hf_top(file);
12292+ if (h_file->f_op && h_file->f_op->fasync)
12293+ err = h_file->f_op->fasync(fd, h_file, flag);
12294+
12295+ di_read_unlock(dentry, AuLock_IR);
12296+ fi_read_unlock(file);
1308ab2a 12297+
4f0767ce 12298+out:
4a4d8108 12299+ si_read_unlock(sb);
1308ab2a 12300+ return err;
dece6358 12301+}
4a4d8108
AM
12302+
12303+/* ---------------------------------------------------------------------- */
12304+
12305+/* no one supports this operation, currently */
12306+#if 0
12307+static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
12308+ size_t len, loff_t *pos , int more)
12309+{
12310+}
12311+#endif
12312+
12313+/* ---------------------------------------------------------------------- */
12314+
12315+const struct file_operations aufs_file_fop = {
12316+ .owner = THIS_MODULE,
2cbb1c4b 12317+
027c5e7a 12318+ .llseek = default_llseek,
4a4d8108
AM
12319+
12320+ .read = aufs_read,
12321+ .write = aufs_write,
12322+ .aio_read = aufs_aio_read,
12323+ .aio_write = aufs_aio_write,
12324+#ifdef CONFIG_AUFS_POLL
12325+ .poll = aufs_poll,
12326+#endif
12327+ .unlocked_ioctl = aufs_ioctl_nondir,
b752ccd1 12328+#ifdef CONFIG_COMPAT
c2b27bf2 12329+ .compat_ioctl = aufs_compat_ioctl_nondir,
b752ccd1 12330+#endif
4a4d8108
AM
12331+ .mmap = aufs_mmap,
12332+ .open = aufs_open_nondir,
12333+ .flush = aufs_flush_nondir,
12334+ .release = aufs_release_nondir,
12335+ .fsync = aufs_fsync_nondir,
12336+ /* .aio_fsync = aufs_aio_fsync_nondir, */
12337+ .fasync = aufs_fasync,
12338+ /* .sendpage = aufs_sendpage, */
12339+ .splice_write = aufs_splice_write,
12340+ .splice_read = aufs_splice_read,
12341+#if 0
12342+ .aio_splice_write = aufs_aio_splice_write,
12343+ .aio_splice_read = aufs_aio_splice_read
12344+#endif
12345+};
7f207e10
AM
12346diff -urN /usr/share/empty/fs/aufs/f_op_sp.c linux/fs/aufs/f_op_sp.c
12347--- /usr/share/empty/fs/aufs/f_op_sp.c 1970-01-01 01:00:00.000000000 +0100
392086de 12348+++ linux/fs/aufs/f_op_sp.c 2013-10-26 16:51:32.273040419 +0200
c2b27bf2 12349@@ -0,0 +1,383 @@
1308ab2a 12350+/*
7a9e40b8 12351+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1308ab2a 12352+ *
12353+ * This program, aufs is free software; you can redistribute it and/or modify
12354+ * it under the terms of the GNU General Public License as published by
12355+ * the Free Software Foundation; either version 2 of the License, or
12356+ * (at your option) any later version.
12357+ *
12358+ * This program is distributed in the hope that it will be useful,
12359+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12360+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12361+ * GNU General Public License for more details.
12362+ *
12363+ * You should have received a copy of the GNU General Public License
12364+ * along with this program; if not, write to the Free Software
12365+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12366+ */
dece6358 12367+
1308ab2a 12368+/*
4a4d8108
AM
12369+ * file operations for special files.
12370+ * while they exist in aufs virtually,
12371+ * their file I/O is handled out of aufs.
1308ab2a 12372+ */
12373+
86dc4139 12374+#include <linux/aio.h>
4a4d8108 12375+#include "aufs.h"
1308ab2a 12376+
86dc4139
AM
12377+/*
12378+ * I don't think the size of this list grows much.
12379+ * so here is a very simple list implemented in order to find finfo matching a
12380+ * given file.
12381+ */
12382+static struct au_sphlhead au_finfo_sp = {
12383+ .spin = __SPIN_LOCK_INITIALIZER(au_finfo_sp.spin),
12384+ .head = HLIST_HEAD_INIT
12385+};
12386+
12387+struct au_finfo_sp {
12388+ struct hlist_node hlist;
c2b27bf2 12389+ struct file *file;
86dc4139
AM
12390+ struct au_finfo *finfo;
12391+};
12392+
12393+struct au_finfo *au_fi_sp(struct file *file)
12394+{
12395+ struct au_finfo *finfo;
12396+ struct au_finfo_sp *sp;
12397+
12398+ finfo = NULL;
12399+ spin_lock(&au_finfo_sp.spin);
12400+ hlist_for_each_entry(sp, &au_finfo_sp.head, hlist) {
12401+ if (sp->file != file)
12402+ continue;
12403+ finfo = sp->finfo;
12404+ break;
12405+ }
12406+ spin_unlock(&au_finfo_sp.spin);
12407+
12408+ return finfo;
12409+}
12410+
12411+static int au_fi_sp_add(struct file *file)
12412+{
12413+ int err;
12414+ struct au_finfo_sp *sp;
12415+
12416+ err = -ENOMEM;
12417+ sp = kmalloc(sizeof(*sp), GFP_NOFS);
12418+ if (sp) {
12419+ err = 0;
12420+ sp->file = file;
12421+ sp->finfo = file->private_data;
12422+ spin_lock(&au_finfo_sp.spin);
12423+ hlist_add_head(&sp->hlist, &au_finfo_sp.head);
12424+ spin_unlock(&au_finfo_sp.spin);
12425+ }
12426+ return err;
12427+}
12428+
12429+static void au_fi_sp_del(struct file *file)
12430+{
12431+ struct au_finfo_sp *sp, *do_free;
12432+
12433+ do_free = NULL;
12434+ spin_lock(&au_finfo_sp.spin);
12435+ hlist_for_each_entry(sp, &au_finfo_sp.head, hlist) {
12436+ if (sp->file != file)
12437+ continue;
12438+ hlist_del(&sp->hlist);
12439+ do_free = sp;
12440+ break;
12441+ }
12442+ spin_unlock(&au_finfo_sp.spin);
12443+ kfree(do_free);
12444+}
12445+
12446+/* ---------------------------------------------------------------------- */
12447+
4a4d8108
AM
12448+static ssize_t aufs_aio_read_sp(struct kiocb *kio, const struct iovec *iov,
12449+ unsigned long nv, loff_t pos)
dece6358 12450+{
4a4d8108
AM
12451+ ssize_t err;
12452+ aufs_bindex_t bstart;
12453+ unsigned char wbr;
12454+ struct file *file, *h_file;
12455+ struct super_block *sb;
1308ab2a 12456+
4a4d8108
AM
12457+ file = kio->ki_filp;
12458+ sb = file->f_dentry->d_sb;
12459+ si_read_lock(sb, AuLock_FLUSH);
12460+ fi_read_lock(file);
12461+ bstart = au_fbstart(file);
12462+ h_file = au_hf_top(file);
12463+ fi_read_unlock(file);
12464+ wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
12465+ si_read_unlock(sb);
12466+
12467+ /* do not change the file in kio */
12468+ AuDebugOn(!h_file->f_op || !h_file->f_op->aio_read);
12469+ err = h_file->f_op->aio_read(kio, iov, nv, pos);
12470+ if (err > 0 && wbr)
12471+ file_accessed(h_file);
12472+
12473+ return err;
12474+}
12475+
12476+static ssize_t aufs_aio_write_sp(struct kiocb *kio, const struct iovec *iov,
12477+ unsigned long nv, loff_t pos)
12478+{
12479+ ssize_t err;
12480+ aufs_bindex_t bstart;
12481+ unsigned char wbr;
12482+ struct super_block *sb;
12483+ struct file *file, *h_file;
12484+
12485+ file = kio->ki_filp;
12486+ sb = file->f_dentry->d_sb;
12487+ si_read_lock(sb, AuLock_FLUSH);
12488+ fi_read_lock(file);
12489+ bstart = au_fbstart(file);
12490+ h_file = au_hf_top(file);
12491+ fi_read_unlock(file);
12492+ wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
12493+ si_read_unlock(sb);
12494+
12495+ /* do not change the file in kio */
12496+ AuDebugOn(!h_file->f_op || !h_file->f_op->aio_write);
12497+ err = h_file->f_op->aio_write(kio, iov, nv, pos);
4a4d8108
AM
12498+ return err;
12499+}
12500+
12501+/* ---------------------------------------------------------------------- */
12502+
12503+static int aufs_release_sp(struct inode *inode, struct file *file)
12504+{
12505+ int err;
12506+ struct file *h_file;
12507+
12508+ fi_read_lock(file);
12509+ h_file = au_hf_top(file);
12510+ fi_read_unlock(file);
12511+ /* close this fifo in aufs */
12512+ err = h_file->f_op->release(inode, file); /* ignore */
12513+ aufs_release_nondir(inode, file); /* ignore */
86dc4139 12514+ au_fi_sp_del(file);
4a4d8108
AM
12515+ return err;
12516+}
12517+
12518+/* ---------------------------------------------------------------------- */
12519+
12520+/* currently, support only FIFO */
4f0767ce
JR
12521+enum {
12522+ AuSp_FIFO, AuSp_FIFO_R, AuSp_FIFO_W, AuSp_FIFO_RW,
12523+ /* AuSp_SOCK, AuSp_CHR, AuSp_BLK, */
12524+ AuSp_Last
12525+};
4a4d8108
AM
12526+static int aufs_open_sp(struct inode *inode, struct file *file);
12527+static struct au_sp_fop {
12528+ int done;
12529+ struct file_operations fop; /* not 'const' */
12530+ spinlock_t spin;
12531+} au_sp_fop[AuSp_Last] = {
12532+ [AuSp_FIFO] = {
12533+ .fop = {
12534+ .owner = THIS_MODULE,
12535+ .open = aufs_open_sp
12536+ }
12537+ }
12538+};
12539+
12540+static void au_init_fop_sp(struct file *file)
12541+{
12542+ struct au_sp_fop *p;
12543+ int i;
12544+ struct file *h_file;
12545+
12546+ p = au_sp_fop;
12547+ if (unlikely(!p->done)) {
12548+ /* initialize first time only */
12549+ static DEFINE_SPINLOCK(spin);
12550+
12551+ spin_lock(&spin);
12552+ if (!p->done) {
12553+ BUILD_BUG_ON(sizeof(au_sp_fop)/sizeof(*au_sp_fop)
12554+ != AuSp_Last);
12555+ for (i = 0; i < AuSp_Last; i++)
12556+ spin_lock_init(&p[i].spin);
12557+ p->done = 1;
12558+ }
12559+ spin_unlock(&spin);
12560+ }
12561+
12562+ switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) {
12563+ case FMODE_READ:
12564+ i = AuSp_FIFO_R;
12565+ break;
12566+ case FMODE_WRITE:
12567+ i = AuSp_FIFO_W;
12568+ break;
12569+ case FMODE_READ | FMODE_WRITE:
12570+ i = AuSp_FIFO_RW;
12571+ break;
12572+ default:
12573+ BUG();
12574+ }
12575+
12576+ p += i;
12577+ if (unlikely(!p->done)) {
12578+ /* initialize first time only */
12579+ h_file = au_hf_top(file);
12580+ spin_lock(&p->spin);
12581+ if (!p->done) {
12582+ p->fop = *h_file->f_op;
12583+ p->fop.owner = THIS_MODULE;
12584+ if (p->fop.aio_read)
12585+ p->fop.aio_read = aufs_aio_read_sp;
12586+ if (p->fop.aio_write)
12587+ p->fop.aio_write = aufs_aio_write_sp;
12588+ p->fop.release = aufs_release_sp;
12589+ p->done = 1;
12590+ }
12591+ spin_unlock(&p->spin);
12592+ }
12593+ file->f_op = &p->fop;
12594+}
12595+
12596+static int au_cpup_sp(struct dentry *dentry)
12597+{
12598+ int err;
4a4d8108
AM
12599+ struct au_pin pin;
12600+ struct au_wr_dir_args wr_dir_args = {
12601+ .force_btgt = -1,
12602+ .flags = 0
12603+ };
c2b27bf2
AM
12604+ struct au_cp_generic cpg = {
12605+ .dentry = dentry,
12606+ .bdst = -1,
12607+ .bsrc = -1,
12608+ .len = -1,
12609+ .pin = &pin,
12610+ .flags = AuCpup_DTIME
12611+ };
4a4d8108
AM
12612+
12613+ AuDbg("%.*s\n", AuDLNPair(dentry));
12614+
12615+ di_read_unlock(dentry, AuLock_IR);
12616+ di_write_lock_child(dentry);
12617+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
12618+ if (unlikely(err < 0))
12619+ goto out;
c2b27bf2 12620+ cpg.bdst = err;
4a4d8108 12621+ err = 0;
c2b27bf2 12622+ if (cpg.bdst == au_dbstart(dentry))
4a4d8108
AM
12623+ goto out; /* success */
12624+
c2b27bf2 12625+ err = au_pin(&pin, dentry, cpg.bdst, au_opt_udba(dentry->d_sb),
4a4d8108
AM
12626+ AuPin_MNT_WRITE);
12627+ if (!err) {
c2b27bf2 12628+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
12629+ au_unpin(&pin);
12630+ }
12631+
4f0767ce 12632+out:
4a4d8108
AM
12633+ di_downgrade_lock(dentry, AuLock_IR);
12634+ return err;
12635+}
12636+
12637+static int au_do_open_sp(struct file *file, int flags)
12638+{
12639+ int err;
12640+ struct dentry *dentry;
12641+ struct super_block *sb;
12642+ struct file *h_file;
12643+ struct inode *h_inode;
12644+
86dc4139
AM
12645+ err = au_fi_sp_add(file);
12646+ if (unlikely(err))
12647+ goto out;
12648+
4a4d8108
AM
12649+ dentry = file->f_dentry;
12650+ AuDbg("%.*s\n", AuDLNPair(dentry));
12651+
12652+ /*
12653+ * try copying-up.
12654+ * operate on the ro branch is not an error.
12655+ */
12656+ au_cpup_sp(dentry); /* ignore */
12657+
12658+ /* prepare h_file */
12659+ err = au_do_open_nondir(file, vfsub_file_flags(file));
12660+ if (unlikely(err))
86dc4139 12661+ goto out_del;
4a4d8108
AM
12662+
12663+ sb = dentry->d_sb;
12664+ h_file = au_hf_top(file);
c06a8ce3 12665+ h_inode = file_inode(h_file);
4a4d8108
AM
12666+ di_read_unlock(dentry, AuLock_IR);
12667+ fi_write_unlock(file);
12668+ si_read_unlock(sb);
12669+ /* open this fifo in aufs */
c06a8ce3 12670+ err = h_inode->i_fop->open(file_inode(file), file);
4a4d8108
AM
12671+ si_noflush_read_lock(sb);
12672+ fi_write_lock(file);
12673+ di_read_lock_child(dentry, AuLock_IR);
86dc4139 12674+ if (!err) {
4a4d8108 12675+ au_init_fop_sp(file);
86dc4139
AM
12676+ goto out; /* success */
12677+ }
4a4d8108 12678+
86dc4139
AM
12679+out_del:
12680+ au_fi_sp_del(file);
4f0767ce 12681+out:
4a4d8108
AM
12682+ return err;
12683+}
12684+
12685+static int aufs_open_sp(struct inode *inode, struct file *file)
12686+{
12687+ int err;
12688+ struct super_block *sb;
12689+
12690+ sb = file->f_dentry->d_sb;
12691+ si_read_lock(sb, AuLock_FLUSH);
12692+ err = au_do_open(file, au_do_open_sp, /*fidir*/NULL);
12693+ si_read_unlock(sb);
12694+ return err;
12695+}
12696+
12697+/* ---------------------------------------------------------------------- */
12698+
12699+void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev)
12700+{
12701+ init_special_inode(inode, mode, rdev);
12702+
12703+ switch (mode & S_IFMT) {
12704+ case S_IFIFO:
12705+ inode->i_fop = &au_sp_fop[AuSp_FIFO].fop;
12706+ /*FALLTHROUGH*/
12707+ case S_IFCHR:
12708+ case S_IFBLK:
12709+ case S_IFSOCK:
12710+ break;
12711+ default:
12712+ AuDebugOn(1);
12713+ }
12714+}
12715+
12716+int au_special_file(umode_t mode)
12717+{
12718+ int ret;
12719+
12720+ ret = 0;
12721+ switch (mode & S_IFMT) {
12722+ case S_IFIFO:
12723+#if 0
12724+ case S_IFCHR:
12725+ case S_IFBLK:
12726+ case S_IFSOCK:
12727+#endif
12728+ ret = 1;
12729+ }
12730+
12731+ return ret;
12732+}
7f207e10
AM
12733diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
12734--- /usr/share/empty/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100
392086de 12735+++ linux/fs/aufs/fstype.h 2013-10-26 16:51:32.273040419 +0200
c2b27bf2 12736@@ -0,0 +1,470 @@
4a4d8108 12737+/*
7a9e40b8 12738+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
12739+ *
12740+ * This program, aufs is free software; you can redistribute it and/or modify
12741+ * it under the terms of the GNU General Public License as published by
12742+ * the Free Software Foundation; either version 2 of the License, or
12743+ * (at your option) any later version.
12744+ *
12745+ * This program is distributed in the hope that it will be useful,
12746+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12747+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12748+ * GNU General Public License for more details.
12749+ *
12750+ * You should have received a copy of the GNU General Public License
12751+ * along with this program; if not, write to the Free Software
12752+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12753+ */
12754+
12755+/*
12756+ * judging filesystem type
12757+ */
12758+
12759+#ifndef __AUFS_FSTYPE_H__
12760+#define __AUFS_FSTYPE_H__
12761+
12762+#ifdef __KERNEL__
12763+
12764+#include <linux/fs.h>
12765+#include <linux/magic.h>
12766+#include <linux/romfs_fs.h>
4a4d8108
AM
12767+
12768+static inline int au_test_aufs(struct super_block *sb)
12769+{
12770+ return sb->s_magic == AUFS_SUPER_MAGIC;
12771+}
12772+
12773+static inline const char *au_sbtype(struct super_block *sb)
12774+{
12775+ return sb->s_type->name;
12776+}
1308ab2a 12777+
12778+static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
12779+{
12780+#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE)
12781+ return sb->s_magic == ROMFS_MAGIC;
dece6358
AM
12782+#else
12783+ return 0;
12784+#endif
12785+}
12786+
1308ab2a 12787+static inline int au_test_romfs(struct super_block *sb __maybe_unused)
dece6358 12788+{
1308ab2a 12789+#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE)
12790+ return sb->s_magic == ISOFS_SUPER_MAGIC;
dece6358
AM
12791+#else
12792+ return 0;
12793+#endif
12794+}
12795+
1308ab2a 12796+static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
dece6358 12797+{
1308ab2a 12798+#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE)
12799+ return sb->s_magic == CRAMFS_MAGIC;
12800+#endif
12801+ return 0;
12802+}
12803+
12804+static inline int au_test_nfs(struct super_block *sb __maybe_unused)
12805+{
12806+#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE)
12807+ return sb->s_magic == NFS_SUPER_MAGIC;
dece6358
AM
12808+#else
12809+ return 0;
12810+#endif
12811+}
12812+
1308ab2a 12813+static inline int au_test_fuse(struct super_block *sb __maybe_unused)
dece6358 12814+{
1308ab2a 12815+#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE)
12816+ return sb->s_magic == FUSE_SUPER_MAGIC;
dece6358
AM
12817+#else
12818+ return 0;
12819+#endif
12820+}
12821+
1308ab2a 12822+static inline int au_test_xfs(struct super_block *sb __maybe_unused)
dece6358 12823+{
1308ab2a 12824+#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE)
12825+ return sb->s_magic == XFS_SB_MAGIC;
dece6358
AM
12826+#else
12827+ return 0;
12828+#endif
12829+}
12830+
1308ab2a 12831+static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
dece6358 12832+{
1308ab2a 12833+#ifdef CONFIG_TMPFS
12834+ return sb->s_magic == TMPFS_MAGIC;
12835+#else
12836+ return 0;
dece6358 12837+#endif
dece6358
AM
12838+}
12839+
1308ab2a 12840+static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
1facf9fc 12841+{
1308ab2a 12842+#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE)
12843+ return !strcmp(au_sbtype(sb), "ecryptfs");
12844+#else
12845+ return 0;
12846+#endif
1facf9fc 12847+}
12848+
1308ab2a 12849+static inline int au_test_ocfs2(struct super_block *sb __maybe_unused)
1facf9fc 12850+{
1308ab2a 12851+#if defined(CONFIG_OCFS2_FS) || defined(CONFIG_OCFS2_FS_MODULE)
12852+ return sb->s_magic == OCFS2_SUPER_MAGIC;
12853+#else
12854+ return 0;
12855+#endif
1facf9fc 12856+}
12857+
1308ab2a 12858+static inline int au_test_ocfs2_dlmfs(struct super_block *sb __maybe_unused)
1facf9fc 12859+{
1308ab2a 12860+#if defined(CONFIG_OCFS2_FS_O2CB) || defined(CONFIG_OCFS2_FS_O2CB_MODULE)
12861+ return sb->s_magic == DLMFS_MAGIC;
12862+#else
12863+ return 0;
12864+#endif
1facf9fc 12865+}
12866+
1308ab2a 12867+static inline int au_test_coda(struct super_block *sb __maybe_unused)
1facf9fc 12868+{
1308ab2a 12869+#if defined(CONFIG_CODA_FS) || defined(CONFIG_CODA_FS_MODULE)
12870+ return sb->s_magic == CODA_SUPER_MAGIC;
12871+#else
12872+ return 0;
12873+#endif
12874+}
12875+
12876+static inline int au_test_v9fs(struct super_block *sb __maybe_unused)
12877+{
12878+#if defined(CONFIG_9P_FS) || defined(CONFIG_9P_FS_MODULE)
12879+ return sb->s_magic == V9FS_MAGIC;
12880+#else
12881+ return 0;
12882+#endif
12883+}
12884+
12885+static inline int au_test_ext4(struct super_block *sb __maybe_unused)
12886+{
c2b27bf2 12887+#if defined(CONFIG_EXT4_FS) || defined(CONFIG_EXT4_FS_MODULE)
1308ab2a 12888+ return sb->s_magic == EXT4_SUPER_MAGIC;
12889+#else
12890+ return 0;
12891+#endif
12892+}
12893+
12894+static inline int au_test_sysv(struct super_block *sb __maybe_unused)
12895+{
12896+#if defined(CONFIG_SYSV_FS) || defined(CONFIG_SYSV_FS_MODULE)
12897+ return !strcmp(au_sbtype(sb), "sysv");
12898+#else
12899+ return 0;
12900+#endif
12901+}
12902+
12903+static inline int au_test_ramfs(struct super_block *sb)
12904+{
12905+ return sb->s_magic == RAMFS_MAGIC;
12906+}
12907+
12908+static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
12909+{
12910+#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE)
12911+ return sb->s_magic == UBIFS_SUPER_MAGIC;
12912+#else
12913+ return 0;
12914+#endif
12915+}
12916+
12917+static inline int au_test_procfs(struct super_block *sb __maybe_unused)
12918+{
12919+#ifdef CONFIG_PROC_FS
12920+ return sb->s_magic == PROC_SUPER_MAGIC;
12921+#else
12922+ return 0;
12923+#endif
12924+}
12925+
12926+static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
12927+{
12928+#ifdef CONFIG_SYSFS
12929+ return sb->s_magic == SYSFS_MAGIC;
12930+#else
12931+ return 0;
12932+#endif
12933+}
12934+
12935+static inline int au_test_configfs(struct super_block *sb __maybe_unused)
12936+{
12937+#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE)
12938+ return sb->s_magic == CONFIGFS_MAGIC;
12939+#else
12940+ return 0;
12941+#endif
12942+}
12943+
12944+static inline int au_test_minix(struct super_block *sb __maybe_unused)
12945+{
12946+#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE)
12947+ return sb->s_magic == MINIX3_SUPER_MAGIC
12948+ || sb->s_magic == MINIX2_SUPER_MAGIC
12949+ || sb->s_magic == MINIX2_SUPER_MAGIC2
12950+ || sb->s_magic == MINIX_SUPER_MAGIC
12951+ || sb->s_magic == MINIX_SUPER_MAGIC2;
12952+#else
12953+ return 0;
12954+#endif
12955+}
12956+
12957+static inline int au_test_cifs(struct super_block *sb __maybe_unused)
12958+{
12959+#if defined(CONFIG_CIFS_FS) || defined(CONFIGCIFS_FS_MODULE)
12960+ return sb->s_magic == CIFS_MAGIC_NUMBER;
12961+#else
12962+ return 0;
12963+#endif
12964+}
12965+
12966+static inline int au_test_fat(struct super_block *sb __maybe_unused)
12967+{
12968+#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE)
12969+ return sb->s_magic == MSDOS_SUPER_MAGIC;
12970+#else
12971+ return 0;
12972+#endif
12973+}
12974+
12975+static inline int au_test_msdos(struct super_block *sb)
12976+{
12977+ return au_test_fat(sb);
12978+}
12979+
12980+static inline int au_test_vfat(struct super_block *sb)
12981+{
12982+ return au_test_fat(sb);
12983+}
12984+
12985+static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
12986+{
12987+#ifdef CONFIG_SECURITYFS
12988+ return sb->s_magic == SECURITYFS_MAGIC;
12989+#else
12990+ return 0;
12991+#endif
12992+}
12993+
12994+static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
12995+{
12996+#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE)
12997+ return sb->s_magic == SQUASHFS_MAGIC;
12998+#else
12999+ return 0;
13000+#endif
13001+}
13002+
13003+static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
13004+{
13005+#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE)
13006+ return sb->s_magic == BTRFS_SUPER_MAGIC;
13007+#else
13008+ return 0;
13009+#endif
13010+}
13011+
13012+static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
13013+{
13014+#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE)
13015+ return sb->s_magic == XENFS_SUPER_MAGIC;
13016+#else
13017+ return 0;
13018+#endif
13019+}
13020+
13021+static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
13022+{
13023+#ifdef CONFIG_DEBUG_FS
13024+ return sb->s_magic == DEBUGFS_MAGIC;
13025+#else
13026+ return 0;
13027+#endif
13028+}
13029+
13030+static inline int au_test_nilfs(struct super_block *sb __maybe_unused)
13031+{
13032+#if defined(CONFIG_NILFS) || defined(CONFIG_NILFS_MODULE)
13033+ return sb->s_magic == NILFS_SUPER_MAGIC;
13034+#else
13035+ return 0;
13036+#endif
13037+}
13038+
4a4d8108
AM
13039+static inline int au_test_hfsplus(struct super_block *sb __maybe_unused)
13040+{
13041+#if defined(CONFIG_HFSPLUS_FS) || defined(CONFIG_HFSPLUS_FS_MODULE)
13042+ return sb->s_magic == HFSPLUS_SUPER_MAGIC;
13043+#else
13044+ return 0;
13045+#endif
13046+}
13047+
1308ab2a 13048+/* ---------------------------------------------------------------------- */
13049+/*
13050+ * they can't be an aufs branch.
13051+ */
13052+static inline int au_test_fs_unsuppoted(struct super_block *sb)
13053+{
13054+ return
13055+#ifndef CONFIG_AUFS_BR_RAMFS
13056+ au_test_ramfs(sb) ||
13057+#endif
13058+ au_test_procfs(sb)
13059+ || au_test_sysfs(sb)
13060+ || au_test_configfs(sb)
13061+ || au_test_debugfs(sb)
13062+ || au_test_securityfs(sb)
13063+ || au_test_xenfs(sb)
13064+ || au_test_ecryptfs(sb)
13065+ /* || !strcmp(au_sbtype(sb), "unionfs") */
13066+ || au_test_aufs(sb); /* will be supported in next version */
13067+}
13068+
1308ab2a 13069+static inline int au_test_fs_remote(struct super_block *sb)
13070+{
13071+ return !au_test_tmpfs(sb)
13072+#ifdef CONFIG_AUFS_BR_RAMFS
13073+ && !au_test_ramfs(sb)
13074+#endif
13075+ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
13076+}
13077+
13078+/* ---------------------------------------------------------------------- */
13079+
13080+/*
13081+ * Note: these functions (below) are created after reading ->getattr() in all
13082+ * filesystems under linux/fs. it means we have to do so in every update...
13083+ */
13084+
13085+/*
13086+ * some filesystems require getattr to refresh the inode attributes before
13087+ * referencing.
13088+ * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
13089+ * and leave the work for d_revalidate()
13090+ */
13091+static inline int au_test_fs_refresh_iattr(struct super_block *sb)
13092+{
13093+ return au_test_nfs(sb)
13094+ || au_test_fuse(sb)
1308ab2a 13095+ /* || au_test_ocfs2(sb) */ /* untested */
13096+ /* || au_test_btrfs(sb) */ /* untested */
13097+ /* || au_test_coda(sb) */ /* untested */
13098+ /* || au_test_v9fs(sb) */ /* untested */
13099+ ;
13100+}
13101+
13102+/*
13103+ * filesystems which don't maintain i_size or i_blocks.
13104+ */
13105+static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
13106+{
13107+ return au_test_xfs(sb)
4a4d8108
AM
13108+ || au_test_btrfs(sb)
13109+ || au_test_ubifs(sb)
13110+ || au_test_hfsplus(sb) /* maintained, but incorrect */
1308ab2a 13111+ /* || au_test_ext4(sb) */ /* untested */
13112+ /* || au_test_ocfs2(sb) */ /* untested */
13113+ /* || au_test_ocfs2_dlmfs(sb) */ /* untested */
13114+ /* || au_test_sysv(sb) */ /* untested */
1308ab2a 13115+ /* || au_test_minix(sb) */ /* untested */
13116+ ;
13117+}
13118+
13119+/*
13120+ * filesystems which don't store the correct value in some of their inode
13121+ * attributes.
13122+ */
13123+static inline int au_test_fs_bad_iattr(struct super_block *sb)
13124+{
13125+ return au_test_fs_bad_iattr_size(sb)
13126+ /* || au_test_cifs(sb) */ /* untested */
13127+ || au_test_fat(sb)
13128+ || au_test_msdos(sb)
13129+ || au_test_vfat(sb);
1facf9fc 13130+}
13131+
13132+/* they don't check i_nlink in link(2) */
13133+static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
13134+{
13135+ return au_test_tmpfs(sb)
13136+#ifdef CONFIG_AUFS_BR_RAMFS
13137+ || au_test_ramfs(sb)
13138+#endif
4a4d8108 13139+ || au_test_ubifs(sb)
4a4d8108 13140+ || au_test_hfsplus(sb);
1facf9fc 13141+}
13142+
13143+/*
13144+ * filesystems which sets S_NOATIME and S_NOCMTIME.
13145+ */
13146+static inline int au_test_fs_notime(struct super_block *sb)
13147+{
13148+ return au_test_nfs(sb)
13149+ || au_test_fuse(sb)
dece6358 13150+ || au_test_ubifs(sb)
1facf9fc 13151+ /* || au_test_cifs(sb) */ /* untested */
1facf9fc 13152+ ;
13153+}
13154+
13155+/*
13156+ * filesystems which requires replacing i_mapping.
13157+ */
13158+static inline int au_test_fs_bad_mapping(struct super_block *sb)
13159+{
dece6358
AM
13160+ return au_test_fuse(sb)
13161+ || au_test_ubifs(sb);
1facf9fc 13162+}
13163+
13164+/* temporary support for i#1 in cramfs */
13165+static inline int au_test_fs_unique_ino(struct inode *inode)
13166+{
13167+ if (au_test_cramfs(inode->i_sb))
13168+ return inode->i_ino != 1;
13169+ return 1;
13170+}
13171+
13172+/* ---------------------------------------------------------------------- */
13173+
13174+/*
13175+ * the filesystem where the xino files placed must support i/o after unlink and
13176+ * maintain i_size and i_blocks.
13177+ */
13178+static inline int au_test_fs_bad_xino(struct super_block *sb)
13179+{
13180+ return au_test_fs_remote(sb)
13181+ || au_test_fs_bad_iattr_size(sb)
1facf9fc 13182+ /* don't want unnecessary work for xino */
13183+ || au_test_aufs(sb)
1308ab2a 13184+ || au_test_ecryptfs(sb)
13185+ || au_test_nilfs(sb);
1facf9fc 13186+}
13187+
13188+static inline int au_test_fs_trunc_xino(struct super_block *sb)
13189+{
13190+ return au_test_tmpfs(sb)
13191+ || au_test_ramfs(sb);
13192+}
13193+
13194+/*
13195+ * test if the @sb is real-readonly.
13196+ */
13197+static inline int au_test_fs_rr(struct super_block *sb)
13198+{
13199+ return au_test_squashfs(sb)
13200+ || au_test_iso9660(sb)
13201+ || au_test_cramfs(sb)
13202+ || au_test_romfs(sb);
13203+}
13204+
13205+#endif /* __KERNEL__ */
13206+#endif /* __AUFS_FSTYPE_H__ */
7f207e10
AM
13207diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
13208--- /usr/share/empty/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100
392086de 13209+++ linux/fs/aufs/hfsnotify.c 2013-10-26 16:51:32.273040419 +0200
c06a8ce3 13210@@ -0,0 +1,296 @@
1facf9fc 13211+/*
7a9e40b8 13212+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 13213+ *
13214+ * This program, aufs is free software; you can redistribute it and/or modify
13215+ * it under the terms of the GNU General Public License as published by
13216+ * the Free Software Foundation; either version 2 of the License, or
13217+ * (at your option) any later version.
dece6358
AM
13218+ *
13219+ * This program is distributed in the hope that it will be useful,
13220+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13221+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13222+ * GNU General Public License for more details.
13223+ *
13224+ * You should have received a copy of the GNU General Public License
13225+ * along with this program; if not, write to the Free Software
13226+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 13227+ */
13228+
13229+/*
4a4d8108 13230+ * fsnotify for the lower directories
1facf9fc 13231+ */
13232+
13233+#include "aufs.h"
13234+
4a4d8108
AM
13235+/* FS_IN_IGNORED is unnecessary */
13236+static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE
13237+ | FS_CREATE | FS_EVENT_ON_CHILD);
7f207e10 13238+static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
7eafdf33 13239+static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0);
1facf9fc 13240+
0c5527e5 13241+static void au_hfsn_free_mark(struct fsnotify_mark *mark)
1facf9fc 13242+{
0c5527e5
AM
13243+ struct au_hnotify *hn = container_of(mark, struct au_hnotify,
13244+ hn_mark);
4a4d8108 13245+ AuDbg("here\n");
7eafdf33
AM
13246+ au_cache_free_hnotify(hn);
13247+ smp_mb__before_atomic_dec();
1716fcea
AM
13248+ if (atomic64_dec_and_test(&au_hfsn_ifree))
13249+ wake_up(&au_hfsn_wq);
4a4d8108 13250+}
1facf9fc 13251+
027c5e7a 13252+static int au_hfsn_alloc(struct au_hinode *hinode)
4a4d8108 13253+{
1716fcea 13254+ int err;
027c5e7a
AM
13255+ struct au_hnotify *hn;
13256+ struct super_block *sb;
13257+ struct au_branch *br;
0c5527e5 13258+ struct fsnotify_mark *mark;
027c5e7a 13259+ aufs_bindex_t bindex;
1facf9fc 13260+
027c5e7a
AM
13261+ hn = hinode->hi_notify;
13262+ sb = hn->hn_aufs_inode->i_sb;
13263+ bindex = au_br_index(sb, hinode->hi_id);
13264+ br = au_sbr(sb, bindex);
1716fcea
AM
13265+ AuDebugOn(!br->br_hfsn);
13266+
0c5527e5
AM
13267+ mark = &hn->hn_mark;
13268+ fsnotify_init_mark(mark, au_hfsn_free_mark);
13269+ mark->mask = AuHfsnMask;
7f207e10
AM
13270+ /*
13271+ * by udba rename or rmdir, aufs assign a new inode to the known
13272+ * h_inode, so specify 1 to allow dups.
13273+ */
1716fcea 13274+ err = fsnotify_add_mark(mark, br->br_hfsn->hfsn_group, hinode->hi_inode,
027c5e7a 13275+ /*mnt*/NULL, /*allow_dups*/1);
1716fcea
AM
13276+ /* even if err */
13277+ fsnotify_put_mark(mark);
13278+
13279+ return err;
1facf9fc 13280+}
13281+
7eafdf33 13282+static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn)
1facf9fc 13283+{
0c5527e5 13284+ struct fsnotify_mark *mark;
7eafdf33 13285+ unsigned long long ull;
1716fcea 13286+ struct fsnotify_group *group;
7eafdf33
AM
13287+
13288+ ull = atomic64_inc_return(&au_hfsn_ifree);
13289+ BUG_ON(!ull);
953406b4 13290+
0c5527e5 13291+ mark = &hn->hn_mark;
1716fcea
AM
13292+ spin_lock(&mark->lock);
13293+ group = mark->group;
13294+ fsnotify_get_group(group);
13295+ spin_unlock(&mark->lock);
13296+ fsnotify_destroy_mark(mark, group);
13297+ fsnotify_put_group(group);
7f207e10 13298+
7eafdf33
AM
13299+ /* free hn by myself */
13300+ return 0;
1facf9fc 13301+}
13302+
13303+/* ---------------------------------------------------------------------- */
13304+
4a4d8108 13305+static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
1facf9fc 13306+{
0c5527e5 13307+ struct fsnotify_mark *mark;
1facf9fc 13308+
0c5527e5
AM
13309+ mark = &hinode->hi_notify->hn_mark;
13310+ spin_lock(&mark->lock);
1facf9fc 13311+ if (do_set) {
0c5527e5
AM
13312+ AuDebugOn(mark->mask & AuHfsnMask);
13313+ mark->mask |= AuHfsnMask;
1facf9fc 13314+ } else {
0c5527e5
AM
13315+ AuDebugOn(!(mark->mask & AuHfsnMask));
13316+ mark->mask &= ~AuHfsnMask;
1facf9fc 13317+ }
0c5527e5 13318+ spin_unlock(&mark->lock);
4a4d8108 13319+ /* fsnotify_recalc_inode_mask(hinode->hi_inode); */
1facf9fc 13320+}
13321+
4a4d8108 13322+/* ---------------------------------------------------------------------- */
1facf9fc 13323+
4a4d8108
AM
13324+/* #define AuDbgHnotify */
13325+#ifdef AuDbgHnotify
13326+static char *au_hfsn_name(u32 mask)
13327+{
13328+#ifdef CONFIG_AUFS_DEBUG
c06a8ce3
AM
13329+#define test_ret(flag) \
13330+ do { \
13331+ if (mask & flag) \
13332+ return #flag; \
13333+ } while (0)
4a4d8108
AM
13334+ test_ret(FS_ACCESS);
13335+ test_ret(FS_MODIFY);
13336+ test_ret(FS_ATTRIB);
13337+ test_ret(FS_CLOSE_WRITE);
13338+ test_ret(FS_CLOSE_NOWRITE);
13339+ test_ret(FS_OPEN);
13340+ test_ret(FS_MOVED_FROM);
13341+ test_ret(FS_MOVED_TO);
13342+ test_ret(FS_CREATE);
13343+ test_ret(FS_DELETE);
13344+ test_ret(FS_DELETE_SELF);
13345+ test_ret(FS_MOVE_SELF);
13346+ test_ret(FS_UNMOUNT);
13347+ test_ret(FS_Q_OVERFLOW);
13348+ test_ret(FS_IN_IGNORED);
13349+ test_ret(FS_IN_ISDIR);
13350+ test_ret(FS_IN_ONESHOT);
13351+ test_ret(FS_EVENT_ON_CHILD);
13352+ return "";
13353+#undef test_ret
13354+#else
13355+ return "??";
13356+#endif
1facf9fc 13357+}
4a4d8108 13358+#endif
1facf9fc 13359+
13360+/* ---------------------------------------------------------------------- */
13361+
1716fcea
AM
13362+static void au_hfsn_free_group(struct fsnotify_group *group)
13363+{
13364+ struct au_br_hfsnotify *hfsn = group->private;
13365+
13366+ AuDbg("here\n");
13367+ kfree(hfsn);
13368+}
13369+
4a4d8108 13370+static int au_hfsn_handle_event(struct fsnotify_group *group,
0c5527e5
AM
13371+ struct fsnotify_mark *inode_mark,
13372+ struct fsnotify_mark *vfsmount_mark,
4a4d8108 13373+ struct fsnotify_event *event)
1facf9fc 13374+{
13375+ int err;
4a4d8108
AM
13376+ struct au_hnotify *hnotify;
13377+ struct inode *h_dir, *h_inode;
13378+ __u32 mask;
0c3ec466 13379+ struct qstr h_child_qstr = QSTR_INIT(event->file_name, event->name_len);
4a4d8108
AM
13380+
13381+ AuDebugOn(event->data_type != FSNOTIFY_EVENT_INODE);
1facf9fc 13382+
13383+ err = 0;
0c5527e5 13384+ /* if FS_UNMOUNT happens, there must be another bug */
4a4d8108
AM
13385+ mask = event->mask;
13386+ AuDebugOn(mask & FS_UNMOUNT);
0c5527e5 13387+ if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
1facf9fc 13388+ goto out;
1facf9fc 13389+
4a4d8108
AM
13390+ h_dir = event->to_tell;
13391+ h_inode = event->inode;
13392+#ifdef AuDbgHnotify
392086de 13393+ au_debug_on();
4a4d8108
AM
13394+ if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
13395+ || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
13396+ AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
13397+ h_dir->i_ino, mask, au_hfsn_name(mask),
13398+ AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
13399+ /* WARN_ON(1); */
1facf9fc 13400+ }
392086de 13401+ au_debug_off();
1facf9fc 13402+#endif
4a4d8108 13403+
0c5527e5
AM
13404+ AuDebugOn(!inode_mark);
13405+ hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
13406+ err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode);
1facf9fc 13407+
4a4d8108
AM
13408+out:
13409+ return err;
13410+}
1facf9fc 13411+
027c5e7a 13412+/* isn't it waste to ask every registered 'group'? */
7f207e10 13413+/* copied from linux/fs/notify/inotify/inotify_fsnotiry.c */
4a4d8108 13414+/* it should be exported to modules */
7f207e10
AM
13415+static bool au_hfsn_should_send_event(struct fsnotify_group *group,
13416+ struct inode *h_inode,
0c5527e5
AM
13417+ struct fsnotify_mark *inode_mark,
13418+ struct fsnotify_mark *vfsmount_mark,
13419+ __u32 mask, void *data, int data_type)
4a4d8108 13420+{
4a4d8108 13421+ mask = (mask & ~FS_EVENT_ON_CHILD);
7f207e10 13422+ return inode_mark->mask & mask;
4a4d8108
AM
13423+}
13424+
13425+static struct fsnotify_ops au_hfsn_ops = {
13426+ .should_send_event = au_hfsn_should_send_event,
1716fcea
AM
13427+ .handle_event = au_hfsn_handle_event,
13428+ .free_group_priv = au_hfsn_free_group
4a4d8108
AM
13429+};
13430+
13431+/* ---------------------------------------------------------------------- */
13432+
027c5e7a
AM
13433+static void au_hfsn_fin_br(struct au_branch *br)
13434+{
1716fcea 13435+ struct au_br_hfsnotify *hfsn;
027c5e7a 13436+
1716fcea
AM
13437+ hfsn = br->br_hfsn;
13438+ if (hfsn)
13439+ fsnotify_put_group(hfsn->hfsn_group);
027c5e7a
AM
13440+}
13441+
1716fcea 13442+static int au_hfsn_init_br(struct au_branch *br, int perm)
4a4d8108
AM
13443+{
13444+ int err;
1716fcea
AM
13445+ struct fsnotify_group *group;
13446+ struct au_br_hfsnotify *hfsn;
1facf9fc 13447+
4a4d8108 13448+ err = 0;
1716fcea
AM
13449+ br->br_hfsn = NULL;
13450+ if (!au_br_hnotifyable(perm))
027c5e7a 13451+ goto out;
027c5e7a 13452+
1716fcea
AM
13453+ err = -ENOMEM;
13454+ hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS);
13455+ if (unlikely(!hfsn))
027c5e7a
AM
13456+ goto out;
13457+
1716fcea
AM
13458+ err = 0;
13459+ group = fsnotify_alloc_group(&au_hfsn_ops);
13460+ if (IS_ERR(group)) {
13461+ err = PTR_ERR(group);
0c5527e5 13462+ pr_err("fsnotify_alloc_group() failed, %d\n", err);
1716fcea 13463+ goto out_hfsn;
4a4d8108 13464+ }
1facf9fc 13465+
1716fcea
AM
13466+ group->private = hfsn;
13467+ hfsn->hfsn_group = group;
13468+ br->br_hfsn = hfsn;
13469+ goto out; /* success */
13470+
13471+out_hfsn:
13472+ kfree(hfsn);
027c5e7a 13473+out:
1716fcea
AM
13474+ return err;
13475+}
13476+
13477+static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm)
13478+{
13479+ int err;
13480+
13481+ err = 0;
13482+ if (!br->br_hfsn)
13483+ err = au_hfsn_init_br(br, perm);
13484+
1facf9fc 13485+ return err;
13486+}
13487+
7eafdf33
AM
13488+/* ---------------------------------------------------------------------- */
13489+
13490+static void au_hfsn_fin(void)
13491+{
13492+ AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree));
13493+ wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree));
13494+}
13495+
4a4d8108
AM
13496+const struct au_hnotify_op au_hnotify_op = {
13497+ .ctl = au_hfsn_ctl,
13498+ .alloc = au_hfsn_alloc,
13499+ .free = au_hfsn_free,
1facf9fc 13500+
7eafdf33
AM
13501+ .fin = au_hfsn_fin,
13502+
027c5e7a
AM
13503+ .reset_br = au_hfsn_reset_br,
13504+ .fin_br = au_hfsn_fin_br,
13505+ .init_br = au_hfsn_init_br
4a4d8108 13506+};
7f207e10
AM
13507diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c
13508--- /usr/share/empty/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
13509+++ linux/fs/aufs/hfsplus.c 2013-10-26 16:51:32.273040419 +0200
13510@@ -0,0 +1,57 @@
4a4d8108 13511+/*
7a9e40b8 13512+ * Copyright (C) 2010-2013 Junjiro R. Okajima
4a4d8108
AM
13513+ *
13514+ * This program, aufs is free software; you can redistribute it and/or modify
13515+ * it under the terms of the GNU General Public License as published by
13516+ * the Free Software Foundation; either version 2 of the License, or
13517+ * (at your option) any later version.
13518+ *
13519+ * This program is distributed in the hope that it will be useful,
13520+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13521+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13522+ * GNU General Public License for more details.
13523+ *
13524+ * You should have received a copy of the GNU General Public License
13525+ * along with this program; if not, write to the Free Software
13526+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13527+ */
1facf9fc 13528+
4a4d8108
AM
13529+/*
13530+ * special support for filesystems which aqucires an inode mutex
13531+ * at final closing a file, eg, hfsplus.
13532+ *
13533+ * This trick is very simple and stupid, just to open the file before really
13534+ * neceeary open to tell hfsplus that this is not the final closing.
13535+ * The caller should call au_h_open_pre() after acquiring the inode mutex,
13536+ * and au_h_open_post() after releasing it.
13537+ */
1facf9fc 13538+
4a4d8108 13539+#include "aufs.h"
1facf9fc 13540+
392086de
AM
13541+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
13542+ int force_wr)
4a4d8108
AM
13543+{
13544+ struct file *h_file;
13545+ struct dentry *h_dentry;
1facf9fc 13546+
4a4d8108
AM
13547+ h_dentry = au_h_dptr(dentry, bindex);
13548+ AuDebugOn(!h_dentry);
13549+ AuDebugOn(!h_dentry->d_inode);
4a4d8108
AM
13550+
13551+ h_file = NULL;
13552+ if (au_test_hfsplus(h_dentry->d_sb)
13553+ && S_ISREG(h_dentry->d_inode->i_mode))
13554+ h_file = au_h_open(dentry, bindex,
13555+ O_RDONLY | O_NOATIME | O_LARGEFILE,
392086de 13556+ /*file*/NULL, force_wr);
4a4d8108 13557+ return h_file;
1facf9fc 13558+}
13559+
4a4d8108
AM
13560+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
13561+ struct file *h_file)
13562+{
13563+ if (h_file) {
13564+ fput(h_file);
13565+ au_sbr_put(dentry->d_sb, bindex);
13566+ }
13567+}
7f207e10
AM
13568diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
13569--- /usr/share/empty/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100
392086de 13570+++ linux/fs/aufs/hnotify.c 2013-10-26 16:51:29.582964925 +0200
c06a8ce3 13571@@ -0,0 +1,712 @@
e49829fe 13572+/*
7a9e40b8 13573+ * Copyright (C) 2005-2013 Junjiro R. Okajima
e49829fe
JR
13574+ *
13575+ * This program, aufs is free software; you can redistribute it and/or modify
13576+ * it under the terms of the GNU General Public License as published by
13577+ * the Free Software Foundation; either version 2 of the License, or
13578+ * (at your option) any later version.
13579+ *
13580+ * This program is distributed in the hope that it will be useful,
13581+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13582+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13583+ * GNU General Public License for more details.
13584+ *
13585+ * You should have received a copy of the GNU General Public License
13586+ * along with this program; if not, write to the Free Software
13587+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13588+ */
13589+
13590+/*
7f207e10 13591+ * abstraction to notify the direct changes on lower directories
e49829fe
JR
13592+ */
13593+
13594+#include "aufs.h"
13595+
027c5e7a 13596+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
e49829fe
JR
13597+{
13598+ int err;
7f207e10 13599+ struct au_hnotify *hn;
1facf9fc 13600+
4a4d8108
AM
13601+ err = -ENOMEM;
13602+ hn = au_cache_alloc_hnotify();
13603+ if (hn) {
13604+ hn->hn_aufs_inode = inode;
027c5e7a
AM
13605+ hinode->hi_notify = hn;
13606+ err = au_hnotify_op.alloc(hinode);
13607+ AuTraceErr(err);
13608+ if (unlikely(err)) {
13609+ hinode->hi_notify = NULL;
4a4d8108
AM
13610+ au_cache_free_hnotify(hn);
13611+ /*
13612+ * The upper dir was removed by udba, but the same named
13613+ * dir left. In this case, aufs assignes a new inode
13614+ * number and set the monitor again.
13615+ * For the lower dir, the old monitnor is still left.
13616+ */
13617+ if (err == -EEXIST)
13618+ err = 0;
13619+ }
1308ab2a 13620+ }
1308ab2a 13621+
027c5e7a 13622+ AuTraceErr(err);
1308ab2a 13623+ return err;
dece6358 13624+}
1facf9fc 13625+
4a4d8108 13626+void au_hn_free(struct au_hinode *hinode)
dece6358 13627+{
4a4d8108 13628+ struct au_hnotify *hn;
1facf9fc 13629+
4a4d8108
AM
13630+ hn = hinode->hi_notify;
13631+ if (hn) {
4a4d8108 13632+ hinode->hi_notify = NULL;
7eafdf33
AM
13633+ if (au_hnotify_op.free(hinode, hn))
13634+ au_cache_free_hnotify(hn);
4a4d8108
AM
13635+ }
13636+}
dece6358 13637+
4a4d8108 13638+/* ---------------------------------------------------------------------- */
dece6358 13639+
4a4d8108
AM
13640+void au_hn_ctl(struct au_hinode *hinode, int do_set)
13641+{
13642+ if (hinode->hi_notify)
13643+ au_hnotify_op.ctl(hinode, do_set);
13644+}
13645+
13646+void au_hn_reset(struct inode *inode, unsigned int flags)
13647+{
13648+ aufs_bindex_t bindex, bend;
13649+ struct inode *hi;
13650+ struct dentry *iwhdentry;
1facf9fc 13651+
1308ab2a 13652+ bend = au_ibend(inode);
4a4d8108
AM
13653+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
13654+ hi = au_h_iptr(inode, bindex);
13655+ if (!hi)
13656+ continue;
1308ab2a 13657+
4a4d8108
AM
13658+ /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */
13659+ iwhdentry = au_hi_wh(inode, bindex);
13660+ if (iwhdentry)
13661+ dget(iwhdentry);
13662+ au_igrab(hi);
13663+ au_set_h_iptr(inode, bindex, NULL, 0);
13664+ au_set_h_iptr(inode, bindex, au_igrab(hi),
13665+ flags & ~AuHi_XINO);
13666+ iput(hi);
13667+ dput(iwhdentry);
13668+ /* mutex_unlock(&hi->i_mutex); */
1facf9fc 13669+ }
1facf9fc 13670+}
13671+
1308ab2a 13672+/* ---------------------------------------------------------------------- */
1facf9fc 13673+
4a4d8108 13674+static int hn_xino(struct inode *inode, struct inode *h_inode)
1facf9fc 13675+{
4a4d8108
AM
13676+ int err;
13677+ aufs_bindex_t bindex, bend, bfound, bstart;
13678+ struct inode *h_i;
1facf9fc 13679+
4a4d8108
AM
13680+ err = 0;
13681+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 13682+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
13683+ goto out;
13684+ }
1facf9fc 13685+
4a4d8108
AM
13686+ bfound = -1;
13687+ bend = au_ibend(inode);
13688+ bstart = au_ibstart(inode);
13689+#if 0 /* reserved for future use */
13690+ if (bindex == bend) {
13691+ /* keep this ino in rename case */
13692+ goto out;
13693+ }
13694+#endif
13695+ for (bindex = bstart; bindex <= bend; bindex++)
13696+ if (au_h_iptr(inode, bindex) == h_inode) {
13697+ bfound = bindex;
13698+ break;
13699+ }
13700+ if (bfound < 0)
1308ab2a 13701+ goto out;
1facf9fc 13702+
4a4d8108
AM
13703+ for (bindex = bstart; bindex <= bend; bindex++) {
13704+ h_i = au_h_iptr(inode, bindex);
13705+ if (!h_i)
13706+ continue;
1facf9fc 13707+
4a4d8108
AM
13708+ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
13709+ /* ignore this error */
13710+ /* bad action? */
1facf9fc 13711+ }
1facf9fc 13712+
4a4d8108 13713+ /* children inode number will be broken */
1facf9fc 13714+
4f0767ce 13715+out:
4a4d8108
AM
13716+ AuTraceErr(err);
13717+ return err;
1facf9fc 13718+}
13719+
4a4d8108 13720+static int hn_gen_tree(struct dentry *dentry)
1facf9fc 13721+{
4a4d8108
AM
13722+ int err, i, j, ndentry;
13723+ struct au_dcsub_pages dpages;
13724+ struct au_dpage *dpage;
13725+ struct dentry **dentries;
1facf9fc 13726+
4a4d8108
AM
13727+ err = au_dpages_init(&dpages, GFP_NOFS);
13728+ if (unlikely(err))
13729+ goto out;
13730+ err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
13731+ if (unlikely(err))
13732+ goto out_dpages;
1facf9fc 13733+
4a4d8108
AM
13734+ for (i = 0; i < dpages.ndpage; i++) {
13735+ dpage = dpages.dpages + i;
13736+ dentries = dpage->dentries;
13737+ ndentry = dpage->ndentry;
13738+ for (j = 0; j < ndentry; j++) {
13739+ struct dentry *d;
13740+
13741+ d = dentries[j];
13742+ if (IS_ROOT(d))
13743+ continue;
13744+
4a4d8108
AM
13745+ au_digen_dec(d);
13746+ if (d->d_inode)
13747+ /* todo: reset children xino?
13748+ cached children only? */
13749+ au_iigen_dec(d->d_inode);
1308ab2a 13750+ }
dece6358 13751+ }
1facf9fc 13752+
4f0767ce 13753+out_dpages:
4a4d8108 13754+ au_dpages_free(&dpages);
dece6358 13755+
027c5e7a 13756+#if 0
4a4d8108
AM
13757+ /* discard children */
13758+ dentry_unhash(dentry);
13759+ dput(dentry);
027c5e7a 13760+#endif
4f0767ce 13761+out:
dece6358
AM
13762+ return err;
13763+}
13764+
1308ab2a 13765+/*
4a4d8108 13766+ * return 0 if processed.
1308ab2a 13767+ */
4a4d8108
AM
13768+static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
13769+ const unsigned int isdir)
dece6358 13770+{
1308ab2a 13771+ int err;
4a4d8108
AM
13772+ struct dentry *d;
13773+ struct qstr *dname;
1facf9fc 13774+
4a4d8108
AM
13775+ err = 1;
13776+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 13777+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
13778+ err = 0;
13779+ goto out;
13780+ }
dece6358 13781+
4a4d8108
AM
13782+ if (!isdir) {
13783+ AuDebugOn(!name);
13784+ au_iigen_dec(inode);
027c5e7a 13785+ spin_lock(&inode->i_lock);
c06a8ce3 13786+ hlist_for_each_entry(d, &inode->i_dentry, d_alias) {
027c5e7a 13787+ spin_lock(&d->d_lock);
4a4d8108
AM
13788+ dname = &d->d_name;
13789+ if (dname->len != nlen
027c5e7a
AM
13790+ && memcmp(dname->name, name, nlen)) {
13791+ spin_unlock(&d->d_lock);
4a4d8108 13792+ continue;
027c5e7a 13793+ }
4a4d8108 13794+ err = 0;
4a4d8108
AM
13795+ au_digen_dec(d);
13796+ spin_unlock(&d->d_lock);
13797+ break;
1facf9fc 13798+ }
027c5e7a 13799+ spin_unlock(&inode->i_lock);
1308ab2a 13800+ } else {
027c5e7a 13801+ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
4a4d8108
AM
13802+ d = d_find_alias(inode);
13803+ if (!d) {
13804+ au_iigen_dec(inode);
13805+ goto out;
13806+ }
1facf9fc 13807+
027c5e7a 13808+ spin_lock(&d->d_lock);
4a4d8108 13809+ dname = &d->d_name;
027c5e7a
AM
13810+ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
13811+ spin_unlock(&d->d_lock);
4a4d8108 13812+ err = hn_gen_tree(d);
027c5e7a
AM
13813+ spin_lock(&d->d_lock);
13814+ }
13815+ spin_unlock(&d->d_lock);
4a4d8108
AM
13816+ dput(d);
13817+ }
1facf9fc 13818+
4f0767ce 13819+out:
4a4d8108 13820+ AuTraceErr(err);
1308ab2a 13821+ return err;
13822+}
dece6358 13823+
4a4d8108 13824+static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
1facf9fc 13825+{
4a4d8108
AM
13826+ int err;
13827+ struct inode *inode;
1facf9fc 13828+
4a4d8108
AM
13829+ inode = dentry->d_inode;
13830+ if (IS_ROOT(dentry)
13831+ /* || (inode && inode->i_ino == AUFS_ROOT_INO) */
13832+ ) {
0c3ec466 13833+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
13834+ return 0;
13835+ }
1308ab2a 13836+
4a4d8108
AM
13837+ err = 0;
13838+ if (!isdir) {
4a4d8108
AM
13839+ au_digen_dec(dentry);
13840+ if (inode)
13841+ au_iigen_dec(inode);
13842+ } else {
027c5e7a 13843+ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
4a4d8108
AM
13844+ if (inode)
13845+ err = hn_gen_tree(dentry);
13846+ }
13847+
13848+ AuTraceErr(err);
13849+ return err;
1facf9fc 13850+}
13851+
4a4d8108 13852+/* ---------------------------------------------------------------------- */
1facf9fc 13853+
4a4d8108
AM
13854+/* hnotify job flags */
13855+#define AuHnJob_XINO0 1
13856+#define AuHnJob_GEN (1 << 1)
13857+#define AuHnJob_DIRENT (1 << 2)
13858+#define AuHnJob_ISDIR (1 << 3)
13859+#define AuHnJob_TRYXINO0 (1 << 4)
13860+#define AuHnJob_MNTPNT (1 << 5)
13861+#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name)
7f207e10
AM
13862+#define au_fset_hnjob(flags, name) \
13863+ do { (flags) |= AuHnJob_##name; } while (0)
13864+#define au_fclr_hnjob(flags, name) \
13865+ do { (flags) &= ~AuHnJob_##name; } while (0)
1facf9fc 13866+
4a4d8108
AM
13867+enum {
13868+ AuHn_CHILD,
13869+ AuHn_PARENT,
13870+ AuHnLast
13871+};
1facf9fc 13872+
4a4d8108
AM
13873+struct au_hnotify_args {
13874+ struct inode *h_dir, *dir, *h_child_inode;
13875+ u32 mask;
13876+ unsigned int flags[AuHnLast];
13877+ unsigned int h_child_nlen;
13878+ char h_child_name[];
13879+};
1facf9fc 13880+
4a4d8108
AM
13881+struct hn_job_args {
13882+ unsigned int flags;
13883+ struct inode *inode, *h_inode, *dir, *h_dir;
13884+ struct dentry *dentry;
13885+ char *h_name;
13886+ int h_nlen;
13887+};
1308ab2a 13888+
4a4d8108
AM
13889+static int hn_job(struct hn_job_args *a)
13890+{
13891+ const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
1308ab2a 13892+
4a4d8108
AM
13893+ /* reset xino */
13894+ if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
13895+ hn_xino(a->inode, a->h_inode); /* ignore this error */
1308ab2a 13896+
4a4d8108
AM
13897+ if (au_ftest_hnjob(a->flags, TRYXINO0)
13898+ && a->inode
13899+ && a->h_inode) {
13900+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
13901+ if (!a->h_inode->i_nlink)
13902+ hn_xino(a->inode, a->h_inode); /* ignore this error */
13903+ mutex_unlock(&a->h_inode->i_mutex);
1308ab2a 13904+ }
1facf9fc 13905+
4a4d8108
AM
13906+ /* make the generation obsolete */
13907+ if (au_ftest_hnjob(a->flags, GEN)) {
13908+ int err = -1;
13909+ if (a->inode)
13910+ err = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
13911+ isdir);
13912+ if (err && a->dentry)
13913+ hn_gen_by_name(a->dentry, isdir);
13914+ /* ignore this error */
1facf9fc 13915+ }
1facf9fc 13916+
4a4d8108
AM
13917+ /* make dir entries obsolete */
13918+ if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
13919+ struct au_vdir *vdir;
1facf9fc 13920+
4a4d8108
AM
13921+ vdir = au_ivdir(a->inode);
13922+ if (vdir)
13923+ vdir->vd_jiffy = 0;
13924+ /* IMustLock(a->inode); */
13925+ /* a->inode->i_version++; */
13926+ }
1facf9fc 13927+
4a4d8108
AM
13928+ /* can do nothing but warn */
13929+ if (au_ftest_hnjob(a->flags, MNTPNT)
13930+ && a->dentry
13931+ && d_mountpoint(a->dentry))
0c3ec466
AM
13932+ pr_warn("mount-point %.*s is removed or renamed\n",
13933+ AuDLNPair(a->dentry));
1facf9fc 13934+
4a4d8108 13935+ return 0;
1308ab2a 13936+}
1facf9fc 13937+
1308ab2a 13938+/* ---------------------------------------------------------------------- */
1facf9fc 13939+
4a4d8108
AM
13940+static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
13941+ struct inode *dir)
1308ab2a 13942+{
4a4d8108
AM
13943+ struct dentry *dentry, *d, *parent;
13944+ struct qstr *dname;
1308ab2a 13945+
4a4d8108
AM
13946+ parent = d_find_alias(dir);
13947+ if (!parent)
13948+ return NULL;
1308ab2a 13949+
4a4d8108 13950+ dentry = NULL;
027c5e7a 13951+ spin_lock(&parent->d_lock);
4a4d8108
AM
13952+ list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) {
13953+ /* AuDbg("%.*s\n", AuDLNPair(d)); */
027c5e7a 13954+ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
4a4d8108
AM
13955+ dname = &d->d_name;
13956+ if (dname->len != nlen || memcmp(dname->name, name, nlen))
027c5e7a
AM
13957+ goto cont_unlock;
13958+ if (au_di(d))
13959+ au_digen_dec(d);
13960+ else
13961+ goto cont_unlock;
392086de 13962+ if (d_count(d)) {
027c5e7a 13963+ dentry = dget_dlock(d);
4a4d8108 13964+ spin_unlock(&d->d_lock);
027c5e7a 13965+ break;
dece6358 13966+ }
1facf9fc 13967+
027c5e7a
AM
13968+ cont_unlock:
13969+ spin_unlock(&d->d_lock);
1308ab2a 13970+ }
027c5e7a 13971+ spin_unlock(&parent->d_lock);
4a4d8108 13972+ dput(parent);
1facf9fc 13973+
4a4d8108
AM
13974+ if (dentry)
13975+ di_write_lock_child(dentry);
1308ab2a 13976+
4a4d8108
AM
13977+ return dentry;
13978+}
dece6358 13979+
4a4d8108
AM
13980+static struct inode *lookup_wlock_by_ino(struct super_block *sb,
13981+ aufs_bindex_t bindex, ino_t h_ino)
13982+{
13983+ struct inode *inode;
13984+ ino_t ino;
13985+ int err;
13986+
13987+ inode = NULL;
13988+ err = au_xino_read(sb, bindex, h_ino, &ino);
13989+ if (!err && ino)
13990+ inode = ilookup(sb, ino);
13991+ if (!inode)
13992+ goto out;
13993+
13994+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 13995+ pr_warn("wrong root branch\n");
4a4d8108
AM
13996+ iput(inode);
13997+ inode = NULL;
13998+ goto out;
1308ab2a 13999+ }
14000+
4a4d8108 14001+ ii_write_lock_child(inode);
1308ab2a 14002+
4f0767ce 14003+out:
4a4d8108 14004+ return inode;
dece6358
AM
14005+}
14006+
4a4d8108 14007+static void au_hn_bh(void *_args)
1facf9fc 14008+{
4a4d8108
AM
14009+ struct au_hnotify_args *a = _args;
14010+ struct super_block *sb;
14011+ aufs_bindex_t bindex, bend, bfound;
14012+ unsigned char xino, try_iput;
1facf9fc 14013+ int err;
1308ab2a 14014+ struct inode *inode;
4a4d8108
AM
14015+ ino_t h_ino;
14016+ struct hn_job_args args;
14017+ struct dentry *dentry;
14018+ struct au_sbinfo *sbinfo;
1facf9fc 14019+
4a4d8108
AM
14020+ AuDebugOn(!_args);
14021+ AuDebugOn(!a->h_dir);
14022+ AuDebugOn(!a->dir);
14023+ AuDebugOn(!a->mask);
14024+ AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
14025+ a->mask, a->dir->i_ino, a->h_dir->i_ino,
14026+ a->h_child_inode ? a->h_child_inode->i_ino : 0);
1facf9fc 14027+
4a4d8108
AM
14028+ inode = NULL;
14029+ dentry = NULL;
14030+ /*
14031+ * do not lock a->dir->i_mutex here
14032+ * because of d_revalidate() may cause a deadlock.
14033+ */
14034+ sb = a->dir->i_sb;
14035+ AuDebugOn(!sb);
14036+ sbinfo = au_sbi(sb);
14037+ AuDebugOn(!sbinfo);
7f207e10 14038+ si_write_lock(sb, AuLock_NOPLMW);
1facf9fc 14039+
4a4d8108
AM
14040+ ii_read_lock_parent(a->dir);
14041+ bfound = -1;
14042+ bend = au_ibend(a->dir);
14043+ for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
14044+ if (au_h_iptr(a->dir, bindex) == a->h_dir) {
14045+ bfound = bindex;
14046+ break;
14047+ }
14048+ ii_read_unlock(a->dir);
14049+ if (unlikely(bfound < 0))
14050+ goto out;
1facf9fc 14051+
4a4d8108
AM
14052+ xino = !!au_opt_test(au_mntflags(sb), XINO);
14053+ h_ino = 0;
14054+ if (a->h_child_inode)
14055+ h_ino = a->h_child_inode->i_ino;
1facf9fc 14056+
4a4d8108
AM
14057+ if (a->h_child_nlen
14058+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
14059+ || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
14060+ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
14061+ a->dir);
14062+ try_iput = 0;
14063+ if (dentry)
14064+ inode = dentry->d_inode;
14065+ if (xino && !inode && h_ino
14066+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
14067+ || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
14068+ || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
14069+ inode = lookup_wlock_by_ino(sb, bfound, h_ino);
14070+ try_iput = 1;
14071+ }
1facf9fc 14072+
4a4d8108
AM
14073+ args.flags = a->flags[AuHn_CHILD];
14074+ args.dentry = dentry;
14075+ args.inode = inode;
14076+ args.h_inode = a->h_child_inode;
14077+ args.dir = a->dir;
14078+ args.h_dir = a->h_dir;
14079+ args.h_name = a->h_child_name;
14080+ args.h_nlen = a->h_child_nlen;
14081+ err = hn_job(&args);
14082+ if (dentry) {
027c5e7a 14083+ if (au_di(dentry))
4a4d8108
AM
14084+ di_write_unlock(dentry);
14085+ dput(dentry);
14086+ }
14087+ if (inode && try_iput) {
14088+ ii_write_unlock(inode);
14089+ iput(inode);
14090+ }
1facf9fc 14091+
4a4d8108
AM
14092+ ii_write_lock_parent(a->dir);
14093+ args.flags = a->flags[AuHn_PARENT];
14094+ args.dentry = NULL;
14095+ args.inode = a->dir;
14096+ args.h_inode = a->h_dir;
14097+ args.dir = NULL;
14098+ args.h_dir = NULL;
14099+ args.h_name = NULL;
14100+ args.h_nlen = 0;
14101+ err = hn_job(&args);
14102+ ii_write_unlock(a->dir);
1facf9fc 14103+
4f0767ce 14104+out:
4a4d8108
AM
14105+ iput(a->h_child_inode);
14106+ iput(a->h_dir);
14107+ iput(a->dir);
027c5e7a
AM
14108+ si_write_unlock(sb);
14109+ au_nwt_done(&sbinfo->si_nowait);
1308ab2a 14110+ kfree(a);
dece6358 14111+}
1facf9fc 14112+
4a4d8108
AM
14113+/* ---------------------------------------------------------------------- */
14114+
14115+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
14116+ struct qstr *h_child_qstr, struct inode *h_child_inode)
dece6358 14117+{
4a4d8108 14118+ int err, len;
53392da6 14119+ unsigned int flags[AuHnLast], f;
4a4d8108
AM
14120+ unsigned char isdir, isroot, wh;
14121+ struct inode *dir;
14122+ struct au_hnotify_args *args;
14123+ char *p, *h_child_name;
dece6358 14124+
1308ab2a 14125+ err = 0;
4a4d8108
AM
14126+ AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
14127+ dir = igrab(hnotify->hn_aufs_inode);
14128+ if (!dir)
14129+ goto out;
1facf9fc 14130+
4a4d8108
AM
14131+ isroot = (dir->i_ino == AUFS_ROOT_INO);
14132+ wh = 0;
14133+ h_child_name = (void *)h_child_qstr->name;
14134+ len = h_child_qstr->len;
14135+ if (h_child_name) {
14136+ if (len > AUFS_WH_PFX_LEN
14137+ && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
14138+ h_child_name += AUFS_WH_PFX_LEN;
14139+ len -= AUFS_WH_PFX_LEN;
14140+ wh = 1;
14141+ }
1facf9fc 14142+ }
dece6358 14143+
4a4d8108
AM
14144+ isdir = 0;
14145+ if (h_child_inode)
14146+ isdir = !!S_ISDIR(h_child_inode->i_mode);
14147+ flags[AuHn_PARENT] = AuHnJob_ISDIR;
14148+ flags[AuHn_CHILD] = 0;
14149+ if (isdir)
14150+ flags[AuHn_CHILD] = AuHnJob_ISDIR;
14151+ au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
14152+ au_fset_hnjob(flags[AuHn_CHILD], GEN);
14153+ switch (mask & FS_EVENTS_POSS_ON_CHILD) {
14154+ case FS_MOVED_FROM:
14155+ case FS_MOVED_TO:
14156+ au_fset_hnjob(flags[AuHn_CHILD], XINO0);
14157+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
14158+ /*FALLTHROUGH*/
14159+ case FS_CREATE:
14160+ AuDebugOn(!h_child_name || !h_child_inode);
14161+ break;
1facf9fc 14162+
4a4d8108
AM
14163+ case FS_DELETE:
14164+ /*
14165+ * aufs never be able to get this child inode.
14166+ * revalidation should be in d_revalidate()
14167+ * by checking i_nlink, i_generation or d_unhashed().
14168+ */
14169+ AuDebugOn(!h_child_name);
14170+ au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
14171+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
14172+ break;
dece6358 14173+
4a4d8108
AM
14174+ default:
14175+ AuDebugOn(1);
14176+ }
1308ab2a 14177+
4a4d8108
AM
14178+ if (wh)
14179+ h_child_inode = NULL;
1308ab2a 14180+
4a4d8108
AM
14181+ err = -ENOMEM;
14182+ /* iput() and kfree() will be called in au_hnotify() */
4a4d8108 14183+ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
4a4d8108
AM
14184+ if (unlikely(!args)) {
14185+ AuErr1("no memory\n");
14186+ iput(dir);
14187+ goto out;
14188+ }
14189+ args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
14190+ args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
14191+ args->mask = mask;
14192+ args->dir = dir;
14193+ args->h_dir = igrab(h_dir);
14194+ if (h_child_inode)
14195+ h_child_inode = igrab(h_child_inode); /* can be NULL */
14196+ args->h_child_inode = h_child_inode;
14197+ args->h_child_nlen = len;
14198+ if (len) {
14199+ p = (void *)args;
14200+ p += sizeof(*args);
14201+ memcpy(p, h_child_name, len);
14202+ p[len] = 0;
1308ab2a 14203+ }
1308ab2a 14204+
53392da6
AM
14205+ f = 0;
14206+ if (!dir->i_nlink)
14207+ f = AuWkq_NEST;
14208+ err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
4a4d8108
AM
14209+ if (unlikely(err)) {
14210+ pr_err("wkq %d\n", err);
14211+ iput(args->h_child_inode);
14212+ iput(args->h_dir);
14213+ iput(args->dir);
14214+ kfree(args);
1facf9fc 14215+ }
1facf9fc 14216+
4a4d8108 14217+out:
1facf9fc 14218+ return err;
14219+}
14220+
027c5e7a
AM
14221+/* ---------------------------------------------------------------------- */
14222+
14223+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
14224+{
14225+ int err;
14226+
14227+ AuDebugOn(!(udba & AuOptMask_UDBA));
14228+
14229+ err = 0;
14230+ if (au_hnotify_op.reset_br)
14231+ err = au_hnotify_op.reset_br(udba, br, perm);
14232+
14233+ return err;
14234+}
14235+
14236+int au_hnotify_init_br(struct au_branch *br, int perm)
14237+{
14238+ int err;
14239+
14240+ err = 0;
14241+ if (au_hnotify_op.init_br)
14242+ err = au_hnotify_op.init_br(br, perm);
14243+
14244+ return err;
14245+}
14246+
14247+void au_hnotify_fin_br(struct au_branch *br)
14248+{
14249+ if (au_hnotify_op.fin_br)
14250+ au_hnotify_op.fin_br(br);
14251+}
14252+
4a4d8108
AM
14253+static void au_hn_destroy_cache(void)
14254+{
14255+ kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]);
14256+ au_cachep[AuCache_HNOTIFY] = NULL;
14257+}
1308ab2a 14258+
4a4d8108 14259+int __init au_hnotify_init(void)
1facf9fc 14260+{
1308ab2a 14261+ int err;
1308ab2a 14262+
4a4d8108
AM
14263+ err = -ENOMEM;
14264+ au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify);
14265+ if (au_cachep[AuCache_HNOTIFY]) {
027c5e7a
AM
14266+ err = 0;
14267+ if (au_hnotify_op.init)
14268+ err = au_hnotify_op.init();
4a4d8108
AM
14269+ if (unlikely(err))
14270+ au_hn_destroy_cache();
1308ab2a 14271+ }
1308ab2a 14272+ AuTraceErr(err);
4a4d8108 14273+ return err;
1308ab2a 14274+}
14275+
4a4d8108 14276+void au_hnotify_fin(void)
1308ab2a 14277+{
027c5e7a
AM
14278+ if (au_hnotify_op.fin)
14279+ au_hnotify_op.fin();
4a4d8108
AM
14280+ /* cf. au_cache_fin() */
14281+ if (au_cachep[AuCache_HNOTIFY])
14282+ au_hn_destroy_cache();
dece6358 14283+}
7f207e10
AM
14284diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
14285--- /usr/share/empty/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100
86dc4139 14286+++ linux/fs/aufs/iinfo.c 2013-07-06 13:20:47.750198454 +0200
537831f9 14287@@ -0,0 +1,276 @@
dece6358 14288+/*
7a9e40b8 14289+ * Copyright (C) 2005-2013 Junjiro R. Okajima
dece6358
AM
14290+ *
14291+ * This program, aufs is free software; you can redistribute it and/or modify
14292+ * it under the terms of the GNU General Public License as published by
14293+ * the Free Software Foundation; either version 2 of the License, or
14294+ * (at your option) any later version.
14295+ *
14296+ * This program is distributed in the hope that it will be useful,
14297+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14298+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14299+ * GNU General Public License for more details.
14300+ *
14301+ * You should have received a copy of the GNU General Public License
14302+ * along with this program; if not, write to the Free Software
14303+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14304+ */
1facf9fc 14305+
dece6358 14306+/*
4a4d8108 14307+ * inode private data
dece6358 14308+ */
1facf9fc 14309+
1308ab2a 14310+#include "aufs.h"
1facf9fc 14311+
4a4d8108 14312+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 14313+{
4a4d8108 14314+ struct inode *h_inode;
1facf9fc 14315+
4a4d8108 14316+ IiMustAnyLock(inode);
1facf9fc 14317+
4a4d8108
AM
14318+ h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode;
14319+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
14320+ return h_inode;
14321+}
1facf9fc 14322+
4a4d8108
AM
14323+/* todo: hard/soft set? */
14324+void au_hiput(struct au_hinode *hinode)
14325+{
14326+ au_hn_free(hinode);
14327+ dput(hinode->hi_whdentry);
14328+ iput(hinode->hi_inode);
14329+}
1facf9fc 14330+
4a4d8108
AM
14331+unsigned int au_hi_flags(struct inode *inode, int isdir)
14332+{
14333+ unsigned int flags;
14334+ const unsigned int mnt_flags = au_mntflags(inode->i_sb);
1facf9fc 14335+
4a4d8108
AM
14336+ flags = 0;
14337+ if (au_opt_test(mnt_flags, XINO))
14338+ au_fset_hi(flags, XINO);
14339+ if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY))
14340+ au_fset_hi(flags, HNOTIFY);
14341+ return flags;
1facf9fc 14342+}
14343+
4a4d8108
AM
14344+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
14345+ struct inode *h_inode, unsigned int flags)
1308ab2a 14346+{
4a4d8108
AM
14347+ struct au_hinode *hinode;
14348+ struct inode *hi;
14349+ struct au_iinfo *iinfo = au_ii(inode);
1facf9fc 14350+
4a4d8108 14351+ IiMustWriteLock(inode);
dece6358 14352+
4a4d8108
AM
14353+ hinode = iinfo->ii_hinode + bindex;
14354+ hi = hinode->hi_inode;
14355+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
14356+
14357+ if (hi)
14358+ au_hiput(hinode);
14359+ hinode->hi_inode = h_inode;
14360+ if (h_inode) {
14361+ int err;
14362+ struct super_block *sb = inode->i_sb;
14363+ struct au_branch *br;
14364+
027c5e7a
AM
14365+ AuDebugOn(inode->i_mode
14366+ && (h_inode->i_mode & S_IFMT)
14367+ != (inode->i_mode & S_IFMT));
4a4d8108
AM
14368+ if (bindex == iinfo->ii_bstart)
14369+ au_cpup_igen(inode, h_inode);
14370+ br = au_sbr(sb, bindex);
14371+ hinode->hi_id = br->br_id;
14372+ if (au_ftest_hi(flags, XINO)) {
14373+ err = au_xino_write(sb, bindex, h_inode->i_ino,
14374+ inode->i_ino);
14375+ if (unlikely(err))
14376+ AuIOErr1("failed au_xino_write() %d\n", err);
14377+ }
14378+
14379+ if (au_ftest_hi(flags, HNOTIFY)
14380+ && au_br_hnotifyable(br->br_perm)) {
027c5e7a 14381+ err = au_hn_alloc(hinode, inode);
4a4d8108
AM
14382+ if (unlikely(err))
14383+ AuIOErr1("au_hn_alloc() %d\n", err);
1308ab2a 14384+ }
14385+ }
4a4d8108 14386+}
dece6358 14387+
4a4d8108
AM
14388+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
14389+ struct dentry *h_wh)
14390+{
14391+ struct au_hinode *hinode;
dece6358 14392+
4a4d8108
AM
14393+ IiMustWriteLock(inode);
14394+
14395+ hinode = au_ii(inode)->ii_hinode + bindex;
14396+ AuDebugOn(hinode->hi_whdentry);
14397+ hinode->hi_whdentry = h_wh;
1facf9fc 14398+}
14399+
537831f9 14400+void au_update_iigen(struct inode *inode, int half)
1308ab2a 14401+{
537831f9
AM
14402+ struct au_iinfo *iinfo;
14403+ struct au_iigen *iigen;
14404+ unsigned int sigen;
14405+
14406+ sigen = au_sigen(inode->i_sb);
14407+ iinfo = au_ii(inode);
14408+ iigen = &iinfo->ii_generation;
14409+ spin_lock(&iinfo->ii_genspin);
14410+ iigen->ig_generation = sigen;
14411+ if (half)
14412+ au_ig_fset(iigen->ig_flags, HALF_REFRESHED);
14413+ else
14414+ au_ig_fclr(iigen->ig_flags, HALF_REFRESHED);
14415+ spin_unlock(&iinfo->ii_genspin);
4a4d8108 14416+}
1facf9fc 14417+
4a4d8108
AM
14418+/* it may be called at remount time, too */
14419+void au_update_ibrange(struct inode *inode, int do_put_zero)
14420+{
14421+ struct au_iinfo *iinfo;
027c5e7a 14422+ aufs_bindex_t bindex, bend;
1facf9fc 14423+
4a4d8108 14424+ iinfo = au_ii(inode);
027c5e7a 14425+ if (!iinfo)
4a4d8108 14426+ return;
1facf9fc 14427+
4a4d8108 14428+ IiMustWriteLock(inode);
1facf9fc 14429+
027c5e7a 14430+ if (do_put_zero && iinfo->ii_bstart >= 0) {
4a4d8108
AM
14431+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
14432+ bindex++) {
14433+ struct inode *h_i;
1facf9fc 14434+
4a4d8108 14435+ h_i = iinfo->ii_hinode[0 + bindex].hi_inode;
027c5e7a
AM
14436+ if (h_i && !h_i->i_nlink)
14437+ au_set_h_iptr(inode, bindex, NULL, 0);
14438+ }
4a4d8108
AM
14439+ }
14440+
027c5e7a
AM
14441+ iinfo->ii_bstart = -1;
14442+ iinfo->ii_bend = -1;
14443+ bend = au_sbend(inode->i_sb);
14444+ for (bindex = 0; bindex <= bend; bindex++)
14445+ if (iinfo->ii_hinode[0 + bindex].hi_inode) {
14446+ iinfo->ii_bstart = bindex;
4a4d8108 14447+ break;
027c5e7a
AM
14448+ }
14449+ if (iinfo->ii_bstart >= 0)
14450+ for (bindex = bend; bindex >= iinfo->ii_bstart; bindex--)
14451+ if (iinfo->ii_hinode[0 + bindex].hi_inode) {
14452+ iinfo->ii_bend = bindex;
14453+ break;
14454+ }
14455+ AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend);
1308ab2a 14456+}
1facf9fc 14457+
dece6358 14458+/* ---------------------------------------------------------------------- */
1facf9fc 14459+
4a4d8108 14460+void au_icntnr_init_once(void *_c)
dece6358 14461+{
4a4d8108
AM
14462+ struct au_icntnr *c = _c;
14463+ struct au_iinfo *iinfo = &c->iinfo;
e49829fe 14464+ static struct lock_class_key aufs_ii;
1facf9fc 14465+
537831f9 14466+ spin_lock_init(&iinfo->ii_genspin);
4a4d8108 14467+ au_rw_init(&iinfo->ii_rwsem);
e49829fe 14468+ au_rw_class(&iinfo->ii_rwsem, &aufs_ii);
4a4d8108
AM
14469+ inode_init_once(&c->vfs_inode);
14470+}
1facf9fc 14471+
4a4d8108
AM
14472+int au_iinfo_init(struct inode *inode)
14473+{
14474+ struct au_iinfo *iinfo;
14475+ struct super_block *sb;
14476+ int nbr, i;
1facf9fc 14477+
4a4d8108
AM
14478+ sb = inode->i_sb;
14479+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
14480+ nbr = au_sbend(sb) + 1;
14481+ if (unlikely(nbr <= 0))
14482+ nbr = 1;
14483+ iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
14484+ if (iinfo->ii_hinode) {
7f207e10 14485+ au_ninodes_inc(sb);
4a4d8108
AM
14486+ for (i = 0; i < nbr; i++)
14487+ iinfo->ii_hinode[i].hi_id = -1;
1facf9fc 14488+
537831f9 14489+ iinfo->ii_generation.ig_generation = au_sigen(sb);
4a4d8108
AM
14490+ iinfo->ii_bstart = -1;
14491+ iinfo->ii_bend = -1;
14492+ iinfo->ii_vdir = NULL;
14493+ return 0;
1308ab2a 14494+ }
4a4d8108
AM
14495+ return -ENOMEM;
14496+}
1facf9fc 14497+
4a4d8108
AM
14498+int au_ii_realloc(struct au_iinfo *iinfo, int nbr)
14499+{
14500+ int err, sz;
14501+ struct au_hinode *hip;
1facf9fc 14502+
4a4d8108
AM
14503+ AuRwMustWriteLock(&iinfo->ii_rwsem);
14504+
14505+ err = -ENOMEM;
14506+ sz = sizeof(*hip) * (iinfo->ii_bend + 1);
14507+ if (!sz)
14508+ sz = sizeof(*hip);
14509+ hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS);
14510+ if (hip) {
14511+ iinfo->ii_hinode = hip;
14512+ err = 0;
1308ab2a 14513+ }
4a4d8108 14514+
1308ab2a 14515+ return err;
1facf9fc 14516+}
14517+
4a4d8108 14518+void au_iinfo_fin(struct inode *inode)
1facf9fc 14519+{
4a4d8108
AM
14520+ struct au_iinfo *iinfo;
14521+ struct au_hinode *hi;
14522+ struct super_block *sb;
b752ccd1
AM
14523+ aufs_bindex_t bindex, bend;
14524+ const unsigned char unlinked = !inode->i_nlink;
1308ab2a 14525+
4a4d8108
AM
14526+ iinfo = au_ii(inode);
14527+ /* bad_inode case */
14528+ if (!iinfo)
14529+ return;
1308ab2a 14530+
b752ccd1 14531+ sb = inode->i_sb;
7f207e10 14532+ au_ninodes_dec(sb);
b752ccd1
AM
14533+ if (si_pid_test(sb))
14534+ au_xino_delete_inode(inode, unlinked);
14535+ else {
14536+ /*
14537+ * it is safe to hide the dependency between sbinfo and
14538+ * sb->s_umount.
14539+ */
14540+ lockdep_off();
14541+ si_noflush_read_lock(sb);
14542+ au_xino_delete_inode(inode, unlinked);
14543+ si_read_unlock(sb);
14544+ lockdep_on();
14545+ }
14546+
4a4d8108
AM
14547+ if (iinfo->ii_vdir)
14548+ au_vdir_free(iinfo->ii_vdir);
1308ab2a 14549+
b752ccd1
AM
14550+ bindex = iinfo->ii_bstart;
14551+ if (bindex >= 0) {
14552+ hi = iinfo->ii_hinode + bindex;
4a4d8108 14553+ bend = iinfo->ii_bend;
b752ccd1
AM
14554+ while (bindex++ <= bend) {
14555+ if (hi->hi_inode)
4a4d8108 14556+ au_hiput(hi);
4a4d8108
AM
14557+ hi++;
14558+ }
14559+ }
4a4d8108 14560+ kfree(iinfo->ii_hinode);
027c5e7a 14561+ iinfo->ii_hinode = NULL;
4a4d8108 14562+ AuRwDestroy(&iinfo->ii_rwsem);
dece6358 14563+}
7f207e10
AM
14564diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
14565--- /usr/share/empty/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100
86dc4139 14566+++ linux/fs/aufs/inode.c 2013-07-06 13:20:47.750198454 +0200
1716fcea 14567@@ -0,0 +1,492 @@
4a4d8108 14568+/*
7a9e40b8 14569+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
14570+ *
14571+ * This program, aufs is free software; you can redistribute it and/or modify
14572+ * it under the terms of the GNU General Public License as published by
14573+ * the Free Software Foundation; either version 2 of the License, or
14574+ * (at your option) any later version.
14575+ *
14576+ * This program is distributed in the hope that it will be useful,
14577+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14578+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14579+ * GNU General Public License for more details.
14580+ *
14581+ * You should have received a copy of the GNU General Public License
14582+ * along with this program; if not, write to the Free Software
14583+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14584+ */
1facf9fc 14585+
4a4d8108
AM
14586+/*
14587+ * inode functions
14588+ */
1facf9fc 14589+
4a4d8108 14590+#include "aufs.h"
1308ab2a 14591+
4a4d8108
AM
14592+struct inode *au_igrab(struct inode *inode)
14593+{
14594+ if (inode) {
14595+ AuDebugOn(!atomic_read(&inode->i_count));
027c5e7a 14596+ ihold(inode);
1facf9fc 14597+ }
4a4d8108
AM
14598+ return inode;
14599+}
1facf9fc 14600+
4a4d8108
AM
14601+static void au_refresh_hinode_attr(struct inode *inode, int do_version)
14602+{
14603+ au_cpup_attr_all(inode, /*force*/0);
537831f9 14604+ au_update_iigen(inode, /*half*/1);
4a4d8108
AM
14605+ if (do_version)
14606+ inode->i_version++;
dece6358 14607+}
1facf9fc 14608+
027c5e7a 14609+static int au_ii_refresh(struct inode *inode, int *update)
dece6358 14610+{
4a4d8108 14611+ int err, e;
027c5e7a 14612+ umode_t type;
4a4d8108 14613+ aufs_bindex_t bindex, new_bindex;
1308ab2a 14614+ struct super_block *sb;
4a4d8108 14615+ struct au_iinfo *iinfo;
027c5e7a 14616+ struct au_hinode *p, *q, tmp;
1facf9fc 14617+
4a4d8108 14618+ IiMustWriteLock(inode);
1facf9fc 14619+
027c5e7a 14620+ *update = 0;
4a4d8108 14621+ sb = inode->i_sb;
027c5e7a 14622+ type = inode->i_mode & S_IFMT;
4a4d8108
AM
14623+ iinfo = au_ii(inode);
14624+ err = au_ii_realloc(iinfo, au_sbend(sb) + 1);
14625+ if (unlikely(err))
1308ab2a 14626+ goto out;
1facf9fc 14627+
027c5e7a 14628+ AuDebugOn(iinfo->ii_bstart < 0);
4a4d8108 14629+ p = iinfo->ii_hinode + iinfo->ii_bstart;
4a4d8108
AM
14630+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
14631+ bindex++, p++) {
14632+ if (!p->hi_inode)
14633+ continue;
1facf9fc 14634+
027c5e7a 14635+ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT));
4a4d8108
AM
14636+ new_bindex = au_br_index(sb, p->hi_id);
14637+ if (new_bindex == bindex)
14638+ continue;
1facf9fc 14639+
4a4d8108 14640+ if (new_bindex < 0) {
027c5e7a 14641+ *update = 1;
4a4d8108
AM
14642+ au_hiput(p);
14643+ p->hi_inode = NULL;
14644+ continue;
1308ab2a 14645+ }
4a4d8108
AM
14646+
14647+ if (new_bindex < iinfo->ii_bstart)
14648+ iinfo->ii_bstart = new_bindex;
14649+ if (iinfo->ii_bend < new_bindex)
14650+ iinfo->ii_bend = new_bindex;
14651+ /* swap two lower inode, and loop again */
14652+ q = iinfo->ii_hinode + new_bindex;
14653+ tmp = *q;
14654+ *q = *p;
14655+ *p = tmp;
14656+ if (tmp.hi_inode) {
14657+ bindex--;
14658+ p--;
1308ab2a 14659+ }
14660+ }
4a4d8108
AM
14661+ au_update_ibrange(inode, /*do_put_zero*/0);
14662+ e = au_dy_irefresh(inode);
14663+ if (unlikely(e && !err))
14664+ err = e;
1facf9fc 14665+
4f0767ce 14666+out:
027c5e7a
AM
14667+ AuTraceErr(err);
14668+ return err;
14669+}
14670+
14671+int au_refresh_hinode_self(struct inode *inode)
14672+{
14673+ int err, update;
14674+
14675+ err = au_ii_refresh(inode, &update);
14676+ if (!err)
14677+ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
14678+
14679+ AuTraceErr(err);
4a4d8108
AM
14680+ return err;
14681+}
1facf9fc 14682+
4a4d8108
AM
14683+int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
14684+{
027c5e7a 14685+ int err, e, update;
4a4d8108 14686+ unsigned int flags;
027c5e7a 14687+ umode_t mode;
4a4d8108 14688+ aufs_bindex_t bindex, bend;
027c5e7a 14689+ unsigned char isdir;
4a4d8108
AM
14690+ struct au_hinode *p;
14691+ struct au_iinfo *iinfo;
1facf9fc 14692+
027c5e7a 14693+ err = au_ii_refresh(inode, &update);
4a4d8108
AM
14694+ if (unlikely(err))
14695+ goto out;
14696+
14697+ update = 0;
14698+ iinfo = au_ii(inode);
14699+ p = iinfo->ii_hinode + iinfo->ii_bstart;
027c5e7a
AM
14700+ mode = (inode->i_mode & S_IFMT);
14701+ isdir = S_ISDIR(mode);
4a4d8108
AM
14702+ flags = au_hi_flags(inode, isdir);
14703+ bend = au_dbend(dentry);
14704+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
14705+ struct inode *h_i;
14706+ struct dentry *h_d;
14707+
14708+ h_d = au_h_dptr(dentry, bindex);
14709+ if (!h_d || !h_d->d_inode)
14710+ continue;
14711+
027c5e7a 14712+ AuDebugOn(mode != (h_d->d_inode->i_mode & S_IFMT));
4a4d8108
AM
14713+ if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) {
14714+ h_i = au_h_iptr(inode, bindex);
14715+ if (h_i) {
14716+ if (h_i == h_d->d_inode)
14717+ continue;
14718+ err = -EIO;
14719+ break;
14720+ }
14721+ }
14722+ if (bindex < iinfo->ii_bstart)
14723+ iinfo->ii_bstart = bindex;
14724+ if (iinfo->ii_bend < bindex)
14725+ iinfo->ii_bend = bindex;
14726+ au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags);
14727+ update = 1;
1308ab2a 14728+ }
4a4d8108
AM
14729+ au_update_ibrange(inode, /*do_put_zero*/0);
14730+ e = au_dy_irefresh(inode);
14731+ if (unlikely(e && !err))
14732+ err = e;
027c5e7a
AM
14733+ if (!err)
14734+ au_refresh_hinode_attr(inode, update && isdir);
4a4d8108 14735+
4f0767ce 14736+out:
4a4d8108 14737+ AuTraceErr(err);
1308ab2a 14738+ return err;
dece6358
AM
14739+}
14740+
4a4d8108 14741+static int set_inode(struct inode *inode, struct dentry *dentry)
dece6358 14742+{
4a4d8108
AM
14743+ int err;
14744+ unsigned int flags;
14745+ umode_t mode;
14746+ aufs_bindex_t bindex, bstart, btail;
14747+ unsigned char isdir;
14748+ struct dentry *h_dentry;
14749+ struct inode *h_inode;
14750+ struct au_iinfo *iinfo;
dece6358 14751+
4a4d8108 14752+ IiMustWriteLock(inode);
dece6358 14753+
4a4d8108
AM
14754+ err = 0;
14755+ isdir = 0;
14756+ bstart = au_dbstart(dentry);
14757+ h_inode = au_h_dptr(dentry, bstart)->d_inode;
14758+ mode = h_inode->i_mode;
14759+ switch (mode & S_IFMT) {
14760+ case S_IFREG:
14761+ btail = au_dbtail(dentry);
14762+ inode->i_op = &aufs_iop;
14763+ inode->i_fop = &aufs_file_fop;
14764+ err = au_dy_iaop(inode, bstart, h_inode);
14765+ if (unlikely(err))
14766+ goto out;
14767+ break;
14768+ case S_IFDIR:
14769+ isdir = 1;
14770+ btail = au_dbtaildir(dentry);
14771+ inode->i_op = &aufs_dir_iop;
14772+ inode->i_fop = &aufs_dir_fop;
14773+ break;
14774+ case S_IFLNK:
14775+ btail = au_dbtail(dentry);
14776+ inode->i_op = &aufs_symlink_iop;
14777+ break;
14778+ case S_IFBLK:
14779+ case S_IFCHR:
14780+ case S_IFIFO:
14781+ case S_IFSOCK:
14782+ btail = au_dbtail(dentry);
14783+ inode->i_op = &aufs_iop;
14784+ au_init_special_fop(inode, mode, h_inode->i_rdev);
14785+ break;
14786+ default:
14787+ AuIOErr("Unknown file type 0%o\n", mode);
14788+ err = -EIO;
1308ab2a 14789+ goto out;
4a4d8108 14790+ }
dece6358 14791+
4a4d8108
AM
14792+ /* do not set hnotify for whiteouted dirs (SHWH mode) */
14793+ flags = au_hi_flags(inode, isdir);
14794+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
14795+ && au_ftest_hi(flags, HNOTIFY)
14796+ && dentry->d_name.len > AUFS_WH_PFX_LEN
14797+ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
14798+ au_fclr_hi(flags, HNOTIFY);
14799+ iinfo = au_ii(inode);
14800+ iinfo->ii_bstart = bstart;
14801+ iinfo->ii_bend = btail;
14802+ for (bindex = bstart; bindex <= btail; bindex++) {
14803+ h_dentry = au_h_dptr(dentry, bindex);
14804+ if (h_dentry)
14805+ au_set_h_iptr(inode, bindex,
14806+ au_igrab(h_dentry->d_inode), flags);
14807+ }
14808+ au_cpup_attr_all(inode, /*force*/1);
dece6358 14809+
4f0767ce 14810+out:
4a4d8108
AM
14811+ return err;
14812+}
dece6358 14813+
027c5e7a
AM
14814+/*
14815+ * successful returns with iinfo write_locked
14816+ * minus: errno
14817+ * zero: success, matched
14818+ * plus: no error, but unmatched
14819+ */
14820+static int reval_inode(struct inode *inode, struct dentry *dentry)
4a4d8108
AM
14821+{
14822+ int err;
537831f9
AM
14823+ unsigned int gen;
14824+ struct au_iigen iigen;
4a4d8108
AM
14825+ aufs_bindex_t bindex, bend;
14826+ struct inode *h_inode, *h_dinode;
dece6358 14827+
4a4d8108
AM
14828+ /*
14829+ * before this function, if aufs got any iinfo lock, it must be only
14830+ * one, the parent dir.
14831+ * it can happen by UDBA and the obsoleted inode number.
14832+ */
14833+ err = -EIO;
14834+ if (unlikely(inode->i_ino == parent_ino(dentry)))
14835+ goto out;
14836+
027c5e7a 14837+ err = 1;
4a4d8108
AM
14838+ ii_write_lock_new_child(inode);
14839+ h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode;
14840+ bend = au_ibend(inode);
14841+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
14842+ h_inode = au_h_iptr(inode, bindex);
537831f9
AM
14843+ if (!h_inode || h_inode != h_dinode)
14844+ continue;
14845+
14846+ err = 0;
14847+ gen = au_iigen(inode, &iigen);
14848+ if (gen == au_digen(dentry)
14849+ && !au_ig_ftest(iigen.ig_flags, HALF_REFRESHED))
4a4d8108 14850+ break;
537831f9
AM
14851+
14852+ /* fully refresh inode using dentry */
14853+ err = au_refresh_hinode(inode, dentry);
14854+ if (!err)
14855+ au_update_iigen(inode, /*half*/0);
14856+ break;
1facf9fc 14857+ }
dece6358 14858+
4a4d8108
AM
14859+ if (unlikely(err))
14860+ ii_write_unlock(inode);
4f0767ce 14861+out:
1facf9fc 14862+ return err;
14863+}
1facf9fc 14864+
4a4d8108
AM
14865+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
14866+ unsigned int d_type, ino_t *ino)
1facf9fc 14867+{
4a4d8108
AM
14868+ int err;
14869+ struct mutex *mtx;
1facf9fc 14870+
b752ccd1 14871+ /* prevent hardlinked inode number from race condition */
4a4d8108 14872+ mtx = NULL;
b752ccd1 14873+ if (d_type != DT_DIR) {
4a4d8108
AM
14874+ mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx;
14875+ mutex_lock(mtx);
14876+ }
14877+ err = au_xino_read(sb, bindex, h_ino, ino);
14878+ if (unlikely(err))
14879+ goto out;
1308ab2a 14880+
4a4d8108
AM
14881+ if (!*ino) {
14882+ err = -EIO;
14883+ *ino = au_xino_new_ino(sb);
14884+ if (unlikely(!*ino))
1facf9fc 14885+ goto out;
4a4d8108
AM
14886+ err = au_xino_write(sb, bindex, h_ino, *ino);
14887+ if (unlikely(err))
1308ab2a 14888+ goto out;
1308ab2a 14889+ }
1facf9fc 14890+
4f0767ce 14891+out:
b752ccd1 14892+ if (mtx)
4a4d8108 14893+ mutex_unlock(mtx);
1facf9fc 14894+ return err;
14895+}
14896+
4a4d8108
AM
14897+/* successful returns with iinfo write_locked */
14898+/* todo: return with unlocked? */
14899+struct inode *au_new_inode(struct dentry *dentry, int must_new)
1facf9fc 14900+{
b752ccd1 14901+ struct inode *inode, *h_inode;
4a4d8108
AM
14902+ struct dentry *h_dentry;
14903+ struct super_block *sb;
b752ccd1 14904+ struct mutex *mtx;
4a4d8108 14905+ ino_t h_ino, ino;
1716fcea 14906+ int err;
4a4d8108 14907+ aufs_bindex_t bstart;
1facf9fc 14908+
4a4d8108
AM
14909+ sb = dentry->d_sb;
14910+ bstart = au_dbstart(dentry);
14911+ h_dentry = au_h_dptr(dentry, bstart);
b752ccd1
AM
14912+ h_inode = h_dentry->d_inode;
14913+ h_ino = h_inode->i_ino;
14914+
14915+ /*
14916+ * stop 'race'-ing between hardlinks under different
14917+ * parents.
14918+ */
14919+ mtx = NULL;
14920+ if (!S_ISDIR(h_inode->i_mode))
14921+ mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;
14922+
4f0767ce 14923+new_ino:
b752ccd1
AM
14924+ if (mtx)
14925+ mutex_lock(mtx);
4a4d8108
AM
14926+ err = au_xino_read(sb, bstart, h_ino, &ino);
14927+ inode = ERR_PTR(err);
14928+ if (unlikely(err))
14929+ goto out;
b752ccd1 14930+
4a4d8108
AM
14931+ if (!ino) {
14932+ ino = au_xino_new_ino(sb);
14933+ if (unlikely(!ino)) {
14934+ inode = ERR_PTR(-EIO);
dece6358
AM
14935+ goto out;
14936+ }
14937+ }
1facf9fc 14938+
4a4d8108
AM
14939+ AuDbg("i%lu\n", (unsigned long)ino);
14940+ inode = au_iget_locked(sb, ino);
14941+ err = PTR_ERR(inode);
14942+ if (IS_ERR(inode))
1facf9fc 14943+ goto out;
1facf9fc 14944+
4a4d8108
AM
14945+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
14946+ if (inode->i_state & I_NEW) {
1716fcea
AM
14947+ /* verbose coding for lock class name */
14948+ if (unlikely(S_ISLNK(h_inode->i_mode)))
14949+ au_rw_class(&au_ii(inode)->ii_rwsem,
14950+ au_lc_key + AuLcSymlink_IIINFO);
14951+ else if (unlikely(S_ISDIR(h_inode->i_mode)))
14952+ au_rw_class(&au_ii(inode)->ii_rwsem,
14953+ au_lc_key + AuLcDir_IIINFO);
14954+ else /* likely */
14955+ au_rw_class(&au_ii(inode)->ii_rwsem,
14956+ au_lc_key + AuLcNonDir_IIINFO);
2dfbb274 14957+
4a4d8108
AM
14958+ ii_write_lock_new_child(inode);
14959+ err = set_inode(inode, dentry);
14960+ if (!err) {
14961+ unlock_new_inode(inode);
14962+ goto out; /* success */
14963+ }
1308ab2a 14964+
027c5e7a
AM
14965+ /*
14966+ * iget_failed() calls iput(), but we need to call
14967+ * ii_write_unlock() after iget_failed(). so dirty hack for
14968+ * i_count.
14969+ */
14970+ atomic_inc(&inode->i_count);
4a4d8108 14971+ iget_failed(inode);
027c5e7a
AM
14972+ ii_write_unlock(inode);
14973+ au_xino_write(sb, bstart, h_ino, /*ino*/0);
14974+ /* ignore this error */
14975+ goto out_iput;
14976+ } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) {
b752ccd1
AM
14977+ /*
14978+ * horrible race condition between lookup, readdir and copyup
14979+ * (or something).
14980+ */
14981+ if (mtx)
14982+ mutex_unlock(mtx);
027c5e7a
AM
14983+ err = reval_inode(inode, dentry);
14984+ if (unlikely(err < 0)) {
14985+ mtx = NULL;
14986+ goto out_iput;
14987+ }
14988+
b752ccd1
AM
14989+ if (!err) {
14990+ mtx = NULL;
4a4d8108 14991+ goto out; /* success */
b752ccd1
AM
14992+ } else if (mtx)
14993+ mutex_lock(mtx);
4a4d8108
AM
14994+ }
14995+
14996+ if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode)))
14997+ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
14998+ " b%d, %s, %.*s, hi%lu, i%lu.\n",
14999+ bstart, au_sbtype(h_dentry->d_sb), AuDLNPair(dentry),
15000+ (unsigned long)h_ino, (unsigned long)ino);
15001+ ino = 0;
15002+ err = au_xino_write(sb, bstart, h_ino, /*ino*/0);
15003+ if (!err) {
15004+ iput(inode);
b752ccd1
AM
15005+ if (mtx)
15006+ mutex_unlock(mtx);
4a4d8108
AM
15007+ goto new_ino;
15008+ }
1308ab2a 15009+
4f0767ce 15010+out_iput:
4a4d8108 15011+ iput(inode);
4a4d8108 15012+ inode = ERR_PTR(err);
4f0767ce 15013+out:
b752ccd1
AM
15014+ if (mtx)
15015+ mutex_unlock(mtx);
4a4d8108 15016+ return inode;
1facf9fc 15017+}
15018+
4a4d8108 15019+/* ---------------------------------------------------------------------- */
1facf9fc 15020+
4a4d8108
AM
15021+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
15022+ struct inode *inode)
15023+{
15024+ int err;
1facf9fc 15025+
4a4d8108 15026+ err = au_br_rdonly(au_sbr(sb, bindex));
1facf9fc 15027+
4a4d8108
AM
15028+ /* pseudo-link after flushed may happen out of bounds */
15029+ if (!err
15030+ && inode
15031+ && au_ibstart(inode) <= bindex
15032+ && bindex <= au_ibend(inode)) {
15033+ /*
15034+ * permission check is unnecessary since vfsub routine
15035+ * will be called later
15036+ */
15037+ struct inode *hi = au_h_iptr(inode, bindex);
15038+ if (hi)
15039+ err = IS_IMMUTABLE(hi) ? -EROFS : 0;
1facf9fc 15040+ }
15041+
4a4d8108
AM
15042+ return err;
15043+}
dece6358 15044+
4a4d8108
AM
15045+int au_test_h_perm(struct inode *h_inode, int mask)
15046+{
2dfbb274 15047+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
4a4d8108
AM
15048+ return 0;
15049+ return inode_permission(h_inode, mask);
15050+}
1facf9fc 15051+
4a4d8108
AM
15052+int au_test_h_perm_sio(struct inode *h_inode, int mask)
15053+{
15054+ if (au_test_nfs(h_inode->i_sb)
15055+ && (mask & MAY_WRITE)
15056+ && S_ISDIR(h_inode->i_mode))
15057+ mask |= MAY_READ; /* force permission check */
15058+ return au_test_h_perm(h_inode, mask);
1facf9fc 15059+}
7f207e10
AM
15060diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
15061--- /usr/share/empty/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
86dc4139
AM
15062+++ linux/fs/aufs/inode.h 2013-07-06 13:20:47.750198454 +0200
15063@@ -0,0 +1,600 @@
4a4d8108 15064+/*
7a9e40b8 15065+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
15066+ *
15067+ * This program, aufs is free software; you can redistribute it and/or modify
15068+ * it under the terms of the GNU General Public License as published by
15069+ * the Free Software Foundation; either version 2 of the License, or
15070+ * (at your option) any later version.
15071+ *
15072+ * This program is distributed in the hope that it will be useful,
15073+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15074+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15075+ * GNU General Public License for more details.
15076+ *
15077+ * You should have received a copy of the GNU General Public License
15078+ * along with this program; if not, write to the Free Software
15079+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15080+ */
1facf9fc 15081+
1308ab2a 15082+/*
4a4d8108 15083+ * inode operations
1308ab2a 15084+ */
dece6358 15085+
4a4d8108
AM
15086+#ifndef __AUFS_INODE_H__
15087+#define __AUFS_INODE_H__
dece6358 15088+
4a4d8108 15089+#ifdef __KERNEL__
1308ab2a 15090+
4a4d8108 15091+#include <linux/fsnotify.h>
4a4d8108 15092+#include "rwsem.h"
1308ab2a 15093+
4a4d8108 15094+struct vfsmount;
1facf9fc 15095+
4a4d8108
AM
15096+struct au_hnotify {
15097+#ifdef CONFIG_AUFS_HNOTIFY
15098+#ifdef CONFIG_AUFS_HFSNOTIFY
7f207e10 15099+ /* never use fsnotify_add_vfsmount_mark() */
0c5527e5 15100+ struct fsnotify_mark hn_mark;
4a4d8108 15101+#endif
7f207e10 15102+ struct inode *hn_aufs_inode; /* no get/put */
4a4d8108
AM
15103+#endif
15104+} ____cacheline_aligned_in_smp;
1facf9fc 15105+
4a4d8108
AM
15106+struct au_hinode {
15107+ struct inode *hi_inode;
15108+ aufs_bindex_t hi_id;
15109+#ifdef CONFIG_AUFS_HNOTIFY
15110+ struct au_hnotify *hi_notify;
15111+#endif
dece6358 15112+
4a4d8108
AM
15113+ /* reference to the copied-up whiteout with get/put */
15114+ struct dentry *hi_whdentry;
15115+};
dece6358 15116+
537831f9
AM
15117+/* ig_flags */
15118+#define AuIG_HALF_REFRESHED 1
15119+#define au_ig_ftest(flags, name) ((flags) & AuIG_##name)
15120+#define au_ig_fset(flags, name) \
15121+ do { (flags) |= AuIG_##name; } while (0)
15122+#define au_ig_fclr(flags, name) \
15123+ do { (flags) &= ~AuIG_##name; } while (0)
15124+
15125+struct au_iigen {
15126+ __u32 ig_generation, ig_flags;
15127+};
15128+
4a4d8108
AM
15129+struct au_vdir;
15130+struct au_iinfo {
537831f9 15131+ spinlock_t ii_genspin;
7a9e40b8 15132+ struct au_iigen ii_generation;
4a4d8108 15133+ struct super_block *ii_hsb1; /* no get/put */
1facf9fc 15134+
4a4d8108
AM
15135+ struct au_rwsem ii_rwsem;
15136+ aufs_bindex_t ii_bstart, ii_bend;
15137+ __u32 ii_higen;
15138+ struct au_hinode *ii_hinode;
15139+ struct au_vdir *ii_vdir;
15140+};
1facf9fc 15141+
4a4d8108
AM
15142+struct au_icntnr {
15143+ struct au_iinfo iinfo;
15144+ struct inode vfs_inode;
15145+} ____cacheline_aligned_in_smp;
1308ab2a 15146+
4a4d8108
AM
15147+/* au_pin flags */
15148+#define AuPin_DI_LOCKED 1
15149+#define AuPin_MNT_WRITE (1 << 1)
15150+#define au_ftest_pin(flags, name) ((flags) & AuPin_##name)
7f207e10
AM
15151+#define au_fset_pin(flags, name) \
15152+ do { (flags) |= AuPin_##name; } while (0)
15153+#define au_fclr_pin(flags, name) \
15154+ do { (flags) &= ~AuPin_##name; } while (0)
4a4d8108
AM
15155+
15156+struct au_pin {
15157+ /* input */
15158+ struct dentry *dentry;
15159+ unsigned int udba;
15160+ unsigned char lsc_di, lsc_hi, flags;
15161+ aufs_bindex_t bindex;
15162+
15163+ /* output */
15164+ struct dentry *parent;
15165+ struct au_hinode *hdir;
15166+ struct vfsmount *h_mnt;
86dc4139
AM
15167+
15168+ /* temporary unlock/relock for copyup */
15169+ struct dentry *h_dentry, *h_parent;
15170+ struct au_branch *br;
15171+ struct task_struct *task;
4a4d8108 15172+};
1facf9fc 15173+
86dc4139
AM
15174+void au_pin_hdir_unlock(struct au_pin *p);
15175+int au_pin_hdir_relock(struct au_pin *p);
15176+void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task);
15177+void au_pin_hdir_acquire_nest(struct au_pin *p);
15178+void au_pin_hdir_release(struct au_pin *p);
15179+
1308ab2a 15180+/* ---------------------------------------------------------------------- */
15181+
4a4d8108 15182+static inline struct au_iinfo *au_ii(struct inode *inode)
1facf9fc 15183+{
4a4d8108 15184+ struct au_iinfo *iinfo;
1facf9fc 15185+
4a4d8108
AM
15186+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
15187+ if (iinfo->ii_hinode)
15188+ return iinfo;
15189+ return NULL; /* debugging bad_inode case */
15190+}
1facf9fc 15191+
4a4d8108 15192+/* ---------------------------------------------------------------------- */
1facf9fc 15193+
4a4d8108
AM
15194+/* inode.c */
15195+struct inode *au_igrab(struct inode *inode);
027c5e7a 15196+int au_refresh_hinode_self(struct inode *inode);
4a4d8108
AM
15197+int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
15198+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
15199+ unsigned int d_type, ino_t *ino);
15200+struct inode *au_new_inode(struct dentry *dentry, int must_new);
15201+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
15202+ struct inode *inode);
15203+int au_test_h_perm(struct inode *h_inode, int mask);
15204+int au_test_h_perm_sio(struct inode *h_inode, int mask);
1facf9fc 15205+
4a4d8108
AM
15206+static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex,
15207+ ino_t h_ino, unsigned int d_type, ino_t *ino)
15208+{
15209+#ifdef CONFIG_AUFS_SHWH
15210+ return au_ino(sb, bindex, h_ino, d_type, ino);
15211+#else
15212+ return 0;
15213+#endif
15214+}
1facf9fc 15215+
4a4d8108
AM
15216+/* i_op.c */
15217+extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
1308ab2a 15218+
4a4d8108
AM
15219+/* au_wr_dir flags */
15220+#define AuWrDir_ADD_ENTRY 1
86dc4139
AM
15221+#define AuWrDir_TMP_WHENTRY (1 << 1)
15222+#define AuWrDir_ISDIR (1 << 2)
4a4d8108 15223+#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
7f207e10
AM
15224+#define au_fset_wrdir(flags, name) \
15225+ do { (flags) |= AuWrDir_##name; } while (0)
15226+#define au_fclr_wrdir(flags, name) \
15227+ do { (flags) &= ~AuWrDir_##name; } while (0)
1facf9fc 15228+
4a4d8108
AM
15229+struct au_wr_dir_args {
15230+ aufs_bindex_t force_btgt;
15231+ unsigned char flags;
15232+};
15233+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
15234+ struct au_wr_dir_args *args);
dece6358 15235+
4a4d8108
AM
15236+struct dentry *au_pinned_h_parent(struct au_pin *pin);
15237+void au_pin_init(struct au_pin *pin, struct dentry *dentry,
15238+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
15239+ unsigned int udba, unsigned char flags);
15240+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
15241+ unsigned int udba, unsigned char flags) __must_check;
15242+int au_do_pin(struct au_pin *pin) __must_check;
15243+void au_unpin(struct au_pin *pin);
1facf9fc 15244+
4a4d8108
AM
15245+/* i_op_add.c */
15246+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
15247+ struct dentry *h_parent, int isdir);
7eafdf33
AM
15248+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
15249+ dev_t dev);
4a4d8108 15250+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
7eafdf33 15251+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 15252+ bool want_excl);
4a4d8108
AM
15253+int aufs_link(struct dentry *src_dentry, struct inode *dir,
15254+ struct dentry *dentry);
7eafdf33 15255+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
1facf9fc 15256+
4a4d8108
AM
15257+/* i_op_del.c */
15258+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
15259+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
15260+ struct dentry *h_parent, int isdir);
15261+int aufs_unlink(struct inode *dir, struct dentry *dentry);
15262+int aufs_rmdir(struct inode *dir, struct dentry *dentry);
1308ab2a 15263+
4a4d8108
AM
15264+/* i_op_ren.c */
15265+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
15266+int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
15267+ struct inode *dir, struct dentry *dentry);
1facf9fc 15268+
4a4d8108
AM
15269+/* iinfo.c */
15270+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
15271+void au_hiput(struct au_hinode *hinode);
15272+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
15273+ struct dentry *h_wh);
15274+unsigned int au_hi_flags(struct inode *inode, int isdir);
1308ab2a 15275+
4a4d8108
AM
15276+/* hinode flags */
15277+#define AuHi_XINO 1
15278+#define AuHi_HNOTIFY (1 << 1)
15279+#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
7f207e10
AM
15280+#define au_fset_hi(flags, name) \
15281+ do { (flags) |= AuHi_##name; } while (0)
15282+#define au_fclr_hi(flags, name) \
15283+ do { (flags) &= ~AuHi_##name; } while (0)
1facf9fc 15284+
4a4d8108
AM
15285+#ifndef CONFIG_AUFS_HNOTIFY
15286+#undef AuHi_HNOTIFY
15287+#define AuHi_HNOTIFY 0
15288+#endif
1facf9fc 15289+
4a4d8108
AM
15290+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
15291+ struct inode *h_inode, unsigned int flags);
1facf9fc 15292+
537831f9 15293+void au_update_iigen(struct inode *inode, int half);
4a4d8108 15294+void au_update_ibrange(struct inode *inode, int do_put_zero);
1facf9fc 15295+
4a4d8108
AM
15296+void au_icntnr_init_once(void *_c);
15297+int au_iinfo_init(struct inode *inode);
15298+void au_iinfo_fin(struct inode *inode);
15299+int au_ii_realloc(struct au_iinfo *iinfo, int nbr);
1308ab2a 15300+
e49829fe 15301+#ifdef CONFIG_PROC_FS
4a4d8108 15302+/* plink.c */
e49829fe
JR
15303+int au_plink_maint(struct super_block *sb, int flags);
15304+void au_plink_maint_leave(struct au_sbinfo *sbinfo);
15305+int au_plink_maint_enter(struct super_block *sb);
4a4d8108
AM
15306+#ifdef CONFIG_AUFS_DEBUG
15307+void au_plink_list(struct super_block *sb);
15308+#else
15309+AuStubVoid(au_plink_list, struct super_block *sb)
15310+#endif
15311+int au_plink_test(struct inode *inode);
15312+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
15313+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
15314+ struct dentry *h_dentry);
e49829fe
JR
15315+void au_plink_put(struct super_block *sb, int verbose);
15316+void au_plink_clean(struct super_block *sb, int verbose);
4a4d8108 15317+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
e49829fe
JR
15318+#else
15319+AuStubInt0(au_plink_maint, struct super_block *sb, int flags);
15320+AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo);
15321+AuStubInt0(au_plink_maint_enter, struct super_block *sb);
15322+AuStubVoid(au_plink_list, struct super_block *sb);
15323+AuStubInt0(au_plink_test, struct inode *inode);
15324+AuStub(struct dentry *, au_plink_lkup, return NULL,
15325+ struct inode *inode, aufs_bindex_t bindex);
15326+AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex,
15327+ struct dentry *h_dentry);
15328+AuStubVoid(au_plink_put, struct super_block *sb, int verbose);
15329+AuStubVoid(au_plink_clean, struct super_block *sb, int verbose);
15330+AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id);
15331+#endif /* CONFIG_PROC_FS */
1facf9fc 15332+
4a4d8108 15333+/* ---------------------------------------------------------------------- */
1308ab2a 15334+
4a4d8108
AM
15335+/* lock subclass for iinfo */
15336+enum {
15337+ AuLsc_II_CHILD, /* child first */
15338+ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */
15339+ AuLsc_II_CHILD3, /* copyup dirs */
15340+ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
15341+ AuLsc_II_PARENT2,
15342+ AuLsc_II_PARENT3, /* copyup dirs */
15343+ AuLsc_II_NEW_CHILD
15344+};
1308ab2a 15345+
1facf9fc 15346+/*
4a4d8108
AM
15347+ * ii_read_lock_child, ii_write_lock_child,
15348+ * ii_read_lock_child2, ii_write_lock_child2,
15349+ * ii_read_lock_child3, ii_write_lock_child3,
15350+ * ii_read_lock_parent, ii_write_lock_parent,
15351+ * ii_read_lock_parent2, ii_write_lock_parent2,
15352+ * ii_read_lock_parent3, ii_write_lock_parent3,
15353+ * ii_read_lock_new_child, ii_write_lock_new_child,
1facf9fc 15354+ */
4a4d8108
AM
15355+#define AuReadLockFunc(name, lsc) \
15356+static inline void ii_read_lock_##name(struct inode *i) \
15357+{ \
15358+ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
15359+}
15360+
15361+#define AuWriteLockFunc(name, lsc) \
15362+static inline void ii_write_lock_##name(struct inode *i) \
15363+{ \
15364+ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
15365+}
15366+
15367+#define AuRWLockFuncs(name, lsc) \
15368+ AuReadLockFunc(name, lsc) \
15369+ AuWriteLockFunc(name, lsc)
15370+
15371+AuRWLockFuncs(child, CHILD);
15372+AuRWLockFuncs(child2, CHILD2);
15373+AuRWLockFuncs(child3, CHILD3);
15374+AuRWLockFuncs(parent, PARENT);
15375+AuRWLockFuncs(parent2, PARENT2);
15376+AuRWLockFuncs(parent3, PARENT3);
15377+AuRWLockFuncs(new_child, NEW_CHILD);
15378+
15379+#undef AuReadLockFunc
15380+#undef AuWriteLockFunc
15381+#undef AuRWLockFuncs
1facf9fc 15382+
15383+/*
4a4d8108 15384+ * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
1facf9fc 15385+ */
4a4d8108 15386+AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
1facf9fc 15387+
4a4d8108
AM
15388+#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
15389+#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
15390+#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
1facf9fc 15391+
4a4d8108 15392+/* ---------------------------------------------------------------------- */
1308ab2a 15393+
027c5e7a
AM
15394+static inline void au_icntnr_init(struct au_icntnr *c)
15395+{
15396+#ifdef CONFIG_AUFS_DEBUG
15397+ c->vfs_inode.i_mode = 0;
15398+#endif
15399+}
15400+
537831f9 15401+static inline unsigned int au_iigen(struct inode *inode, struct au_iigen *iigen)
4a4d8108 15402+{
537831f9
AM
15403+ unsigned int gen;
15404+ struct au_iinfo *iinfo;
15405+
15406+ iinfo = au_ii(inode);
15407+ spin_lock(&iinfo->ii_genspin);
15408+ if (iigen)
15409+ *iigen = iinfo->ii_generation;
15410+ gen = iinfo->ii_generation.ig_generation;
15411+ spin_unlock(&iinfo->ii_genspin);
15412+
15413+ return gen;
4a4d8108 15414+}
1308ab2a 15415+
4a4d8108
AM
15416+/* tiny test for inode number */
15417+/* tmpfs generation is too rough */
15418+static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
15419+{
15420+ struct au_iinfo *iinfo;
1308ab2a 15421+
4a4d8108
AM
15422+ iinfo = au_ii(inode);
15423+ AuRwMustAnyLock(&iinfo->ii_rwsem);
15424+ return !(iinfo->ii_hsb1 == h_inode->i_sb
15425+ && iinfo->ii_higen == h_inode->i_generation);
15426+}
1308ab2a 15427+
4a4d8108
AM
15428+static inline void au_iigen_dec(struct inode *inode)
15429+{
537831f9
AM
15430+ struct au_iinfo *iinfo;
15431+
15432+ iinfo = au_ii(inode);
15433+ spin_lock(&iinfo->ii_genspin);
15434+ iinfo->ii_generation.ig_generation--;
15435+ spin_unlock(&iinfo->ii_genspin);
027c5e7a
AM
15436+}
15437+
15438+static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
15439+{
15440+ int err;
15441+
15442+ err = 0;
537831f9 15443+ if (unlikely(inode && au_iigen(inode, NULL) != sigen))
027c5e7a
AM
15444+ err = -EIO;
15445+
15446+ return err;
4a4d8108 15447+}
1308ab2a 15448+
4a4d8108 15449+/* ---------------------------------------------------------------------- */
1308ab2a 15450+
4a4d8108
AM
15451+static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
15452+ aufs_bindex_t bindex)
15453+{
15454+ IiMustAnyLock(inode);
15455+ return au_ii(inode)->ii_hinode[0 + bindex].hi_id;
15456+}
1308ab2a 15457+
4a4d8108
AM
15458+static inline aufs_bindex_t au_ibstart(struct inode *inode)
15459+{
15460+ IiMustAnyLock(inode);
15461+ return au_ii(inode)->ii_bstart;
15462+}
1308ab2a 15463+
4a4d8108
AM
15464+static inline aufs_bindex_t au_ibend(struct inode *inode)
15465+{
15466+ IiMustAnyLock(inode);
15467+ return au_ii(inode)->ii_bend;
15468+}
1308ab2a 15469+
4a4d8108
AM
15470+static inline struct au_vdir *au_ivdir(struct inode *inode)
15471+{
15472+ IiMustAnyLock(inode);
15473+ return au_ii(inode)->ii_vdir;
15474+}
1308ab2a 15475+
4a4d8108
AM
15476+static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
15477+{
15478+ IiMustAnyLock(inode);
15479+ return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry;
15480+}
1308ab2a 15481+
4a4d8108 15482+static inline void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 15483+{
4a4d8108
AM
15484+ IiMustWriteLock(inode);
15485+ au_ii(inode)->ii_bstart = bindex;
15486+}
1308ab2a 15487+
4a4d8108
AM
15488+static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex)
15489+{
15490+ IiMustWriteLock(inode);
15491+ au_ii(inode)->ii_bend = bindex;
1308ab2a 15492+}
15493+
4a4d8108
AM
15494+static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
15495+{
15496+ IiMustWriteLock(inode);
15497+ au_ii(inode)->ii_vdir = vdir;
15498+}
1facf9fc 15499+
4a4d8108 15500+static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 15501+{
4a4d8108
AM
15502+ IiMustAnyLock(inode);
15503+ return au_ii(inode)->ii_hinode + bindex;
15504+}
dece6358 15505+
4a4d8108 15506+/* ---------------------------------------------------------------------- */
1facf9fc 15507+
4a4d8108
AM
15508+static inline struct dentry *au_pinned_parent(struct au_pin *pin)
15509+{
15510+ if (pin)
15511+ return pin->parent;
15512+ return NULL;
1facf9fc 15513+}
15514+
4a4d8108 15515+static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
1facf9fc 15516+{
4a4d8108
AM
15517+ if (pin && pin->hdir)
15518+ return pin->hdir->hi_inode;
15519+ return NULL;
1308ab2a 15520+}
1facf9fc 15521+
4a4d8108
AM
15522+static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
15523+{
15524+ if (pin)
15525+ return pin->hdir;
15526+ return NULL;
15527+}
1facf9fc 15528+
4a4d8108 15529+static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
1308ab2a 15530+{
4a4d8108
AM
15531+ if (pin)
15532+ pin->dentry = dentry;
15533+}
1308ab2a 15534+
4a4d8108
AM
15535+static inline void au_pin_set_parent_lflag(struct au_pin *pin,
15536+ unsigned char lflag)
15537+{
15538+ if (pin) {
7f207e10 15539+ if (lflag)
4a4d8108 15540+ au_fset_pin(pin->flags, DI_LOCKED);
7f207e10 15541+ else
4a4d8108 15542+ au_fclr_pin(pin->flags, DI_LOCKED);
1308ab2a 15543+ }
4a4d8108
AM
15544+}
15545+
15546+static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
15547+{
15548+ if (pin) {
15549+ dput(pin->parent);
15550+ pin->parent = dget(parent);
1facf9fc 15551+ }
4a4d8108 15552+}
1facf9fc 15553+
4a4d8108
AM
15554+/* ---------------------------------------------------------------------- */
15555+
027c5e7a 15556+struct au_branch;
4a4d8108
AM
15557+#ifdef CONFIG_AUFS_HNOTIFY
15558+struct au_hnotify_op {
15559+ void (*ctl)(struct au_hinode *hinode, int do_set);
027c5e7a 15560+ int (*alloc)(struct au_hinode *hinode);
7eafdf33
AM
15561+
15562+ /*
15563+ * if it returns true, the the caller should free hinode->hi_notify,
15564+ * otherwise ->free() frees it.
15565+ */
15566+ int (*free)(struct au_hinode *hinode,
15567+ struct au_hnotify *hn) __must_check;
4a4d8108
AM
15568+
15569+ void (*fin)(void);
15570+ int (*init)(void);
027c5e7a
AM
15571+
15572+ int (*reset_br)(unsigned int udba, struct au_branch *br, int perm);
15573+ void (*fin_br)(struct au_branch *br);
15574+ int (*init_br)(struct au_branch *br, int perm);
4a4d8108
AM
15575+};
15576+
15577+/* hnotify.c */
027c5e7a 15578+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
4a4d8108
AM
15579+void au_hn_free(struct au_hinode *hinode);
15580+void au_hn_ctl(struct au_hinode *hinode, int do_set);
15581+void au_hn_reset(struct inode *inode, unsigned int flags);
15582+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
15583+ struct qstr *h_child_qstr, struct inode *h_child_inode);
027c5e7a
AM
15584+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm);
15585+int au_hnotify_init_br(struct au_branch *br, int perm);
15586+void au_hnotify_fin_br(struct au_branch *br);
4a4d8108
AM
15587+int __init au_hnotify_init(void);
15588+void au_hnotify_fin(void);
15589+
7f207e10 15590+/* hfsnotify.c */
4a4d8108
AM
15591+extern const struct au_hnotify_op au_hnotify_op;
15592+
15593+static inline
15594+void au_hn_init(struct au_hinode *hinode)
15595+{
15596+ hinode->hi_notify = NULL;
1308ab2a 15597+}
15598+
53392da6
AM
15599+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
15600+{
15601+ return hinode->hi_notify;
15602+}
15603+
4a4d8108
AM
15604+#else
15605+static inline
15606+int au_hn_alloc(struct au_hinode *hinode __maybe_unused,
027c5e7a 15607+ struct inode *inode __maybe_unused)
1308ab2a 15608+{
4a4d8108
AM
15609+ return -EOPNOTSUPP;
15610+}
1308ab2a 15611+
53392da6
AM
15612+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
15613+{
15614+ return NULL;
15615+}
15616+
4a4d8108
AM
15617+AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused)
15618+AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused,
15619+ int do_set __maybe_unused)
15620+AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused,
15621+ unsigned int flags __maybe_unused)
027c5e7a
AM
15622+AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused,
15623+ struct au_branch *br __maybe_unused,
15624+ int perm __maybe_unused)
15625+AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused,
15626+ int perm __maybe_unused)
15627+AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused)
4a4d8108
AM
15628+AuStubInt0(__init au_hnotify_init, void)
15629+AuStubVoid(au_hnotify_fin, void)
15630+AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused)
15631+#endif /* CONFIG_AUFS_HNOTIFY */
15632+
15633+static inline void au_hn_suspend(struct au_hinode *hdir)
15634+{
15635+ au_hn_ctl(hdir, /*do_set*/0);
1308ab2a 15636+}
15637+
4a4d8108 15638+static inline void au_hn_resume(struct au_hinode *hdir)
1308ab2a 15639+{
4a4d8108
AM
15640+ au_hn_ctl(hdir, /*do_set*/1);
15641+}
1308ab2a 15642+
4a4d8108
AM
15643+static inline void au_hn_imtx_lock(struct au_hinode *hdir)
15644+{
15645+ mutex_lock(&hdir->hi_inode->i_mutex);
15646+ au_hn_suspend(hdir);
15647+}
dece6358 15648+
4a4d8108
AM
15649+static inline void au_hn_imtx_lock_nested(struct au_hinode *hdir,
15650+ unsigned int sc __maybe_unused)
15651+{
15652+ mutex_lock_nested(&hdir->hi_inode->i_mutex, sc);
15653+ au_hn_suspend(hdir);
1facf9fc 15654+}
1facf9fc 15655+
4a4d8108
AM
15656+static inline void au_hn_imtx_unlock(struct au_hinode *hdir)
15657+{
15658+ au_hn_resume(hdir);
15659+ mutex_unlock(&hdir->hi_inode->i_mutex);
15660+}
15661+
15662+#endif /* __KERNEL__ */
15663+#endif /* __AUFS_INODE_H__ */
7f207e10
AM
15664diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c
15665--- /usr/share/empty/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100
392086de 15666+++ linux/fs/aufs/ioctl.c 2013-10-26 16:51:32.276373845 +0200
c2b27bf2 15667@@ -0,0 +1,202 @@
4a4d8108 15668+/*
7a9e40b8 15669+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
15670+ *
15671+ * This program, aufs is free software; you can redistribute it and/or modify
15672+ * it under the terms of the GNU General Public License as published by
15673+ * the Free Software Foundation; either version 2 of the License, or
15674+ * (at your option) any later version.
15675+ *
15676+ * This program is distributed in the hope that it will be useful,
15677+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15678+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15679+ * GNU General Public License for more details.
15680+ *
15681+ * You should have received a copy of the GNU General Public License
15682+ * along with this program; if not, write to the Free Software
15683+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15684+ */
15685+
15686+/*
15687+ * ioctl
15688+ * plink-management and readdir in userspace.
15689+ * assist the pathconf(3) wrapper library.
c2b27bf2 15690+ * move-down
4a4d8108
AM
15691+ */
15692+
c2b27bf2
AM
15693+#include <linux/compat.h>
15694+#include <linux/file.h>
4a4d8108
AM
15695+#include "aufs.h"
15696+
1e00d052 15697+static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
4a4d8108
AM
15698+{
15699+ int err, fd;
15700+ aufs_bindex_t wbi, bindex, bend;
15701+ struct file *h_file;
15702+ struct super_block *sb;
15703+ struct dentry *root;
1e00d052
AM
15704+ struct au_branch *br;
15705+ struct aufs_wbr_fd wbrfd = {
15706+ .oflags = au_dir_roflags,
15707+ .brid = -1
15708+ };
15709+ const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY
15710+ | O_NOATIME | O_CLOEXEC;
4a4d8108 15711+
1e00d052
AM
15712+ AuDebugOn(wbrfd.oflags & ~valid);
15713+
15714+ if (arg) {
15715+ err = copy_from_user(&wbrfd, arg, sizeof(wbrfd));
15716+ if (unlikely(err)) {
15717+ err = -EFAULT;
15718+ goto out;
15719+ }
15720+
15721+ err = -EINVAL;
15722+ AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid);
15723+ wbrfd.oflags |= au_dir_roflags;
15724+ AuDbg("0%o\n", wbrfd.oflags);
15725+ if (unlikely(wbrfd.oflags & ~valid))
15726+ goto out;
15727+ }
15728+
15729+ fd = get_unused_fd();
15730+ err = fd;
15731+ if (unlikely(fd < 0))
4a4d8108 15732+ goto out;
4a4d8108 15733+
1e00d052 15734+ h_file = ERR_PTR(-EINVAL);
4a4d8108 15735+ wbi = 0;
1e00d052 15736+ br = NULL;
4a4d8108
AM
15737+ sb = path->dentry->d_sb;
15738+ root = sb->s_root;
15739+ aufs_read_lock(root, AuLock_IR);
1e00d052
AM
15740+ bend = au_sbend(sb);
15741+ if (wbrfd.brid >= 0) {
15742+ wbi = au_br_index(sb, wbrfd.brid);
15743+ if (unlikely(wbi < 0 || wbi > bend))
15744+ goto out_unlock;
15745+ }
15746+
15747+ h_file = ERR_PTR(-ENOENT);
15748+ br = au_sbr(sb, wbi);
15749+ if (!au_br_writable(br->br_perm)) {
15750+ if (arg)
15751+ goto out_unlock;
15752+
15753+ bindex = wbi + 1;
15754+ wbi = -1;
15755+ for (; bindex <= bend; bindex++) {
15756+ br = au_sbr(sb, bindex);
15757+ if (au_br_writable(br->br_perm)) {
4a4d8108 15758+ wbi = bindex;
1e00d052 15759+ br = au_sbr(sb, wbi);
4a4d8108
AM
15760+ break;
15761+ }
15762+ }
4a4d8108
AM
15763+ }
15764+ AuDbg("wbi %d\n", wbi);
1e00d052 15765+ if (wbi >= 0)
392086de
AM
15766+ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL,
15767+ /*force_wr*/0);
1e00d052
AM
15768+
15769+out_unlock:
4a4d8108
AM
15770+ aufs_read_unlock(root, AuLock_IR);
15771+ err = PTR_ERR(h_file);
15772+ if (IS_ERR(h_file))
15773+ goto out_fd;
15774+
1e00d052 15775+ atomic_dec(&br->br_count); /* cf. au_h_open() */
4a4d8108
AM
15776+ fd_install(fd, h_file);
15777+ err = fd;
15778+ goto out; /* success */
15779+
4f0767ce 15780+out_fd:
4a4d8108 15781+ put_unused_fd(fd);
4f0767ce 15782+out:
1e00d052 15783+ AuTraceErr(err);
4a4d8108
AM
15784+ return err;
15785+}
15786+
15787+/* ---------------------------------------------------------------------- */
15788+
15789+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
15790+{
15791+ long err;
15792+
15793+ switch (cmd) {
4a4d8108
AM
15794+ case AUFS_CTL_RDU:
15795+ case AUFS_CTL_RDU_INO:
15796+ err = au_rdu_ioctl(file, cmd, arg);
15797+ break;
15798+
15799+ case AUFS_CTL_WBR_FD:
1e00d052 15800+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
15801+ break;
15802+
027c5e7a
AM
15803+ case AUFS_CTL_IBUSY:
15804+ err = au_ibusy_ioctl(file, arg);
15805+ break;
15806+
4a4d8108
AM
15807+ default:
15808+ /* do not call the lower */
15809+ AuDbg("0x%x\n", cmd);
15810+ err = -ENOTTY;
15811+ }
15812+
15813+ AuTraceErr(err);
15814+ return err;
15815+}
15816+
15817+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
15818+{
15819+ long err;
15820+
15821+ switch (cmd) {
c2b27bf2 15822+ case AUFS_CTL_MVDOWN:
c2b27bf2
AM
15823+ err = au_mvdown(file->f_dentry, (void __user *)arg);
15824+ break;
15825+
4a4d8108 15826+ case AUFS_CTL_WBR_FD:
1e00d052 15827+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
15828+ break;
15829+
15830+ default:
15831+ /* do not call the lower */
15832+ AuDbg("0x%x\n", cmd);
15833+ err = -ENOTTY;
15834+ }
15835+
15836+ AuTraceErr(err);
15837+ return err;
15838+}
b752ccd1
AM
15839+
15840+#ifdef CONFIG_COMPAT
15841+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
15842+ unsigned long arg)
15843+{
15844+ long err;
15845+
15846+ switch (cmd) {
15847+ case AUFS_CTL_RDU:
15848+ case AUFS_CTL_RDU_INO:
15849+ err = au_rdu_compat_ioctl(file, cmd, arg);
15850+ break;
15851+
027c5e7a
AM
15852+ case AUFS_CTL_IBUSY:
15853+ err = au_ibusy_compat_ioctl(file, arg);
15854+ break;
15855+
b752ccd1
AM
15856+ default:
15857+ err = aufs_ioctl_dir(file, cmd, arg);
15858+ }
15859+
15860+ AuTraceErr(err);
15861+ return err;
15862+}
15863+
b752ccd1
AM
15864+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
15865+ unsigned long arg)
15866+{
15867+ return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg));
15868+}
15869+#endif
7f207e10
AM
15870diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
15871--- /usr/share/empty/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
392086de 15872+++ linux/fs/aufs/i_op_add.c 2013-10-26 16:51:32.273040419 +0200
c2b27bf2 15873@@ -0,0 +1,739 @@
4a4d8108 15874+/*
7a9e40b8 15875+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
15876+ *
15877+ * This program, aufs is free software; you can redistribute it and/or modify
15878+ * it under the terms of the GNU General Public License as published by
15879+ * the Free Software Foundation; either version 2 of the License, or
15880+ * (at your option) any later version.
15881+ *
15882+ * This program is distributed in the hope that it will be useful,
15883+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15884+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15885+ * GNU General Public License for more details.
15886+ *
15887+ * You should have received a copy of the GNU General Public License
15888+ * along with this program; if not, write to the Free Software
15889+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15890+ */
15891+
15892+/*
15893+ * inode operations (add entry)
15894+ */
15895+
15896+#include "aufs.h"
15897+
15898+/*
15899+ * final procedure of adding a new entry, except link(2).
15900+ * remove whiteout, instantiate, copyup the parent dir's times and size
15901+ * and update version.
15902+ * if it failed, re-create the removed whiteout.
15903+ */
15904+static int epilog(struct inode *dir, aufs_bindex_t bindex,
15905+ struct dentry *wh_dentry, struct dentry *dentry)
15906+{
15907+ int err, rerr;
15908+ aufs_bindex_t bwh;
15909+ struct path h_path;
15910+ struct inode *inode, *h_dir;
15911+ struct dentry *wh;
15912+
15913+ bwh = -1;
15914+ if (wh_dentry) {
15915+ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
15916+ IMustLock(h_dir);
15917+ AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
15918+ bwh = au_dbwh(dentry);
15919+ h_path.dentry = wh_dentry;
15920+ h_path.mnt = au_sbr_mnt(dir->i_sb, bindex);
15921+ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
15922+ dentry);
15923+ if (unlikely(err))
15924+ goto out;
15925+ }
15926+
15927+ inode = au_new_inode(dentry, /*must_new*/1);
15928+ if (!IS_ERR(inode)) {
15929+ d_instantiate(dentry, inode);
15930+ dir = dentry->d_parent->d_inode; /* dir inode is locked */
15931+ IMustLock(dir);
15932+ if (au_ibstart(dir) == au_dbstart(dentry))
15933+ au_cpup_attr_timesizes(dir);
15934+ dir->i_version++;
15935+ return 0; /* success */
15936+ }
15937+
15938+ err = PTR_ERR(inode);
15939+ if (!wh_dentry)
15940+ goto out;
15941+
15942+ /* revert */
15943+ /* dir inode is locked */
15944+ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
15945+ rerr = PTR_ERR(wh);
15946+ if (IS_ERR(wh)) {
15947+ AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
15948+ AuDLNPair(dentry), err, rerr);
15949+ err = -EIO;
15950+ } else
15951+ dput(wh);
15952+
4f0767ce 15953+out:
4a4d8108
AM
15954+ return err;
15955+}
15956+
027c5e7a
AM
15957+static int au_d_may_add(struct dentry *dentry)
15958+{
15959+ int err;
15960+
15961+ err = 0;
15962+ if (unlikely(d_unhashed(dentry)))
15963+ err = -ENOENT;
15964+ if (unlikely(dentry->d_inode))
15965+ err = -EEXIST;
15966+ return err;
15967+}
15968+
4a4d8108
AM
15969+/*
15970+ * simple tests for the adding inode operations.
15971+ * following the checks in vfs, plus the parent-child relationship.
15972+ */
15973+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
15974+ struct dentry *h_parent, int isdir)
15975+{
15976+ int err;
15977+ umode_t h_mode;
15978+ struct dentry *h_dentry;
15979+ struct inode *h_inode;
15980+
15981+ err = -ENAMETOOLONG;
15982+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
15983+ goto out;
15984+
15985+ h_dentry = au_h_dptr(dentry, bindex);
15986+ h_inode = h_dentry->d_inode;
15987+ if (!dentry->d_inode) {
15988+ err = -EEXIST;
15989+ if (unlikely(h_inode))
15990+ goto out;
15991+ } else {
15992+ /* rename(2) case */
15993+ err = -EIO;
15994+ if (unlikely(!h_inode || !h_inode->i_nlink))
15995+ goto out;
15996+
15997+ h_mode = h_inode->i_mode;
15998+ if (!isdir) {
15999+ err = -EISDIR;
16000+ if (unlikely(S_ISDIR(h_mode)))
16001+ goto out;
16002+ } else if (unlikely(!S_ISDIR(h_mode))) {
16003+ err = -ENOTDIR;
16004+ goto out;
16005+ }
16006+ }
16007+
16008+ err = 0;
16009+ /* expected parent dir is locked */
16010+ if (unlikely(h_parent != h_dentry->d_parent))
16011+ err = -EIO;
16012+
4f0767ce 16013+out:
4a4d8108
AM
16014+ AuTraceErr(err);
16015+ return err;
16016+}
16017+
16018+/*
16019+ * initial procedure of adding a new entry.
16020+ * prepare writable branch and the parent dir, lock it,
16021+ * and lookup whiteout for the new entry.
16022+ */
16023+static struct dentry*
16024+lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
16025+ struct dentry *src_dentry, struct au_pin *pin,
16026+ struct au_wr_dir_args *wr_dir_args)
16027+{
16028+ struct dentry *wh_dentry, *h_parent;
16029+ struct super_block *sb;
16030+ struct au_branch *br;
16031+ int err;
16032+ unsigned int udba;
16033+ aufs_bindex_t bcpup;
16034+
16035+ AuDbg("%.*s\n", AuDLNPair(dentry));
16036+
16037+ err = au_wr_dir(dentry, src_dentry, wr_dir_args);
16038+ bcpup = err;
16039+ wh_dentry = ERR_PTR(err);
16040+ if (unlikely(err < 0))
16041+ goto out;
16042+
16043+ sb = dentry->d_sb;
16044+ udba = au_opt_udba(sb);
16045+ err = au_pin(pin, dentry, bcpup, udba,
16046+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
16047+ wh_dentry = ERR_PTR(err);
16048+ if (unlikely(err))
16049+ goto out;
16050+
16051+ h_parent = au_pinned_h_parent(pin);
16052+ if (udba != AuOpt_UDBA_NONE
16053+ && au_dbstart(dentry) == bcpup)
16054+ err = au_may_add(dentry, bcpup, h_parent,
16055+ au_ftest_wrdir(wr_dir_args->flags, ISDIR));
16056+ else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
16057+ err = -ENAMETOOLONG;
16058+ wh_dentry = ERR_PTR(err);
16059+ if (unlikely(err))
16060+ goto out_unpin;
16061+
16062+ br = au_sbr(sb, bcpup);
16063+ if (dt) {
16064+ struct path tmp = {
16065+ .dentry = h_parent,
86dc4139 16066+ .mnt = au_br_mnt(br)
4a4d8108
AM
16067+ };
16068+ au_dtime_store(dt, au_pinned_parent(pin), &tmp);
16069+ }
16070+
16071+ wh_dentry = NULL;
16072+ if (bcpup != au_dbwh(dentry))
16073+ goto out; /* success */
16074+
16075+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
16076+
4f0767ce 16077+out_unpin:
4a4d8108
AM
16078+ if (IS_ERR(wh_dentry))
16079+ au_unpin(pin);
4f0767ce 16080+out:
4a4d8108
AM
16081+ return wh_dentry;
16082+}
16083+
16084+/* ---------------------------------------------------------------------- */
16085+
16086+enum { Mknod, Symlink, Creat };
16087+struct simple_arg {
16088+ int type;
16089+ union {
16090+ struct {
7eafdf33 16091+ umode_t mode;
b4510431 16092+ bool want_excl;
4a4d8108
AM
16093+ } c;
16094+ struct {
16095+ const char *symname;
16096+ } s;
16097+ struct {
7eafdf33 16098+ umode_t mode;
4a4d8108
AM
16099+ dev_t dev;
16100+ } m;
16101+ } u;
16102+};
16103+
16104+static int add_simple(struct inode *dir, struct dentry *dentry,
16105+ struct simple_arg *arg)
16106+{
16107+ int err;
16108+ aufs_bindex_t bstart;
16109+ unsigned char created;
4a4d8108
AM
16110+ struct dentry *wh_dentry, *parent;
16111+ struct inode *h_dir;
c2b27bf2
AM
16112+ /* to reuduce stack size */
16113+ struct {
16114+ struct au_dtime dt;
16115+ struct au_pin pin;
16116+ struct path h_path;
16117+ struct au_wr_dir_args wr_dir_args;
16118+ } *a;
4a4d8108
AM
16119+
16120+ AuDbg("%.*s\n", AuDLNPair(dentry));
16121+ IMustLock(dir);
16122+
c2b27bf2
AM
16123+ err = -ENOMEM;
16124+ a = kmalloc(sizeof(*a), GFP_NOFS);
16125+ if (unlikely(!a))
16126+ goto out;
16127+ a->wr_dir_args.force_btgt = -1;
16128+ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY;
16129+
4a4d8108 16130+ parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
16131+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
16132+ if (unlikely(err))
c2b27bf2 16133+ goto out_free;
027c5e7a
AM
16134+ err = au_d_may_add(dentry);
16135+ if (unlikely(err))
16136+ goto out_unlock;
4a4d8108 16137+ di_write_lock_parent(parent);
c2b27bf2
AM
16138+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
16139+ &a->pin, &a->wr_dir_args);
4a4d8108
AM
16140+ err = PTR_ERR(wh_dentry);
16141+ if (IS_ERR(wh_dentry))
027c5e7a 16142+ goto out_parent;
4a4d8108
AM
16143+
16144+ bstart = au_dbstart(dentry);
c2b27bf2
AM
16145+ a->h_path.dentry = au_h_dptr(dentry, bstart);
16146+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
16147+ h_dir = au_pinned_h_dir(&a->pin);
4a4d8108
AM
16148+ switch (arg->type) {
16149+ case Creat:
c2b27bf2 16150+ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode,
537831f9 16151+ arg->u.c.want_excl);
4a4d8108
AM
16152+ break;
16153+ case Symlink:
c2b27bf2 16154+ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname);
4a4d8108
AM
16155+ break;
16156+ case Mknod:
c2b27bf2
AM
16157+ err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode,
16158+ arg->u.m.dev);
4a4d8108
AM
16159+ break;
16160+ default:
16161+ BUG();
16162+ }
16163+ created = !err;
16164+ if (!err)
16165+ err = epilog(dir, bstart, wh_dentry, dentry);
16166+
16167+ /* revert */
c2b27bf2 16168+ if (unlikely(created && err && a->h_path.dentry->d_inode)) {
4a4d8108 16169+ int rerr;
c2b27bf2 16170+ rerr = vfsub_unlink(h_dir, &a->h_path, /*force*/0);
4a4d8108
AM
16171+ if (rerr) {
16172+ AuIOErr("%.*s revert failure(%d, %d)\n",
16173+ AuDLNPair(dentry), err, rerr);
16174+ err = -EIO;
16175+ }
c2b27bf2 16176+ au_dtime_revert(&a->dt);
4a4d8108
AM
16177+ }
16178+
c2b27bf2 16179+ au_unpin(&a->pin);
4a4d8108
AM
16180+ dput(wh_dentry);
16181+
027c5e7a
AM
16182+out_parent:
16183+ di_write_unlock(parent);
16184+out_unlock:
4a4d8108
AM
16185+ if (unlikely(err)) {
16186+ au_update_dbstart(dentry);
16187+ d_drop(dentry);
16188+ }
4a4d8108 16189+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
16190+out_free:
16191+ kfree(a);
027c5e7a 16192+out:
4a4d8108
AM
16193+ return err;
16194+}
16195+
7eafdf33
AM
16196+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
16197+ dev_t dev)
4a4d8108
AM
16198+{
16199+ struct simple_arg arg = {
16200+ .type = Mknod,
16201+ .u.m = {
16202+ .mode = mode,
16203+ .dev = dev
16204+ }
16205+ };
16206+ return add_simple(dir, dentry, &arg);
16207+}
16208+
16209+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
16210+{
16211+ struct simple_arg arg = {
16212+ .type = Symlink,
16213+ .u.s.symname = symname
16214+ };
16215+ return add_simple(dir, dentry, &arg);
16216+}
16217+
7eafdf33 16218+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 16219+ bool want_excl)
4a4d8108
AM
16220+{
16221+ struct simple_arg arg = {
16222+ .type = Creat,
16223+ .u.c = {
b4510431
AM
16224+ .mode = mode,
16225+ .want_excl = want_excl
4a4d8108
AM
16226+ }
16227+ };
16228+ return add_simple(dir, dentry, &arg);
16229+}
16230+
16231+/* ---------------------------------------------------------------------- */
16232+
16233+struct au_link_args {
16234+ aufs_bindex_t bdst, bsrc;
16235+ struct au_pin pin;
16236+ struct path h_path;
16237+ struct dentry *src_parent, *parent;
16238+};
16239+
16240+static int au_cpup_before_link(struct dentry *src_dentry,
16241+ struct au_link_args *a)
16242+{
16243+ int err;
16244+ struct dentry *h_src_dentry;
c2b27bf2
AM
16245+ struct au_cp_generic cpg = {
16246+ .dentry = src_dentry,
16247+ .bdst = a->bdst,
16248+ .bsrc = a->bsrc,
16249+ .len = -1,
16250+ .pin = &a->pin,
16251+ .flags = AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */
16252+ };
4a4d8108
AM
16253+
16254+ di_read_lock_parent(a->src_parent, AuLock_IR);
16255+ err = au_test_and_cpup_dirs(src_dentry, a->bdst);
16256+ if (unlikely(err))
16257+ goto out;
16258+
16259+ h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
4a4d8108
AM
16260+ err = au_pin(&a->pin, src_dentry, a->bdst,
16261+ au_opt_udba(src_dentry->d_sb),
16262+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
16263+ if (unlikely(err))
16264+ goto out;
367653fa 16265+
c2b27bf2 16266+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
16267+ au_unpin(&a->pin);
16268+
4f0767ce 16269+out:
4a4d8108
AM
16270+ di_read_unlock(a->src_parent, AuLock_IR);
16271+ return err;
16272+}
16273+
86dc4139
AM
16274+static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry,
16275+ struct au_link_args *a)
4a4d8108
AM
16276+{
16277+ int err;
16278+ unsigned char plink;
86dc4139 16279+ aufs_bindex_t bend;
4a4d8108 16280+ struct dentry *h_src_dentry;
86dc4139 16281+ struct inode *h_inode, *inode;
4a4d8108
AM
16282+ struct super_block *sb;
16283+ struct file *h_file;
16284+
16285+ plink = 0;
16286+ h_inode = NULL;
16287+ sb = src_dentry->d_sb;
16288+ inode = src_dentry->d_inode;
16289+ if (au_ibstart(inode) <= a->bdst)
16290+ h_inode = au_h_iptr(inode, a->bdst);
16291+ if (!h_inode || !h_inode->i_nlink) {
16292+ /* copyup src_dentry as the name of dentry. */
86dc4139
AM
16293+ bend = au_dbend(dentry);
16294+ if (bend < a->bsrc)
16295+ au_set_dbend(dentry, a->bsrc);
16296+ au_set_h_dptr(dentry, a->bsrc,
16297+ dget(au_h_dptr(src_dentry, a->bsrc)));
16298+ dget(a->h_path.dentry);
16299+ au_set_h_dptr(dentry, a->bdst, NULL);
16300+ dentry->d_inode = src_dentry->d_inode; /* tmp */
392086de 16301+ h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0);
86dc4139 16302+ if (IS_ERR(h_file))
4a4d8108 16303+ err = PTR_ERR(h_file);
86dc4139 16304+ else {
c2b27bf2
AM
16305+ struct au_cp_generic cpg = {
16306+ .dentry = dentry,
16307+ .bdst = a->bdst,
16308+ .bsrc = -1,
16309+ .len = -1,
16310+ .pin = &a->pin,
16311+ .flags = AuCpup_KEEPLINO
16312+ };
16313+ err = au_sio_cpup_simple(&cpg);
86dc4139
AM
16314+ au_h_open_post(dentry, a->bsrc, h_file);
16315+ if (!err) {
16316+ dput(a->h_path.dentry);
16317+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
16318+ } else
16319+ au_set_h_dptr(dentry, a->bdst,
16320+ a->h_path.dentry);
16321+ }
16322+ dentry->d_inode = NULL; /* restore */
16323+ au_set_h_dptr(dentry, a->bsrc, NULL);
16324+ au_set_dbend(dentry, bend);
4a4d8108
AM
16325+ } else {
16326+ /* the inode of src_dentry already exists on a.bdst branch */
16327+ h_src_dentry = d_find_alias(h_inode);
16328+ if (!h_src_dentry && au_plink_test(inode)) {
16329+ plink = 1;
16330+ h_src_dentry = au_plink_lkup(inode, a->bdst);
16331+ err = PTR_ERR(h_src_dentry);
16332+ if (IS_ERR(h_src_dentry))
16333+ goto out;
16334+
16335+ if (unlikely(!h_src_dentry->d_inode)) {
16336+ dput(h_src_dentry);
16337+ h_src_dentry = NULL;
16338+ }
16339+
16340+ }
16341+ if (h_src_dentry) {
16342+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
16343+ &a->h_path);
16344+ dput(h_src_dentry);
16345+ } else {
16346+ AuIOErr("no dentry found for hi%lu on b%d\n",
16347+ h_inode->i_ino, a->bdst);
16348+ err = -EIO;
16349+ }
16350+ }
16351+
16352+ if (!err && !plink)
16353+ au_plink_append(inode, a->bdst, a->h_path.dentry);
16354+
16355+out:
2cbb1c4b 16356+ AuTraceErr(err);
4a4d8108
AM
16357+ return err;
16358+}
16359+
16360+int aufs_link(struct dentry *src_dentry, struct inode *dir,
16361+ struct dentry *dentry)
16362+{
16363+ int err, rerr;
16364+ struct au_dtime dt;
16365+ struct au_link_args *a;
16366+ struct dentry *wh_dentry, *h_src_dentry;
16367+ struct inode *inode;
16368+ struct super_block *sb;
16369+ struct au_wr_dir_args wr_dir_args = {
16370+ /* .force_btgt = -1, */
16371+ .flags = AuWrDir_ADD_ENTRY
16372+ };
16373+
16374+ IMustLock(dir);
16375+ inode = src_dentry->d_inode;
16376+ IMustLock(inode);
16377+
4a4d8108
AM
16378+ err = -ENOMEM;
16379+ a = kzalloc(sizeof(*a), GFP_NOFS);
16380+ if (unlikely(!a))
16381+ goto out;
16382+
16383+ a->parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
16384+ err = aufs_read_and_write_lock2(dentry, src_dentry,
16385+ AuLock_NOPLM | AuLock_GEN);
e49829fe
JR
16386+ if (unlikely(err))
16387+ goto out_kfree;
027c5e7a
AM
16388+ err = au_d_hashed_positive(src_dentry);
16389+ if (unlikely(err))
16390+ goto out_unlock;
16391+ err = au_d_may_add(dentry);
16392+ if (unlikely(err))
16393+ goto out_unlock;
e49829fe 16394+
4a4d8108 16395+ a->src_parent = dget_parent(src_dentry);
2cbb1c4b 16396+ wr_dir_args.force_btgt = au_ibstart(inode);
4a4d8108
AM
16397+
16398+ di_write_lock_parent(a->parent);
16399+ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
16400+ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
16401+ &wr_dir_args);
16402+ err = PTR_ERR(wh_dentry);
16403+ if (IS_ERR(wh_dentry))
027c5e7a 16404+ goto out_parent;
4a4d8108
AM
16405+
16406+ err = 0;
16407+ sb = dentry->d_sb;
16408+ a->bdst = au_dbstart(dentry);
16409+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
16410+ a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
2cbb1c4b
JR
16411+ a->bsrc = au_ibstart(inode);
16412+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
16413+ if (!h_src_dentry) {
16414+ a->bsrc = au_dbstart(src_dentry);
16415+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
16416+ AuDebugOn(!h_src_dentry);
16417+ } else if (IS_ERR(h_src_dentry))
16418+ goto out_parent;
16419+
4a4d8108
AM
16420+ if (au_opt_test(au_mntflags(sb), PLINK)) {
16421+ if (a->bdst < a->bsrc
16422+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
86dc4139 16423+ err = au_cpup_or_link(src_dentry, dentry, a);
2cbb1c4b 16424+ else
4a4d8108
AM
16425+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
16426+ &a->h_path);
2cbb1c4b 16427+ dput(h_src_dentry);
4a4d8108
AM
16428+ } else {
16429+ /*
16430+ * copyup src_dentry to the branch we process,
16431+ * and then link(2) to it.
16432+ */
2cbb1c4b 16433+ dput(h_src_dentry);
4a4d8108
AM
16434+ if (a->bdst < a->bsrc
16435+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
16436+ au_unpin(&a->pin);
16437+ di_write_unlock(a->parent);
16438+ err = au_cpup_before_link(src_dentry, a);
16439+ di_write_lock_parent(a->parent);
16440+ if (!err)
16441+ err = au_pin(&a->pin, dentry, a->bdst,
16442+ au_opt_udba(sb),
16443+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
16444+ if (unlikely(err))
16445+ goto out_wh;
16446+ }
16447+ if (!err) {
16448+ h_src_dentry = au_h_dptr(src_dentry, a->bdst);
16449+ err = -ENOENT;
16450+ if (h_src_dentry && h_src_dentry->d_inode)
16451+ err = vfsub_link(h_src_dentry,
16452+ au_pinned_h_dir(&a->pin),
16453+ &a->h_path);
16454+ }
16455+ }
16456+ if (unlikely(err))
16457+ goto out_unpin;
16458+
16459+ if (wh_dentry) {
16460+ a->h_path.dentry = wh_dentry;
16461+ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
16462+ dentry);
16463+ if (unlikely(err))
16464+ goto out_revert;
16465+ }
16466+
16467+ dir->i_version++;
16468+ if (au_ibstart(dir) == au_dbstart(dentry))
16469+ au_cpup_attr_timesizes(dir);
16470+ inc_nlink(inode);
16471+ inode->i_ctime = dir->i_ctime;
027c5e7a
AM
16472+ d_instantiate(dentry, au_igrab(inode));
16473+ if (d_unhashed(a->h_path.dentry))
4a4d8108
AM
16474+ /* some filesystem calls d_drop() */
16475+ d_drop(dentry);
16476+ goto out_unpin; /* success */
16477+
4f0767ce 16478+out_revert:
4a4d8108 16479+ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path, /*force*/0);
027c5e7a
AM
16480+ if (unlikely(rerr)) {
16481+ AuIOErr("%.*s reverting failed(%d, %d)\n",
16482+ AuDLNPair(dentry), err, rerr);
16483+ err = -EIO;
16484+ }
4a4d8108 16485+ au_dtime_revert(&dt);
4f0767ce 16486+out_unpin:
4a4d8108 16487+ au_unpin(&a->pin);
4f0767ce 16488+out_wh:
4a4d8108 16489+ dput(wh_dentry);
027c5e7a
AM
16490+out_parent:
16491+ di_write_unlock(a->parent);
16492+ dput(a->src_parent);
4f0767ce 16493+out_unlock:
4a4d8108
AM
16494+ if (unlikely(err)) {
16495+ au_update_dbstart(dentry);
16496+ d_drop(dentry);
16497+ }
4a4d8108 16498+ aufs_read_and_write_unlock2(dentry, src_dentry);
e49829fe 16499+out_kfree:
4a4d8108 16500+ kfree(a);
4f0767ce 16501+out:
86dc4139 16502+ AuTraceErr(err);
4a4d8108
AM
16503+ return err;
16504+}
16505+
7eafdf33 16506+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
4a4d8108
AM
16507+{
16508+ int err, rerr;
16509+ aufs_bindex_t bindex;
16510+ unsigned char diropq;
16511+ struct path h_path;
16512+ struct dentry *wh_dentry, *parent, *opq_dentry;
16513+ struct mutex *h_mtx;
16514+ struct super_block *sb;
16515+ struct {
16516+ struct au_pin pin;
16517+ struct au_dtime dt;
16518+ } *a; /* reduce the stack usage */
16519+ struct au_wr_dir_args wr_dir_args = {
16520+ .force_btgt = -1,
16521+ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
16522+ };
16523+
16524+ IMustLock(dir);
16525+
16526+ err = -ENOMEM;
16527+ a = kmalloc(sizeof(*a), GFP_NOFS);
16528+ if (unlikely(!a))
16529+ goto out;
16530+
027c5e7a
AM
16531+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
16532+ if (unlikely(err))
16533+ goto out_free;
16534+ err = au_d_may_add(dentry);
16535+ if (unlikely(err))
16536+ goto out_unlock;
16537+
4a4d8108
AM
16538+ parent = dentry->d_parent; /* dir inode is locked */
16539+ di_write_lock_parent(parent);
16540+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
16541+ &a->pin, &wr_dir_args);
16542+ err = PTR_ERR(wh_dentry);
16543+ if (IS_ERR(wh_dentry))
027c5e7a 16544+ goto out_parent;
4a4d8108
AM
16545+
16546+ sb = dentry->d_sb;
16547+ bindex = au_dbstart(dentry);
16548+ h_path.dentry = au_h_dptr(dentry, bindex);
16549+ h_path.mnt = au_sbr_mnt(sb, bindex);
16550+ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
16551+ if (unlikely(err))
027c5e7a 16552+ goto out_unpin;
4a4d8108
AM
16553+
16554+ /* make the dir opaque */
16555+ diropq = 0;
16556+ h_mtx = &h_path.dentry->d_inode->i_mutex;
16557+ if (wh_dentry
16558+ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
16559+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
16560+ opq_dentry = au_diropq_create(dentry, bindex);
16561+ mutex_unlock(h_mtx);
16562+ err = PTR_ERR(opq_dentry);
16563+ if (IS_ERR(opq_dentry))
16564+ goto out_dir;
16565+ dput(opq_dentry);
16566+ diropq = 1;
16567+ }
16568+
16569+ err = epilog(dir, bindex, wh_dentry, dentry);
16570+ if (!err) {
16571+ inc_nlink(dir);
027c5e7a 16572+ goto out_unpin; /* success */
4a4d8108
AM
16573+ }
16574+
16575+ /* revert */
16576+ if (diropq) {
16577+ AuLabel(revert opq);
16578+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
16579+ rerr = au_diropq_remove(dentry, bindex);
16580+ mutex_unlock(h_mtx);
16581+ if (rerr) {
16582+ AuIOErr("%.*s reverting diropq failed(%d, %d)\n",
16583+ AuDLNPair(dentry), err, rerr);
16584+ err = -EIO;
16585+ }
16586+ }
16587+
4f0767ce 16588+out_dir:
4a4d8108
AM
16589+ AuLabel(revert dir);
16590+ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
16591+ if (rerr) {
16592+ AuIOErr("%.*s reverting dir failed(%d, %d)\n",
16593+ AuDLNPair(dentry), err, rerr);
16594+ err = -EIO;
16595+ }
4a4d8108 16596+ au_dtime_revert(&a->dt);
027c5e7a 16597+out_unpin:
4a4d8108
AM
16598+ au_unpin(&a->pin);
16599+ dput(wh_dentry);
027c5e7a
AM
16600+out_parent:
16601+ di_write_unlock(parent);
16602+out_unlock:
4a4d8108
AM
16603+ if (unlikely(err)) {
16604+ au_update_dbstart(dentry);
16605+ d_drop(dentry);
16606+ }
4a4d8108 16607+ aufs_read_unlock(dentry, AuLock_DW);
027c5e7a 16608+out_free:
4a4d8108 16609+ kfree(a);
4f0767ce 16610+out:
4a4d8108
AM
16611+ return err;
16612+}
7f207e10
AM
16613diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
16614--- /usr/share/empty/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
16615+++ linux/fs/aufs/i_op.c 2013-10-26 16:51:32.273040419 +0200
16616@@ -0,0 +1,1118 @@
4a4d8108 16617+/*
7a9e40b8 16618+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
16619+ *
16620+ * This program, aufs is free software; you can redistribute it and/or modify
16621+ * it under the terms of the GNU General Public License as published by
16622+ * the Free Software Foundation; either version 2 of the License, or
16623+ * (at your option) any later version.
16624+ *
16625+ * This program is distributed in the hope that it will be useful,
16626+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16627+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16628+ * GNU General Public License for more details.
16629+ *
16630+ * You should have received a copy of the GNU General Public License
16631+ * along with this program; if not, write to the Free Software
16632+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16633+ */
1facf9fc 16634+
1308ab2a 16635+/*
4a4d8108 16636+ * inode operations (except add/del/rename)
1308ab2a 16637+ */
4a4d8108
AM
16638+
16639+#include <linux/device_cgroup.h>
16640+#include <linux/fs_stack.h>
92d182d2 16641+#include <linux/mm.h>
4a4d8108
AM
16642+#include <linux/namei.h>
16643+#include <linux/security.h>
4a4d8108
AM
16644+#include "aufs.h"
16645+
1e00d052 16646+static int h_permission(struct inode *h_inode, int mask,
4a4d8108 16647+ struct vfsmount *h_mnt, int brperm)
1facf9fc 16648+{
1308ab2a 16649+ int err;
4a4d8108 16650+ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
1facf9fc 16651+
4a4d8108
AM
16652+ err = -EACCES;
16653+ if ((write_mask && IS_IMMUTABLE(h_inode))
16654+ || ((mask & MAY_EXEC)
16655+ && S_ISREG(h_inode->i_mode)
16656+ && ((h_mnt->mnt_flags & MNT_NOEXEC)
16657+ || !(h_inode->i_mode & S_IXUGO))))
16658+ goto out;
16659+
16660+ /*
16661+ * - skip the lower fs test in the case of write to ro branch.
16662+ * - nfs dir permission write check is optimized, but a policy for
16663+ * link/rename requires a real check.
16664+ */
16665+ if ((write_mask && !au_br_writable(brperm))
16666+ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
16667+ && write_mask && !(mask & MAY_READ))
16668+ || !h_inode->i_op->permission) {
16669+ /* AuLabel(generic_permission); */
1e00d052 16670+ err = generic_permission(h_inode, mask);
1308ab2a 16671+ } else {
4a4d8108 16672+ /* AuLabel(h_inode->permission); */
1e00d052 16673+ err = h_inode->i_op->permission(h_inode, mask);
4a4d8108
AM
16674+ AuTraceErr(err);
16675+ }
1facf9fc 16676+
4a4d8108
AM
16677+ if (!err)
16678+ err = devcgroup_inode_permission(h_inode, mask);
7f207e10 16679+ if (!err)
4a4d8108 16680+ err = security_inode_permission(h_inode, mask);
4a4d8108
AM
16681+
16682+#if 0
16683+ if (!err) {
16684+ /* todo: do we need to call ima_path_check()? */
16685+ struct path h_path = {
16686+ .dentry =
16687+ .mnt = h_mnt
16688+ };
16689+ err = ima_path_check(&h_path,
16690+ mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
16691+ IMA_COUNT_LEAVE);
1308ab2a 16692+ }
4a4d8108 16693+#endif
dece6358 16694+
4f0767ce 16695+out:
1308ab2a 16696+ return err;
16697+}
dece6358 16698+
1e00d052 16699+static int aufs_permission(struct inode *inode, int mask)
1308ab2a 16700+{
16701+ int err;
4a4d8108
AM
16702+ aufs_bindex_t bindex, bend;
16703+ const unsigned char isdir = !!S_ISDIR(inode->i_mode),
16704+ write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
16705+ struct inode *h_inode;
16706+ struct super_block *sb;
16707+ struct au_branch *br;
1facf9fc 16708+
027c5e7a 16709+ /* todo: support rcu-walk? */
1e00d052 16710+ if (mask & MAY_NOT_BLOCK)
027c5e7a
AM
16711+ return -ECHILD;
16712+
4a4d8108
AM
16713+ sb = inode->i_sb;
16714+ si_read_lock(sb, AuLock_FLUSH);
16715+ ii_read_lock_child(inode);
027c5e7a
AM
16716+#if 0
16717+ err = au_iigen_test(inode, au_sigen(sb));
16718+ if (unlikely(err))
16719+ goto out;
16720+#endif
dece6358 16721+
4a4d8108
AM
16722+ if (!isdir || write_mask) {
16723+ err = au_busy_or_stale();
16724+ h_inode = au_h_iptr(inode, au_ibstart(inode));
16725+ if (unlikely(!h_inode
16726+ || (h_inode->i_mode & S_IFMT)
16727+ != (inode->i_mode & S_IFMT)))
16728+ goto out;
1facf9fc 16729+
4a4d8108
AM
16730+ err = 0;
16731+ bindex = au_ibstart(inode);
16732+ br = au_sbr(sb, bindex);
86dc4139 16733+ err = h_permission(h_inode, mask, au_br_mnt(br), br->br_perm);
4a4d8108
AM
16734+ if (write_mask
16735+ && !err
16736+ && !special_file(h_inode->i_mode)) {
16737+ /* test whether the upper writable branch exists */
16738+ err = -EROFS;
16739+ for (; bindex >= 0; bindex--)
16740+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
16741+ err = 0;
16742+ break;
16743+ }
16744+ }
16745+ goto out;
16746+ }
dece6358 16747+
4a4d8108 16748+ /* non-write to dir */
1308ab2a 16749+ err = 0;
4a4d8108
AM
16750+ bend = au_ibend(inode);
16751+ for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) {
16752+ h_inode = au_h_iptr(inode, bindex);
16753+ if (h_inode) {
16754+ err = au_busy_or_stale();
16755+ if (unlikely(!S_ISDIR(h_inode->i_mode)))
16756+ break;
16757+
16758+ br = au_sbr(sb, bindex);
86dc4139 16759+ err = h_permission(h_inode, mask, au_br_mnt(br),
4a4d8108
AM
16760+ br->br_perm);
16761+ }
16762+ }
1308ab2a 16763+
4f0767ce 16764+out:
4a4d8108
AM
16765+ ii_read_unlock(inode);
16766+ si_read_unlock(sb);
1308ab2a 16767+ return err;
16768+}
16769+
4a4d8108 16770+/* ---------------------------------------------------------------------- */
1facf9fc 16771+
4a4d8108 16772+static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
b4510431 16773+ unsigned int flags)
4a4d8108
AM
16774+{
16775+ struct dentry *ret, *parent;
b752ccd1 16776+ struct inode *inode;
4a4d8108 16777+ struct super_block *sb;
1716fcea 16778+ int err, npositive;
dece6358 16779+
4a4d8108 16780+ IMustLock(dir);
1308ab2a 16781+
537831f9
AM
16782+ /* todo: support rcu-walk? */
16783+ ret = ERR_PTR(-ECHILD);
16784+ if (flags & LOOKUP_RCU)
16785+ goto out;
16786+
16787+ ret = ERR_PTR(-ENAMETOOLONG);
16788+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
16789+ goto out;
16790+
4a4d8108 16791+ sb = dir->i_sb;
7f207e10
AM
16792+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
16793+ ret = ERR_PTR(err);
16794+ if (unlikely(err))
16795+ goto out;
16796+
4a4d8108
AM
16797+ err = au_di_init(dentry);
16798+ ret = ERR_PTR(err);
16799+ if (unlikely(err))
7f207e10 16800+ goto out_si;
1308ab2a 16801+
9dbd164d 16802+ inode = NULL;
027c5e7a 16803+ npositive = 0; /* suppress a warning */
4a4d8108
AM
16804+ parent = dentry->d_parent; /* dir inode is locked */
16805+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
16806+ err = au_alive_dir(parent);
16807+ if (!err)
16808+ err = au_digen_test(parent, au_sigen(sb));
16809+ if (!err) {
16810+ npositive = au_lkup_dentry(dentry, au_dbstart(parent),
537831f9 16811+ /*type*/0);
027c5e7a
AM
16812+ err = npositive;
16813+ }
4a4d8108 16814+ di_read_unlock(parent, AuLock_IR);
4a4d8108
AM
16815+ ret = ERR_PTR(err);
16816+ if (unlikely(err < 0))
16817+ goto out_unlock;
1308ab2a 16818+
4a4d8108 16819+ if (npositive) {
b752ccd1 16820+ inode = au_new_inode(dentry, /*must_new*/0);
4a4d8108 16821+ ret = (void *)inode;
1facf9fc 16822+ }
9dbd164d
AM
16823+ if (IS_ERR(inode)) {
16824+ inode = NULL;
4a4d8108 16825+ goto out_unlock;
9dbd164d 16826+ }
4a4d8108
AM
16827+
16828+ ret = d_splice_alias(inode, dentry);
537831f9
AM
16829+#if 0
16830+ if (unlikely(d_need_lookup(dentry))) {
16831+ spin_lock(&dentry->d_lock);
16832+ dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
16833+ spin_unlock(&dentry->d_lock);
16834+ } else
16835+#endif
7f207e10 16836+ if (unlikely(IS_ERR(ret) && inode)) {
4a4d8108 16837+ ii_write_unlock(inode);
7f207e10 16838+ iput(inode);
2dfbb274 16839+ inode = NULL;
7f207e10 16840+ }
1facf9fc 16841+
4f0767ce 16842+out_unlock:
4a4d8108 16843+ di_write_unlock(dentry);
2dfbb274 16844+ if (inode) {
1716fcea
AM
16845+ /* verbose coding for lock class name */
16846+ if (unlikely(S_ISLNK(inode->i_mode)))
16847+ au_rw_class(&au_di(dentry)->di_rwsem,
16848+ au_lc_key + AuLcSymlink_DIINFO);
16849+ else if (unlikely(S_ISDIR(inode->i_mode)))
16850+ au_rw_class(&au_di(dentry)->di_rwsem,
16851+ au_lc_key + AuLcDir_DIINFO);
16852+ else /* likely */
16853+ au_rw_class(&au_di(dentry)->di_rwsem,
16854+ au_lc_key + AuLcNonDir_DIINFO);
9dbd164d 16855+ }
7f207e10 16856+out_si:
4a4d8108 16857+ si_read_unlock(sb);
7f207e10 16858+out:
4a4d8108
AM
16859+ return ret;
16860+}
1facf9fc 16861+
4a4d8108 16862+/* ---------------------------------------------------------------------- */
1facf9fc 16863+
4a4d8108
AM
16864+static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
16865+ const unsigned char add_entry, aufs_bindex_t bcpup,
16866+ aufs_bindex_t bstart)
16867+{
16868+ int err;
16869+ struct dentry *h_parent;
16870+ struct inode *h_dir;
1facf9fc 16871+
027c5e7a 16872+ if (add_entry)
4a4d8108 16873+ IMustLock(parent->d_inode);
027c5e7a 16874+ else
4a4d8108
AM
16875+ di_write_lock_parent(parent);
16876+
16877+ err = 0;
16878+ if (!au_h_dptr(parent, bcpup)) {
c2b27bf2
AM
16879+ if (bstart > bcpup)
16880+ err = au_cpup_dirs(dentry, bcpup);
16881+ else if (bstart < bcpup)
4a4d8108
AM
16882+ err = au_cpdown_dirs(dentry, bcpup);
16883+ else
c2b27bf2 16884+ BUG();
4a4d8108
AM
16885+ }
16886+ if (!err && add_entry) {
16887+ h_parent = au_h_dptr(parent, bcpup);
16888+ h_dir = h_parent->d_inode;
16889+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
86dc4139
AM
16890+ err = au_lkup_neg(dentry, bcpup,
16891+ au_ftest_wrdir(add_entry, TMP_WHENTRY));
4a4d8108
AM
16892+ /* todo: no unlock here */
16893+ mutex_unlock(&h_dir->i_mutex);
027c5e7a
AM
16894+
16895+ AuDbg("bcpup %d\n", bcpup);
16896+ if (!err) {
16897+ if (!dentry->d_inode)
16898+ au_set_h_dptr(dentry, bstart, NULL);
4a4d8108
AM
16899+ au_update_dbrange(dentry, /*do_put_zero*/0);
16900+ }
1308ab2a 16901+ }
1facf9fc 16902+
4a4d8108
AM
16903+ if (!add_entry)
16904+ di_write_unlock(parent);
16905+ if (!err)
16906+ err = bcpup; /* success */
1308ab2a 16907+
027c5e7a 16908+ AuTraceErr(err);
4a4d8108
AM
16909+ return err;
16910+}
1facf9fc 16911+
4a4d8108
AM
16912+/*
16913+ * decide the branch and the parent dir where we will create a new entry.
16914+ * returns new bindex or an error.
16915+ * copyup the parent dir if needed.
16916+ */
16917+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
16918+ struct au_wr_dir_args *args)
16919+{
16920+ int err;
392086de 16921+ unsigned int flags;
4a4d8108 16922+ aufs_bindex_t bcpup, bstart, src_bstart;
86dc4139
AM
16923+ const unsigned char add_entry
16924+ = au_ftest_wrdir(args->flags, ADD_ENTRY)
16925+ | au_ftest_wrdir(args->flags, TMP_WHENTRY);
4a4d8108
AM
16926+ struct super_block *sb;
16927+ struct dentry *parent;
16928+ struct au_sbinfo *sbinfo;
1facf9fc 16929+
4a4d8108
AM
16930+ sb = dentry->d_sb;
16931+ sbinfo = au_sbi(sb);
16932+ parent = dget_parent(dentry);
16933+ bstart = au_dbstart(dentry);
16934+ bcpup = bstart;
16935+ if (args->force_btgt < 0) {
16936+ if (src_dentry) {
16937+ src_bstart = au_dbstart(src_dentry);
16938+ if (src_bstart < bstart)
16939+ bcpup = src_bstart;
16940+ } else if (add_entry) {
392086de
AM
16941+ flags = 0;
16942+ if (au_ftest_wrdir(args->flags, ISDIR))
16943+ au_fset_wbr(flags, DIR);
16944+ err = AuWbrCreate(sbinfo, dentry, flags);
4a4d8108
AM
16945+ bcpup = err;
16946+ }
1facf9fc 16947+
4a4d8108
AM
16948+ if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) {
16949+ if (add_entry)
16950+ err = AuWbrCopyup(sbinfo, dentry);
16951+ else {
16952+ if (!IS_ROOT(dentry)) {
16953+ di_read_lock_parent(parent, !AuLock_IR);
16954+ err = AuWbrCopyup(sbinfo, dentry);
16955+ di_read_unlock(parent, !AuLock_IR);
16956+ } else
16957+ err = AuWbrCopyup(sbinfo, dentry);
16958+ }
16959+ bcpup = err;
16960+ if (unlikely(err < 0))
16961+ goto out;
16962+ }
16963+ } else {
16964+ bcpup = args->force_btgt;
16965+ AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode));
1308ab2a 16966+ }
027c5e7a 16967+
4a4d8108
AM
16968+ AuDbg("bstart %d, bcpup %d\n", bstart, bcpup);
16969+ err = bcpup;
16970+ if (bcpup == bstart)
16971+ goto out; /* success */
4a4d8108
AM
16972+
16973+ /* copyup the new parent into the branch we process */
16974+ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart);
027c5e7a
AM
16975+ if (err >= 0) {
16976+ if (!dentry->d_inode) {
16977+ au_set_h_dptr(dentry, bstart, NULL);
16978+ au_set_dbstart(dentry, bcpup);
16979+ au_set_dbend(dentry, bcpup);
16980+ }
16981+ AuDebugOn(add_entry && !au_h_dptr(dentry, bcpup));
16982+ }
86dc4139
AM
16983+
16984+out:
16985+ dput(parent);
16986+ return err;
16987+}
16988+
16989+/* ---------------------------------------------------------------------- */
16990+
16991+void au_pin_hdir_unlock(struct au_pin *p)
16992+{
16993+ if (p->hdir)
16994+ au_hn_imtx_unlock(p->hdir);
16995+}
16996+
16997+static int au_pin_hdir_lock(struct au_pin *p)
16998+{
16999+ int err;
17000+
17001+ err = 0;
17002+ if (!p->hdir)
17003+ goto out;
17004+
17005+ /* even if an error happens later, keep this lock */
17006+ au_hn_imtx_lock_nested(p->hdir, p->lsc_hi);
17007+
17008+ err = -EBUSY;
17009+ if (unlikely(p->hdir->hi_inode != p->h_parent->d_inode))
17010+ goto out;
17011+
17012+ err = 0;
17013+ if (p->h_dentry)
17014+ err = au_h_verify(p->h_dentry, p->udba, p->hdir->hi_inode,
17015+ p->h_parent, p->br);
17016+
17017+out:
17018+ return err;
17019+}
17020+
17021+int au_pin_hdir_relock(struct au_pin *p)
17022+{
17023+ int err, i;
17024+ struct inode *h_i;
17025+ struct dentry *h_d[] = {
17026+ p->h_dentry,
17027+ p->h_parent
17028+ };
17029+
17030+ err = au_pin_hdir_lock(p);
17031+ if (unlikely(err))
17032+ goto out;
17033+
17034+ for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) {
17035+ if (!h_d[i])
17036+ continue;
17037+ h_i = h_d[i]->d_inode;
17038+ if (h_i)
17039+ err = !h_i->i_nlink;
17040+ }
17041+
17042+out:
17043+ return err;
17044+}
17045+
17046+void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task)
17047+{
17048+#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP)
17049+ p->hdir->hi_inode->i_mutex.owner = task;
17050+#endif
17051+}
17052+
17053+void au_pin_hdir_acquire_nest(struct au_pin *p)
17054+{
17055+ if (p->hdir) {
17056+ mutex_acquire_nest(&p->hdir->hi_inode->i_mutex.dep_map,
17057+ p->lsc_hi, 0, NULL, _RET_IP_);
17058+ au_pin_hdir_set_owner(p, current);
17059+ }
dece6358 17060+}
1facf9fc 17061+
86dc4139
AM
17062+void au_pin_hdir_release(struct au_pin *p)
17063+{
17064+ if (p->hdir) {
17065+ au_pin_hdir_set_owner(p, p->task);
17066+ mutex_release(&p->hdir->hi_inode->i_mutex.dep_map, 1, _RET_IP_);
17067+ }
17068+}
1308ab2a 17069+
4a4d8108 17070+struct dentry *au_pinned_h_parent(struct au_pin *pin)
1308ab2a 17071+{
4a4d8108
AM
17072+ if (pin && pin->parent)
17073+ return au_h_dptr(pin->parent, pin->bindex);
17074+ return NULL;
dece6358 17075+}
1facf9fc 17076+
4a4d8108 17077+void au_unpin(struct au_pin *p)
dece6358 17078+{
86dc4139
AM
17079+ if (p->hdir)
17080+ au_pin_hdir_unlock(p);
e49829fe 17081+ if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE))
b4510431 17082+ vfsub_mnt_drop_write(p->h_mnt);
4a4d8108
AM
17083+ if (!p->hdir)
17084+ return;
1facf9fc 17085+
4a4d8108
AM
17086+ if (!au_ftest_pin(p->flags, DI_LOCKED))
17087+ di_read_unlock(p->parent, AuLock_IR);
17088+ iput(p->hdir->hi_inode);
17089+ dput(p->parent);
17090+ p->parent = NULL;
17091+ p->hdir = NULL;
17092+ p->h_mnt = NULL;
86dc4139 17093+ /* do not clear p->task */
4a4d8108 17094+}
1308ab2a 17095+
4a4d8108
AM
17096+int au_do_pin(struct au_pin *p)
17097+{
17098+ int err;
17099+ struct super_block *sb;
4a4d8108
AM
17100+ struct inode *h_dir;
17101+
17102+ err = 0;
17103+ sb = p->dentry->d_sb;
86dc4139 17104+ p->br = au_sbr(sb, p->bindex);
4a4d8108
AM
17105+ if (IS_ROOT(p->dentry)) {
17106+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 17107+ p->h_mnt = au_br_mnt(p->br);
b4510431 17108+ err = vfsub_mnt_want_write(p->h_mnt);
4a4d8108
AM
17109+ if (unlikely(err)) {
17110+ au_fclr_pin(p->flags, MNT_WRITE);
17111+ goto out_err;
17112+ }
17113+ }
dece6358 17114+ goto out;
1facf9fc 17115+ }
17116+
86dc4139 17117+ p->h_dentry = NULL;
4a4d8108 17118+ if (p->bindex <= au_dbend(p->dentry))
86dc4139 17119+ p->h_dentry = au_h_dptr(p->dentry, p->bindex);
dece6358 17120+
4a4d8108
AM
17121+ p->parent = dget_parent(p->dentry);
17122+ if (!au_ftest_pin(p->flags, DI_LOCKED))
17123+ di_read_lock(p->parent, AuLock_IR, p->lsc_di);
dece6358 17124+
4a4d8108 17125+ h_dir = NULL;
86dc4139 17126+ p->h_parent = au_h_dptr(p->parent, p->bindex);
4a4d8108
AM
17127+ p->hdir = au_hi(p->parent->d_inode, p->bindex);
17128+ if (p->hdir)
17129+ h_dir = p->hdir->hi_inode;
dece6358 17130+
b752ccd1
AM
17131+ /*
17132+ * udba case, or
17133+ * if DI_LOCKED is not set, then p->parent may be different
17134+ * and h_parent can be NULL.
17135+ */
86dc4139 17136+ if (unlikely(!p->hdir || !h_dir || !p->h_parent)) {
e49829fe 17137+ err = -EBUSY;
4a4d8108
AM
17138+ if (!au_ftest_pin(p->flags, DI_LOCKED))
17139+ di_read_unlock(p->parent, AuLock_IR);
17140+ dput(p->parent);
17141+ p->parent = NULL;
17142+ goto out_err;
17143+ }
1308ab2a 17144+
4a4d8108 17145+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 17146+ p->h_mnt = au_br_mnt(p->br);
b4510431 17147+ err = vfsub_mnt_want_write(p->h_mnt);
dece6358 17148+ if (unlikely(err)) {
4a4d8108 17149+ au_fclr_pin(p->flags, MNT_WRITE);
86dc4139
AM
17150+ if (!au_ftest_pin(p->flags, DI_LOCKED))
17151+ di_read_unlock(p->parent, AuLock_IR);
17152+ dput(p->parent);
17153+ p->parent = NULL;
17154+ goto out_err;
dece6358
AM
17155+ }
17156+ }
4a4d8108 17157+
86dc4139
AM
17158+ au_igrab(h_dir);
17159+ err = au_pin_hdir_lock(p);
17160+ if (!err)
17161+ goto out; /* success */
17162+
4f0767ce 17163+out_err:
4a4d8108
AM
17164+ pr_err("err %d\n", err);
17165+ err = au_busy_or_stale();
4f0767ce 17166+out:
1facf9fc 17167+ return err;
17168+}
17169+
4a4d8108
AM
17170+void au_pin_init(struct au_pin *p, struct dentry *dentry,
17171+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
17172+ unsigned int udba, unsigned char flags)
17173+{
17174+ p->dentry = dentry;
17175+ p->udba = udba;
17176+ p->lsc_di = lsc_di;
17177+ p->lsc_hi = lsc_hi;
17178+ p->flags = flags;
17179+ p->bindex = bindex;
17180+
17181+ p->parent = NULL;
17182+ p->hdir = NULL;
17183+ p->h_mnt = NULL;
86dc4139
AM
17184+
17185+ p->h_dentry = NULL;
17186+ p->h_parent = NULL;
17187+ p->br = NULL;
17188+ p->task = current;
4a4d8108
AM
17189+}
17190+
17191+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
17192+ unsigned int udba, unsigned char flags)
17193+{
17194+ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
17195+ udba, flags);
17196+ return au_do_pin(pin);
17197+}
17198+
dece6358
AM
17199+/* ---------------------------------------------------------------------- */
17200+
1308ab2a 17201+/*
4a4d8108
AM
17202+ * ->setattr() and ->getattr() are called in various cases.
17203+ * chmod, stat: dentry is revalidated.
17204+ * fchmod, fstat: file and dentry are not revalidated, additionally they may be
17205+ * unhashed.
17206+ * for ->setattr(), ia->ia_file is passed from ftruncate only.
1308ab2a 17207+ */
027c5e7a 17208+/* todo: consolidate with do_refresh() and simple_reval_dpath() */
4a4d8108 17209+static int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
1facf9fc 17210+{
4a4d8108
AM
17211+ int err;
17212+ struct inode *inode;
17213+ struct dentry *parent;
1facf9fc 17214+
1308ab2a 17215+ err = 0;
4a4d8108 17216+ inode = dentry->d_inode;
027c5e7a 17217+ if (au_digen_test(dentry, sigen)) {
4a4d8108
AM
17218+ parent = dget_parent(dentry);
17219+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 17220+ err = au_refresh_dentry(dentry, parent);
4a4d8108
AM
17221+ di_read_unlock(parent, AuLock_IR);
17222+ dput(parent);
dece6358 17223+ }
1facf9fc 17224+
4a4d8108 17225+ AuTraceErr(err);
1308ab2a 17226+ return err;
17227+}
dece6358 17228+
4a4d8108
AM
17229+#define AuIcpup_DID_CPUP 1
17230+#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
7f207e10
AM
17231+#define au_fset_icpup(flags, name) \
17232+ do { (flags) |= AuIcpup_##name; } while (0)
17233+#define au_fclr_icpup(flags, name) \
17234+ do { (flags) &= ~AuIcpup_##name; } while (0)
1308ab2a 17235+
4a4d8108
AM
17236+struct au_icpup_args {
17237+ unsigned char flags;
17238+ unsigned char pin_flags;
17239+ aufs_bindex_t btgt;
17240+ unsigned int udba;
17241+ struct au_pin pin;
17242+ struct path h_path;
17243+ struct inode *h_inode;
17244+};
1308ab2a 17245+
4a4d8108
AM
17246+static int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
17247+ struct au_icpup_args *a)
1308ab2a 17248+{
17249+ int err;
4a4d8108 17250+ loff_t sz;
e49829fe 17251+ aufs_bindex_t bstart, ibstart;
4a4d8108
AM
17252+ struct dentry *hi_wh, *parent;
17253+ struct inode *inode;
4a4d8108
AM
17254+ struct au_wr_dir_args wr_dir_args = {
17255+ .force_btgt = -1,
17256+ .flags = 0
17257+ };
17258+
17259+ bstart = au_dbstart(dentry);
17260+ inode = dentry->d_inode;
17261+ if (S_ISDIR(inode->i_mode))
17262+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
17263+ /* plink or hi_wh() case */
e49829fe 17264+ ibstart = au_ibstart(inode);
027c5e7a 17265+ if (bstart != ibstart && !au_test_ro(inode->i_sb, ibstart, inode))
e49829fe 17266+ wr_dir_args.force_btgt = ibstart;
4a4d8108
AM
17267+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
17268+ if (unlikely(err < 0))
17269+ goto out;
17270+ a->btgt = err;
17271+ if (err != bstart)
17272+ au_fset_icpup(a->flags, DID_CPUP);
17273+
17274+ err = 0;
17275+ a->pin_flags = AuPin_MNT_WRITE;
17276+ parent = NULL;
17277+ if (!IS_ROOT(dentry)) {
17278+ au_fset_pin(a->pin_flags, DI_LOCKED);
17279+ parent = dget_parent(dentry);
17280+ di_write_lock_parent(parent);
17281+ }
17282+
17283+ err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags);
17284+ if (unlikely(err))
17285+ goto out_parent;
17286+
17287+ a->h_path.dentry = au_h_dptr(dentry, bstart);
17288+ a->h_inode = a->h_path.dentry->d_inode;
17289+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
17290+ sz = -1;
17291+ if ((ia->ia_valid & ATTR_SIZE) && ia->ia_size < i_size_read(a->h_inode))
17292+ sz = ia->ia_size;
86dc4139 17293+ mutex_unlock(&a->h_inode->i_mutex);
4a4d8108 17294+
4a4d8108 17295+ hi_wh = NULL;
027c5e7a 17296+ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) {
4a4d8108
AM
17297+ hi_wh = au_hi_wh(inode, a->btgt);
17298+ if (!hi_wh) {
c2b27bf2
AM
17299+ struct au_cp_generic cpg = {
17300+ .dentry = dentry,
17301+ .bdst = a->btgt,
17302+ .bsrc = -1,
17303+ .len = sz,
17304+ .pin = &a->pin
17305+ };
17306+ err = au_sio_cpup_wh(&cpg, /*file*/NULL);
4a4d8108
AM
17307+ if (unlikely(err))
17308+ goto out_unlock;
17309+ hi_wh = au_hi_wh(inode, a->btgt);
17310+ /* todo: revalidate hi_wh? */
17311+ }
17312+ }
17313+
17314+ if (parent) {
17315+ au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
17316+ di_downgrade_lock(parent, AuLock_IR);
17317+ dput(parent);
17318+ parent = NULL;
17319+ }
17320+ if (!au_ftest_icpup(a->flags, DID_CPUP))
17321+ goto out; /* success */
17322+
17323+ if (!d_unhashed(dentry)) {
c2b27bf2
AM
17324+ struct au_cp_generic cpg = {
17325+ .dentry = dentry,
17326+ .bdst = a->btgt,
17327+ .bsrc = bstart,
17328+ .len = sz,
17329+ .pin = &a->pin,
17330+ .flags = AuCpup_DTIME | AuCpup_HOPEN
17331+ };
17332+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
17333+ if (!err)
17334+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
17335+ } else if (!hi_wh)
17336+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
17337+ else
17338+ a->h_path.dentry = hi_wh; /* do not dget here */
1308ab2a 17339+
4f0767ce 17340+out_unlock:
4a4d8108 17341+ a->h_inode = a->h_path.dentry->d_inode;
86dc4139 17342+ if (!err)
dece6358 17343+ goto out; /* success */
4a4d8108 17344+ au_unpin(&a->pin);
4f0767ce 17345+out_parent:
4a4d8108
AM
17346+ if (parent) {
17347+ di_write_unlock(parent);
17348+ dput(parent);
17349+ }
4f0767ce 17350+out:
86dc4139
AM
17351+ if (!err)
17352+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
1facf9fc 17353+ return err;
17354+}
17355+
4a4d8108 17356+static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
1facf9fc 17357+{
4a4d8108
AM
17358+ int err;
17359+ struct inode *inode;
17360+ struct super_block *sb;
17361+ struct file *file;
17362+ struct au_icpup_args *a;
1facf9fc 17363+
4a4d8108
AM
17364+ inode = dentry->d_inode;
17365+ IMustLock(inode);
dece6358 17366+
4a4d8108
AM
17367+ err = -ENOMEM;
17368+ a = kzalloc(sizeof(*a), GFP_NOFS);
17369+ if (unlikely(!a))
17370+ goto out;
1facf9fc 17371+
4a4d8108
AM
17372+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
17373+ ia->ia_valid &= ~ATTR_MODE;
dece6358 17374+
4a4d8108
AM
17375+ file = NULL;
17376+ sb = dentry->d_sb;
e49829fe
JR
17377+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
17378+ if (unlikely(err))
17379+ goto out_kfree;
17380+
4a4d8108
AM
17381+ if (ia->ia_valid & ATTR_FILE) {
17382+ /* currently ftruncate(2) only */
17383+ AuDebugOn(!S_ISREG(inode->i_mode));
17384+ file = ia->ia_file;
17385+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
17386+ if (unlikely(err))
17387+ goto out_si;
17388+ ia->ia_file = au_hf_top(file);
17389+ a->udba = AuOpt_UDBA_NONE;
17390+ } else {
17391+ /* fchmod() doesn't pass ia_file */
17392+ a->udba = au_opt_udba(sb);
027c5e7a
AM
17393+ di_write_lock_child(dentry);
17394+ /* no d_unlinked(), to set UDBA_NONE for root */
4a4d8108
AM
17395+ if (d_unhashed(dentry))
17396+ a->udba = AuOpt_UDBA_NONE;
4a4d8108
AM
17397+ if (a->udba != AuOpt_UDBA_NONE) {
17398+ AuDebugOn(IS_ROOT(dentry));
17399+ err = au_reval_for_attr(dentry, au_sigen(sb));
17400+ if (unlikely(err))
17401+ goto out_dentry;
17402+ }
dece6358 17403+ }
dece6358 17404+
4a4d8108
AM
17405+ err = au_pin_and_icpup(dentry, ia, a);
17406+ if (unlikely(err < 0))
17407+ goto out_dentry;
17408+ if (au_ftest_icpup(a->flags, DID_CPUP)) {
17409+ ia->ia_file = NULL;
17410+ ia->ia_valid &= ~ATTR_FILE;
1308ab2a 17411+ }
dece6358 17412+
4a4d8108
AM
17413+ a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
17414+ if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME))
17415+ == (ATTR_MODE | ATTR_CTIME)) {
7eafdf33 17416+ err = security_path_chmod(&a->h_path, ia->ia_mode);
4a4d8108
AM
17417+ if (unlikely(err))
17418+ goto out_unlock;
17419+ } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
17420+ && (ia->ia_valid & ATTR_CTIME)) {
86dc4139 17421+ err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid);
4a4d8108
AM
17422+ if (unlikely(err))
17423+ goto out_unlock;
17424+ }
dece6358 17425+
4a4d8108
AM
17426+ if (ia->ia_valid & ATTR_SIZE) {
17427+ struct file *f;
1308ab2a 17428+
953406b4 17429+ if (ia->ia_size < i_size_read(inode))
4a4d8108 17430+ /* unmap only */
953406b4 17431+ truncate_setsize(inode, ia->ia_size);
1308ab2a 17432+
4a4d8108
AM
17433+ f = NULL;
17434+ if (ia->ia_valid & ATTR_FILE)
17435+ f = ia->ia_file;
17436+ mutex_unlock(&a->h_inode->i_mutex);
17437+ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
17438+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
17439+ } else
17440+ err = vfsub_notify_change(&a->h_path, ia);
17441+ if (!err)
17442+ au_cpup_attr_changeable(inode);
1308ab2a 17443+
4f0767ce 17444+out_unlock:
4a4d8108
AM
17445+ mutex_unlock(&a->h_inode->i_mutex);
17446+ au_unpin(&a->pin);
027c5e7a
AM
17447+ if (unlikely(err))
17448+ au_update_dbstart(dentry);
4f0767ce 17449+out_dentry:
4a4d8108
AM
17450+ di_write_unlock(dentry);
17451+ if (file) {
17452+ fi_write_unlock(file);
17453+ ia->ia_file = file;
17454+ ia->ia_valid |= ATTR_FILE;
17455+ }
4f0767ce 17456+out_si:
4a4d8108 17457+ si_read_unlock(sb);
e49829fe 17458+out_kfree:
4a4d8108 17459+ kfree(a);
4f0767ce 17460+out:
4a4d8108
AM
17461+ AuTraceErr(err);
17462+ return err;
1facf9fc 17463+}
17464+
4a4d8108
AM
17465+static void au_refresh_iattr(struct inode *inode, struct kstat *st,
17466+ unsigned int nlink)
1facf9fc 17467+{
9dbd164d
AM
17468+ unsigned int n;
17469+
4a4d8108 17470+ inode->i_mode = st->mode;
86dc4139
AM
17471+ /* don't i_[ug]id_write() here */
17472+ inode->i_uid = st->uid;
17473+ inode->i_gid = st->gid;
4a4d8108
AM
17474+ inode->i_atime = st->atime;
17475+ inode->i_mtime = st->mtime;
17476+ inode->i_ctime = st->ctime;
1facf9fc 17477+
4a4d8108
AM
17478+ au_cpup_attr_nlink(inode, /*force*/0);
17479+ if (S_ISDIR(inode->i_mode)) {
9dbd164d
AM
17480+ n = inode->i_nlink;
17481+ n -= nlink;
17482+ n += st->nlink;
86dc4139 17483+ smp_mb();
7eafdf33 17484+ /* 0 can happen */
92d182d2 17485+ set_nlink(inode, n);
4a4d8108 17486+ }
1facf9fc 17487+
4a4d8108
AM
17488+ spin_lock(&inode->i_lock);
17489+ inode->i_blocks = st->blocks;
17490+ i_size_write(inode, st->size);
17491+ spin_unlock(&inode->i_lock);
1facf9fc 17492+}
17493+
4a4d8108
AM
17494+static int aufs_getattr(struct vfsmount *mnt __maybe_unused,
17495+ struct dentry *dentry, struct kstat *st)
1facf9fc 17496+{
4a4d8108
AM
17497+ int err;
17498+ unsigned int mnt_flags;
17499+ aufs_bindex_t bindex;
17500+ unsigned char udba_none, positive;
17501+ struct super_block *sb, *h_sb;
17502+ struct inode *inode;
c06a8ce3 17503+ struct path h_path;
1facf9fc 17504+
4a4d8108
AM
17505+ sb = dentry->d_sb;
17506+ inode = dentry->d_inode;
7f207e10
AM
17507+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
17508+ if (unlikely(err))
17509+ goto out;
4a4d8108
AM
17510+ mnt_flags = au_mntflags(sb);
17511+ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
1facf9fc 17512+
4a4d8108 17513+ /* support fstat(2) */
027c5e7a 17514+ if (!d_unlinked(dentry) && !udba_none) {
4a4d8108 17515+ unsigned int sigen = au_sigen(sb);
027c5e7a
AM
17516+ err = au_digen_test(dentry, sigen);
17517+ if (!err) {
4a4d8108 17518+ di_read_lock_child(dentry, AuLock_IR);
027c5e7a
AM
17519+ err = au_dbrange_test(dentry);
17520+ if (unlikely(err))
17521+ goto out_unlock;
17522+ } else {
4a4d8108
AM
17523+ AuDebugOn(IS_ROOT(dentry));
17524+ di_write_lock_child(dentry);
027c5e7a
AM
17525+ err = au_dbrange_test(dentry);
17526+ if (!err)
17527+ err = au_reval_for_attr(dentry, sigen);
4a4d8108
AM
17528+ di_downgrade_lock(dentry, AuLock_IR);
17529+ if (unlikely(err))
7f207e10 17530+ goto out_unlock;
4a4d8108
AM
17531+ }
17532+ } else
17533+ di_read_lock_child(dentry, AuLock_IR);
1facf9fc 17534+
4a4d8108 17535+ bindex = au_ibstart(inode);
c06a8ce3
AM
17536+ h_path.mnt = au_sbr_mnt(sb, bindex);
17537+ h_sb = h_path.mnt->mnt_sb;
4a4d8108
AM
17538+ if (!au_test_fs_bad_iattr(h_sb) && udba_none)
17539+ goto out_fill; /* success */
1facf9fc 17540+
c06a8ce3 17541+ h_path.dentry = NULL;
4a4d8108 17542+ if (au_dbstart(dentry) == bindex)
c06a8ce3 17543+ h_path.dentry = dget(au_h_dptr(dentry, bindex));
4a4d8108 17544+ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
c06a8ce3
AM
17545+ h_path.dentry = au_plink_lkup(inode, bindex);
17546+ if (IS_ERR(h_path.dentry))
4a4d8108
AM
17547+ goto out_fill; /* pretending success */
17548+ }
17549+ /* illegally overlapped or something */
c06a8ce3 17550+ if (unlikely(!h_path.dentry))
4a4d8108
AM
17551+ goto out_fill; /* pretending success */
17552+
c06a8ce3 17553+ positive = !!h_path.dentry->d_inode;
4a4d8108 17554+ if (positive)
c06a8ce3
AM
17555+ err = vfs_getattr(&h_path, st);
17556+ dput(h_path.dentry);
4a4d8108
AM
17557+ if (!err) {
17558+ if (positive)
c06a8ce3
AM
17559+ au_refresh_iattr(inode, st,
17560+ h_path.dentry->d_inode->i_nlink);
4a4d8108 17561+ goto out_fill; /* success */
1facf9fc 17562+ }
7f207e10
AM
17563+ AuTraceErr(err);
17564+ goto out_unlock;
4a4d8108 17565+
4f0767ce 17566+out_fill:
4a4d8108 17567+ generic_fillattr(inode, st);
7f207e10 17568+out_unlock:
4a4d8108
AM
17569+ di_read_unlock(dentry, AuLock_IR);
17570+ si_read_unlock(sb);
7f207e10
AM
17571+out:
17572+ AuTraceErr(err);
4a4d8108 17573+ return err;
1facf9fc 17574+}
17575+
17576+/* ---------------------------------------------------------------------- */
17577+
4a4d8108
AM
17578+static int h_readlink(struct dentry *dentry, int bindex, char __user *buf,
17579+ int bufsiz)
1facf9fc 17580+{
17581+ int err;
4a4d8108
AM
17582+ struct super_block *sb;
17583+ struct dentry *h_dentry;
1facf9fc 17584+
4a4d8108
AM
17585+ err = -EINVAL;
17586+ h_dentry = au_h_dptr(dentry, bindex);
17587+ if (unlikely(!h_dentry->d_inode->i_op->readlink))
17588+ goto out;
1facf9fc 17589+
4a4d8108
AM
17590+ err = security_inode_readlink(h_dentry);
17591+ if (unlikely(err))
dece6358 17592+ goto out;
1facf9fc 17593+
4a4d8108
AM
17594+ sb = dentry->d_sb;
17595+ if (!au_test_ro(sb, bindex, dentry->d_inode)) {
17596+ vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry);
17597+ fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode);
1facf9fc 17598+ }
4a4d8108 17599+ err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz);
1facf9fc 17600+
4f0767ce 17601+out:
4a4d8108
AM
17602+ return err;
17603+}
1facf9fc 17604+
4a4d8108
AM
17605+static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
17606+{
17607+ int err;
1facf9fc 17608+
027c5e7a
AM
17609+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
17610+ if (unlikely(err))
17611+ goto out;
17612+ err = au_d_hashed_positive(dentry);
17613+ if (!err)
17614+ err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz);
4a4d8108 17615+ aufs_read_unlock(dentry, AuLock_IR);
1facf9fc 17616+
027c5e7a 17617+out:
4a4d8108
AM
17618+ return err;
17619+}
1facf9fc 17620+
4a4d8108
AM
17621+static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd)
17622+{
17623+ int err;
4a4d8108 17624+ mm_segment_t old_fs;
b752ccd1
AM
17625+ union {
17626+ char *k;
17627+ char __user *u;
17628+ } buf;
1facf9fc 17629+
4a4d8108 17630+ err = -ENOMEM;
537831f9 17631+ buf.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 17632+ if (unlikely(!buf.k))
4a4d8108 17633+ goto out;
1facf9fc 17634+
027c5e7a
AM
17635+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
17636+ if (unlikely(err))
17637+ goto out_name;
17638+
17639+ err = au_d_hashed_positive(dentry);
17640+ if (!err) {
17641+ old_fs = get_fs();
17642+ set_fs(KERNEL_DS);
17643+ err = h_readlink(dentry, au_dbstart(dentry), buf.u, PATH_MAX);
17644+ set_fs(old_fs);
17645+ }
4a4d8108 17646+ aufs_read_unlock(dentry, AuLock_IR);
1facf9fc 17647+
4a4d8108 17648+ if (err >= 0) {
b752ccd1 17649+ buf.k[err] = 0;
4a4d8108 17650+ /* will be freed by put_link */
b752ccd1 17651+ nd_set_link(nd, buf.k);
4a4d8108 17652+ return NULL; /* success */
1308ab2a 17653+ }
1facf9fc 17654+
027c5e7a 17655+out_name:
537831f9 17656+ free_page((unsigned long)buf.k);
4f0767ce 17657+out:
4a4d8108
AM
17658+ AuTraceErr(err);
17659+ return ERR_PTR(err);
17660+}
1facf9fc 17661+
4a4d8108
AM
17662+static void aufs_put_link(struct dentry *dentry __maybe_unused,
17663+ struct nameidata *nd, void *cookie __maybe_unused)
17664+{
537831f9
AM
17665+ char *p;
17666+
17667+ p = nd_get_link(nd);
17668+ if (!IS_ERR_OR_NULL(p))
17669+ free_page((unsigned long)p);
4a4d8108 17670+}
1facf9fc 17671+
4a4d8108 17672+/* ---------------------------------------------------------------------- */
1facf9fc 17673+
0c3ec466 17674+static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags)
4a4d8108 17675+{
0c3ec466
AM
17676+ int err;
17677+ struct super_block *sb;
17678+ struct inode *h_inode;
17679+
17680+ sb = inode->i_sb;
17681+ /* mmap_sem might be acquired already, cf. aufs_mmap() */
17682+ lockdep_off();
17683+ si_read_lock(sb, AuLock_FLUSH);
17684+ ii_write_lock_child(inode);
17685+ lockdep_on();
17686+ h_inode = au_h_iptr(inode, au_ibstart(inode));
17687+ err = vfsub_update_time(h_inode, ts, flags);
17688+ lockdep_off();
17689+ ii_write_unlock(inode);
17690+ si_read_unlock(sb);
17691+ lockdep_on();
17692+ return err;
4a4d8108 17693+}
1facf9fc 17694+
4a4d8108 17695+/* ---------------------------------------------------------------------- */
1308ab2a 17696+
4a4d8108
AM
17697+struct inode_operations aufs_symlink_iop = {
17698+ .permission = aufs_permission,
17699+ .setattr = aufs_setattr,
17700+ .getattr = aufs_getattr,
0c3ec466 17701+
4a4d8108
AM
17702+ .readlink = aufs_readlink,
17703+ .follow_link = aufs_follow_link,
0c3ec466
AM
17704+ .put_link = aufs_put_link,
17705+
17706+ /* .update_time = aufs_update_time */
4a4d8108
AM
17707+};
17708+
17709+struct inode_operations aufs_dir_iop = {
17710+ .create = aufs_create,
17711+ .lookup = aufs_lookup,
17712+ .link = aufs_link,
17713+ .unlink = aufs_unlink,
17714+ .symlink = aufs_symlink,
17715+ .mkdir = aufs_mkdir,
17716+ .rmdir = aufs_rmdir,
17717+ .mknod = aufs_mknod,
17718+ .rename = aufs_rename,
17719+
17720+ .permission = aufs_permission,
17721+ .setattr = aufs_setattr,
0c3ec466
AM
17722+ .getattr = aufs_getattr,
17723+
17724+ .update_time = aufs_update_time
b4510431 17725+ /* no support for atomic_open() */
4a4d8108
AM
17726+};
17727+
17728+struct inode_operations aufs_iop = {
17729+ .permission = aufs_permission,
17730+ .setattr = aufs_setattr,
17731+ .getattr = aufs_getattr,
0c3ec466
AM
17732+
17733+ .update_time = aufs_update_time
4a4d8108 17734+};
7f207e10
AM
17735diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
17736--- /usr/share/empty/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
392086de 17737+++ linux/fs/aufs/i_op_del.c 2013-10-26 16:51:32.276373845 +0200
c2b27bf2 17738@@ -0,0 +1,502 @@
1facf9fc 17739+/*
7a9e40b8 17740+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 17741+ *
17742+ * This program, aufs is free software; you can redistribute it and/or modify
17743+ * it under the terms of the GNU General Public License as published by
17744+ * the Free Software Foundation; either version 2 of the License, or
17745+ * (at your option) any later version.
dece6358
AM
17746+ *
17747+ * This program is distributed in the hope that it will be useful,
17748+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17749+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17750+ * GNU General Public License for more details.
17751+ *
17752+ * You should have received a copy of the GNU General Public License
17753+ * along with this program; if not, write to the Free Software
17754+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 17755+ */
17756+
17757+/*
4a4d8108 17758+ * inode operations (del entry)
1308ab2a 17759+ */
dece6358 17760+
1308ab2a 17761+#include "aufs.h"
dece6358 17762+
4a4d8108
AM
17763+/*
17764+ * decide if a new whiteout for @dentry is necessary or not.
17765+ * when it is necessary, prepare the parent dir for the upper branch whose
17766+ * branch index is @bcpup for creation. the actual creation of the whiteout will
17767+ * be done by caller.
17768+ * return value:
17769+ * 0: wh is unnecessary
17770+ * plus: wh is necessary
17771+ * minus: error
17772+ */
17773+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
1308ab2a 17774+{
4a4d8108
AM
17775+ int need_wh, err;
17776+ aufs_bindex_t bstart;
17777+ struct super_block *sb;
dece6358 17778+
4a4d8108
AM
17779+ sb = dentry->d_sb;
17780+ bstart = au_dbstart(dentry);
17781+ if (*bcpup < 0) {
17782+ *bcpup = bstart;
17783+ if (au_test_ro(sb, bstart, dentry->d_inode)) {
17784+ err = AuWbrCopyup(au_sbi(sb), dentry);
17785+ *bcpup = err;
17786+ if (unlikely(err < 0))
17787+ goto out;
17788+ }
17789+ } else
17790+ AuDebugOn(bstart < *bcpup
17791+ || au_test_ro(sb, *bcpup, dentry->d_inode));
17792+ AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
1308ab2a 17793+
4a4d8108
AM
17794+ if (*bcpup != bstart) {
17795+ err = au_cpup_dirs(dentry, *bcpup);
17796+ if (unlikely(err))
17797+ goto out;
17798+ need_wh = 1;
17799+ } else {
027c5e7a 17800+ struct au_dinfo *dinfo, *tmp;
4a4d8108 17801+
027c5e7a
AM
17802+ need_wh = -ENOMEM;
17803+ dinfo = au_di(dentry);
17804+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
17805+ if (tmp) {
17806+ au_di_cp(tmp, dinfo);
17807+ au_di_swap(tmp, dinfo);
17808+ /* returns the number of positive dentries */
537831f9 17809+ need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0);
027c5e7a
AM
17810+ au_di_swap(tmp, dinfo);
17811+ au_rw_write_unlock(&tmp->di_rwsem);
17812+ au_di_free(tmp);
4a4d8108
AM
17813+ }
17814+ }
17815+ AuDbg("need_wh %d\n", need_wh);
17816+ err = need_wh;
17817+
4f0767ce 17818+out:
4a4d8108 17819+ return err;
1facf9fc 17820+}
17821+
4a4d8108
AM
17822+/*
17823+ * simple tests for the del-entry operations.
17824+ * following the checks in vfs, plus the parent-child relationship.
17825+ */
17826+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
17827+ struct dentry *h_parent, int isdir)
1facf9fc 17828+{
4a4d8108
AM
17829+ int err;
17830+ umode_t h_mode;
17831+ struct dentry *h_dentry, *h_latest;
1308ab2a 17832+ struct inode *h_inode;
1facf9fc 17833+
4a4d8108
AM
17834+ h_dentry = au_h_dptr(dentry, bindex);
17835+ h_inode = h_dentry->d_inode;
17836+ if (dentry->d_inode) {
17837+ err = -ENOENT;
17838+ if (unlikely(!h_inode || !h_inode->i_nlink))
17839+ goto out;
1facf9fc 17840+
4a4d8108
AM
17841+ h_mode = h_inode->i_mode;
17842+ if (!isdir) {
17843+ err = -EISDIR;
17844+ if (unlikely(S_ISDIR(h_mode)))
17845+ goto out;
17846+ } else if (unlikely(!S_ISDIR(h_mode))) {
17847+ err = -ENOTDIR;
17848+ goto out;
17849+ }
17850+ } else {
17851+ /* rename(2) case */
17852+ err = -EIO;
17853+ if (unlikely(h_inode))
17854+ goto out;
17855+ }
1facf9fc 17856+
4a4d8108
AM
17857+ err = -ENOENT;
17858+ /* expected parent dir is locked */
17859+ if (unlikely(h_parent != h_dentry->d_parent))
17860+ goto out;
17861+ err = 0;
17862+
17863+ /*
17864+ * rmdir a dir may break the consistency on some filesystem.
17865+ * let's try heavy test.
17866+ */
17867+ err = -EACCES;
17868+ if (unlikely(au_test_h_perm(h_parent->d_inode, MAY_EXEC | MAY_WRITE)))
17869+ goto out;
17870+
17871+ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent,
17872+ au_sbr(dentry->d_sb, bindex));
17873+ err = -EIO;
17874+ if (IS_ERR(h_latest))
17875+ goto out;
17876+ if (h_latest == h_dentry)
17877+ err = 0;
17878+ dput(h_latest);
17879+
4f0767ce 17880+out:
4a4d8108 17881+ return err;
1308ab2a 17882+}
1facf9fc 17883+
4a4d8108
AM
17884+/*
17885+ * decide the branch where we operate for @dentry. the branch index will be set
17886+ * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
17887+ * dir for reverting.
17888+ * when a new whiteout is necessary, create it.
17889+ */
17890+static struct dentry*
17891+lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
17892+ struct au_dtime *dt, struct au_pin *pin)
1308ab2a 17893+{
4a4d8108
AM
17894+ struct dentry *wh_dentry;
17895+ struct super_block *sb;
17896+ struct path h_path;
17897+ int err, need_wh;
17898+ unsigned int udba;
17899+ aufs_bindex_t bcpup;
dece6358 17900+
4a4d8108
AM
17901+ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
17902+ wh_dentry = ERR_PTR(need_wh);
17903+ if (unlikely(need_wh < 0))
17904+ goto out;
17905+
17906+ sb = dentry->d_sb;
17907+ udba = au_opt_udba(sb);
17908+ bcpup = *rbcpup;
17909+ err = au_pin(pin, dentry, bcpup, udba,
17910+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17911+ wh_dentry = ERR_PTR(err);
17912+ if (unlikely(err))
17913+ goto out;
17914+
17915+ h_path.dentry = au_pinned_h_parent(pin);
17916+ if (udba != AuOpt_UDBA_NONE
17917+ && au_dbstart(dentry) == bcpup) {
17918+ err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
17919+ wh_dentry = ERR_PTR(err);
17920+ if (unlikely(err))
17921+ goto out_unpin;
17922+ }
17923+
17924+ h_path.mnt = au_sbr_mnt(sb, bcpup);
17925+ au_dtime_store(dt, au_pinned_parent(pin), &h_path);
17926+ wh_dentry = NULL;
17927+ if (!need_wh)
17928+ goto out; /* success, no need to create whiteout */
17929+
17930+ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
17931+ if (IS_ERR(wh_dentry))
17932+ goto out_unpin;
17933+
17934+ /* returns with the parent is locked and wh_dentry is dget-ed */
17935+ goto out; /* success */
17936+
4f0767ce 17937+out_unpin:
4a4d8108 17938+ au_unpin(pin);
4f0767ce 17939+out:
4a4d8108 17940+ return wh_dentry;
1facf9fc 17941+}
17942+
4a4d8108
AM
17943+/*
17944+ * when removing a dir, rename it to a unique temporary whiteout-ed name first
17945+ * in order to be revertible and save time for removing many child whiteouts
17946+ * under the dir.
17947+ * returns 1 when there are too many child whiteout and caller should remove
17948+ * them asynchronously. returns 0 when the number of children is enough small to
17949+ * remove now or the branch fs is a remote fs.
17950+ * otherwise return an error.
17951+ */
17952+static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
17953+ struct au_nhash *whlist, struct inode *dir)
1facf9fc 17954+{
4a4d8108
AM
17955+ int rmdir_later, err, dirwh;
17956+ struct dentry *h_dentry;
17957+ struct super_block *sb;
17958+
17959+ sb = dentry->d_sb;
17960+ SiMustAnyLock(sb);
17961+ h_dentry = au_h_dptr(dentry, bindex);
17962+ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
17963+ if (unlikely(err))
17964+ goto out;
17965+
17966+ /* stop monitoring */
17967+ au_hn_free(au_hi(dentry->d_inode, bindex));
17968+
17969+ if (!au_test_fs_remote(h_dentry->d_sb)) {
17970+ dirwh = au_sbi(sb)->si_dirwh;
17971+ rmdir_later = (dirwh <= 1);
17972+ if (!rmdir_later)
17973+ rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
17974+ dirwh);
17975+ if (rmdir_later)
17976+ return rmdir_later;
17977+ }
1facf9fc 17978+
4a4d8108
AM
17979+ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
17980+ if (unlikely(err)) {
17981+ AuIOErr("rmdir %.*s, b%d failed, %d. ignored\n",
17982+ AuDLNPair(h_dentry), bindex, err);
17983+ err = 0;
17984+ }
dece6358 17985+
4f0767ce 17986+out:
4a4d8108
AM
17987+ AuTraceErr(err);
17988+ return err;
17989+}
1308ab2a 17990+
4a4d8108
AM
17991+/*
17992+ * final procedure for deleting a entry.
17993+ * maintain dentry and iattr.
17994+ */
17995+static void epilog(struct inode *dir, struct dentry *dentry,
17996+ aufs_bindex_t bindex)
17997+{
17998+ struct inode *inode;
1308ab2a 17999+
4a4d8108
AM
18000+ inode = dentry->d_inode;
18001+ d_drop(dentry);
18002+ inode->i_ctime = dir->i_ctime;
1308ab2a 18003+
4a4d8108
AM
18004+ if (au_ibstart(dir) == bindex)
18005+ au_cpup_attr_timesizes(dir);
18006+ dir->i_version++;
1facf9fc 18007+}
18008+
4a4d8108
AM
18009+/*
18010+ * when an error happened, remove the created whiteout and revert everything.
18011+ */
7f207e10
AM
18012+static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex,
18013+ aufs_bindex_t bwh, struct dentry *wh_dentry,
18014+ struct dentry *dentry, struct au_dtime *dt)
1facf9fc 18015+{
4a4d8108
AM
18016+ int rerr;
18017+ struct path h_path = {
18018+ .dentry = wh_dentry,
7f207e10 18019+ .mnt = au_sbr_mnt(dir->i_sb, bindex)
4a4d8108 18020+ };
dece6358 18021+
7f207e10 18022+ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
4a4d8108
AM
18023+ if (!rerr) {
18024+ au_set_dbwh(dentry, bwh);
18025+ au_dtime_revert(dt);
18026+ return 0;
18027+ }
dece6358 18028+
4a4d8108
AM
18029+ AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
18030+ AuDLNPair(dentry), err, rerr);
18031+ return -EIO;
1facf9fc 18032+}
18033+
4a4d8108 18034+/* ---------------------------------------------------------------------- */
1facf9fc 18035+
4a4d8108 18036+int aufs_unlink(struct inode *dir, struct dentry *dentry)
1308ab2a 18037+{
4a4d8108
AM
18038+ int err;
18039+ aufs_bindex_t bwh, bindex, bstart;
4a4d8108
AM
18040+ struct inode *inode, *h_dir;
18041+ struct dentry *parent, *wh_dentry;
c2b27bf2
AM
18042+ /* to reuduce stack size */
18043+ struct {
18044+ struct au_dtime dt;
18045+ struct au_pin pin;
18046+ struct path h_path;
18047+ } *a;
1facf9fc 18048+
4a4d8108 18049+ IMustLock(dir);
027c5e7a 18050+
c2b27bf2
AM
18051+ err = -ENOMEM;
18052+ a = kmalloc(sizeof(*a), GFP_NOFS);
18053+ if (unlikely(!a))
18054+ goto out;
18055+
027c5e7a
AM
18056+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
18057+ if (unlikely(err))
c2b27bf2 18058+ goto out_free;
027c5e7a
AM
18059+ err = au_d_hashed_positive(dentry);
18060+ if (unlikely(err))
18061+ goto out_unlock;
4a4d8108 18062+ inode = dentry->d_inode;
4a4d8108 18063+ IMustLock(inode);
027c5e7a
AM
18064+ err = -EISDIR;
18065+ if (unlikely(S_ISDIR(inode->i_mode)))
18066+ goto out_unlock; /* possible? */
1facf9fc 18067+
4a4d8108
AM
18068+ bstart = au_dbstart(dentry);
18069+ bwh = au_dbwh(dentry);
18070+ bindex = -1;
027c5e7a
AM
18071+ parent = dentry->d_parent; /* dir inode is locked */
18072+ di_write_lock_parent(parent);
c2b27bf2
AM
18073+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &a->dt,
18074+ &a->pin);
4a4d8108
AM
18075+ err = PTR_ERR(wh_dentry);
18076+ if (IS_ERR(wh_dentry))
027c5e7a 18077+ goto out_parent;
1facf9fc 18078+
c2b27bf2
AM
18079+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
18080+ a->h_path.dentry = au_h_dptr(dentry, bstart);
18081+ dget(a->h_path.dentry);
4a4d8108 18082+ if (bindex == bstart) {
c2b27bf2
AM
18083+ h_dir = au_pinned_h_dir(&a->pin);
18084+ err = vfsub_unlink(h_dir, &a->h_path, /*force*/0);
4a4d8108
AM
18085+ } else {
18086+ /* dir inode is locked */
18087+ h_dir = wh_dentry->d_parent->d_inode;
18088+ IMustLock(h_dir);
18089+ err = 0;
18090+ }
dece6358 18091+
4a4d8108 18092+ if (!err) {
7f207e10 18093+ vfsub_drop_nlink(inode);
4a4d8108
AM
18094+ epilog(dir, dentry, bindex);
18095+
18096+ /* update target timestamps */
18097+ if (bindex == bstart) {
c2b27bf2
AM
18098+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL);
18099+ /*ignore*/
18100+ inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
4a4d8108
AM
18101+ } else
18102+ /* todo: this timestamp may be reverted later */
18103+ inode->i_ctime = h_dir->i_ctime;
027c5e7a 18104+ goto out_unpin; /* success */
1facf9fc 18105+ }
18106+
4a4d8108
AM
18107+ /* revert */
18108+ if (wh_dentry) {
18109+ int rerr;
18110+
c2b27bf2
AM
18111+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
18112+ &a->dt);
4a4d8108
AM
18113+ if (rerr)
18114+ err = rerr;
dece6358 18115+ }
1facf9fc 18116+
027c5e7a 18117+out_unpin:
c2b27bf2 18118+ au_unpin(&a->pin);
4a4d8108 18119+ dput(wh_dentry);
c2b27bf2 18120+ dput(a->h_path.dentry);
027c5e7a 18121+out_parent:
4a4d8108 18122+ di_write_unlock(parent);
027c5e7a 18123+out_unlock:
4a4d8108 18124+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
18125+out_free:
18126+ kfree(a);
027c5e7a 18127+out:
4a4d8108 18128+ return err;
dece6358
AM
18129+}
18130+
4a4d8108 18131+int aufs_rmdir(struct inode *dir, struct dentry *dentry)
1308ab2a 18132+{
4a4d8108
AM
18133+ int err, rmdir_later;
18134+ aufs_bindex_t bwh, bindex, bstart;
4a4d8108
AM
18135+ struct inode *inode;
18136+ struct dentry *parent, *wh_dentry, *h_dentry;
18137+ struct au_whtmp_rmdir *args;
c2b27bf2
AM
18138+ /* to reuduce stack size */
18139+ struct {
18140+ struct au_dtime dt;
18141+ struct au_pin pin;
18142+ } *a;
1facf9fc 18143+
4a4d8108 18144+ IMustLock(dir);
027c5e7a 18145+
c2b27bf2
AM
18146+ err = -ENOMEM;
18147+ a = kmalloc(sizeof(*a), GFP_NOFS);
18148+ if (unlikely(!a))
18149+ goto out;
18150+
027c5e7a
AM
18151+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
18152+ if (unlikely(err))
c2b27bf2 18153+ goto out_free;
53392da6
AM
18154+ err = au_alive_dir(dentry);
18155+ if (unlikely(err))
027c5e7a 18156+ goto out_unlock;
53392da6 18157+ inode = dentry->d_inode;
4a4d8108 18158+ IMustLock(inode);
027c5e7a
AM
18159+ err = -ENOTDIR;
18160+ if (unlikely(!S_ISDIR(inode->i_mode)))
18161+ goto out_unlock; /* possible? */
dece6358 18162+
4a4d8108
AM
18163+ err = -ENOMEM;
18164+ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
18165+ if (unlikely(!args))
18166+ goto out_unlock;
dece6358 18167+
4a4d8108
AM
18168+ parent = dentry->d_parent; /* dir inode is locked */
18169+ di_write_lock_parent(parent);
18170+ err = au_test_empty(dentry, &args->whlist);
18171+ if (unlikely(err))
027c5e7a 18172+ goto out_parent;
1facf9fc 18173+
4a4d8108
AM
18174+ bstart = au_dbstart(dentry);
18175+ bwh = au_dbwh(dentry);
18176+ bindex = -1;
c2b27bf2
AM
18177+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &a->dt,
18178+ &a->pin);
4a4d8108
AM
18179+ err = PTR_ERR(wh_dentry);
18180+ if (IS_ERR(wh_dentry))
027c5e7a 18181+ goto out_parent;
1facf9fc 18182+
4a4d8108
AM
18183+ h_dentry = au_h_dptr(dentry, bstart);
18184+ dget(h_dentry);
18185+ rmdir_later = 0;
18186+ if (bindex == bstart) {
18187+ err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir);
18188+ if (err > 0) {
18189+ rmdir_later = err;
18190+ err = 0;
18191+ }
18192+ } else {
18193+ /* stop monitoring */
18194+ au_hn_free(au_hi(inode, bstart));
18195+
18196+ /* dir inode is locked */
18197+ IMustLock(wh_dentry->d_parent->d_inode);
1facf9fc 18198+ err = 0;
18199+ }
18200+
4a4d8108 18201+ if (!err) {
027c5e7a 18202+ vfsub_dead_dir(inode);
4a4d8108
AM
18203+ au_set_dbdiropq(dentry, -1);
18204+ epilog(dir, dentry, bindex);
1308ab2a 18205+
4a4d8108
AM
18206+ if (rmdir_later) {
18207+ au_whtmp_kick_rmdir(dir, bstart, h_dentry, args);
18208+ args = NULL;
18209+ }
1308ab2a 18210+
4a4d8108 18211+ goto out_unpin; /* success */
1facf9fc 18212+ }
18213+
4a4d8108
AM
18214+ /* revert */
18215+ AuLabel(revert);
18216+ if (wh_dentry) {
18217+ int rerr;
1308ab2a 18218+
c2b27bf2
AM
18219+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
18220+ &a->dt);
4a4d8108
AM
18221+ if (rerr)
18222+ err = rerr;
1facf9fc 18223+ }
18224+
4f0767ce 18225+out_unpin:
c2b27bf2 18226+ au_unpin(&a->pin);
4a4d8108
AM
18227+ dput(wh_dentry);
18228+ dput(h_dentry);
027c5e7a 18229+out_parent:
4a4d8108
AM
18230+ di_write_unlock(parent);
18231+ if (args)
18232+ au_whtmp_rmdir_free(args);
4f0767ce 18233+out_unlock:
4a4d8108 18234+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
18235+out_free:
18236+ kfree(a);
4f0767ce 18237+out:
4a4d8108
AM
18238+ AuTraceErr(err);
18239+ return err;
dece6358 18240+}
7f207e10
AM
18241diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
18242--- /usr/share/empty/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
392086de 18243+++ linux/fs/aufs/i_op_ren.c 2013-10-26 16:51:32.276373845 +0200
c2b27bf2 18244@@ -0,0 +1,1009 @@
1facf9fc 18245+/*
7a9e40b8 18246+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 18247+ *
18248+ * This program, aufs is free software; you can redistribute it and/or modify
18249+ * it under the terms of the GNU General Public License as published by
18250+ * the Free Software Foundation; either version 2 of the License, or
18251+ * (at your option) any later version.
dece6358
AM
18252+ *
18253+ * This program is distributed in the hope that it will be useful,
18254+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18255+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18256+ * GNU General Public License for more details.
18257+ *
18258+ * You should have received a copy of the GNU General Public License
18259+ * along with this program; if not, write to the Free Software
18260+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 18261+ */
18262+
18263+/*
4a4d8108
AM
18264+ * inode operation (rename entry)
18265+ * todo: this is crazy monster
1facf9fc 18266+ */
18267+
18268+#include "aufs.h"
18269+
4a4d8108
AM
18270+enum { AuSRC, AuDST, AuSrcDst };
18271+enum { AuPARENT, AuCHILD, AuParentChild };
1facf9fc 18272+
4a4d8108
AM
18273+#define AuRen_ISDIR 1
18274+#define AuRen_ISSAMEDIR (1 << 1)
18275+#define AuRen_WHSRC (1 << 2)
18276+#define AuRen_WHDST (1 << 3)
18277+#define AuRen_MNT_WRITE (1 << 4)
18278+#define AuRen_DT_DSTDIR (1 << 5)
18279+#define AuRen_DIROPQ (1 << 6)
18280+#define AuRen_CPUP (1 << 7)
18281+#define au_ftest_ren(flags, name) ((flags) & AuRen_##name)
7f207e10
AM
18282+#define au_fset_ren(flags, name) \
18283+ do { (flags) |= AuRen_##name; } while (0)
18284+#define au_fclr_ren(flags, name) \
18285+ do { (flags) &= ~AuRen_##name; } while (0)
1facf9fc 18286+
4a4d8108
AM
18287+struct au_ren_args {
18288+ struct {
18289+ struct dentry *dentry, *h_dentry, *parent, *h_parent,
18290+ *wh_dentry;
18291+ struct inode *dir, *inode;
18292+ struct au_hinode *hdir;
18293+ struct au_dtime dt[AuParentChild];
18294+ aufs_bindex_t bstart;
18295+ } sd[AuSrcDst];
1facf9fc 18296+
4a4d8108
AM
18297+#define src_dentry sd[AuSRC].dentry
18298+#define src_dir sd[AuSRC].dir
18299+#define src_inode sd[AuSRC].inode
18300+#define src_h_dentry sd[AuSRC].h_dentry
18301+#define src_parent sd[AuSRC].parent
18302+#define src_h_parent sd[AuSRC].h_parent
18303+#define src_wh_dentry sd[AuSRC].wh_dentry
18304+#define src_hdir sd[AuSRC].hdir
18305+#define src_h_dir sd[AuSRC].hdir->hi_inode
18306+#define src_dt sd[AuSRC].dt
18307+#define src_bstart sd[AuSRC].bstart
1facf9fc 18308+
4a4d8108
AM
18309+#define dst_dentry sd[AuDST].dentry
18310+#define dst_dir sd[AuDST].dir
18311+#define dst_inode sd[AuDST].inode
18312+#define dst_h_dentry sd[AuDST].h_dentry
18313+#define dst_parent sd[AuDST].parent
18314+#define dst_h_parent sd[AuDST].h_parent
18315+#define dst_wh_dentry sd[AuDST].wh_dentry
18316+#define dst_hdir sd[AuDST].hdir
18317+#define dst_h_dir sd[AuDST].hdir->hi_inode
18318+#define dst_dt sd[AuDST].dt
18319+#define dst_bstart sd[AuDST].bstart
18320+
18321+ struct dentry *h_trap;
18322+ struct au_branch *br;
18323+ struct au_hinode *src_hinode;
18324+ struct path h_path;
18325+ struct au_nhash whlist;
027c5e7a 18326+ aufs_bindex_t btgt, src_bwh, src_bdiropq;
1facf9fc 18327+
1308ab2a 18328+ unsigned int flags;
1facf9fc 18329+
4a4d8108
AM
18330+ struct au_whtmp_rmdir *thargs;
18331+ struct dentry *h_dst;
18332+};
1308ab2a 18333+
4a4d8108 18334+/* ---------------------------------------------------------------------- */
1308ab2a 18335+
4a4d8108
AM
18336+/*
18337+ * functions for reverting.
18338+ * when an error happened in a single rename systemcall, we should revert
18339+ * everything as if nothing happend.
18340+ * we don't need to revert the copied-up/down the parent dir since they are
18341+ * harmless.
18342+ */
1facf9fc 18343+
4a4d8108
AM
18344+#define RevertFailure(fmt, ...) do { \
18345+ AuIOErr("revert failure: " fmt " (%d, %d)\n", \
18346+ ##__VA_ARGS__, err, rerr); \
18347+ err = -EIO; \
18348+} while (0)
1facf9fc 18349+
4a4d8108 18350+static void au_ren_rev_diropq(int err, struct au_ren_args *a)
1facf9fc 18351+{
4a4d8108 18352+ int rerr;
1facf9fc 18353+
4a4d8108
AM
18354+ au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
18355+ rerr = au_diropq_remove(a->src_dentry, a->btgt);
18356+ au_hn_imtx_unlock(a->src_hinode);
027c5e7a 18357+ au_set_dbdiropq(a->src_dentry, a->src_bdiropq);
4a4d8108
AM
18358+ if (rerr)
18359+ RevertFailure("remove diropq %.*s", AuDLNPair(a->src_dentry));
18360+}
1facf9fc 18361+
4a4d8108
AM
18362+static void au_ren_rev_rename(int err, struct au_ren_args *a)
18363+{
18364+ int rerr;
1facf9fc 18365+
b4510431
AM
18366+ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name,
18367+ a->src_h_parent);
4a4d8108
AM
18368+ rerr = PTR_ERR(a->h_path.dentry);
18369+ if (IS_ERR(a->h_path.dentry)) {
b4510431 18370+ RevertFailure("lkup one %.*s", AuDLNPair(a->src_dentry));
4a4d8108 18371+ return;
1facf9fc 18372+ }
18373+
4a4d8108
AM
18374+ rerr = vfsub_rename(a->dst_h_dir,
18375+ au_h_dptr(a->src_dentry, a->btgt),
18376+ a->src_h_dir, &a->h_path);
18377+ d_drop(a->h_path.dentry);
18378+ dput(a->h_path.dentry);
18379+ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
18380+ if (rerr)
18381+ RevertFailure("rename %.*s", AuDLNPair(a->src_dentry));
1facf9fc 18382+}
18383+
4a4d8108 18384+static void au_ren_rev_cpup(int err, struct au_ren_args *a)
1facf9fc 18385+{
4a4d8108 18386+ int rerr;
1facf9fc 18387+
4a4d8108
AM
18388+ a->h_path.dentry = a->dst_h_dentry;
18389+ rerr = vfsub_unlink(a->dst_h_dir, &a->h_path, /*force*/0);
18390+ au_set_h_dptr(a->src_dentry, a->btgt, NULL);
18391+ au_set_dbstart(a->src_dentry, a->src_bstart);
18392+ if (rerr)
18393+ RevertFailure("unlink %.*s", AuDLNPair(a->dst_h_dentry));
1facf9fc 18394+}
18395+
4a4d8108 18396+static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
1facf9fc 18397+{
4a4d8108 18398+ int rerr;
dece6358 18399+
b4510431
AM
18400+ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name,
18401+ a->dst_h_parent);
4a4d8108
AM
18402+ rerr = PTR_ERR(a->h_path.dentry);
18403+ if (IS_ERR(a->h_path.dentry)) {
b4510431 18404+ RevertFailure("lkup one %.*s", AuDLNPair(a->dst_dentry));
4a4d8108
AM
18405+ return;
18406+ }
18407+ if (a->h_path.dentry->d_inode) {
18408+ d_drop(a->h_path.dentry);
18409+ dput(a->h_path.dentry);
18410+ return;
dece6358
AM
18411+ }
18412+
4a4d8108
AM
18413+ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path);
18414+ d_drop(a->h_path.dentry);
18415+ dput(a->h_path.dentry);
18416+ if (!rerr)
18417+ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
18418+ else
18419+ RevertFailure("rename %.*s", AuDLNPair(a->h_dst));
18420+}
1308ab2a 18421+
4a4d8108
AM
18422+static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
18423+{
18424+ int rerr;
1308ab2a 18425+
4a4d8108
AM
18426+ a->h_path.dentry = a->src_wh_dentry;
18427+ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
027c5e7a 18428+ au_set_dbwh(a->src_dentry, a->src_bwh);
4a4d8108
AM
18429+ if (rerr)
18430+ RevertFailure("unlink %.*s", AuDLNPair(a->src_wh_dentry));
18431+}
4a4d8108 18432+#undef RevertFailure
1facf9fc 18433+
1308ab2a 18434+/* ---------------------------------------------------------------------- */
18435+
4a4d8108
AM
18436+/*
18437+ * when we have to copyup the renaming entry, do it with the rename-target name
18438+ * in order to minimize the cost (the later actual rename is unnecessary).
18439+ * otherwise rename it on the target branch.
18440+ */
18441+static int au_ren_or_cpup(struct au_ren_args *a)
1facf9fc 18442+{
dece6358 18443+ int err;
4a4d8108 18444+ struct dentry *d;
1facf9fc 18445+
4a4d8108
AM
18446+ d = a->src_dentry;
18447+ if (au_dbstart(d) == a->btgt) {
18448+ a->h_path.dentry = a->dst_h_dentry;
18449+ if (au_ftest_ren(a->flags, DIROPQ)
18450+ && au_dbdiropq(d) == a->btgt)
18451+ au_fclr_ren(a->flags, DIROPQ);
18452+ AuDebugOn(au_dbstart(d) != a->btgt);
18453+ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
18454+ a->dst_h_dir, &a->h_path);
c2b27bf2 18455+ } else
86dc4139 18456+ BUG();
1308ab2a 18457+
027c5e7a
AM
18458+ if (!err && a->h_dst)
18459+ /* it will be set to dinfo later */
18460+ dget(a->h_dst);
1facf9fc 18461+
dece6358
AM
18462+ return err;
18463+}
1facf9fc 18464+
4a4d8108
AM
18465+/* cf. aufs_rmdir() */
18466+static int au_ren_del_whtmp(struct au_ren_args *a)
dece6358 18467+{
4a4d8108
AM
18468+ int err;
18469+ struct inode *dir;
1facf9fc 18470+
4a4d8108
AM
18471+ dir = a->dst_dir;
18472+ SiMustAnyLock(dir->i_sb);
18473+ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
18474+ au_sbi(dir->i_sb)->si_dirwh)
18475+ || au_test_fs_remote(a->h_dst->d_sb)) {
18476+ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
18477+ if (unlikely(err))
0c3ec466
AM
18478+ pr_warn("failed removing whtmp dir %.*s (%d), "
18479+ "ignored.\n", AuDLNPair(a->h_dst), err);
4a4d8108
AM
18480+ } else {
18481+ au_nhash_wh_free(&a->thargs->whlist);
18482+ a->thargs->whlist = a->whlist;
18483+ a->whlist.nh_num = 0;
18484+ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
18485+ dput(a->h_dst);
18486+ a->thargs = NULL;
18487+ }
18488+
18489+ return 0;
1308ab2a 18490+}
1facf9fc 18491+
4a4d8108
AM
18492+/* make it 'opaque' dir. */
18493+static int au_ren_diropq(struct au_ren_args *a)
18494+{
18495+ int err;
18496+ struct dentry *diropq;
1facf9fc 18497+
4a4d8108 18498+ err = 0;
027c5e7a 18499+ a->src_bdiropq = au_dbdiropq(a->src_dentry);
4a4d8108
AM
18500+ a->src_hinode = au_hi(a->src_inode, a->btgt);
18501+ au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
18502+ diropq = au_diropq_create(a->src_dentry, a->btgt);
18503+ au_hn_imtx_unlock(a->src_hinode);
18504+ if (IS_ERR(diropq))
18505+ err = PTR_ERR(diropq);
18506+ dput(diropq);
1facf9fc 18507+
4a4d8108
AM
18508+ return err;
18509+}
1facf9fc 18510+
4a4d8108
AM
18511+static int do_rename(struct au_ren_args *a)
18512+{
18513+ int err;
18514+ struct dentry *d, *h_d;
1facf9fc 18515+
4a4d8108
AM
18516+ /* prepare workqueue args for asynchronous rmdir */
18517+ h_d = a->dst_h_dentry;
18518+ if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) {
18519+ err = -ENOMEM;
18520+ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS);
18521+ if (unlikely(!a->thargs))
18522+ goto out;
18523+ a->h_dst = dget(h_d);
18524+ }
1facf9fc 18525+
4a4d8108
AM
18526+ /* create whiteout for src_dentry */
18527+ if (au_ftest_ren(a->flags, WHSRC)) {
027c5e7a
AM
18528+ a->src_bwh = au_dbwh(a->src_dentry);
18529+ AuDebugOn(a->src_bwh >= 0);
4a4d8108
AM
18530+ a->src_wh_dentry
18531+ = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent);
18532+ err = PTR_ERR(a->src_wh_dentry);
18533+ if (IS_ERR(a->src_wh_dentry))
18534+ goto out_thargs;
18535+ }
1facf9fc 18536+
4a4d8108
AM
18537+ /* lookup whiteout for dentry */
18538+ if (au_ftest_ren(a->flags, WHDST)) {
18539+ h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name,
18540+ a->br);
18541+ err = PTR_ERR(h_d);
18542+ if (IS_ERR(h_d))
18543+ goto out_whsrc;
18544+ if (!h_d->d_inode)
18545+ dput(h_d);
18546+ else
18547+ a->dst_wh_dentry = h_d;
18548+ }
1facf9fc 18549+
4a4d8108
AM
18550+ /* rename dentry to tmpwh */
18551+ if (a->thargs) {
18552+ err = au_whtmp_ren(a->dst_h_dentry, a->br);
18553+ if (unlikely(err))
18554+ goto out_whdst;
dece6358 18555+
4a4d8108
AM
18556+ d = a->dst_dentry;
18557+ au_set_h_dptr(d, a->btgt, NULL);
86dc4139 18558+ err = au_lkup_neg(d, a->btgt, /*wh*/0);
4a4d8108
AM
18559+ if (unlikely(err))
18560+ goto out_whtmp;
18561+ a->dst_h_dentry = au_h_dptr(d, a->btgt);
18562+ }
1facf9fc 18563+
c2b27bf2 18564+ BUG_ON(a->dst_h_dentry->d_inode && a->src_bstart != a->btgt);
1facf9fc 18565+
4a4d8108
AM
18566+ /* rename by vfs_rename or cpup */
18567+ d = a->dst_dentry;
18568+ if (au_ftest_ren(a->flags, ISDIR)
18569+ && (a->dst_wh_dentry
18570+ || au_dbdiropq(d) == a->btgt
18571+ /* hide the lower to keep xino */
18572+ || a->btgt < au_dbend(d)
18573+ || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ)))
18574+ au_fset_ren(a->flags, DIROPQ);
18575+ err = au_ren_or_cpup(a);
18576+ if (unlikely(err))
18577+ /* leave the copied-up one */
18578+ goto out_whtmp;
1308ab2a 18579+
4a4d8108
AM
18580+ /* make dir opaque */
18581+ if (au_ftest_ren(a->flags, DIROPQ)) {
18582+ err = au_ren_diropq(a);
18583+ if (unlikely(err))
18584+ goto out_rename;
18585+ }
1308ab2a 18586+
4a4d8108
AM
18587+ /* update target timestamps */
18588+ AuDebugOn(au_dbstart(a->src_dentry) != a->btgt);
18589+ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
18590+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
18591+ a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
1facf9fc 18592+
4a4d8108
AM
18593+ /* remove whiteout for dentry */
18594+ if (a->dst_wh_dentry) {
18595+ a->h_path.dentry = a->dst_wh_dentry;
18596+ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
18597+ a->dst_dentry);
18598+ if (unlikely(err))
18599+ goto out_diropq;
18600+ }
1facf9fc 18601+
4a4d8108
AM
18602+ /* remove whtmp */
18603+ if (a->thargs)
18604+ au_ren_del_whtmp(a); /* ignore this error */
1308ab2a 18605+
4a4d8108
AM
18606+ err = 0;
18607+ goto out_success;
18608+
4f0767ce 18609+out_diropq:
4a4d8108
AM
18610+ if (au_ftest_ren(a->flags, DIROPQ))
18611+ au_ren_rev_diropq(err, a);
4f0767ce 18612+out_rename:
4a4d8108
AM
18613+ if (!au_ftest_ren(a->flags, CPUP))
18614+ au_ren_rev_rename(err, a);
18615+ else
18616+ au_ren_rev_cpup(err, a);
027c5e7a 18617+ dput(a->h_dst);
4f0767ce 18618+out_whtmp:
4a4d8108
AM
18619+ if (a->thargs)
18620+ au_ren_rev_whtmp(err, a);
4f0767ce 18621+out_whdst:
4a4d8108
AM
18622+ dput(a->dst_wh_dentry);
18623+ a->dst_wh_dentry = NULL;
4f0767ce 18624+out_whsrc:
4a4d8108
AM
18625+ if (a->src_wh_dentry)
18626+ au_ren_rev_whsrc(err, a);
4f0767ce 18627+out_success:
4a4d8108
AM
18628+ dput(a->src_wh_dentry);
18629+ dput(a->dst_wh_dentry);
4f0767ce 18630+out_thargs:
4a4d8108
AM
18631+ if (a->thargs) {
18632+ dput(a->h_dst);
18633+ au_whtmp_rmdir_free(a->thargs);
18634+ a->thargs = NULL;
18635+ }
4f0767ce 18636+out:
4a4d8108 18637+ return err;
dece6358 18638+}
1facf9fc 18639+
1308ab2a 18640+/* ---------------------------------------------------------------------- */
1facf9fc 18641+
4a4d8108
AM
18642+/*
18643+ * test if @dentry dir can be rename destination or not.
18644+ * success means, it is a logically empty dir.
18645+ */
18646+static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
1308ab2a 18647+{
4a4d8108 18648+ return au_test_empty(dentry, whlist);
1308ab2a 18649+}
1facf9fc 18650+
4a4d8108
AM
18651+/*
18652+ * test if @dentry dir can be rename source or not.
18653+ * if it can, return 0 and @children is filled.
18654+ * success means,
18655+ * - it is a logically empty dir.
18656+ * - or, it exists on writable branch and has no children including whiteouts
18657+ * on the lower branch.
18658+ */
18659+static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt)
18660+{
18661+ int err;
18662+ unsigned int rdhash;
18663+ aufs_bindex_t bstart;
1facf9fc 18664+
4a4d8108
AM
18665+ bstart = au_dbstart(dentry);
18666+ if (bstart != btgt) {
18667+ struct au_nhash whlist;
dece6358 18668+
4a4d8108
AM
18669+ SiMustAnyLock(dentry->d_sb);
18670+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
18671+ if (!rdhash)
18672+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL,
18673+ dentry));
18674+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
18675+ if (unlikely(err))
18676+ goto out;
18677+ err = au_test_empty(dentry, &whlist);
18678+ au_nhash_wh_free(&whlist);
18679+ goto out;
18680+ }
dece6358 18681+
4a4d8108
AM
18682+ if (bstart == au_dbtaildir(dentry))
18683+ return 0; /* success */
dece6358 18684+
4a4d8108 18685+ err = au_test_empty_lower(dentry);
1facf9fc 18686+
4f0767ce 18687+out:
4a4d8108
AM
18688+ if (err == -ENOTEMPTY) {
18689+ AuWarn1("renaming dir who has child(ren) on multiple branches,"
18690+ " is not supported\n");
18691+ err = -EXDEV;
18692+ }
18693+ return err;
18694+}
1308ab2a 18695+
4a4d8108
AM
18696+/* side effect: sets whlist and h_dentry */
18697+static int au_ren_may_dir(struct au_ren_args *a)
1308ab2a 18698+{
4a4d8108
AM
18699+ int err;
18700+ unsigned int rdhash;
18701+ struct dentry *d;
1facf9fc 18702+
4a4d8108
AM
18703+ d = a->dst_dentry;
18704+ SiMustAnyLock(d->d_sb);
1facf9fc 18705+
4a4d8108
AM
18706+ err = 0;
18707+ if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) {
18708+ rdhash = au_sbi(d->d_sb)->si_rdhash;
18709+ if (!rdhash)
18710+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d));
18711+ err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS);
18712+ if (unlikely(err))
18713+ goto out;
1308ab2a 18714+
4a4d8108
AM
18715+ au_set_dbstart(d, a->dst_bstart);
18716+ err = may_rename_dstdir(d, &a->whlist);
18717+ au_set_dbstart(d, a->btgt);
18718+ }
18719+ a->dst_h_dentry = au_h_dptr(d, au_dbstart(d));
18720+ if (unlikely(err))
18721+ goto out;
18722+
18723+ d = a->src_dentry;
18724+ a->src_h_dentry = au_h_dptr(d, au_dbstart(d));
18725+ if (au_ftest_ren(a->flags, ISDIR)) {
18726+ err = may_rename_srcdir(d, a->btgt);
18727+ if (unlikely(err)) {
18728+ au_nhash_wh_free(&a->whlist);
18729+ a->whlist.nh_num = 0;
18730+ }
18731+ }
4f0767ce 18732+out:
4a4d8108 18733+ return err;
1facf9fc 18734+}
18735+
4a4d8108 18736+/* ---------------------------------------------------------------------- */
1facf9fc 18737+
4a4d8108
AM
18738+/*
18739+ * simple tests for rename.
18740+ * following the checks in vfs, plus the parent-child relationship.
18741+ */
18742+static int au_may_ren(struct au_ren_args *a)
18743+{
18744+ int err, isdir;
18745+ struct inode *h_inode;
1facf9fc 18746+
4a4d8108
AM
18747+ if (a->src_bstart == a->btgt) {
18748+ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
18749+ au_ftest_ren(a->flags, ISDIR));
18750+ if (unlikely(err))
18751+ goto out;
18752+ err = -EINVAL;
18753+ if (unlikely(a->src_h_dentry == a->h_trap))
18754+ goto out;
18755+ }
1facf9fc 18756+
4a4d8108
AM
18757+ err = 0;
18758+ if (a->dst_bstart != a->btgt)
18759+ goto out;
1facf9fc 18760+
027c5e7a
AM
18761+ err = -ENOTEMPTY;
18762+ if (unlikely(a->dst_h_dentry == a->h_trap))
18763+ goto out;
18764+
4a4d8108
AM
18765+ err = -EIO;
18766+ h_inode = a->dst_h_dentry->d_inode;
18767+ isdir = !!au_ftest_ren(a->flags, ISDIR);
18768+ if (!a->dst_dentry->d_inode) {
18769+ if (unlikely(h_inode))
18770+ goto out;
18771+ err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent,
18772+ isdir);
18773+ } else {
18774+ if (unlikely(!h_inode || !h_inode->i_nlink))
18775+ goto out;
18776+ err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent,
18777+ isdir);
18778+ if (unlikely(err))
18779+ goto out;
4a4d8108 18780+ }
1facf9fc 18781+
4f0767ce 18782+out:
4a4d8108
AM
18783+ if (unlikely(err == -ENOENT || err == -EEXIST))
18784+ err = -EIO;
18785+ AuTraceErr(err);
18786+ return err;
18787+}
1facf9fc 18788+
1308ab2a 18789+/* ---------------------------------------------------------------------- */
1facf9fc 18790+
4a4d8108
AM
18791+/*
18792+ * locking order
18793+ * (VFS)
18794+ * - src_dir and dir by lock_rename()
18795+ * - inode if exitsts
18796+ * (aufs)
18797+ * - lock all
18798+ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
18799+ * + si_read_lock
18800+ * + di_write_lock2_child()
18801+ * + di_write_lock_child()
18802+ * + ii_write_lock_child()
18803+ * + di_write_lock_child2()
18804+ * + ii_write_lock_child2()
18805+ * + src_parent and parent
18806+ * + di_write_lock_parent()
18807+ * + ii_write_lock_parent()
18808+ * + di_write_lock_parent2()
18809+ * + ii_write_lock_parent2()
18810+ * + lower src_dir and dir by vfsub_lock_rename()
18811+ * + verify the every relationships between child and parent. if any
18812+ * of them failed, unlock all and return -EBUSY.
18813+ */
18814+static void au_ren_unlock(struct au_ren_args *a)
1308ab2a 18815+{
4a4d8108
AM
18816+ vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
18817+ a->dst_h_parent, a->dst_hdir);
86dc4139
AM
18818+ if (au_ftest_ren(a->flags, MNT_WRITE))
18819+ vfsub_mnt_drop_write(au_br_mnt(a->br));
1308ab2a 18820+}
18821+
4a4d8108 18822+static int au_ren_lock(struct au_ren_args *a)
1308ab2a 18823+{
4a4d8108
AM
18824+ int err;
18825+ unsigned int udba;
1308ab2a 18826+
4a4d8108
AM
18827+ err = 0;
18828+ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
18829+ a->src_hdir = au_hi(a->src_dir, a->btgt);
18830+ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
18831+ a->dst_hdir = au_hi(a->dst_dir, a->btgt);
86dc4139
AM
18832+
18833+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
18834+ if (unlikely(err))
18835+ goto out;
18836+ au_fset_ren(a->flags, MNT_WRITE);
4a4d8108
AM
18837+ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
18838+ a->dst_h_parent, a->dst_hdir);
18839+ udba = au_opt_udba(a->src_dentry->d_sb);
18840+ if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode
18841+ || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode))
18842+ err = au_busy_or_stale();
18843+ if (!err && au_dbstart(a->src_dentry) == a->btgt)
18844+ err = au_h_verify(a->src_h_dentry, udba,
18845+ a->src_h_parent->d_inode, a->src_h_parent,
18846+ a->br);
18847+ if (!err && au_dbstart(a->dst_dentry) == a->btgt)
18848+ err = au_h_verify(a->dst_h_dentry, udba,
18849+ a->dst_h_parent->d_inode, a->dst_h_parent,
18850+ a->br);
86dc4139 18851+ if (!err)
4a4d8108 18852+ goto out; /* success */
4a4d8108
AM
18853+
18854+ err = au_busy_or_stale();
4a4d8108 18855+ au_ren_unlock(a);
86dc4139 18856+
4f0767ce 18857+out:
4a4d8108 18858+ return err;
1facf9fc 18859+}
18860+
18861+/* ---------------------------------------------------------------------- */
18862+
4a4d8108 18863+static void au_ren_refresh_dir(struct au_ren_args *a)
1facf9fc 18864+{
4a4d8108 18865+ struct inode *dir;
dece6358 18866+
4a4d8108
AM
18867+ dir = a->dst_dir;
18868+ dir->i_version++;
18869+ if (au_ftest_ren(a->flags, ISDIR)) {
18870+ /* is this updating defined in POSIX? */
18871+ au_cpup_attr_timesizes(a->src_inode);
18872+ au_cpup_attr_nlink(dir, /*force*/1);
4a4d8108 18873+ }
027c5e7a 18874+
4a4d8108
AM
18875+ if (au_ibstart(dir) == a->btgt)
18876+ au_cpup_attr_timesizes(dir);
dece6358 18877+
4a4d8108
AM
18878+ if (au_ftest_ren(a->flags, ISSAMEDIR))
18879+ return;
dece6358 18880+
4a4d8108
AM
18881+ dir = a->src_dir;
18882+ dir->i_version++;
18883+ if (au_ftest_ren(a->flags, ISDIR))
18884+ au_cpup_attr_nlink(dir, /*force*/1);
18885+ if (au_ibstart(dir) == a->btgt)
18886+ au_cpup_attr_timesizes(dir);
1facf9fc 18887+}
18888+
4a4d8108 18889+static void au_ren_refresh(struct au_ren_args *a)
1facf9fc 18890+{
4a4d8108
AM
18891+ aufs_bindex_t bend, bindex;
18892+ struct dentry *d, *h_d;
18893+ struct inode *i, *h_i;
18894+ struct super_block *sb;
dece6358 18895+
027c5e7a
AM
18896+ d = a->dst_dentry;
18897+ d_drop(d);
18898+ if (a->h_dst)
18899+ /* already dget-ed by au_ren_or_cpup() */
18900+ au_set_h_dptr(d, a->btgt, a->h_dst);
18901+
18902+ i = a->dst_inode;
18903+ if (i) {
18904+ if (!au_ftest_ren(a->flags, ISDIR))
18905+ vfsub_drop_nlink(i);
18906+ else {
18907+ vfsub_dead_dir(i);
18908+ au_cpup_attr_timesizes(i);
18909+ }
18910+ au_update_dbrange(d, /*do_put_zero*/1);
18911+ } else {
18912+ bend = a->btgt;
18913+ for (bindex = au_dbstart(d); bindex < bend; bindex++)
18914+ au_set_h_dptr(d, bindex, NULL);
18915+ bend = au_dbend(d);
18916+ for (bindex = a->btgt + 1; bindex <= bend; bindex++)
18917+ au_set_h_dptr(d, bindex, NULL);
18918+ au_update_dbrange(d, /*do_put_zero*/0);
18919+ }
18920+
4a4d8108
AM
18921+ d = a->src_dentry;
18922+ au_set_dbwh(d, -1);
18923+ bend = au_dbend(d);
18924+ for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
18925+ h_d = au_h_dptr(d, bindex);
18926+ if (h_d)
18927+ au_set_h_dptr(d, bindex, NULL);
18928+ }
18929+ au_set_dbend(d, a->btgt);
18930+
18931+ sb = d->d_sb;
18932+ i = a->src_inode;
18933+ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
18934+ return; /* success */
18935+
18936+ bend = au_ibend(i);
18937+ for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
18938+ h_i = au_h_iptr(i, bindex);
18939+ if (h_i) {
18940+ au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
18941+ /* ignore this error */
18942+ au_set_h_iptr(i, bindex, NULL, 0);
18943+ }
18944+ }
18945+ au_set_ibend(i, a->btgt);
1308ab2a 18946+}
dece6358 18947+
4a4d8108
AM
18948+/* ---------------------------------------------------------------------- */
18949+
18950+/* mainly for link(2) and rename(2) */
18951+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
1308ab2a 18952+{
4a4d8108
AM
18953+ aufs_bindex_t bdiropq, bwh;
18954+ struct dentry *parent;
18955+ struct au_branch *br;
18956+
18957+ parent = dentry->d_parent;
18958+ IMustLock(parent->d_inode); /* dir is locked */
18959+
18960+ bdiropq = au_dbdiropq(parent);
18961+ bwh = au_dbwh(dentry);
18962+ br = au_sbr(dentry->d_sb, btgt);
18963+ if (au_br_rdonly(br)
18964+ || (0 <= bdiropq && bdiropq < btgt)
18965+ || (0 <= bwh && bwh < btgt))
18966+ btgt = -1;
18967+
18968+ AuDbg("btgt %d\n", btgt);
18969+ return btgt;
1facf9fc 18970+}
18971+
4a4d8108
AM
18972+/* sets src_bstart, dst_bstart and btgt */
18973+static int au_ren_wbr(struct au_ren_args *a)
1facf9fc 18974+{
4a4d8108
AM
18975+ int err;
18976+ struct au_wr_dir_args wr_dir_args = {
18977+ /* .force_btgt = -1, */
18978+ .flags = AuWrDir_ADD_ENTRY
18979+ };
dece6358 18980+
4a4d8108
AM
18981+ a->src_bstart = au_dbstart(a->src_dentry);
18982+ a->dst_bstart = au_dbstart(a->dst_dentry);
18983+ if (au_ftest_ren(a->flags, ISDIR))
18984+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
18985+ wr_dir_args.force_btgt = a->src_bstart;
18986+ if (a->dst_inode && a->dst_bstart < a->src_bstart)
18987+ wr_dir_args.force_btgt = a->dst_bstart;
18988+ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
18989+ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
18990+ a->btgt = err;
dece6358 18991+
4a4d8108 18992+ return err;
1facf9fc 18993+}
18994+
4a4d8108 18995+static void au_ren_dt(struct au_ren_args *a)
1facf9fc 18996+{
4a4d8108
AM
18997+ a->h_path.dentry = a->src_h_parent;
18998+ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
18999+ if (!au_ftest_ren(a->flags, ISSAMEDIR)) {
19000+ a->h_path.dentry = a->dst_h_parent;
19001+ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
19002+ }
1facf9fc 19003+
4a4d8108
AM
19004+ au_fclr_ren(a->flags, DT_DSTDIR);
19005+ if (!au_ftest_ren(a->flags, ISDIR))
19006+ return;
dece6358 19007+
4a4d8108
AM
19008+ a->h_path.dentry = a->src_h_dentry;
19009+ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
19010+ if (a->dst_h_dentry->d_inode) {
19011+ au_fset_ren(a->flags, DT_DSTDIR);
19012+ a->h_path.dentry = a->dst_h_dentry;
19013+ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
19014+ }
1308ab2a 19015+}
dece6358 19016+
4a4d8108 19017+static void au_ren_rev_dt(int err, struct au_ren_args *a)
1308ab2a 19018+{
4a4d8108
AM
19019+ struct dentry *h_d;
19020+ struct mutex *h_mtx;
19021+
19022+ au_dtime_revert(a->src_dt + AuPARENT);
19023+ if (!au_ftest_ren(a->flags, ISSAMEDIR))
19024+ au_dtime_revert(a->dst_dt + AuPARENT);
19025+
19026+ if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) {
19027+ h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
19028+ h_mtx = &h_d->d_inode->i_mutex;
19029+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
19030+ au_dtime_revert(a->src_dt + AuCHILD);
19031+ mutex_unlock(h_mtx);
19032+
19033+ if (au_ftest_ren(a->flags, DT_DSTDIR)) {
19034+ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
19035+ h_mtx = &h_d->d_inode->i_mutex;
19036+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
19037+ au_dtime_revert(a->dst_dt + AuCHILD);
19038+ mutex_unlock(h_mtx);
1facf9fc 19039+ }
19040+ }
19041+}
19042+
4a4d8108
AM
19043+/* ---------------------------------------------------------------------- */
19044+
19045+int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
19046+ struct inode *_dst_dir, struct dentry *_dst_dentry)
1facf9fc 19047+{
e49829fe 19048+ int err, flags;
4a4d8108
AM
19049+ /* reduce stack space */
19050+ struct au_ren_args *a;
19051+
19052+ AuDbg("%.*s, %.*s\n", AuDLNPair(_src_dentry), AuDLNPair(_dst_dentry));
19053+ IMustLock(_src_dir);
19054+ IMustLock(_dst_dir);
19055+
19056+ err = -ENOMEM;
19057+ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
19058+ a = kzalloc(sizeof(*a), GFP_NOFS);
19059+ if (unlikely(!a))
19060+ goto out;
19061+
19062+ a->src_dir = _src_dir;
19063+ a->src_dentry = _src_dentry;
19064+ a->src_inode = a->src_dentry->d_inode;
19065+ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
19066+ a->dst_dir = _dst_dir;
19067+ a->dst_dentry = _dst_dentry;
19068+ a->dst_inode = a->dst_dentry->d_inode;
19069+ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
19070+ if (a->dst_inode) {
19071+ IMustLock(a->dst_inode);
19072+ au_igrab(a->dst_inode);
1facf9fc 19073+ }
1facf9fc 19074+
4a4d8108 19075+ err = -ENOTDIR;
027c5e7a 19076+ flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
4a4d8108
AM
19077+ if (S_ISDIR(a->src_inode->i_mode)) {
19078+ au_fset_ren(a->flags, ISDIR);
19079+ if (unlikely(a->dst_inode && !S_ISDIR(a->dst_inode->i_mode)))
19080+ goto out_free;
e49829fe
JR
19081+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
19082+ AuLock_DIR | flags);
4a4d8108 19083+ } else
e49829fe
JR
19084+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
19085+ flags);
19086+ if (unlikely(err))
19087+ goto out_free;
1facf9fc 19088+
027c5e7a
AM
19089+ err = au_d_hashed_positive(a->src_dentry);
19090+ if (unlikely(err))
19091+ goto out_unlock;
19092+ err = -ENOENT;
19093+ if (a->dst_inode) {
19094+ /*
19095+ * If it is a dir, VFS unhash dst_dentry before this
19096+ * function. It means we cannot rely upon d_unhashed().
19097+ */
19098+ if (unlikely(!a->dst_inode->i_nlink))
19099+ goto out_unlock;
19100+ if (!S_ISDIR(a->dst_inode->i_mode)) {
19101+ err = au_d_hashed_positive(a->dst_dentry);
19102+ if (unlikely(err))
19103+ goto out_unlock;
19104+ } else if (unlikely(IS_DEADDIR(a->dst_inode)))
19105+ goto out_unlock;
19106+ } else if (unlikely(d_unhashed(a->dst_dentry)))
19107+ goto out_unlock;
19108+
7eafdf33
AM
19109+ /*
19110+ * is it possible?
19111+ * yes, it happend (in linux-3.3-rcN) but I don't know why.
19112+ * there may exist a problem somewhere else.
19113+ */
19114+ err = -EINVAL;
19115+ if (unlikely(a->dst_parent->d_inode == a->src_dentry->d_inode))
19116+ goto out_unlock;
19117+
4a4d8108
AM
19118+ au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
19119+ di_write_lock_parent(a->dst_parent);
1facf9fc 19120+
4a4d8108
AM
19121+ /* which branch we process */
19122+ err = au_ren_wbr(a);
19123+ if (unlikely(err < 0))
027c5e7a 19124+ goto out_parent;
4a4d8108 19125+ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
86dc4139 19126+ a->h_path.mnt = au_br_mnt(a->br);
1facf9fc 19127+
4a4d8108
AM
19128+ /* are they available to be renamed */
19129+ err = au_ren_may_dir(a);
19130+ if (unlikely(err))
19131+ goto out_children;
1facf9fc 19132+
4a4d8108
AM
19133+ /* prepare the writable parent dir on the same branch */
19134+ if (a->dst_bstart == a->btgt) {
19135+ au_fset_ren(a->flags, WHDST);
19136+ } else {
19137+ err = au_cpup_dirs(a->dst_dentry, a->btgt);
19138+ if (unlikely(err))
19139+ goto out_children;
19140+ }
1facf9fc 19141+
4a4d8108
AM
19142+ if (a->src_dir != a->dst_dir) {
19143+ /*
19144+ * this temporary unlock is safe,
19145+ * because both dir->i_mutex are locked.
19146+ */
19147+ di_write_unlock(a->dst_parent);
19148+ di_write_lock_parent(a->src_parent);
19149+ err = au_wr_dir_need_wh(a->src_dentry,
19150+ au_ftest_ren(a->flags, ISDIR),
19151+ &a->btgt);
19152+ di_write_unlock(a->src_parent);
19153+ di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1);
19154+ au_fclr_ren(a->flags, ISSAMEDIR);
19155+ } else
19156+ err = au_wr_dir_need_wh(a->src_dentry,
19157+ au_ftest_ren(a->flags, ISDIR),
19158+ &a->btgt);
19159+ if (unlikely(err < 0))
19160+ goto out_children;
19161+ if (err)
19162+ au_fset_ren(a->flags, WHSRC);
1facf9fc 19163+
86dc4139
AM
19164+ /* cpup src */
19165+ if (a->src_bstart != a->btgt) {
86dc4139
AM
19166+ struct au_pin pin;
19167+
19168+ err = au_pin(&pin, a->src_dentry, a->btgt,
19169+ au_opt_udba(a->src_dentry->d_sb),
19170+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 19171+ if (!err) {
c2b27bf2
AM
19172+ struct au_cp_generic cpg = {
19173+ .dentry = a->src_dentry,
19174+ .bdst = a->btgt,
19175+ .bsrc = a->src_bstart,
19176+ .len = -1,
19177+ .pin = &pin,
19178+ .flags = AuCpup_DTIME | AuCpup_HOPEN
19179+ };
367653fa 19180+ AuDebugOn(au_dbstart(a->src_dentry) != a->src_bstart);
c2b27bf2 19181+ err = au_sio_cpup_simple(&cpg);
367653fa 19182+ au_unpin(&pin);
86dc4139 19183+ }
86dc4139
AM
19184+ if (unlikely(err))
19185+ goto out_children;
19186+ a->src_bstart = a->btgt;
19187+ a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt);
19188+ au_fset_ren(a->flags, WHSRC);
19189+ }
19190+
4a4d8108
AM
19191+ /* lock them all */
19192+ err = au_ren_lock(a);
19193+ if (unlikely(err))
86dc4139 19194+ /* leave the copied-up one */
4a4d8108 19195+ goto out_children;
1facf9fc 19196+
4a4d8108
AM
19197+ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE))
19198+ err = au_may_ren(a);
19199+ else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN))
19200+ err = -ENAMETOOLONG;
19201+ if (unlikely(err))
19202+ goto out_hdir;
1facf9fc 19203+
4a4d8108
AM
19204+ /* store timestamps to be revertible */
19205+ au_ren_dt(a);
1facf9fc 19206+
4a4d8108
AM
19207+ /* here we go */
19208+ err = do_rename(a);
19209+ if (unlikely(err))
19210+ goto out_dt;
19211+
19212+ /* update dir attributes */
19213+ au_ren_refresh_dir(a);
19214+
19215+ /* dput/iput all lower dentries */
19216+ au_ren_refresh(a);
19217+
19218+ goto out_hdir; /* success */
19219+
4f0767ce 19220+out_dt:
4a4d8108 19221+ au_ren_rev_dt(err, a);
4f0767ce 19222+out_hdir:
4a4d8108 19223+ au_ren_unlock(a);
4f0767ce 19224+out_children:
4a4d8108 19225+ au_nhash_wh_free(&a->whlist);
027c5e7a
AM
19226+ if (err && a->dst_inode && a->dst_bstart != a->btgt) {
19227+ AuDbg("bstart %d, btgt %d\n", a->dst_bstart, a->btgt);
19228+ au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
19229+ au_set_dbstart(a->dst_dentry, a->dst_bstart);
4a4d8108 19230+ }
027c5e7a 19231+out_parent:
4a4d8108
AM
19232+ if (!err)
19233+ d_move(a->src_dentry, a->dst_dentry);
027c5e7a
AM
19234+ else {
19235+ au_update_dbstart(a->dst_dentry);
19236+ if (!a->dst_inode)
19237+ d_drop(a->dst_dentry);
19238+ }
4a4d8108
AM
19239+ if (au_ftest_ren(a->flags, ISSAMEDIR))
19240+ di_write_unlock(a->dst_parent);
19241+ else
19242+ di_write_unlock2(a->src_parent, a->dst_parent);
027c5e7a 19243+out_unlock:
4a4d8108 19244+ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
4f0767ce 19245+out_free:
4a4d8108
AM
19246+ iput(a->dst_inode);
19247+ if (a->thargs)
19248+ au_whtmp_rmdir_free(a->thargs);
19249+ kfree(a);
4f0767ce 19250+out:
4a4d8108
AM
19251+ AuTraceErr(err);
19252+ return err;
1308ab2a 19253+}
7f207e10
AM
19254diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
19255--- /usr/share/empty/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100
86dc4139 19256+++ linux/fs/aufs/Kconfig 2013-07-06 13:20:47.736864659 +0200
c06a8ce3 19257@@ -0,0 +1,202 @@
4a4d8108
AM
19258+config AUFS_FS
19259+ tristate "Aufs (Advanced multi layered unification filesystem) support"
4a4d8108
AM
19260+ help
19261+ Aufs is a stackable unification filesystem such as Unionfs,
19262+ which unifies several directories and provides a merged single
19263+ directory.
19264+ In the early days, aufs was entirely re-designed and
19265+ re-implemented Unionfs Version 1.x series. Introducing many
19266+ original ideas, approaches and improvements, it becomes totally
19267+ different from Unionfs while keeping the basic features.
1facf9fc 19268+
4a4d8108
AM
19269+if AUFS_FS
19270+choice
19271+ prompt "Maximum number of branches"
19272+ default AUFS_BRANCH_MAX_127
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_127
19278+ bool "127"
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+config AUFS_BRANCH_MAX_511
19284+ bool "511"
19285+ help
19286+ Specifies the maximum number of branches (or member directories)
19287+ in a single aufs. The larger value consumes more system
19288+ resources and has a minor impact to performance.
19289+config AUFS_BRANCH_MAX_1023
19290+ bool "1023"
19291+ help
19292+ Specifies the maximum number of branches (or member directories)
19293+ in a single aufs. The larger value consumes more system
19294+ resources and has a minor impact to performance.
19295+config AUFS_BRANCH_MAX_32767
19296+ bool "32767"
19297+ help
19298+ Specifies the maximum number of branches (or member directories)
19299+ in a single aufs. The larger value consumes more system
19300+ resources and has a minor impact to performance.
19301+endchoice
1facf9fc 19302+
e49829fe
JR
19303+config AUFS_SBILIST
19304+ bool
19305+ depends on AUFS_MAGIC_SYSRQ || PROC_FS
19306+ default y
19307+ help
19308+ Automatic configuration for internal use.
19309+ When aufs supports Magic SysRq or /proc, enabled automatically.
19310+
4a4d8108
AM
19311+config AUFS_HNOTIFY
19312+ bool "Detect direct branch access (bypassing aufs)"
19313+ help
19314+ If you want to modify files on branches directly, eg. bypassing aufs,
19315+ and want aufs to detect the changes of them fully, then enable this
19316+ option and use 'udba=notify' mount option.
7f207e10 19317+ Currently there is only one available configuration, "fsnotify".
4a4d8108
AM
19318+ It will have a negative impact to the performance.
19319+ See detail in aufs.5.
dece6358 19320+
4a4d8108
AM
19321+choice
19322+ prompt "method" if AUFS_HNOTIFY
19323+ default AUFS_HFSNOTIFY
19324+config AUFS_HFSNOTIFY
19325+ bool "fsnotify"
19326+ select FSNOTIFY
4a4d8108 19327+endchoice
1facf9fc 19328+
4a4d8108
AM
19329+config AUFS_EXPORT
19330+ bool "NFS-exportable aufs"
2cbb1c4b 19331+ depends on EXPORTFS
4a4d8108
AM
19332+ help
19333+ If you want to export your mounted aufs via NFS, then enable this
19334+ option. There are several requirements for this configuration.
19335+ See detail in aufs.5.
1facf9fc 19336+
4a4d8108
AM
19337+config AUFS_INO_T_64
19338+ bool
19339+ depends on AUFS_EXPORT
19340+ depends on 64BIT && !(ALPHA || S390)
19341+ default y
19342+ help
19343+ Automatic configuration for internal use.
19344+ /* typedef unsigned long/int __kernel_ino_t */
19345+ /* alpha and s390x are int */
1facf9fc 19346+
4a4d8108
AM
19347+config AUFS_RDU
19348+ bool "Readdir in userspace"
19349+ help
19350+ Aufs has two methods to provide a merged view for a directory,
19351+ by a user-space library and by kernel-space natively. The latter
19352+ is always enabled but sometimes large and slow.
19353+ If you enable this option, install the library in aufs2-util
19354+ package, and set some environment variables for your readdir(3),
19355+ then the work will be handled in user-space which generally
19356+ shows better performance in most cases.
19357+ See detail in aufs.5.
1facf9fc 19358+
2cbb1c4b
JR
19359+config AUFS_PROC_MAP
19360+ bool "support for /proc/maps and lsof(1)"
19361+ depends on PROC_FS
19362+ help
19363+ When you issue mmap(2) in aufs, it is actually a direct mmap(2)
19364+ call to the file on the branch fs since the file in aufs is
19365+ purely virtual. And the file path printed in /proc/maps (and
19366+ others) will be the path on the branch fs. In most cases, it
19367+ does no harm. But some utilities like lsof(1) may confuse since
19368+ the utility or user may expect the file path in aufs to be
19369+ printed.
19370+ To address this issue, aufs provides a patch which introduces a
19371+ new member called vm_prfile into struct vm_are_struct. The patch
19372+ is meaningless without enabling this configuration since nobody
19373+ sets the new vm_prfile member.
19374+ If you don't apply the patch, then enabling this configuration
19375+ will cause a compile error.
19376+ This approach is fragile since if someone else make some changes
19377+ around vm_file, then vm_prfile may not work anymore. As a
19378+ workaround such case, aufs provides this configuration. If you
19379+ disable it, then lsof(1) may produce incorrect result but the
19380+ problem will be gone even if the aufs patch is applied (I hope).
19381+
4a4d8108
AM
19382+config AUFS_SP_IATTR
19383+ bool "Respect the attributes (mtime/ctime mainly) of special files"
19384+ help
19385+ When you write something to a special file, some attributes of it
19386+ (mtime/ctime mainly) may be updated. Generally such updates are
19387+ less important (actually some device drivers and NFS ignore
19388+ it). But some applications (such like test program) requires
19389+ such updates. If you need these updates, then enable this
19390+ configuration which introduces some overhead.
19391+ Currently this configuration handles FIFO only.
1facf9fc 19392+
4a4d8108
AM
19393+config AUFS_SHWH
19394+ bool "Show whiteouts"
19395+ help
19396+ If you want to make the whiteouts in aufs visible, then enable
19397+ this option and specify 'shwh' mount option. Although it may
19398+ sounds like philosophy or something, but in technically it
19399+ simply shows the name of whiteout with keeping its behaviour.
1facf9fc 19400+
4a4d8108
AM
19401+config AUFS_BR_RAMFS
19402+ bool "Ramfs (initramfs/rootfs) as an aufs branch"
19403+ help
19404+ If you want to use ramfs as an aufs branch fs, then enable this
19405+ option. Generally tmpfs is recommended.
19406+ Aufs prohibited them to be a branch fs by default, because
19407+ initramfs becomes unusable after switch_root or something
19408+ generally. If you sets initramfs as an aufs branch and boot your
19409+ system by switch_root, you will meet a problem easily since the
19410+ files in initramfs may be inaccessible.
19411+ Unless you are going to use ramfs as an aufs branch fs without
19412+ switch_root or something, leave it N.
1facf9fc 19413+
4a4d8108
AM
19414+config AUFS_BR_FUSE
19415+ bool "Fuse fs as an aufs branch"
19416+ depends on FUSE_FS
19417+ select AUFS_POLL
19418+ help
19419+ If you want to use fuse-based userspace filesystem as an aufs
19420+ branch fs, then enable this option.
19421+ It implements the internal poll(2) operation which is
19422+ implemented by fuse only (curretnly).
1facf9fc 19423+
4a4d8108
AM
19424+config AUFS_POLL
19425+ bool
19426+ help
19427+ Automatic configuration for internal use.
1facf9fc 19428+
4a4d8108
AM
19429+config AUFS_BR_HFSPLUS
19430+ bool "Hfsplus as an aufs branch"
19431+ depends on HFSPLUS_FS
19432+ default y
19433+ help
19434+ If you want to use hfsplus fs as an aufs branch fs, then enable
19435+ this option. This option introduces a small overhead at
19436+ copying-up a file on hfsplus.
1facf9fc 19437+
4a4d8108
AM
19438+config AUFS_BDEV_LOOP
19439+ bool
19440+ depends on BLK_DEV_LOOP
19441+ default y
19442+ help
19443+ Automatic configuration for internal use.
19444+ Convert =[ym] into =y.
1308ab2a 19445+
4a4d8108
AM
19446+config AUFS_DEBUG
19447+ bool "Debug aufs"
19448+ help
19449+ Enable this to compile aufs internal debug code.
19450+ It will have a negative impact to the performance.
19451+
19452+config AUFS_MAGIC_SYSRQ
19453+ bool
19454+ depends on AUFS_DEBUG && MAGIC_SYSRQ
19455+ default y
19456+ help
19457+ Automatic configuration for internal use.
19458+ When aufs supports Magic SysRq, enabled automatically.
19459+endif
7f207e10
AM
19460diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
19461--- /usr/share/empty/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
19462+++ linux/fs/aufs/loop.c 2013-10-26 16:51:32.276373845 +0200
19463@@ -0,0 +1,146 @@
1facf9fc 19464+/*
7a9e40b8 19465+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 19466+ *
19467+ * This program, aufs is free software; you can redistribute it and/or modify
19468+ * it under the terms of the GNU General Public License as published by
19469+ * the Free Software Foundation; either version 2 of the License, or
19470+ * (at your option) any later version.
dece6358
AM
19471+ *
19472+ * This program is distributed in the hope that it will be useful,
19473+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19474+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19475+ * GNU General Public License for more details.
19476+ *
19477+ * You should have received a copy of the GNU General Public License
19478+ * along with this program; if not, write to the Free Software
19479+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 19480+ */
19481+
19482+/*
19483+ * support for loopback block device as a branch
19484+ */
19485+
1facf9fc 19486+#include "aufs.h"
19487+
392086de
AM
19488+/* added into drivers/block/loop.c */
19489+static struct file *(*backing_file_func)(struct super_block *sb);
19490+
1facf9fc 19491+/*
19492+ * test if two lower dentries have overlapping branches.
19493+ */
b752ccd1 19494+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
1facf9fc 19495+{
b752ccd1 19496+ struct super_block *h_sb;
392086de
AM
19497+ struct file *backing_file;
19498+
19499+ if (unlikely(!backing_file_func)) {
19500+ /* don't load "loop" module here */
19501+ backing_file_func = symbol_get(loop_backing_file);
19502+ if (unlikely(!backing_file_func))
19503+ /* "loop" module is not loaded */
19504+ return 0;
19505+ }
1facf9fc 19506+
b752ccd1 19507+ h_sb = h_adding->d_sb;
392086de
AM
19508+ backing_file = backing_file_func(h_sb);
19509+ if (!backing_file)
1facf9fc 19510+ return 0;
19511+
392086de 19512+ h_adding = backing_file->f_dentry;
b752ccd1
AM
19513+ /*
19514+ * h_adding can be local NFS.
19515+ * in this case aufs cannot detect the loop.
19516+ */
19517+ if (unlikely(h_adding->d_sb == sb))
1facf9fc 19518+ return 1;
b752ccd1 19519+ return !!au_test_subdir(h_adding, sb->s_root);
1facf9fc 19520+}
19521+
19522+/* true if a kernel thread named 'loop[0-9].*' accesses a file */
19523+int au_test_loopback_kthread(void)
19524+{
b752ccd1
AM
19525+ int ret;
19526+ struct task_struct *tsk = current;
a2a7ad62 19527+ char c, comm[sizeof(tsk->comm)];
b752ccd1
AM
19528+
19529+ ret = 0;
19530+ if (tsk->flags & PF_KTHREAD) {
a2a7ad62
AM
19531+ get_task_comm(comm, tsk);
19532+ c = comm[4];
b752ccd1 19533+ ret = ('0' <= c && c <= '9'
a2a7ad62 19534+ && !strncmp(comm, "loop", 4));
b752ccd1 19535+ }
1facf9fc 19536+
b752ccd1 19537+ return ret;
1facf9fc 19538+}
87a755f4
AM
19539+
19540+/* ---------------------------------------------------------------------- */
19541+
19542+#define au_warn_loopback_step 16
19543+static int au_warn_loopback_nelem = au_warn_loopback_step;
19544+static unsigned long *au_warn_loopback_array;
19545+
19546+void au_warn_loopback(struct super_block *h_sb)
19547+{
19548+ int i, new_nelem;
19549+ unsigned long *a, magic;
19550+ static DEFINE_SPINLOCK(spin);
19551+
19552+ magic = h_sb->s_magic;
19553+ spin_lock(&spin);
19554+ a = au_warn_loopback_array;
19555+ for (i = 0; i < au_warn_loopback_nelem && *a; i++)
19556+ if (a[i] == magic) {
19557+ spin_unlock(&spin);
19558+ return;
19559+ }
19560+
19561+ /* h_sb is new to us, print it */
19562+ if (i < au_warn_loopback_nelem) {
19563+ a[i] = magic;
19564+ goto pr;
19565+ }
19566+
19567+ /* expand the array */
19568+ new_nelem = au_warn_loopback_nelem + au_warn_loopback_step;
19569+ a = au_kzrealloc(au_warn_loopback_array,
19570+ au_warn_loopback_nelem * sizeof(unsigned long),
19571+ new_nelem * sizeof(unsigned long), GFP_ATOMIC);
19572+ if (a) {
19573+ au_warn_loopback_nelem = new_nelem;
19574+ au_warn_loopback_array = a;
19575+ a[i] = magic;
19576+ goto pr;
19577+ }
19578+
19579+ spin_unlock(&spin);
19580+ AuWarn1("realloc failed, ignored\n");
19581+ return;
19582+
19583+pr:
19584+ spin_unlock(&spin);
0c3ec466
AM
19585+ pr_warn("you may want to try another patch for loopback file "
19586+ "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic);
87a755f4
AM
19587+}
19588+
19589+int au_loopback_init(void)
19590+{
19591+ int err;
19592+ struct super_block *sb __maybe_unused;
19593+
19594+ AuDebugOn(sizeof(sb->s_magic) != sizeof(unsigned long));
19595+
19596+ err = 0;
19597+ au_warn_loopback_array = kcalloc(au_warn_loopback_step,
19598+ sizeof(unsigned long), GFP_NOFS);
19599+ if (unlikely(!au_warn_loopback_array))
19600+ err = -ENOMEM;
19601+
19602+ return err;
19603+}
19604+
19605+void au_loopback_fin(void)
19606+{
392086de 19607+ symbol_put(loop_backing_file);
87a755f4
AM
19608+ kfree(au_warn_loopback_array);
19609+}
7f207e10
AM
19610diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
19611--- /usr/share/empty/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
392086de
AM
19612+++ linux/fs/aufs/loop.h 2013-10-26 16:51:29.586298347 +0200
19613@@ -0,0 +1,53 @@
1facf9fc 19614+/*
7a9e40b8 19615+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 19616+ *
19617+ * This program, aufs is free software; you can redistribute it and/or modify
19618+ * it under the terms of the GNU General Public License as published by
19619+ * the Free Software Foundation; either version 2 of the License, or
19620+ * (at your option) any later version.
dece6358
AM
19621+ *
19622+ * This program is distributed in the hope that it will be useful,
19623+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19624+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19625+ * GNU General Public License for more details.
19626+ *
19627+ * You should have received a copy of the GNU General Public License
19628+ * along with this program; if not, write to the Free Software
19629+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 19630+ */
19631+
19632+/*
19633+ * support for loopback mount as a branch
19634+ */
19635+
19636+#ifndef __AUFS_LOOP_H__
19637+#define __AUFS_LOOP_H__
19638+
19639+#ifdef __KERNEL__
19640+
dece6358
AM
19641+struct dentry;
19642+struct super_block;
1facf9fc 19643+
19644+#ifdef CONFIG_AUFS_BDEV_LOOP
392086de
AM
19645+/* drivers/block/loop.c */
19646+struct file *loop_backing_file(struct super_block *sb);
19647+
1facf9fc 19648+/* loop.c */
b752ccd1 19649+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding);
1facf9fc 19650+int au_test_loopback_kthread(void);
87a755f4
AM
19651+void au_warn_loopback(struct super_block *h_sb);
19652+
19653+int au_loopback_init(void);
19654+void au_loopback_fin(void);
1facf9fc 19655+#else
4a4d8108 19656+AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
b752ccd1 19657+ struct dentry *h_adding)
4a4d8108 19658+AuStubInt0(au_test_loopback_kthread, void)
87a755f4
AM
19659+AuStubVoid(au_warn_loopback, struct super_block *h_sb)
19660+
19661+AuStubInt0(au_loopback_init, void)
19662+AuStubVoid(au_loopback_fin, void)
1facf9fc 19663+#endif /* BLK_DEV_LOOP */
19664+
19665+#endif /* __KERNEL__ */
19666+#endif /* __AUFS_LOOP_H__ */
7f207e10
AM
19667diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
19668--- /usr/share/empty/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100
86dc4139 19669+++ linux/fs/aufs/magic.mk 2013-07-06 13:20:47.750198454 +0200
4a4d8108 19670@@ -0,0 +1,54 @@
1facf9fc 19671+
19672+# defined in ${srctree}/fs/fuse/inode.c
19673+# tristate
19674+ifdef CONFIG_FUSE_FS
19675+ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
19676+endif
19677+
19678+# defined in ${srctree}/fs/ocfs2/ocfs2_fs.h
19679+# tristate
19680+ifdef CONFIG_OCFS2_FS
19681+ccflags-y += -DOCFS2_SUPER_MAGIC=0x7461636f
19682+endif
19683+
19684+# defined in ${srctree}/fs/ocfs2/dlm/userdlm.h
19685+# tristate
19686+ifdef CONFIG_OCFS2_FS_O2CB
19687+ccflags-y += -DDLMFS_MAGIC=0x76a9f425
19688+endif
19689+
1facf9fc 19690+# defined in ${srctree}/fs/cifs/cifsfs.c
19691+# tristate
19692+ifdef CONFIG_CIFS_FS
19693+ccflags-y += -DCIFS_MAGIC_NUMBER=0xFF534D42
19694+endif
19695+
19696+# defined in ${srctree}/fs/xfs/xfs_sb.h
19697+# tristate
19698+ifdef CONFIG_XFS_FS
19699+ccflags-y += -DXFS_SB_MAGIC=0x58465342
19700+endif
19701+
19702+# defined in ${srctree}/fs/configfs/mount.c
19703+# tristate
19704+ifdef CONFIG_CONFIGFS_FS
19705+ccflags-y += -DCONFIGFS_MAGIC=0x62656570
19706+endif
19707+
19708+# defined in ${srctree}/fs/9p/v9fs.h
19709+# tristate
19710+ifdef CONFIG_9P_FS
19711+ccflags-y += -DV9FS_MAGIC=0x01021997
19712+endif
19713+
19714+# defined in ${srctree}/fs/ubifs/ubifs.h
19715+# tristate
19716+ifdef CONFIG_UBIFS_FS
19717+ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
19718+endif
4a4d8108
AM
19719+
19720+# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h
19721+# tristate
19722+ifdef CONFIG_HFSPLUS_FS
19723+ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b
19724+endif
7f207e10
AM
19725diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
19726--- /usr/share/empty/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100
392086de 19727+++ linux/fs/aufs/Makefile 2013-10-26 16:51:32.273040419 +0200
2dfbb274 19728@@ -0,0 +1,42 @@
4a4d8108
AM
19729+
19730+include ${src}/magic.mk
19731+ifeq (${CONFIG_AUFS_FS},m)
19732+include ${src}/conf.mk
19733+endif
19734+-include ${src}/priv_def.mk
19735+
19736+# cf. include/linux/kernel.h
19737+# enable pr_debug
19738+ccflags-y += -DDEBUG
f6c5ef8b
AM
19739+# sparse requires the full pathname
19740+ifdef M
19741+ccflags-y += -include ${M}/../../include/linux/aufs_type.h
19742+else
19743+ccflags-y += -include ${srctree}/include/linux/aufs_type.h
19744+endif
4a4d8108
AM
19745+
19746+obj-$(CONFIG_AUFS_FS) += aufs.o
19747+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
19748+ wkq.o vfsub.o dcsub.o \
e49829fe 19749+ cpup.o whout.o wbr_policy.o \
4a4d8108
AM
19750+ dinfo.o dentry.o \
19751+ dynop.o \
19752+ finfo.o file.o f_op.o \
19753+ dir.o vdir.o \
19754+ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
c2b27bf2 19755+ mvdown.o ioctl.o
4a4d8108
AM
19756+
19757+# all are boolean
e49829fe 19758+aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
4a4d8108
AM
19759+aufs-$(CONFIG_SYSFS) += sysfs.o
19760+aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
19761+aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
19762+aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
19763+aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
4a4d8108
AM
19764+aufs-$(CONFIG_AUFS_EXPORT) += export.o
19765+aufs-$(CONFIG_AUFS_POLL) += poll.o
19766+aufs-$(CONFIG_AUFS_RDU) += rdu.o
19767+aufs-$(CONFIG_AUFS_SP_IATTR) += f_op_sp.o
19768+aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
19769+aufs-$(CONFIG_AUFS_DEBUG) += debug.o
19770+aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
7f207e10
AM
19771diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
19772--- /usr/share/empty/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100
86dc4139 19773+++ linux/fs/aufs/module.c 2013-07-06 13:20:47.750198454 +0200
c06a8ce3 19774@@ -0,0 +1,203 @@
1facf9fc 19775+/*
7a9e40b8 19776+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 19777+ *
19778+ * This program, aufs is free software; you can redistribute it and/or modify
19779+ * it under the terms of the GNU General Public License as published by
19780+ * the Free Software Foundation; either version 2 of the License, or
19781+ * (at your option) any later version.
dece6358
AM
19782+ *
19783+ * This program is distributed in the hope that it will be useful,
19784+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19785+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19786+ * GNU General Public License for more details.
19787+ *
19788+ * You should have received a copy of the GNU General Public License
19789+ * along with this program; if not, write to the Free Software
19790+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 19791+ */
19792+
19793+/*
19794+ * module global variables and operations
19795+ */
19796+
19797+#include <linux/module.h>
19798+#include <linux/seq_file.h>
19799+#include "aufs.h"
19800+
19801+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp)
19802+{
19803+ if (new_sz <= nused)
19804+ return p;
19805+
19806+ p = krealloc(p, new_sz, gfp);
19807+ if (p)
19808+ memset(p + nused, 0, new_sz - nused);
19809+ return p;
19810+}
19811+
19812+/* ---------------------------------------------------------------------- */
19813+
19814+/*
19815+ * aufs caches
19816+ */
19817+struct kmem_cache *au_cachep[AuCache_Last];
19818+static int __init au_cache_init(void)
19819+{
4a4d8108 19820+ au_cachep[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
1facf9fc 19821+ if (au_cachep[AuCache_DINFO])
027c5e7a 19822+ /* SLAB_DESTROY_BY_RCU */
4a4d8108
AM
19823+ au_cachep[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
19824+ au_icntnr_init_once);
1facf9fc 19825+ if (au_cachep[AuCache_ICNTNR])
4a4d8108
AM
19826+ au_cachep[AuCache_FINFO] = AuCacheCtor(au_finfo,
19827+ au_fi_init_once);
1facf9fc 19828+ if (au_cachep[AuCache_FINFO])
19829+ au_cachep[AuCache_VDIR] = AuCache(au_vdir);
19830+ if (au_cachep[AuCache_VDIR])
19831+ au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
19832+ if (au_cachep[AuCache_DEHSTR])
19833+ return 0;
19834+
19835+ return -ENOMEM;
19836+}
19837+
19838+static void au_cache_fin(void)
19839+{
19840+ int i;
4a4d8108 19841+
537831f9
AM
19842+ /*
19843+ * Make sure all delayed rcu free inodes are flushed before we
19844+ * destroy cache.
19845+ */
19846+ rcu_barrier();
19847+
7eafdf33
AM
19848+ /* excluding AuCache_HNOTIFY */
19849+ BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
19850+ for (i = 0; i < AuCache_HNOTIFY; i++)
1facf9fc 19851+ if (au_cachep[i]) {
19852+ kmem_cache_destroy(au_cachep[i]);
19853+ au_cachep[i] = NULL;
19854+ }
19855+}
19856+
19857+/* ---------------------------------------------------------------------- */
19858+
19859+int au_dir_roflags;
19860+
e49829fe 19861+#ifdef CONFIG_AUFS_SBILIST
1e00d052
AM
19862+/*
19863+ * iterate_supers_type() doesn't protect us from
19864+ * remounting (branch management)
19865+ */
e49829fe
JR
19866+struct au_splhead au_sbilist;
19867+#endif
19868+
9dbd164d
AM
19869+struct lock_class_key au_lc_key[AuLcKey_Last];
19870+
1facf9fc 19871+/*
19872+ * functions for module interface.
19873+ */
19874+MODULE_LICENSE("GPL");
19875+/* MODULE_LICENSE("GPL v2"); */
dece6358 19876+MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
1facf9fc 19877+MODULE_DESCRIPTION(AUFS_NAME
19878+ " -- Advanced multi layered unification filesystem");
19879+MODULE_VERSION(AUFS_VERSION);
c06a8ce3 19880+MODULE_ALIAS_FS(AUFS_NAME);
1facf9fc 19881+
1facf9fc 19882+/* this module parameter has no meaning when SYSFS is disabled */
19883+int sysaufs_brs = 1;
19884+MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
19885+module_param_named(brs, sysaufs_brs, int, S_IRUGO);
19886+
19887+/* ---------------------------------------------------------------------- */
19888+
19889+static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
19890+
19891+int au_seq_path(struct seq_file *seq, struct path *path)
19892+{
19893+ return seq_path(seq, path, au_esc_chars);
19894+}
19895+
19896+/* ---------------------------------------------------------------------- */
19897+
19898+static int __init aufs_init(void)
19899+{
19900+ int err, i;
19901+ char *p;
19902+
19903+ p = au_esc_chars;
19904+ for (i = 1; i <= ' '; i++)
19905+ *p++ = i;
19906+ *p++ = '\\';
19907+ *p++ = '\x7f';
19908+ *p = 0;
19909+
19910+ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
19911+
e49829fe 19912+ au_sbilist_init();
1facf9fc 19913+ sysaufs_brs_init();
19914+ au_debug_init();
4a4d8108 19915+ au_dy_init();
1facf9fc 19916+ err = sysaufs_init();
19917+ if (unlikely(err))
19918+ goto out;
e49829fe 19919+ err = au_procfs_init();
4f0767ce 19920+ if (unlikely(err))
953406b4 19921+ goto out_sysaufs;
e49829fe
JR
19922+ err = au_wkq_init();
19923+ if (unlikely(err))
19924+ goto out_procfs;
87a755f4 19925+ err = au_loopback_init();
1facf9fc 19926+ if (unlikely(err))
19927+ goto out_wkq;
87a755f4
AM
19928+ err = au_hnotify_init();
19929+ if (unlikely(err))
19930+ goto out_loopback;
1facf9fc 19931+ err = au_sysrq_init();
19932+ if (unlikely(err))
19933+ goto out_hin;
19934+ err = au_cache_init();
19935+ if (unlikely(err))
19936+ goto out_sysrq;
19937+ err = register_filesystem(&aufs_fs_type);
19938+ if (unlikely(err))
19939+ goto out_cache;
4a4d8108
AM
19940+ /* since we define pr_fmt, call printk directly */
19941+ printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
1facf9fc 19942+ goto out; /* success */
19943+
4f0767ce 19944+out_cache:
1facf9fc 19945+ au_cache_fin();
4f0767ce 19946+out_sysrq:
1facf9fc 19947+ au_sysrq_fin();
4f0767ce 19948+out_hin:
4a4d8108 19949+ au_hnotify_fin();
87a755f4
AM
19950+out_loopback:
19951+ au_loopback_fin();
4f0767ce 19952+out_wkq:
1facf9fc 19953+ au_wkq_fin();
e49829fe
JR
19954+out_procfs:
19955+ au_procfs_fin();
4f0767ce 19956+out_sysaufs:
1facf9fc 19957+ sysaufs_fin();
4a4d8108 19958+ au_dy_fin();
4f0767ce 19959+out:
1facf9fc 19960+ return err;
19961+}
19962+
19963+static void __exit aufs_exit(void)
19964+{
19965+ unregister_filesystem(&aufs_fs_type);
19966+ au_cache_fin();
19967+ au_sysrq_fin();
4a4d8108 19968+ au_hnotify_fin();
87a755f4 19969+ au_loopback_fin();
1facf9fc 19970+ au_wkq_fin();
e49829fe 19971+ au_procfs_fin();
1facf9fc 19972+ sysaufs_fin();
4a4d8108 19973+ au_dy_fin();
1facf9fc 19974+}
19975+
19976+module_init(aufs_init);
19977+module_exit(aufs_exit);
7f207e10
AM
19978diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
19979--- /usr/share/empty/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100
86dc4139 19980+++ linux/fs/aufs/module.h 2013-07-06 13:20:47.750198454 +0200
7eafdf33 19981@@ -0,0 +1,105 @@
1facf9fc 19982+/*
7a9e40b8 19983+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 19984+ *
19985+ * This program, aufs is free software; you can redistribute it and/or modify
19986+ * it under the terms of the GNU General Public License as published by
19987+ * the Free Software Foundation; either version 2 of the License, or
19988+ * (at your option) any later version.
dece6358
AM
19989+ *
19990+ * This program is distributed in the hope that it will be useful,
19991+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19992+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19993+ * GNU General Public License for more details.
19994+ *
19995+ * You should have received a copy of the GNU General Public License
19996+ * along with this program; if not, write to the Free Software
19997+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 19998+ */
19999+
20000+/*
20001+ * module initialization and module-global
20002+ */
20003+
20004+#ifndef __AUFS_MODULE_H__
20005+#define __AUFS_MODULE_H__
20006+
20007+#ifdef __KERNEL__
20008+
20009+#include <linux/slab.h>
20010+
dece6358
AM
20011+struct path;
20012+struct seq_file;
20013+
1facf9fc 20014+/* module parameters */
1facf9fc 20015+extern int sysaufs_brs;
20016+
20017+/* ---------------------------------------------------------------------- */
20018+
20019+extern int au_dir_roflags;
20020+
9dbd164d
AM
20021+enum {
20022+ AuLcNonDir_FIINFO,
20023+ AuLcNonDir_DIINFO,
20024+ AuLcNonDir_IIINFO,
20025+
20026+ AuLcDir_FIINFO,
20027+ AuLcDir_DIINFO,
20028+ AuLcDir_IIINFO,
20029+
20030+ AuLcSymlink_DIINFO,
20031+ AuLcSymlink_IIINFO,
20032+
20033+ AuLcKey_Last
20034+};
20035+extern struct lock_class_key au_lc_key[AuLcKey_Last];
20036+
1facf9fc 20037+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp);
20038+int au_seq_path(struct seq_file *seq, struct path *path);
20039+
e49829fe
JR
20040+#ifdef CONFIG_PROC_FS
20041+/* procfs.c */
20042+int __init au_procfs_init(void);
20043+void au_procfs_fin(void);
20044+#else
20045+AuStubInt0(au_procfs_init, void);
20046+AuStubVoid(au_procfs_fin, void);
20047+#endif
20048+
4f0767ce
JR
20049+/* ---------------------------------------------------------------------- */
20050+
20051+/* kmem cache */
1facf9fc 20052+enum {
20053+ AuCache_DINFO,
20054+ AuCache_ICNTNR,
20055+ AuCache_FINFO,
20056+ AuCache_VDIR,
20057+ AuCache_DEHSTR,
7eafdf33 20058+ AuCache_HNOTIFY, /* must be last */
1facf9fc 20059+ AuCache_Last
20060+};
20061+
4a4d8108
AM
20062+#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
20063+#define AuCache(type) KMEM_CACHE(type, AuCacheFlags)
20064+#define AuCacheCtor(type, ctor) \
20065+ kmem_cache_create(#type, sizeof(struct type), \
20066+ __alignof__(struct type), AuCacheFlags, ctor)
1facf9fc 20067+
20068+extern struct kmem_cache *au_cachep[];
20069+
20070+#define AuCacheFuncs(name, index) \
4a4d8108 20071+static inline struct au_##name *au_cache_alloc_##name(void) \
1facf9fc 20072+{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \
4a4d8108 20073+static inline void au_cache_free_##name(struct au_##name *p) \
1facf9fc 20074+{ kmem_cache_free(au_cachep[AuCache_##index], p); }
20075+
20076+AuCacheFuncs(dinfo, DINFO);
20077+AuCacheFuncs(icntnr, ICNTNR);
20078+AuCacheFuncs(finfo, FINFO);
20079+AuCacheFuncs(vdir, VDIR);
4a4d8108
AM
20080+AuCacheFuncs(vdir_dehstr, DEHSTR);
20081+#ifdef CONFIG_AUFS_HNOTIFY
20082+AuCacheFuncs(hnotify, HNOTIFY);
20083+#endif
1facf9fc 20084+
4a4d8108
AM
20085+#endif /* __KERNEL__ */
20086+#endif /* __AUFS_MODULE_H__ */
c2b27bf2
AM
20087diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
20088--- /usr/share/empty/fs/aufs/mvdown.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
20089+++ linux/fs/aufs/mvdown.c 2013-10-26 16:51:32.276373845 +0200
20090@@ -0,0 +1,610 @@
c2b27bf2
AM
20091+/*
20092+ * Copyright (C) 2011-2013 Junjiro R. Okajima
20093+ *
20094+ * This program, aufs is free software; you can redistribute it and/or modify
20095+ * it under the terms of the GNU General Public License as published by
20096+ * the Free Software Foundation; either version 2 of the License, or
20097+ * (at your option) any later version.
20098+ *
20099+ * This program is distributed in the hope that it will be useful,
20100+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20101+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20102+ * GNU General Public License for more details.
20103+ *
20104+ * You should have received a copy of the GNU General Public License
20105+ * along with this program; if not, write to the Free Software
20106+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20107+ */
20108+
20109+#include "aufs.h"
20110+
c2b27bf2
AM
20111+struct au_mvd_args {
20112+ struct {
c2b27bf2
AM
20113+ struct super_block *h_sb;
20114+ struct dentry *h_parent;
20115+ struct au_hinode *hdir;
392086de 20116+ struct inode *h_dir, *h_inode;
c2b27bf2
AM
20117+ } info[AUFS_MVDOWN_NARRAY];
20118+
20119+ struct aufs_mvdown mvdown;
20120+ struct dentry *dentry, *parent;
20121+ struct inode *inode, *dir;
20122+ struct super_block *sb;
20123+ aufs_bindex_t bopq, bwh, bfound;
20124+ unsigned char rename_lock;
20125+ struct au_pin pin;
20126+};
20127+
392086de
AM
20128+#define mvd_errno mvdown.au_errno
20129+#define mvd_bsrc mvdown.a[AUFS_MVDOWN_UPPER].bindex
20130+#define mvd_src_brid mvdown.a[AUFS_MVDOWN_UPPER].brid
20131+#define mvd_bdst mvdown.a[AUFS_MVDOWN_LOWER].bindex
20132+#define mvd_dst_brid mvdown.a[AUFS_MVDOWN_LOWER].brid
c2b27bf2 20133+
392086de
AM
20134+#define mvd_h_src_sb info[AUFS_MVDOWN_UPPER].h_sb
20135+#define mvd_h_src_parent info[AUFS_MVDOWN_UPPER].h_parent
20136+#define mvd_hdir_src info[AUFS_MVDOWN_UPPER].hdir
20137+#define mvd_h_src_dir info[AUFS_MVDOWN_UPPER].h_dir
20138+#define mvd_h_src_inode info[AUFS_MVDOWN_UPPER].h_inode
20139+
20140+#define mvd_h_dst_sb info[AUFS_MVDOWN_LOWER].h_sb
20141+#define mvd_h_dst_parent info[AUFS_MVDOWN_LOWER].h_parent
20142+#define mvd_hdir_dst info[AUFS_MVDOWN_LOWER].hdir
20143+#define mvd_h_dst_dir info[AUFS_MVDOWN_LOWER].h_dir
20144+#define mvd_h_dst_inode info[AUFS_MVDOWN_LOWER].h_inode
c2b27bf2
AM
20145+
20146+#define AU_MVD_PR(flag, ...) do { \
20147+ if (flag) \
20148+ pr_err(__VA_ARGS__); \
20149+ } while (0)
20150+
20151+/* make the parent dir on bdst */
392086de 20152+static int au_do_mkdir(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20153+{
20154+ int err;
20155+
20156+ err = 0;
20157+ a->mvd_hdir_src = au_hi(a->dir, a->mvd_bsrc);
20158+ a->mvd_hdir_dst = au_hi(a->dir, a->mvd_bdst);
20159+ a->mvd_h_src_parent = au_h_dptr(a->parent, a->mvd_bsrc);
20160+ a->mvd_h_dst_parent = NULL;
20161+ if (au_dbend(a->parent) >= a->mvd_bdst)
20162+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
20163+ if (!a->mvd_h_dst_parent) {
20164+ err = au_cpdown_dirs(a->dentry, a->mvd_bdst);
20165+ if (unlikely(err)) {
392086de 20166+ AU_MVD_PR(dmsg, "cpdown_dirs failed\n");
c2b27bf2
AM
20167+ goto out;
20168+ }
20169+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
20170+ }
20171+
20172+out:
20173+ AuTraceErr(err);
20174+ return err;
20175+}
20176+
20177+/* lock them all */
392086de 20178+static int au_do_lock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20179+{
20180+ int err;
20181+ struct dentry *h_trap;
20182+
20183+ a->mvd_h_src_sb = au_sbr_sb(a->sb, a->mvd_bsrc);
20184+ a->mvd_h_dst_sb = au_sbr_sb(a->sb, a->mvd_bdst);
20185+ if (a->mvd_h_src_sb != a->mvd_h_dst_sb) {
20186+ a->rename_lock = 0;
392086de
AM
20187+ err = au_pin(&a->pin, a->dentry, a->mvd_bdst,
20188+ au_opt_udba(a->sb),
c2b27bf2
AM
20189+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
20190+ if (!err) {
20191+ a->mvd_h_src_dir = a->mvd_h_src_parent->d_inode;
20192+ mutex_lock_nested(&a->mvd_h_src_dir->i_mutex,
20193+ AuLsc_I_PARENT3);
20194+ } else
392086de 20195+ AU_MVD_PR(dmsg, "pin failed\n");
c2b27bf2
AM
20196+ goto out;
20197+ }
20198+
20199+ err = 0;
20200+ a->rename_lock = 1;
20201+ h_trap = vfsub_lock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
20202+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
20203+ if (h_trap) {
20204+ err = (h_trap != a->mvd_h_src_parent);
20205+ if (err)
20206+ err = (h_trap != a->mvd_h_dst_parent);
20207+ }
20208+ BUG_ON(err); /* it should never happen */
20209+
20210+out:
20211+ AuTraceErr(err);
20212+ return err;
20213+}
20214+
392086de 20215+static void au_do_unlock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20216+{
20217+ if (!a->rename_lock) {
20218+ mutex_unlock(&a->mvd_h_src_dir->i_mutex);
20219+ au_unpin(&a->pin);
20220+ } else
20221+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
20222+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
20223+}
20224+
20225+/* copy-down the file */
392086de 20226+static int au_do_cpdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20227+{
20228+ int err;
20229+ struct au_cp_generic cpg = {
20230+ .dentry = a->dentry,
20231+ .bdst = a->mvd_bdst,
20232+ .bsrc = a->mvd_bsrc,
20233+ .len = -1,
20234+ .pin = &a->pin,
20235+ .flags = AuCpup_DTIME | AuCpup_HOPEN
20236+ };
20237+
20238+ AuDbg("b%d, b%d\n", cpg.bsrc, cpg.bdst);
392086de
AM
20239+ if (a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
20240+ au_fset_cpup(cpg.flags, OVERWRITE);
20241+ if (a->mvdown.flags & AUFS_MVDOWN_ROLOWER)
20242+ au_fset_cpup(cpg.flags, RWDST);
c2b27bf2
AM
20243+ err = au_sio_cpdown_simple(&cpg);
20244+ if (unlikely(err))
392086de 20245+ AU_MVD_PR(dmsg, "cpdown failed\n");
c2b27bf2
AM
20246+
20247+ AuTraceErr(err);
20248+ return err;
20249+}
20250+
20251+/*
20252+ * unlink the whiteout on bdst if exist which may be created by UDBA while we
20253+ * were sleeping
20254+ */
392086de 20255+static int au_do_unlink_wh(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20256+{
20257+ int err;
20258+ struct path h_path;
20259+ struct au_branch *br;
20260+
20261+ br = au_sbr(a->sb, a->mvd_bdst);
20262+ h_path.dentry = au_wh_lkup(a->mvd_h_dst_parent, &a->dentry->d_name, br);
20263+ err = PTR_ERR(h_path.dentry);
20264+ if (IS_ERR(h_path.dentry)) {
392086de 20265+ AU_MVD_PR(dmsg, "wh_lkup failed\n");
c2b27bf2
AM
20266+ goto out;
20267+ }
20268+
20269+ err = 0;
20270+ if (h_path.dentry->d_inode) {
20271+ h_path.mnt = au_br_mnt(br);
20272+ err = vfsub_unlink(a->mvd_h_dst_parent->d_inode, &h_path,
20273+ /*force*/0);
20274+ if (unlikely(err))
392086de 20275+ AU_MVD_PR(dmsg, "wh_unlink failed\n");
c2b27bf2
AM
20276+ }
20277+ dput(h_path.dentry);
20278+
20279+out:
20280+ AuTraceErr(err);
20281+ return err;
20282+}
20283+
20284+/*
20285+ * unlink the topmost h_dentry
20286+ * Note: the target file MAY be modified by UDBA between this mutex_unlock() and
20287+ * mutex_lock() in vfs_unlink(). in this case, such changes may be lost.
20288+ */
392086de 20289+static int au_do_unlink(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20290+{
20291+ int err;
20292+ struct path h_path;
20293+
20294+ h_path.mnt = au_sbr_mnt(a->sb, a->mvd_bsrc);
20295+ h_path.dentry = au_h_dptr(a->dentry, a->mvd_bsrc);
20296+ err = vfsub_unlink(a->mvd_h_src_dir, &h_path, /*force*/0);
20297+ if (unlikely(err))
392086de 20298+ AU_MVD_PR(dmsg, "unlink failed\n");
c2b27bf2
AM
20299+
20300+ AuTraceErr(err);
20301+ return err;
20302+}
20303+
20304+/*
20305+ * copy-down the file and unlink the bsrc file.
20306+ * - unlink the bdst whout if exist
20307+ * - copy-down the file (with whtmp name and rename)
20308+ * - unlink the bsrc file
20309+ */
392086de 20310+static int au_do_mvdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20311+{
20312+ int err;
20313+
392086de 20314+ err = au_do_mkdir(dmsg, a);
c2b27bf2 20315+ if (!err)
392086de 20316+ err = au_do_lock(dmsg, a);
c2b27bf2
AM
20317+ if (unlikely(err))
20318+ goto out;
20319+
20320+ /*
20321+ * do not revert the activities we made on bdst since they should be
20322+ * harmless in aufs.
20323+ */
20324+
392086de 20325+ err = au_do_cpdown(dmsg, a);
c2b27bf2 20326+ if (!err)
392086de
AM
20327+ err = au_do_unlink_wh(dmsg, a);
20328+ if (!err && !(a->mvdown.flags & AUFS_MVDOWN_KUPPER))
20329+ err = au_do_unlink(dmsg, a);
c2b27bf2
AM
20330+ if (unlikely(err))
20331+ goto out_unlock;
20332+
20333+ /* maintain internal array */
392086de
AM
20334+ if (!(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) {
20335+ au_set_h_dptr(a->dentry, a->mvd_bsrc, NULL);
20336+ au_set_dbstart(a->dentry, a->mvd_bdst);
20337+ au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0);
20338+ au_set_ibstart(a->inode, a->mvd_bdst);
20339+ }
c2b27bf2
AM
20340+ if (au_dbend(a->dentry) < a->mvd_bdst)
20341+ au_set_dbend(a->dentry, a->mvd_bdst);
c2b27bf2
AM
20342+ if (au_ibend(a->inode) < a->mvd_bdst)
20343+ au_set_ibend(a->inode, a->mvd_bdst);
20344+
20345+out_unlock:
392086de 20346+ au_do_unlock(dmsg, a);
c2b27bf2
AM
20347+out:
20348+ AuTraceErr(err);
20349+ return err;
20350+}
20351+
20352+/* ---------------------------------------------------------------------- */
20353+
392086de 20354+static int find_lower_writable(struct au_mvd_args *a)
c2b27bf2 20355+{
392086de
AM
20356+ struct super_block *sb;
20357+ aufs_bindex_t bindex, bend;
c2b27bf2
AM
20358+ struct au_branch *br;
20359+
392086de
AM
20360+ sb = a->sb;
20361+ bindex = a->mvd_bsrc;
c2b27bf2 20362+ bend = au_sbend(sb);
392086de
AM
20363+ if (!(a->mvdown.flags & AUFS_MVDOWN_ROLOWER)) {
20364+ for (bindex++; bindex <= bend; bindex++) {
20365+ br = au_sbr(sb, bindex);
20366+ if (!au_br_rdonly(br))
20367+ return bindex;
20368+ }
20369+ } else {
20370+ for (bindex++; bindex <= bend; bindex++) {
20371+ br = au_sbr(sb, bindex);
20372+ if (!(au_br_sb(br)->s_flags & MS_RDONLY)) {
20373+ if (au_br_rdonly(br))
20374+ a->mvdown.flags
20375+ |= AUFS_MVDOWN_ROLOWER_R;
20376+ return bindex;
20377+ }
20378+ }
c2b27bf2
AM
20379+ }
20380+
20381+ return -1;
20382+}
20383+
20384+/* make sure the file is idle */
392086de 20385+static int au_mvd_args_busy(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20386+{
20387+ int err, plinked;
c2b27bf2
AM
20388+
20389+ err = 0;
c2b27bf2
AM
20390+ plinked = !!au_opt_test(au_mntflags(a->sb), PLINK);
20391+ if (au_dbstart(a->dentry) == a->mvd_bsrc
392086de 20392+ && d_count(a->dentry) == 1
c2b27bf2 20393+ && atomic_read(&a->inode->i_count) == 1
392086de 20394+ /* && a->mvd_h_src_inode->i_nlink == 1 */
c2b27bf2
AM
20395+ && (!plinked || !au_plink_test(a->inode))
20396+ && a->inode->i_nlink == 1)
20397+ goto out;
20398+
20399+ err = -EBUSY;
392086de 20400+ AU_MVD_PR(dmsg,
c2b27bf2 20401+ "b%d, d{b%d, c%u?}, i{c%d?, l%u}, hi{l%u}, p{%d, %d}\n",
392086de 20402+ a->mvd_bsrc, au_dbstart(a->dentry), d_count(a->dentry),
c2b27bf2 20403+ atomic_read(&a->inode->i_count), a->inode->i_nlink,
392086de 20404+ a->mvd_h_src_inode->i_nlink,
c2b27bf2
AM
20405+ plinked, plinked ? au_plink_test(a->inode) : 0);
20406+
20407+out:
20408+ AuTraceErr(err);
20409+ return err;
20410+}
20411+
20412+/* make sure the parent dir is fine */
392086de 20413+static int au_mvd_args_parent(const unsigned char dmsg,
c2b27bf2
AM
20414+ struct au_mvd_args *a)
20415+{
20416+ int err;
20417+ aufs_bindex_t bindex;
20418+
20419+ err = 0;
20420+ if (unlikely(au_alive_dir(a->parent))) {
20421+ err = -ENOENT;
392086de 20422+ AU_MVD_PR(dmsg, "parent dir is dead\n");
c2b27bf2
AM
20423+ goto out;
20424+ }
20425+
20426+ a->bopq = au_dbdiropq(a->parent);
20427+ bindex = au_wbr_nonopq(a->dentry, a->mvd_bdst);
20428+ AuDbg("b%d\n", bindex);
20429+ if (unlikely((bindex >= 0 && bindex < a->mvd_bdst)
20430+ || (a->bopq != -1 && a->bopq < a->mvd_bdst))) {
20431+ err = -EINVAL;
392086de
AM
20432+ a->mvd_errno = EAU_MVDOWN_OPAQUE;
20433+ AU_MVD_PR(dmsg, "ancestor is opaque b%d, b%d\n",
c2b27bf2
AM
20434+ a->bopq, a->mvd_bdst);
20435+ }
20436+
20437+out:
20438+ AuTraceErr(err);
20439+ return err;
20440+}
20441+
392086de 20442+static int au_mvd_args_intermediate(const unsigned char dmsg,
c2b27bf2
AM
20443+ struct au_mvd_args *a)
20444+{
20445+ int err;
20446+ struct au_dinfo *dinfo, *tmp;
20447+
20448+ /* lookup the next lower positive entry */
20449+ err = -ENOMEM;
20450+ tmp = au_di_alloc(a->sb, AuLsc_DI_TMP);
20451+ if (unlikely(!tmp))
20452+ goto out;
20453+
20454+ a->bfound = -1;
20455+ a->bwh = -1;
20456+ dinfo = au_di(a->dentry);
20457+ au_di_cp(tmp, dinfo);
20458+ au_di_swap(tmp, dinfo);
20459+
20460+ /* returns the number of positive dentries */
20461+ err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1, /*type*/0);
20462+ if (!err)
20463+ a->bwh = au_dbwh(a->dentry);
20464+ else if (err > 0)
20465+ a->bfound = au_dbstart(a->dentry);
20466+
20467+ au_di_swap(tmp, dinfo);
20468+ au_rw_write_unlock(&tmp->di_rwsem);
20469+ au_di_free(tmp);
20470+ if (unlikely(err < 0))
392086de 20471+ AU_MVD_PR(dmsg, "failed look-up lower\n");
c2b27bf2
AM
20472+
20473+ /*
20474+ * here, we have these cases.
20475+ * bfound == -1
20476+ * no positive dentry under bsrc. there are more sub-cases.
20477+ * bwh < 0
20478+ * there no whiteout, we can safely move-down.
20479+ * bwh <= bsrc
20480+ * impossible
20481+ * bsrc < bwh && bwh < bdst
20482+ * there is a whiteout on RO branch. cannot proceed.
20483+ * bwh == bdst
20484+ * there is a whiteout on the RW target branch. it should
20485+ * be removed.
20486+ * bdst < bwh
20487+ * there is a whiteout somewhere unrelated branch.
20488+ * -1 < bfound && bfound <= bsrc
20489+ * impossible.
20490+ * bfound < bdst
20491+ * found, but it is on RO branch between bsrc and bdst. cannot
20492+ * proceed.
20493+ * bfound == bdst
20494+ * found, replace it if AUFS_MVDOWN_FORCE is set. otherwise return
20495+ * error.
20496+ * bdst < bfound
20497+ * found, after we create the file on bdst, it will be hidden.
20498+ */
20499+
20500+ AuDebugOn(a->bfound == -1
20501+ && a->bwh != -1
20502+ && a->bwh <= a->mvd_bsrc);
20503+ AuDebugOn(-1 < a->bfound
20504+ && a->bfound <= a->mvd_bsrc);
20505+
20506+ err = -EINVAL;
20507+ if (a->bfound == -1
20508+ && a->mvd_bsrc < a->bwh
20509+ && a->bwh != -1
20510+ && a->bwh < a->mvd_bdst) {
392086de
AM
20511+ a->mvd_errno = EAU_MVDOWN_WHITEOUT;
20512+ AU_MVD_PR(dmsg, "bsrc %d, bdst %d, bfound %d, bwh %d\n",
c2b27bf2
AM
20513+ a->mvd_bsrc, a->mvd_bdst, a->bfound, a->bwh);
20514+ goto out;
20515+ } else if (a->bfound != -1 && a->bfound < a->mvd_bdst) {
392086de
AM
20516+ a->mvd_errno = EAU_MVDOWN_UPPER;
20517+ AU_MVD_PR(dmsg, "bdst %d, bfound %d\n",
c2b27bf2
AM
20518+ a->mvd_bdst, a->bfound);
20519+ goto out;
20520+ }
20521+
20522+ err = 0; /* success */
20523+
20524+out:
20525+ AuTraceErr(err);
20526+ return err;
20527+}
20528+
392086de 20529+static int au_mvd_args_exist(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20530+{
20531+ int err;
20532+
392086de
AM
20533+ err = 0;
20534+ if (!(a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
20535+ && a->bfound == a->mvd_bdst)
20536+ err = -EEXIST;
c2b27bf2
AM
20537+ AuTraceErr(err);
20538+ return err;
20539+}
20540+
392086de 20541+static int au_mvd_args(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20542+{
20543+ int err;
20544+ struct au_branch *br;
20545+
20546+ err = -EISDIR;
20547+ if (unlikely(S_ISDIR(a->inode->i_mode)))
20548+ goto out;
20549+
20550+ err = -EINVAL;
392086de
AM
20551+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_UPPER))
20552+ a->mvd_bsrc = au_ibstart(a->inode);
20553+ else {
20554+ a->mvd_bsrc = au_br_index(a->sb, a->mvd_src_brid);
20555+ if (unlikely(a->mvd_bsrc < 0
20556+ || (a->mvd_bsrc < au_dbstart(a->dentry)
20557+ || au_dbend(a->dentry) < a->mvd_bsrc
20558+ || !au_h_dptr(a->dentry, a->mvd_bsrc))
20559+ || (a->mvd_bsrc < au_ibstart(a->inode)
20560+ || au_ibend(a->inode) < a->mvd_bsrc
20561+ || !au_h_iptr(a->inode, a->mvd_bsrc)))) {
20562+ a->mvd_errno = EAU_MVDOWN_NOUPPER;
20563+ AU_MVD_PR(dmsg, "no upper\n");
20564+ goto out;
20565+ }
20566+ }
c2b27bf2 20567+ if (unlikely(a->mvd_bsrc == au_sbend(a->sb))) {
392086de
AM
20568+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
20569+ AU_MVD_PR(dmsg, "on the bottom\n");
c2b27bf2
AM
20570+ goto out;
20571+ }
392086de 20572+ a->mvd_h_src_inode = au_h_iptr(a->inode, a->mvd_bsrc);
c2b27bf2
AM
20573+ br = au_sbr(a->sb, a->mvd_bsrc);
20574+ err = au_br_rdonly(br);
392086de
AM
20575+ if (!(a->mvdown.flags & AUFS_MVDOWN_ROUPPER)) {
20576+ if (unlikely(err))
20577+ goto out;
20578+ } else if (!(vfsub_native_ro(a->mvd_h_src_inode)
20579+ || IS_APPEND(a->mvd_h_src_inode))) {
20580+ if (err)
20581+ a->mvdown.flags |= AUFS_MVDOWN_ROUPPER_R;
20582+ /* go on */
20583+ } else
c2b27bf2
AM
20584+ goto out;
20585+
20586+ err = -EINVAL;
392086de
AM
20587+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_LOWER)) {
20588+ a->mvd_bdst = find_lower_writable(a);
20589+ if (unlikely(a->mvd_bdst < 0)) {
20590+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
20591+ AU_MVD_PR(dmsg, "no writable lower branch\n");
20592+ goto out;
20593+ }
20594+ } else {
20595+ a->mvd_bdst = au_br_index(a->sb, a->mvd_dst_brid);
20596+ if (unlikely(a->mvd_bdst < 0
20597+ || au_sbend(a->sb) < a->mvd_bdst)) {
20598+ a->mvd_errno = EAU_MVDOWN_NOLOWERBR;
20599+ AU_MVD_PR(dmsg, "no lower brid\n");
20600+ goto out;
20601+ }
c2b27bf2
AM
20602+ }
20603+
392086de 20604+ err = au_mvd_args_busy(dmsg, a);
c2b27bf2 20605+ if (!err)
392086de 20606+ err = au_mvd_args_parent(dmsg, a);
c2b27bf2 20607+ if (!err)
392086de 20608+ err = au_mvd_args_intermediate(dmsg, a);
c2b27bf2 20609+ if (!err)
392086de 20610+ err = au_mvd_args_exist(dmsg, a);
c2b27bf2
AM
20611+ if (!err)
20612+ AuDbg("b%d, b%d\n", a->mvd_bsrc, a->mvd_bdst);
20613+
20614+out:
20615+ AuTraceErr(err);
20616+ return err;
20617+}
20618+
20619+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg)
20620+{
392086de
AM
20621+ int err, e;
20622+ unsigned char dmsg;
20623+ struct au_mvd_args *args;
c2b27bf2
AM
20624+
20625+ err = -EPERM;
20626+ if (unlikely(!capable(CAP_SYS_ADMIN)))
20627+ goto out;
20628+
392086de
AM
20629+ WARN_ONCE(1, "move-down is still testing...\n");
20630+
20631+ err = -ENOMEM;
20632+ args = kmalloc(sizeof(*args), GFP_NOFS);
20633+ if (unlikely(!args))
20634+ goto out;
20635+
20636+ err = copy_from_user(&args->mvdown, uarg, sizeof(args->mvdown));
20637+ if (!err)
20638+ err = !access_ok(VERIFY_WRITE, uarg, sizeof(*uarg));
c2b27bf2
AM
20639+ if (unlikely(err)) {
20640+ err = -EFAULT;
392086de
AM
20641+ AuTraceErr(err);
20642+ goto out_free;
c2b27bf2 20643+ }
392086de
AM
20644+ AuDbg("flags 0x%x\n", args->mvdown.flags);
20645+ args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R);
20646+ args->mvdown.au_errno = 0;
20647+ args->dentry = dentry;
20648+ args->inode = dentry->d_inode;
20649+ args->sb = dentry->d_sb;
c2b27bf2 20650+
392086de
AM
20651+ err = -ENOENT;
20652+ dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG);
20653+ args->parent = dget_parent(dentry);
20654+ args->dir = args->parent->d_inode;
20655+ mutex_lock_nested(&args->dir->i_mutex, I_MUTEX_PARENT);
20656+ dput(args->parent);
20657+ if (unlikely(args->parent != dentry->d_parent)) {
20658+ AU_MVD_PR(dmsg, "parent dir is moved\n");
c2b27bf2
AM
20659+ goto out_dir;
20660+ }
20661+
392086de 20662+ mutex_lock_nested(&args->inode->i_mutex, I_MUTEX_CHILD);
c2b27bf2
AM
20663+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH);
20664+ if (unlikely(err))
20665+ goto out_inode;
20666+
392086de
AM
20667+ di_write_lock_parent(args->parent);
20668+ err = au_mvd_args(dmsg, args);
c2b27bf2
AM
20669+ if (unlikely(err))
20670+ goto out_parent;
20671+
20672+ AuDbgDentry(dentry);
392086de
AM
20673+ AuDbgInode(args->inode);
20674+ err = au_do_mvdown(dmsg, args);
c2b27bf2
AM
20675+ if (unlikely(err))
20676+ goto out_parent;
20677+ AuDbgDentry(dentry);
392086de 20678+ AuDbgInode(args->inode);
c2b27bf2 20679+
392086de
AM
20680+ au_cpup_attr_timesizes(args->dir);
20681+ au_cpup_attr_timesizes(args->inode);
20682+ au_cpup_igen(args->inode, au_h_iptr(args->inode, args->mvd_bdst));
c2b27bf2
AM
20683+ /* au_digen_dec(dentry); */
20684+
20685+out_parent:
392086de 20686+ di_write_unlock(args->parent);
c2b27bf2
AM
20687+ aufs_read_unlock(dentry, AuLock_DW);
20688+out_inode:
392086de 20689+ mutex_unlock(&args->inode->i_mutex);
c2b27bf2 20690+out_dir:
392086de
AM
20691+ mutex_unlock(&args->dir->i_mutex);
20692+out_free:
20693+ e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown));
20694+ if (unlikely(e))
20695+ err = -EFAULT;
20696+ kfree(args);
c2b27bf2
AM
20697+out:
20698+ AuTraceErr(err);
20699+ return err;
20700+}
20701diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
20702--- /usr/share/empty/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
20703+++ linux/fs/aufs/opts.c 2013-10-26 16:51:32.276373845 +0200
20704@@ -0,0 +1,1704 @@
1facf9fc 20705+/*
7a9e40b8 20706+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 20707+ *
20708+ * This program, aufs is free software; you can redistribute it and/or modify
20709+ * it under the terms of the GNU General Public License as published by
20710+ * the Free Software Foundation; either version 2 of the License, or
20711+ * (at your option) any later version.
dece6358
AM
20712+ *
20713+ * This program is distributed in the hope that it will be useful,
20714+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20715+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20716+ * GNU General Public License for more details.
20717+ *
20718+ * You should have received a copy of the GNU General Public License
20719+ * along with this program; if not, write to the Free Software
20720+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 20721+ */
20722+
20723+/*
20724+ * mount options/flags
20725+ */
20726+
dece6358 20727+#include <linux/namei.h>
1facf9fc 20728+#include <linux/types.h> /* a distribution requires */
20729+#include <linux/parser.h>
20730+#include "aufs.h"
20731+
20732+/* ---------------------------------------------------------------------- */
20733+
20734+enum {
20735+ Opt_br,
20736+ Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend,
20737+ Opt_idel, Opt_imod, Opt_ireorder,
20738+ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, Opt_rendir,
dece6358 20739+ Opt_rdblk_def, Opt_rdhash_def,
1facf9fc 20740+ Opt_xino, Opt_zxino, Opt_noxino,
20741+ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
20742+ Opt_trunc_xino_path, Opt_itrunc_xino,
20743+ Opt_trunc_xib, Opt_notrunc_xib,
dece6358 20744+ Opt_shwh, Opt_noshwh,
1facf9fc 20745+ Opt_plink, Opt_noplink, Opt_list_plink,
20746+ Opt_udba,
4a4d8108 20747+ Opt_dio, Opt_nodio,
1facf9fc 20748+ /* Opt_lock, Opt_unlock, */
20749+ Opt_cmd, Opt_cmd_args,
20750+ Opt_diropq_a, Opt_diropq_w,
20751+ Opt_warn_perm, Opt_nowarn_perm,
20752+ Opt_wbr_copyup, Opt_wbr_create,
20753+ Opt_refrof, Opt_norefrof,
20754+ Opt_verbose, Opt_noverbose,
20755+ Opt_sum, Opt_nosum, Opt_wsum,
20756+ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
20757+};
20758+
20759+static match_table_t options = {
20760+ {Opt_br, "br=%s"},
20761+ {Opt_br, "br:%s"},
20762+
20763+ {Opt_add, "add=%d:%s"},
20764+ {Opt_add, "add:%d:%s"},
20765+ {Opt_add, "ins=%d:%s"},
20766+ {Opt_add, "ins:%d:%s"},
20767+ {Opt_append, "append=%s"},
20768+ {Opt_append, "append:%s"},
20769+ {Opt_prepend, "prepend=%s"},
20770+ {Opt_prepend, "prepend:%s"},
20771+
20772+ {Opt_del, "del=%s"},
20773+ {Opt_del, "del:%s"},
20774+ /* {Opt_idel, "idel:%d"}, */
20775+ {Opt_mod, "mod=%s"},
20776+ {Opt_mod, "mod:%s"},
20777+ /* {Opt_imod, "imod:%d:%s"}, */
20778+
20779+ {Opt_dirwh, "dirwh=%d"},
20780+
20781+ {Opt_xino, "xino=%s"},
20782+ {Opt_noxino, "noxino"},
20783+ {Opt_trunc_xino, "trunc_xino"},
20784+ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
20785+ {Opt_notrunc_xino, "notrunc_xino"},
20786+ {Opt_trunc_xino_path, "trunc_xino=%s"},
20787+ {Opt_itrunc_xino, "itrunc_xino=%d"},
20788+ /* {Opt_zxino, "zxino=%s"}, */
20789+ {Opt_trunc_xib, "trunc_xib"},
20790+ {Opt_notrunc_xib, "notrunc_xib"},
20791+
e49829fe 20792+#ifdef CONFIG_PROC_FS
1facf9fc 20793+ {Opt_plink, "plink"},
e49829fe
JR
20794+#else
20795+ {Opt_ignore_silent, "plink"},
20796+#endif
20797+
1facf9fc 20798+ {Opt_noplink, "noplink"},
e49829fe 20799+
1facf9fc 20800+#ifdef CONFIG_AUFS_DEBUG
20801+ {Opt_list_plink, "list_plink"},
20802+#endif
20803+
20804+ {Opt_udba, "udba=%s"},
20805+
4a4d8108
AM
20806+ {Opt_dio, "dio"},
20807+ {Opt_nodio, "nodio"},
20808+
1facf9fc 20809+ {Opt_diropq_a, "diropq=always"},
20810+ {Opt_diropq_a, "diropq=a"},
20811+ {Opt_diropq_w, "diropq=whiteouted"},
20812+ {Opt_diropq_w, "diropq=w"},
20813+
20814+ {Opt_warn_perm, "warn_perm"},
20815+ {Opt_nowarn_perm, "nowarn_perm"},
20816+
20817+ /* keep them temporary */
20818+ {Opt_ignore_silent, "coo=%s"},
20819+ {Opt_ignore_silent, "nodlgt"},
20820+ {Opt_ignore_silent, "nodirperm1"},
1facf9fc 20821+ {Opt_ignore_silent, "clean_plink"},
20822+
dece6358
AM
20823+#ifdef CONFIG_AUFS_SHWH
20824+ {Opt_shwh, "shwh"},
20825+#endif
20826+ {Opt_noshwh, "noshwh"},
20827+
1facf9fc 20828+ {Opt_rendir, "rendir=%d"},
20829+
20830+ {Opt_refrof, "refrof"},
20831+ {Opt_norefrof, "norefrof"},
20832+
20833+ {Opt_verbose, "verbose"},
20834+ {Opt_verbose, "v"},
20835+ {Opt_noverbose, "noverbose"},
20836+ {Opt_noverbose, "quiet"},
20837+ {Opt_noverbose, "q"},
20838+ {Opt_noverbose, "silent"},
20839+
20840+ {Opt_sum, "sum"},
20841+ {Opt_nosum, "nosum"},
20842+ {Opt_wsum, "wsum"},
20843+
20844+ {Opt_rdcache, "rdcache=%d"},
20845+ {Opt_rdblk, "rdblk=%d"},
dece6358 20846+ {Opt_rdblk_def, "rdblk=def"},
1facf9fc 20847+ {Opt_rdhash, "rdhash=%d"},
dece6358 20848+ {Opt_rdhash_def, "rdhash=def"},
1facf9fc 20849+
20850+ {Opt_wbr_create, "create=%s"},
20851+ {Opt_wbr_create, "create_policy=%s"},
20852+ {Opt_wbr_copyup, "cpup=%s"},
20853+ {Opt_wbr_copyup, "copyup=%s"},
20854+ {Opt_wbr_copyup, "copyup_policy=%s"},
20855+
20856+ /* internal use for the scripts */
20857+ {Opt_ignore_silent, "si=%s"},
20858+
20859+ {Opt_br, "dirs=%s"},
20860+ {Opt_ignore, "debug=%d"},
20861+ {Opt_ignore, "delete=whiteout"},
20862+ {Opt_ignore, "delete=all"},
20863+ {Opt_ignore, "imap=%s"},
20864+
1308ab2a 20865+ /* temporary workaround, due to old mount(8)? */
20866+ {Opt_ignore_silent, "relatime"},
20867+
1facf9fc 20868+ {Opt_err, NULL}
20869+};
20870+
20871+/* ---------------------------------------------------------------------- */
20872+
20873+static const char *au_parser_pattern(int val, struct match_token *token)
20874+{
20875+ while (token->pattern) {
20876+ if (token->token == val)
20877+ return token->pattern;
20878+ token++;
20879+ }
20880+ BUG();
20881+ return "??";
20882+}
20883+
20884+/* ---------------------------------------------------------------------- */
20885+
1e00d052 20886+static match_table_t brperm = {
1facf9fc 20887+ {AuBrPerm_RO, AUFS_BRPERM_RO},
20888+ {AuBrPerm_RR, AUFS_BRPERM_RR},
20889+ {AuBrPerm_RW, AUFS_BRPERM_RW},
1e00d052
AM
20890+ {0, NULL}
20891+};
1facf9fc 20892+
86dc4139
AM
20893+static match_table_t brattr = {
20894+ {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN},
1e00d052 20895+ {AuBrRAttr_WH, AUFS_BRRATTR_WH},
1e00d052
AM
20896+ {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
20897+ {0, NULL}
1facf9fc 20898+};
20899+
86dc4139
AM
20900+#define AuBrStr_LONGEST AUFS_BRPERM_RW \
20901+ "+" AUFS_BRATTR_UNPIN \
20902+ "+" AUFS_BRWATTR_NLWH
1e00d052
AM
20903+
20904+static int br_attr_val(char *str, match_table_t table, substring_t args[])
20905+{
20906+ int attr, v;
20907+ char *p;
20908+
20909+ attr = 0;
20910+ do {
20911+ p = strchr(str, '+');
20912+ if (p)
20913+ *p = 0;
20914+ v = match_token(str, table, args);
20915+ if (v)
20916+ attr |= v;
20917+ else {
20918+ if (p)
20919+ *p = '+';
0c3ec466 20920+ pr_warn("ignored branch attribute %s\n", str);
1e00d052
AM
20921+ break;
20922+ }
20923+ if (p)
20924+ str = p + 1;
20925+ } while (p);
20926+
20927+ return attr;
20928+}
20929+
4a4d8108 20930+static int noinline_for_stack br_perm_val(char *perm)
1facf9fc 20931+{
20932+ int val;
86dc4139 20933+ char *p, *q;
1facf9fc 20934+ substring_t args[MAX_OPT_ARGS];
20935+
1e00d052
AM
20936+ p = strchr(perm, '+');
20937+ if (p)
20938+ *p = 0;
20939+ val = match_token(perm, brperm, args);
20940+ if (!val) {
20941+ if (p)
20942+ *p = '+';
0c3ec466 20943+ pr_warn("ignored branch permission %s\n", perm);
1e00d052
AM
20944+ val = AuBrPerm_RO;
20945+ goto out;
20946+ }
20947+ if (!p)
20948+ goto out;
20949+
86dc4139
AM
20950+ p++;
20951+ while (1) {
20952+ q = strchr(p, '+');
20953+ if (q)
20954+ *q = 0;
20955+ val |= br_attr_val(p, brattr, args);
20956+ if (q) {
20957+ *q = '+';
20958+ p = q + 1;
20959+ } else
20960+ break;
20961+ }
20962+ switch (val & AuBrPerm_Mask) {
1e00d052
AM
20963+ case AuBrPerm_RO:
20964+ case AuBrPerm_RR:
86dc4139
AM
20965+ if (unlikely(val & AuBrWAttr_NoLinkWH)) {
20966+ pr_warn("ignored branch attribute %s\n",
20967+ AUFS_BRWATTR_NLWH);
20968+ val &= ~AuBrWAttr_NoLinkWH;
20969+ }
1e00d052
AM
20970+ break;
20971+ case AuBrPerm_RW:
86dc4139
AM
20972+ if (unlikely(val & AuBrRAttr_WH)) {
20973+ pr_warn("ignored branch attribute %s\n",
20974+ AUFS_BRRATTR_WH);
20975+ val &= ~AuBrRAttr_WH;
20976+ }
1e00d052
AM
20977+ break;
20978+ }
20979+
20980+out:
1facf9fc 20981+ return val;
20982+}
20983+
1e00d052
AM
20984+/* Caller should free the return value */
20985+char *au_optstr_br_perm(int brperm)
1facf9fc 20986+{
1e00d052
AM
20987+ char *p, a[sizeof(AuBrStr_LONGEST)];
20988+ int sz;
20989+
20990+#define SetPerm(str) do { \
20991+ sz = sizeof(str); \
20992+ memcpy(a, str, sz); \
20993+ p = a + sz - 1; \
20994+ } while (0)
20995+
20996+#define AppendAttr(flag, str) do { \
20997+ if (brperm & flag) { \
20998+ sz = sizeof(str); \
20999+ *p++ = '+'; \
21000+ memcpy(p, str, sz); \
21001+ p += sz - 1; \
21002+ } \
21003+ } while (0)
21004+
21005+ switch (brperm & AuBrPerm_Mask) {
21006+ case AuBrPerm_RO:
21007+ SetPerm(AUFS_BRPERM_RO);
21008+ break;
21009+ case AuBrPerm_RR:
21010+ SetPerm(AUFS_BRPERM_RR);
21011+ break;
21012+ case AuBrPerm_RW:
21013+ SetPerm(AUFS_BRPERM_RW);
21014+ break;
21015+ default:
21016+ AuDebugOn(1);
21017+ }
21018+
86dc4139 21019+ AppendAttr(AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN);
1e00d052
AM
21020+ AppendAttr(AuBrRAttr_WH, AUFS_BRRATTR_WH);
21021+ AppendAttr(AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH);
21022+
21023+ AuDebugOn(strlen(a) >= sizeof(a));
21024+ return kstrdup(a, GFP_NOFS);
21025+#undef SetPerm
21026+#undef AppendAttr
1facf9fc 21027+}
21028+
21029+/* ---------------------------------------------------------------------- */
21030+
21031+static match_table_t udbalevel = {
21032+ {AuOpt_UDBA_REVAL, "reval"},
21033+ {AuOpt_UDBA_NONE, "none"},
4a4d8108
AM
21034+#ifdef CONFIG_AUFS_HNOTIFY
21035+ {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
21036+#ifdef CONFIG_AUFS_HFSNOTIFY
21037+ {AuOpt_UDBA_HNOTIFY, "fsnotify"},
4a4d8108 21038+#endif
1facf9fc 21039+#endif
21040+ {-1, NULL}
21041+};
21042+
4a4d8108 21043+static int noinline_for_stack udba_val(char *str)
1facf9fc 21044+{
21045+ substring_t args[MAX_OPT_ARGS];
21046+
7f207e10 21047+ return match_token(str, udbalevel, args);
1facf9fc 21048+}
21049+
21050+const char *au_optstr_udba(int udba)
21051+{
21052+ return au_parser_pattern(udba, (void *)udbalevel);
21053+}
21054+
21055+/* ---------------------------------------------------------------------- */
21056+
21057+static match_table_t au_wbr_create_policy = {
21058+ {AuWbrCreate_TDP, "tdp"},
21059+ {AuWbrCreate_TDP, "top-down-parent"},
21060+ {AuWbrCreate_RR, "rr"},
21061+ {AuWbrCreate_RR, "round-robin"},
21062+ {AuWbrCreate_MFS, "mfs"},
21063+ {AuWbrCreate_MFS, "most-free-space"},
21064+ {AuWbrCreate_MFSV, "mfs:%d"},
21065+ {AuWbrCreate_MFSV, "most-free-space:%d"},
21066+
21067+ {AuWbrCreate_MFSRR, "mfsrr:%d"},
21068+ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
21069+ {AuWbrCreate_PMFS, "pmfs"},
21070+ {AuWbrCreate_PMFSV, "pmfs:%d"},
392086de
AM
21071+ {AuWbrCreate_PMFSRR, "pmfsrr:%d"},
21072+ {AuWbrCreate_PMFSRRV, "pmfsrr:%d:%d"},
1facf9fc 21073+
21074+ {-1, NULL}
21075+};
21076+
dece6358
AM
21077+/*
21078+ * cf. linux/lib/parser.c and cmdline.c
21079+ * gave up calling memparse() since it uses simple_strtoull() instead of
9dbd164d 21080+ * kstrto...().
dece6358 21081+ */
4a4d8108
AM
21082+static int noinline_for_stack
21083+au_match_ull(substring_t *s, unsigned long long *result)
1facf9fc 21084+{
21085+ int err;
21086+ unsigned int len;
21087+ char a[32];
21088+
21089+ err = -ERANGE;
21090+ len = s->to - s->from;
21091+ if (len + 1 <= sizeof(a)) {
21092+ memcpy(a, s->from, len);
21093+ a[len] = '\0';
9dbd164d 21094+ err = kstrtoull(a, 0, result);
1facf9fc 21095+ }
21096+ return err;
21097+}
21098+
21099+static int au_wbr_mfs_wmark(substring_t *arg, char *str,
21100+ struct au_opt_wbr_create *create)
21101+{
21102+ int err;
21103+ unsigned long long ull;
21104+
21105+ err = 0;
21106+ if (!au_match_ull(arg, &ull))
21107+ create->mfsrr_watermark = ull;
21108+ else {
4a4d8108 21109+ pr_err("bad integer in %s\n", str);
1facf9fc 21110+ err = -EINVAL;
21111+ }
21112+
21113+ return err;
21114+}
21115+
21116+static int au_wbr_mfs_sec(substring_t *arg, char *str,
21117+ struct au_opt_wbr_create *create)
21118+{
21119+ int n, err;
21120+
21121+ err = 0;
027c5e7a 21122+ if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
1facf9fc 21123+ create->mfs_second = n;
21124+ else {
4a4d8108 21125+ pr_err("bad integer in %s\n", str);
1facf9fc 21126+ err = -EINVAL;
21127+ }
21128+
21129+ return err;
21130+}
21131+
4a4d8108
AM
21132+static int noinline_for_stack
21133+au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
1facf9fc 21134+{
21135+ int err, e;
21136+ substring_t args[MAX_OPT_ARGS];
21137+
21138+ err = match_token(str, au_wbr_create_policy, args);
21139+ create->wbr_create = err;
21140+ switch (err) {
21141+ case AuWbrCreate_MFSRRV:
392086de 21142+ case AuWbrCreate_PMFSRRV:
1facf9fc 21143+ e = au_wbr_mfs_wmark(&args[0], str, create);
21144+ if (!e)
21145+ e = au_wbr_mfs_sec(&args[1], str, create);
21146+ if (unlikely(e))
21147+ err = e;
21148+ break;
21149+ case AuWbrCreate_MFSRR:
392086de 21150+ case AuWbrCreate_PMFSRR:
1facf9fc 21151+ e = au_wbr_mfs_wmark(&args[0], str, create);
21152+ if (unlikely(e)) {
21153+ err = e;
21154+ break;
21155+ }
21156+ /*FALLTHROUGH*/
21157+ case AuWbrCreate_MFS:
21158+ case AuWbrCreate_PMFS:
027c5e7a 21159+ create->mfs_second = AUFS_MFS_DEF_SEC;
1facf9fc 21160+ break;
21161+ case AuWbrCreate_MFSV:
21162+ case AuWbrCreate_PMFSV:
21163+ e = au_wbr_mfs_sec(&args[0], str, create);
21164+ if (unlikely(e))
21165+ err = e;
21166+ break;
21167+ }
21168+
21169+ return err;
21170+}
21171+
21172+const char *au_optstr_wbr_create(int wbr_create)
21173+{
21174+ return au_parser_pattern(wbr_create, (void *)au_wbr_create_policy);
21175+}
21176+
21177+static match_table_t au_wbr_copyup_policy = {
21178+ {AuWbrCopyup_TDP, "tdp"},
21179+ {AuWbrCopyup_TDP, "top-down-parent"},
21180+ {AuWbrCopyup_BUP, "bup"},
21181+ {AuWbrCopyup_BUP, "bottom-up-parent"},
21182+ {AuWbrCopyup_BU, "bu"},
21183+ {AuWbrCopyup_BU, "bottom-up"},
21184+ {-1, NULL}
21185+};
21186+
4a4d8108 21187+static int noinline_for_stack au_wbr_copyup_val(char *str)
1facf9fc 21188+{
21189+ substring_t args[MAX_OPT_ARGS];
21190+
21191+ return match_token(str, au_wbr_copyup_policy, args);
21192+}
21193+
21194+const char *au_optstr_wbr_copyup(int wbr_copyup)
21195+{
21196+ return au_parser_pattern(wbr_copyup, (void *)au_wbr_copyup_policy);
21197+}
21198+
21199+/* ---------------------------------------------------------------------- */
21200+
21201+static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
21202+
21203+static void dump_opts(struct au_opts *opts)
21204+{
21205+#ifdef CONFIG_AUFS_DEBUG
21206+ /* reduce stack space */
21207+ union {
21208+ struct au_opt_add *add;
21209+ struct au_opt_del *del;
21210+ struct au_opt_mod *mod;
21211+ struct au_opt_xino *xino;
21212+ struct au_opt_xino_itrunc *xino_itrunc;
21213+ struct au_opt_wbr_create *create;
21214+ } u;
21215+ struct au_opt *opt;
21216+
21217+ opt = opts->opt;
21218+ while (opt->type != Opt_tail) {
21219+ switch (opt->type) {
21220+ case Opt_add:
21221+ u.add = &opt->add;
21222+ AuDbg("add {b%d, %s, 0x%x, %p}\n",
21223+ u.add->bindex, u.add->pathname, u.add->perm,
21224+ u.add->path.dentry);
21225+ break;
21226+ case Opt_del:
21227+ case Opt_idel:
21228+ u.del = &opt->del;
21229+ AuDbg("del {%s, %p}\n",
21230+ u.del->pathname, u.del->h_path.dentry);
21231+ break;
21232+ case Opt_mod:
21233+ case Opt_imod:
21234+ u.mod = &opt->mod;
21235+ AuDbg("mod {%s, 0x%x, %p}\n",
21236+ u.mod->path, u.mod->perm, u.mod->h_root);
21237+ break;
21238+ case Opt_append:
21239+ u.add = &opt->add;
21240+ AuDbg("append {b%d, %s, 0x%x, %p}\n",
21241+ u.add->bindex, u.add->pathname, u.add->perm,
21242+ u.add->path.dentry);
21243+ break;
21244+ case Opt_prepend:
21245+ u.add = &opt->add;
21246+ AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
21247+ u.add->bindex, u.add->pathname, u.add->perm,
21248+ u.add->path.dentry);
21249+ break;
21250+ case Opt_dirwh:
21251+ AuDbg("dirwh %d\n", opt->dirwh);
21252+ break;
21253+ case Opt_rdcache:
21254+ AuDbg("rdcache %d\n", opt->rdcache);
21255+ break;
21256+ case Opt_rdblk:
21257+ AuDbg("rdblk %u\n", opt->rdblk);
21258+ break;
dece6358
AM
21259+ case Opt_rdblk_def:
21260+ AuDbg("rdblk_def\n");
21261+ break;
1facf9fc 21262+ case Opt_rdhash:
21263+ AuDbg("rdhash %u\n", opt->rdhash);
21264+ break;
dece6358
AM
21265+ case Opt_rdhash_def:
21266+ AuDbg("rdhash_def\n");
21267+ break;
1facf9fc 21268+ case Opt_xino:
21269+ u.xino = &opt->xino;
21270+ AuDbg("xino {%s %.*s}\n",
21271+ u.xino->path,
21272+ AuDLNPair(u.xino->file->f_dentry));
21273+ break;
21274+ case Opt_trunc_xino:
21275+ AuLabel(trunc_xino);
21276+ break;
21277+ case Opt_notrunc_xino:
21278+ AuLabel(notrunc_xino);
21279+ break;
21280+ case Opt_trunc_xino_path:
21281+ case Opt_itrunc_xino:
21282+ u.xino_itrunc = &opt->xino_itrunc;
21283+ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
21284+ break;
21285+
21286+ case Opt_noxino:
21287+ AuLabel(noxino);
21288+ break;
21289+ case Opt_trunc_xib:
21290+ AuLabel(trunc_xib);
21291+ break;
21292+ case Opt_notrunc_xib:
21293+ AuLabel(notrunc_xib);
21294+ break;
dece6358
AM
21295+ case Opt_shwh:
21296+ AuLabel(shwh);
21297+ break;
21298+ case Opt_noshwh:
21299+ AuLabel(noshwh);
21300+ break;
1facf9fc 21301+ case Opt_plink:
21302+ AuLabel(plink);
21303+ break;
21304+ case Opt_noplink:
21305+ AuLabel(noplink);
21306+ break;
21307+ case Opt_list_plink:
21308+ AuLabel(list_plink);
21309+ break;
21310+ case Opt_udba:
21311+ AuDbg("udba %d, %s\n",
21312+ opt->udba, au_optstr_udba(opt->udba));
21313+ break;
4a4d8108
AM
21314+ case Opt_dio:
21315+ AuLabel(dio);
21316+ break;
21317+ case Opt_nodio:
21318+ AuLabel(nodio);
21319+ break;
1facf9fc 21320+ case Opt_diropq_a:
21321+ AuLabel(diropq_a);
21322+ break;
21323+ case Opt_diropq_w:
21324+ AuLabel(diropq_w);
21325+ break;
21326+ case Opt_warn_perm:
21327+ AuLabel(warn_perm);
21328+ break;
21329+ case Opt_nowarn_perm:
21330+ AuLabel(nowarn_perm);
21331+ break;
21332+ case Opt_refrof:
21333+ AuLabel(refrof);
21334+ break;
21335+ case Opt_norefrof:
21336+ AuLabel(norefrof);
21337+ break;
21338+ case Opt_verbose:
21339+ AuLabel(verbose);
21340+ break;
21341+ case Opt_noverbose:
21342+ AuLabel(noverbose);
21343+ break;
21344+ case Opt_sum:
21345+ AuLabel(sum);
21346+ break;
21347+ case Opt_nosum:
21348+ AuLabel(nosum);
21349+ break;
21350+ case Opt_wsum:
21351+ AuLabel(wsum);
21352+ break;
21353+ case Opt_wbr_create:
21354+ u.create = &opt->wbr_create;
21355+ AuDbg("create %d, %s\n", u.create->wbr_create,
21356+ au_optstr_wbr_create(u.create->wbr_create));
21357+ switch (u.create->wbr_create) {
21358+ case AuWbrCreate_MFSV:
21359+ case AuWbrCreate_PMFSV:
21360+ AuDbg("%d sec\n", u.create->mfs_second);
21361+ break;
21362+ case AuWbrCreate_MFSRR:
21363+ AuDbg("%llu watermark\n",
21364+ u.create->mfsrr_watermark);
21365+ break;
21366+ case AuWbrCreate_MFSRRV:
392086de 21367+ case AuWbrCreate_PMFSRRV:
1facf9fc 21368+ AuDbg("%llu watermark, %d sec\n",
21369+ u.create->mfsrr_watermark,
21370+ u.create->mfs_second);
21371+ break;
21372+ }
21373+ break;
21374+ case Opt_wbr_copyup:
21375+ AuDbg("copyup %d, %s\n", opt->wbr_copyup,
21376+ au_optstr_wbr_copyup(opt->wbr_copyup));
21377+ break;
21378+ default:
21379+ BUG();
21380+ }
21381+ opt++;
21382+ }
21383+#endif
21384+}
21385+
21386+void au_opts_free(struct au_opts *opts)
21387+{
21388+ struct au_opt *opt;
21389+
21390+ opt = opts->opt;
21391+ while (opt->type != Opt_tail) {
21392+ switch (opt->type) {
21393+ case Opt_add:
21394+ case Opt_append:
21395+ case Opt_prepend:
21396+ path_put(&opt->add.path);
21397+ break;
21398+ case Opt_del:
21399+ case Opt_idel:
21400+ path_put(&opt->del.h_path);
21401+ break;
21402+ case Opt_mod:
21403+ case Opt_imod:
21404+ dput(opt->mod.h_root);
21405+ break;
21406+ case Opt_xino:
21407+ fput(opt->xino.file);
21408+ break;
21409+ }
21410+ opt++;
21411+ }
21412+}
21413+
21414+static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
21415+ aufs_bindex_t bindex)
21416+{
21417+ int err;
21418+ struct au_opt_add *add = &opt->add;
21419+ char *p;
21420+
21421+ add->bindex = bindex;
1e00d052 21422+ add->perm = AuBrPerm_RO;
1facf9fc 21423+ add->pathname = opt_str;
21424+ p = strchr(opt_str, '=');
21425+ if (p) {
21426+ *p++ = 0;
21427+ if (*p)
21428+ add->perm = br_perm_val(p);
21429+ }
21430+
21431+ err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
21432+ if (!err) {
21433+ if (!p) {
21434+ add->perm = AuBrPerm_RO;
21435+ if (au_test_fs_rr(add->path.dentry->d_sb))
21436+ add->perm = AuBrPerm_RR;
21437+ else if (!bindex && !(sb_flags & MS_RDONLY))
21438+ add->perm = AuBrPerm_RW;
21439+ }
21440+ opt->type = Opt_add;
21441+ goto out;
21442+ }
4a4d8108 21443+ pr_err("lookup failed %s (%d)\n", add->pathname, err);
1facf9fc 21444+ err = -EINVAL;
21445+
4f0767ce 21446+out:
1facf9fc 21447+ return err;
21448+}
21449+
21450+static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
21451+{
21452+ int err;
21453+
21454+ del->pathname = args[0].from;
21455+ AuDbg("del path %s\n", del->pathname);
21456+
21457+ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
21458+ if (unlikely(err))
4a4d8108 21459+ pr_err("lookup failed %s (%d)\n", del->pathname, err);
1facf9fc 21460+
21461+ return err;
21462+}
21463+
21464+#if 0 /* reserved for future use */
21465+static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
21466+ struct au_opt_del *del, substring_t args[])
21467+{
21468+ int err;
21469+ struct dentry *root;
21470+
21471+ err = -EINVAL;
21472+ root = sb->s_root;
21473+ aufs_read_lock(root, AuLock_FLUSH);
21474+ if (bindex < 0 || au_sbend(sb) < bindex) {
4a4d8108 21475+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 21476+ goto out;
21477+ }
21478+
21479+ err = 0;
21480+ del->h_path.dentry = dget(au_h_dptr(root, bindex));
21481+ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
21482+
4f0767ce 21483+out:
1facf9fc 21484+ aufs_read_unlock(root, !AuLock_IR);
21485+ return err;
21486+}
21487+#endif
21488+
4a4d8108
AM
21489+static int noinline_for_stack
21490+au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
1facf9fc 21491+{
21492+ int err;
21493+ struct path path;
21494+ char *p;
21495+
21496+ err = -EINVAL;
21497+ mod->path = args[0].from;
21498+ p = strchr(mod->path, '=');
21499+ if (unlikely(!p)) {
4a4d8108 21500+ pr_err("no permssion %s\n", args[0].from);
1facf9fc 21501+ goto out;
21502+ }
21503+
21504+ *p++ = 0;
21505+ err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
21506+ if (unlikely(err)) {
4a4d8108 21507+ pr_err("lookup failed %s (%d)\n", mod->path, err);
1facf9fc 21508+ goto out;
21509+ }
21510+
21511+ mod->perm = br_perm_val(p);
21512+ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
21513+ mod->h_root = dget(path.dentry);
21514+ path_put(&path);
21515+
4f0767ce 21516+out:
1facf9fc 21517+ return err;
21518+}
21519+
21520+#if 0 /* reserved for future use */
21521+static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
21522+ struct au_opt_mod *mod, substring_t args[])
21523+{
21524+ int err;
21525+ struct dentry *root;
21526+
21527+ err = -EINVAL;
21528+ root = sb->s_root;
21529+ aufs_read_lock(root, AuLock_FLUSH);
21530+ if (bindex < 0 || au_sbend(sb) < bindex) {
4a4d8108 21531+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 21532+ goto out;
21533+ }
21534+
21535+ err = 0;
21536+ mod->perm = br_perm_val(args[1].from);
21537+ AuDbg("mod path %s, perm 0x%x, %s\n",
21538+ mod->path, mod->perm, args[1].from);
21539+ mod->h_root = dget(au_h_dptr(root, bindex));
21540+
4f0767ce 21541+out:
1facf9fc 21542+ aufs_read_unlock(root, !AuLock_IR);
21543+ return err;
21544+}
21545+#endif
21546+
21547+static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
21548+ substring_t args[])
21549+{
21550+ int err;
21551+ struct file *file;
21552+
21553+ file = au_xino_create(sb, args[0].from, /*silent*/0);
21554+ err = PTR_ERR(file);
21555+ if (IS_ERR(file))
21556+ goto out;
21557+
21558+ err = -EINVAL;
21559+ if (unlikely(file->f_dentry->d_sb == sb)) {
21560+ fput(file);
4a4d8108 21561+ pr_err("%s must be outside\n", args[0].from);
1facf9fc 21562+ goto out;
21563+ }
21564+
21565+ err = 0;
21566+ xino->file = file;
21567+ xino->path = args[0].from;
21568+
4f0767ce 21569+out:
1facf9fc 21570+ return err;
21571+}
21572+
4a4d8108
AM
21573+static int noinline_for_stack
21574+au_opts_parse_xino_itrunc_path(struct super_block *sb,
21575+ struct au_opt_xino_itrunc *xino_itrunc,
21576+ substring_t args[])
1facf9fc 21577+{
21578+ int err;
21579+ aufs_bindex_t bend, bindex;
21580+ struct path path;
21581+ struct dentry *root;
21582+
21583+ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
21584+ if (unlikely(err)) {
4a4d8108 21585+ pr_err("lookup failed %s (%d)\n", args[0].from, err);
1facf9fc 21586+ goto out;
21587+ }
21588+
21589+ xino_itrunc->bindex = -1;
21590+ root = sb->s_root;
21591+ aufs_read_lock(root, AuLock_FLUSH);
21592+ bend = au_sbend(sb);
21593+ for (bindex = 0; bindex <= bend; bindex++) {
21594+ if (au_h_dptr(root, bindex) == path.dentry) {
21595+ xino_itrunc->bindex = bindex;
21596+ break;
21597+ }
21598+ }
21599+ aufs_read_unlock(root, !AuLock_IR);
21600+ path_put(&path);
21601+
21602+ if (unlikely(xino_itrunc->bindex < 0)) {
4a4d8108 21603+ pr_err("no such branch %s\n", args[0].from);
1facf9fc 21604+ err = -EINVAL;
21605+ }
21606+
4f0767ce 21607+out:
1facf9fc 21608+ return err;
21609+}
21610+
21611+/* called without aufs lock */
21612+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
21613+{
21614+ int err, n, token;
21615+ aufs_bindex_t bindex;
21616+ unsigned char skipped;
21617+ struct dentry *root;
21618+ struct au_opt *opt, *opt_tail;
21619+ char *opt_str;
21620+ /* reduce the stack space */
21621+ union {
21622+ struct au_opt_xino_itrunc *xino_itrunc;
21623+ struct au_opt_wbr_create *create;
21624+ } u;
21625+ struct {
21626+ substring_t args[MAX_OPT_ARGS];
21627+ } *a;
21628+
21629+ err = -ENOMEM;
21630+ a = kmalloc(sizeof(*a), GFP_NOFS);
21631+ if (unlikely(!a))
21632+ goto out;
21633+
21634+ root = sb->s_root;
21635+ err = 0;
21636+ bindex = 0;
21637+ opt = opts->opt;
21638+ opt_tail = opt + opts->max_opt - 1;
21639+ opt->type = Opt_tail;
21640+ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
21641+ err = -EINVAL;
21642+ skipped = 0;
21643+ token = match_token(opt_str, options, a->args);
21644+ switch (token) {
21645+ case Opt_br:
21646+ err = 0;
21647+ while (!err && (opt_str = strsep(&a->args[0].from, ":"))
21648+ && *opt_str) {
21649+ err = opt_add(opt, opt_str, opts->sb_flags,
21650+ bindex++);
21651+ if (unlikely(!err && ++opt > opt_tail)) {
21652+ err = -E2BIG;
21653+ break;
21654+ }
21655+ opt->type = Opt_tail;
21656+ skipped = 1;
21657+ }
21658+ break;
21659+ case Opt_add:
21660+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 21661+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 21662+ break;
21663+ }
21664+ bindex = n;
21665+ err = opt_add(opt, a->args[1].from, opts->sb_flags,
21666+ bindex);
21667+ if (!err)
21668+ opt->type = token;
21669+ break;
21670+ case Opt_append:
21671+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
21672+ /*dummy bindex*/1);
21673+ if (!err)
21674+ opt->type = token;
21675+ break;
21676+ case Opt_prepend:
21677+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
21678+ /*bindex*/0);
21679+ if (!err)
21680+ opt->type = token;
21681+ break;
21682+ case Opt_del:
21683+ err = au_opts_parse_del(&opt->del, a->args);
21684+ if (!err)
21685+ opt->type = token;
21686+ break;
21687+#if 0 /* reserved for future use */
21688+ case Opt_idel:
21689+ del->pathname = "(indexed)";
21690+ if (unlikely(match_int(&args[0], &n))) {
4a4d8108 21691+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 21692+ break;
21693+ }
21694+ err = au_opts_parse_idel(sb, n, &opt->del, a->args);
21695+ if (!err)
21696+ opt->type = token;
21697+ break;
21698+#endif
21699+ case Opt_mod:
21700+ err = au_opts_parse_mod(&opt->mod, a->args);
21701+ if (!err)
21702+ opt->type = token;
21703+ break;
21704+#ifdef IMOD /* reserved for future use */
21705+ case Opt_imod:
21706+ u.mod->path = "(indexed)";
21707+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 21708+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 21709+ break;
21710+ }
21711+ err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
21712+ if (!err)
21713+ opt->type = token;
21714+ break;
21715+#endif
21716+ case Opt_xino:
21717+ err = au_opts_parse_xino(sb, &opt->xino, a->args);
21718+ if (!err)
21719+ opt->type = token;
21720+ break;
21721+
21722+ case Opt_trunc_xino_path:
21723+ err = au_opts_parse_xino_itrunc_path
21724+ (sb, &opt->xino_itrunc, a->args);
21725+ if (!err)
21726+ opt->type = token;
21727+ break;
21728+
21729+ case Opt_itrunc_xino:
21730+ u.xino_itrunc = &opt->xino_itrunc;
21731+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 21732+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 21733+ break;
21734+ }
21735+ u.xino_itrunc->bindex = n;
21736+ aufs_read_lock(root, AuLock_FLUSH);
21737+ if (n < 0 || au_sbend(sb) < n) {
4a4d8108 21738+ pr_err("out of bounds, %d\n", n);
1facf9fc 21739+ aufs_read_unlock(root, !AuLock_IR);
21740+ break;
21741+ }
21742+ aufs_read_unlock(root, !AuLock_IR);
21743+ err = 0;
21744+ opt->type = token;
21745+ break;
21746+
21747+ case Opt_dirwh:
21748+ if (unlikely(match_int(&a->args[0], &opt->dirwh)))
21749+ break;
21750+ err = 0;
21751+ opt->type = token;
21752+ break;
21753+
21754+ case Opt_rdcache:
027c5e7a
AM
21755+ if (unlikely(match_int(&a->args[0], &n))) {
21756+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 21757+ break;
027c5e7a
AM
21758+ }
21759+ if (unlikely(n > AUFS_RDCACHE_MAX)) {
21760+ pr_err("rdcache must be smaller than %d\n",
21761+ AUFS_RDCACHE_MAX);
21762+ break;
21763+ }
21764+ opt->rdcache = n;
1facf9fc 21765+ err = 0;
21766+ opt->type = token;
21767+ break;
21768+ case Opt_rdblk:
21769+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 21770+ || n < 0
1facf9fc 21771+ || n > KMALLOC_MAX_SIZE)) {
4a4d8108 21772+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 21773+ break;
21774+ }
1308ab2a 21775+ if (unlikely(n && n < NAME_MAX)) {
4a4d8108
AM
21776+ pr_err("rdblk must be larger than %d\n",
21777+ NAME_MAX);
1facf9fc 21778+ break;
21779+ }
21780+ opt->rdblk = n;
21781+ err = 0;
21782+ opt->type = token;
21783+ break;
21784+ case Opt_rdhash:
21785+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 21786+ || n < 0
1facf9fc 21787+ || n * sizeof(struct hlist_head)
21788+ > KMALLOC_MAX_SIZE)) {
4a4d8108 21789+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 21790+ break;
21791+ }
21792+ opt->rdhash = n;
21793+ err = 0;
21794+ opt->type = token;
21795+ break;
21796+
21797+ case Opt_trunc_xino:
21798+ case Opt_notrunc_xino:
21799+ case Opt_noxino:
21800+ case Opt_trunc_xib:
21801+ case Opt_notrunc_xib:
dece6358
AM
21802+ case Opt_shwh:
21803+ case Opt_noshwh:
1facf9fc 21804+ case Opt_plink:
21805+ case Opt_noplink:
21806+ case Opt_list_plink:
4a4d8108
AM
21807+ case Opt_dio:
21808+ case Opt_nodio:
1facf9fc 21809+ case Opt_diropq_a:
21810+ case Opt_diropq_w:
21811+ case Opt_warn_perm:
21812+ case Opt_nowarn_perm:
21813+ case Opt_refrof:
21814+ case Opt_norefrof:
21815+ case Opt_verbose:
21816+ case Opt_noverbose:
21817+ case Opt_sum:
21818+ case Opt_nosum:
21819+ case Opt_wsum:
dece6358
AM
21820+ case Opt_rdblk_def:
21821+ case Opt_rdhash_def:
1facf9fc 21822+ err = 0;
21823+ opt->type = token;
21824+ break;
21825+
21826+ case Opt_udba:
21827+ opt->udba = udba_val(a->args[0].from);
21828+ if (opt->udba >= 0) {
21829+ err = 0;
21830+ opt->type = token;
21831+ } else
4a4d8108 21832+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 21833+ break;
21834+
21835+ case Opt_wbr_create:
21836+ u.create = &opt->wbr_create;
21837+ u.create->wbr_create
21838+ = au_wbr_create_val(a->args[0].from, u.create);
21839+ if (u.create->wbr_create >= 0) {
21840+ err = 0;
21841+ opt->type = token;
21842+ } else
4a4d8108 21843+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 21844+ break;
21845+ case Opt_wbr_copyup:
21846+ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
21847+ if (opt->wbr_copyup >= 0) {
21848+ err = 0;
21849+ opt->type = token;
21850+ } else
4a4d8108 21851+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 21852+ break;
21853+
21854+ case Opt_ignore:
0c3ec466 21855+ pr_warn("ignored %s\n", opt_str);
1facf9fc 21856+ /*FALLTHROUGH*/
21857+ case Opt_ignore_silent:
21858+ skipped = 1;
21859+ err = 0;
21860+ break;
21861+ case Opt_err:
4a4d8108 21862+ pr_err("unknown option %s\n", opt_str);
1facf9fc 21863+ break;
21864+ }
21865+
21866+ if (!err && !skipped) {
21867+ if (unlikely(++opt > opt_tail)) {
21868+ err = -E2BIG;
21869+ opt--;
21870+ opt->type = Opt_tail;
21871+ break;
21872+ }
21873+ opt->type = Opt_tail;
21874+ }
21875+ }
21876+
21877+ kfree(a);
21878+ dump_opts(opts);
21879+ if (unlikely(err))
21880+ au_opts_free(opts);
21881+
4f0767ce 21882+out:
1facf9fc 21883+ return err;
21884+}
21885+
21886+static int au_opt_wbr_create(struct super_block *sb,
21887+ struct au_opt_wbr_create *create)
21888+{
21889+ int err;
21890+ struct au_sbinfo *sbinfo;
21891+
dece6358
AM
21892+ SiMustWriteLock(sb);
21893+
1facf9fc 21894+ err = 1; /* handled */
21895+ sbinfo = au_sbi(sb);
21896+ if (sbinfo->si_wbr_create_ops->fin) {
21897+ err = sbinfo->si_wbr_create_ops->fin(sb);
21898+ if (!err)
21899+ err = 1;
21900+ }
21901+
21902+ sbinfo->si_wbr_create = create->wbr_create;
21903+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
21904+ switch (create->wbr_create) {
21905+ case AuWbrCreate_MFSRRV:
21906+ case AuWbrCreate_MFSRR:
392086de
AM
21907+ case AuWbrCreate_PMFSRR:
21908+ case AuWbrCreate_PMFSRRV:
1facf9fc 21909+ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
21910+ /*FALLTHROUGH*/
21911+ case AuWbrCreate_MFS:
21912+ case AuWbrCreate_MFSV:
21913+ case AuWbrCreate_PMFS:
21914+ case AuWbrCreate_PMFSV:
e49829fe
JR
21915+ sbinfo->si_wbr_mfs.mfs_expire
21916+ = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
1facf9fc 21917+ break;
21918+ }
21919+
21920+ if (sbinfo->si_wbr_create_ops->init)
21921+ sbinfo->si_wbr_create_ops->init(sb); /* ignore */
21922+
21923+ return err;
21924+}
21925+
21926+/*
21927+ * returns,
21928+ * plus: processed without an error
21929+ * zero: unprocessed
21930+ */
21931+static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
21932+ struct au_opts *opts)
21933+{
21934+ int err;
21935+ struct au_sbinfo *sbinfo;
21936+
dece6358
AM
21937+ SiMustWriteLock(sb);
21938+
1facf9fc 21939+ err = 1; /* handled */
21940+ sbinfo = au_sbi(sb);
21941+ switch (opt->type) {
21942+ case Opt_udba:
21943+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
21944+ sbinfo->si_mntflags |= opt->udba;
21945+ opts->given_udba |= opt->udba;
21946+ break;
21947+
21948+ case Opt_plink:
21949+ au_opt_set(sbinfo->si_mntflags, PLINK);
21950+ break;
21951+ case Opt_noplink:
21952+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
e49829fe 21953+ au_plink_put(sb, /*verbose*/1);
1facf9fc 21954+ au_opt_clr(sbinfo->si_mntflags, PLINK);
21955+ break;
21956+ case Opt_list_plink:
21957+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
21958+ au_plink_list(sb);
21959+ break;
21960+
4a4d8108
AM
21961+ case Opt_dio:
21962+ au_opt_set(sbinfo->si_mntflags, DIO);
21963+ au_fset_opts(opts->flags, REFRESH_DYAOP);
21964+ break;
21965+ case Opt_nodio:
21966+ au_opt_clr(sbinfo->si_mntflags, DIO);
21967+ au_fset_opts(opts->flags, REFRESH_DYAOP);
21968+ break;
21969+
1facf9fc 21970+ case Opt_diropq_a:
21971+ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
21972+ break;
21973+ case Opt_diropq_w:
21974+ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
21975+ break;
21976+
21977+ case Opt_warn_perm:
21978+ au_opt_set(sbinfo->si_mntflags, WARN_PERM);
21979+ break;
21980+ case Opt_nowarn_perm:
21981+ au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
21982+ break;
21983+
21984+ case Opt_refrof:
21985+ au_opt_set(sbinfo->si_mntflags, REFROF);
21986+ break;
21987+ case Opt_norefrof:
21988+ au_opt_clr(sbinfo->si_mntflags, REFROF);
21989+ break;
21990+
21991+ case Opt_verbose:
21992+ au_opt_set(sbinfo->si_mntflags, VERBOSE);
21993+ break;
21994+ case Opt_noverbose:
21995+ au_opt_clr(sbinfo->si_mntflags, VERBOSE);
21996+ break;
21997+
21998+ case Opt_sum:
21999+ au_opt_set(sbinfo->si_mntflags, SUM);
22000+ break;
22001+ case Opt_wsum:
22002+ au_opt_clr(sbinfo->si_mntflags, SUM);
22003+ au_opt_set(sbinfo->si_mntflags, SUM_W);
22004+ case Opt_nosum:
22005+ au_opt_clr(sbinfo->si_mntflags, SUM);
22006+ au_opt_clr(sbinfo->si_mntflags, SUM_W);
22007+ break;
22008+
22009+ case Opt_wbr_create:
22010+ err = au_opt_wbr_create(sb, &opt->wbr_create);
22011+ break;
22012+ case Opt_wbr_copyup:
22013+ sbinfo->si_wbr_copyup = opt->wbr_copyup;
22014+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
22015+ break;
22016+
22017+ case Opt_dirwh:
22018+ sbinfo->si_dirwh = opt->dirwh;
22019+ break;
22020+
22021+ case Opt_rdcache:
e49829fe
JR
22022+ sbinfo->si_rdcache
22023+ = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
1facf9fc 22024+ break;
22025+ case Opt_rdblk:
22026+ sbinfo->si_rdblk = opt->rdblk;
22027+ break;
dece6358
AM
22028+ case Opt_rdblk_def:
22029+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
22030+ break;
1facf9fc 22031+ case Opt_rdhash:
22032+ sbinfo->si_rdhash = opt->rdhash;
22033+ break;
dece6358
AM
22034+ case Opt_rdhash_def:
22035+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
22036+ break;
22037+
22038+ case Opt_shwh:
22039+ au_opt_set(sbinfo->si_mntflags, SHWH);
22040+ break;
22041+ case Opt_noshwh:
22042+ au_opt_clr(sbinfo->si_mntflags, SHWH);
22043+ break;
1facf9fc 22044+
22045+ case Opt_trunc_xino:
22046+ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
22047+ break;
22048+ case Opt_notrunc_xino:
22049+ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
22050+ break;
22051+
22052+ case Opt_trunc_xino_path:
22053+ case Opt_itrunc_xino:
22054+ err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
22055+ if (!err)
22056+ err = 1;
22057+ break;
22058+
22059+ case Opt_trunc_xib:
22060+ au_fset_opts(opts->flags, TRUNC_XIB);
22061+ break;
22062+ case Opt_notrunc_xib:
22063+ au_fclr_opts(opts->flags, TRUNC_XIB);
22064+ break;
22065+
22066+ default:
22067+ err = 0;
22068+ break;
22069+ }
22070+
22071+ return err;
22072+}
22073+
22074+/*
22075+ * returns tri-state.
22076+ * plus: processed without an error
22077+ * zero: unprocessed
22078+ * minus: error
22079+ */
22080+static int au_opt_br(struct super_block *sb, struct au_opt *opt,
22081+ struct au_opts *opts)
22082+{
22083+ int err, do_refresh;
22084+
22085+ err = 0;
22086+ switch (opt->type) {
22087+ case Opt_append:
22088+ opt->add.bindex = au_sbend(sb) + 1;
22089+ if (opt->add.bindex < 0)
22090+ opt->add.bindex = 0;
22091+ goto add;
22092+ case Opt_prepend:
22093+ opt->add.bindex = 0;
22094+ add:
22095+ case Opt_add:
22096+ err = au_br_add(sb, &opt->add,
22097+ au_ftest_opts(opts->flags, REMOUNT));
22098+ if (!err) {
22099+ err = 1;
027c5e7a 22100+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 22101+ }
22102+ break;
22103+
22104+ case Opt_del:
22105+ case Opt_idel:
22106+ err = au_br_del(sb, &opt->del,
22107+ au_ftest_opts(opts->flags, REMOUNT));
22108+ if (!err) {
22109+ err = 1;
22110+ au_fset_opts(opts->flags, TRUNC_XIB);
027c5e7a 22111+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 22112+ }
22113+ break;
22114+
22115+ case Opt_mod:
22116+ case Opt_imod:
22117+ err = au_br_mod(sb, &opt->mod,
22118+ au_ftest_opts(opts->flags, REMOUNT),
22119+ &do_refresh);
22120+ if (!err) {
22121+ err = 1;
027c5e7a
AM
22122+ if (do_refresh)
22123+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 22124+ }
22125+ break;
22126+ }
22127+
22128+ return err;
22129+}
22130+
22131+static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
22132+ struct au_opt_xino **opt_xino,
22133+ struct au_opts *opts)
22134+{
22135+ int err;
22136+ aufs_bindex_t bend, bindex;
22137+ struct dentry *root, *parent, *h_root;
22138+
22139+ err = 0;
22140+ switch (opt->type) {
22141+ case Opt_xino:
22142+ err = au_xino_set(sb, &opt->xino,
22143+ !!au_ftest_opts(opts->flags, REMOUNT));
22144+ if (unlikely(err))
22145+ break;
22146+
22147+ *opt_xino = &opt->xino;
22148+ au_xino_brid_set(sb, -1);
22149+
22150+ /* safe d_parent access */
22151+ parent = opt->xino.file->f_dentry->d_parent;
22152+ root = sb->s_root;
22153+ bend = au_sbend(sb);
22154+ for (bindex = 0; bindex <= bend; bindex++) {
22155+ h_root = au_h_dptr(root, bindex);
22156+ if (h_root == parent) {
22157+ au_xino_brid_set(sb, au_sbr_id(sb, bindex));
22158+ break;
22159+ }
22160+ }
22161+ break;
22162+
22163+ case Opt_noxino:
22164+ au_xino_clr(sb);
22165+ au_xino_brid_set(sb, -1);
22166+ *opt_xino = (void *)-1;
22167+ break;
22168+ }
22169+
22170+ return err;
22171+}
22172+
22173+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
22174+ unsigned int pending)
22175+{
22176+ int err;
22177+ aufs_bindex_t bindex, bend;
22178+ unsigned char do_plink, skip, do_free;
22179+ struct au_branch *br;
22180+ struct au_wbr *wbr;
22181+ struct dentry *root;
22182+ struct inode *dir, *h_dir;
22183+ struct au_sbinfo *sbinfo;
22184+ struct au_hinode *hdir;
22185+
dece6358
AM
22186+ SiMustAnyLock(sb);
22187+
1facf9fc 22188+ sbinfo = au_sbi(sb);
22189+ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
22190+
dece6358
AM
22191+ if (!(sb_flags & MS_RDONLY)) {
22192+ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
0c3ec466 22193+ pr_warn("first branch should be rw\n");
dece6358 22194+ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
0c3ec466 22195+ pr_warn("shwh should be used with ro\n");
dece6358 22196+ }
1facf9fc 22197+
4a4d8108 22198+ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
1facf9fc 22199+ && !au_opt_test(sbinfo->si_mntflags, XINO))
0c3ec466 22200+ pr_warn("udba=*notify requires xino\n");
1facf9fc 22201+
22202+ err = 0;
22203+ root = sb->s_root;
4a4d8108 22204+ dir = root->d_inode;
1facf9fc 22205+ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
22206+ bend = au_sbend(sb);
22207+ for (bindex = 0; !err && bindex <= bend; bindex++) {
22208+ skip = 0;
22209+ h_dir = au_h_iptr(dir, bindex);
22210+ br = au_sbr(sb, bindex);
22211+ do_free = 0;
22212+
22213+ wbr = br->br_wbr;
22214+ if (wbr)
22215+ wbr_wh_read_lock(wbr);
22216+
1e00d052 22217+ if (!au_br_writable(br->br_perm)) {
1facf9fc 22218+ do_free = !!wbr;
22219+ skip = (!wbr
22220+ || (!wbr->wbr_whbase
22221+ && !wbr->wbr_plink
22222+ && !wbr->wbr_orph));
1e00d052 22223+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 22224+ /* skip = (!br->br_whbase && !br->br_orph); */
22225+ skip = (!wbr || !wbr->wbr_whbase);
22226+ if (skip && wbr) {
22227+ if (do_plink)
22228+ skip = !!wbr->wbr_plink;
22229+ else
22230+ skip = !wbr->wbr_plink;
22231+ }
1e00d052 22232+ } else {
1facf9fc 22233+ /* skip = (br->br_whbase && br->br_ohph); */
22234+ skip = (wbr && wbr->wbr_whbase);
22235+ if (skip) {
22236+ if (do_plink)
22237+ skip = !!wbr->wbr_plink;
22238+ else
22239+ skip = !wbr->wbr_plink;
22240+ }
1facf9fc 22241+ }
22242+ if (wbr)
22243+ wbr_wh_read_unlock(wbr);
22244+
22245+ if (skip)
22246+ continue;
22247+
22248+ hdir = au_hi(dir, bindex);
4a4d8108 22249+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 22250+ if (wbr)
22251+ wbr_wh_write_lock(wbr);
86dc4139 22252+ err = au_wh_init(br, sb);
1facf9fc 22253+ if (wbr)
22254+ wbr_wh_write_unlock(wbr);
4a4d8108 22255+ au_hn_imtx_unlock(hdir);
1facf9fc 22256+
22257+ if (!err && do_free) {
22258+ kfree(wbr);
22259+ br->br_wbr = NULL;
22260+ }
22261+ }
22262+
22263+ return err;
22264+}
22265+
22266+int au_opts_mount(struct super_block *sb, struct au_opts *opts)
22267+{
22268+ int err;
22269+ unsigned int tmp;
027c5e7a 22270+ aufs_bindex_t bindex, bend;
1facf9fc 22271+ struct au_opt *opt;
22272+ struct au_opt_xino *opt_xino, xino;
22273+ struct au_sbinfo *sbinfo;
027c5e7a 22274+ struct au_branch *br;
1facf9fc 22275+
dece6358
AM
22276+ SiMustWriteLock(sb);
22277+
1facf9fc 22278+ err = 0;
22279+ opt_xino = NULL;
22280+ opt = opts->opt;
22281+ while (err >= 0 && opt->type != Opt_tail)
22282+ err = au_opt_simple(sb, opt++, opts);
22283+ if (err > 0)
22284+ err = 0;
22285+ else if (unlikely(err < 0))
22286+ goto out;
22287+
22288+ /* disable xino and udba temporary */
22289+ sbinfo = au_sbi(sb);
22290+ tmp = sbinfo->si_mntflags;
22291+ au_opt_clr(sbinfo->si_mntflags, XINO);
22292+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
22293+
22294+ opt = opts->opt;
22295+ while (err >= 0 && opt->type != Opt_tail)
22296+ err = au_opt_br(sb, opt++, opts);
22297+ if (err > 0)
22298+ err = 0;
22299+ else if (unlikely(err < 0))
22300+ goto out;
22301+
22302+ bend = au_sbend(sb);
22303+ if (unlikely(bend < 0)) {
22304+ err = -EINVAL;
4a4d8108 22305+ pr_err("no branches\n");
1facf9fc 22306+ goto out;
22307+ }
22308+
22309+ if (au_opt_test(tmp, XINO))
22310+ au_opt_set(sbinfo->si_mntflags, XINO);
22311+ opt = opts->opt;
22312+ while (!err && opt->type != Opt_tail)
22313+ err = au_opt_xino(sb, opt++, &opt_xino, opts);
22314+ if (unlikely(err))
22315+ goto out;
22316+
22317+ err = au_opts_verify(sb, sb->s_flags, tmp);
22318+ if (unlikely(err))
22319+ goto out;
22320+
22321+ /* restore xino */
22322+ if (au_opt_test(tmp, XINO) && !opt_xino) {
22323+ xino.file = au_xino_def(sb);
22324+ err = PTR_ERR(xino.file);
22325+ if (IS_ERR(xino.file))
22326+ goto out;
22327+
22328+ err = au_xino_set(sb, &xino, /*remount*/0);
22329+ fput(xino.file);
22330+ if (unlikely(err))
22331+ goto out;
22332+ }
22333+
22334+ /* restore udba */
027c5e7a 22335+ tmp &= AuOptMask_UDBA;
1facf9fc 22336+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
027c5e7a
AM
22337+ sbinfo->si_mntflags |= tmp;
22338+ bend = au_sbend(sb);
22339+ for (bindex = 0; bindex <= bend; bindex++) {
22340+ br = au_sbr(sb, bindex);
22341+ err = au_hnotify_reset_br(tmp, br, br->br_perm);
22342+ if (unlikely(err))
22343+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
22344+ bindex, err);
22345+ /* go on even if err */
22346+ }
4a4d8108 22347+ if (au_opt_test(tmp, UDBA_HNOTIFY)) {
1facf9fc 22348+ struct inode *dir = sb->s_root->d_inode;
4a4d8108 22349+ au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
1facf9fc 22350+ }
22351+
4f0767ce 22352+out:
1facf9fc 22353+ return err;
22354+}
22355+
22356+int au_opts_remount(struct super_block *sb, struct au_opts *opts)
22357+{
22358+ int err, rerr;
22359+ struct inode *dir;
22360+ struct au_opt_xino *opt_xino;
22361+ struct au_opt *opt;
22362+ struct au_sbinfo *sbinfo;
22363+
dece6358
AM
22364+ SiMustWriteLock(sb);
22365+
1facf9fc 22366+ dir = sb->s_root->d_inode;
22367+ sbinfo = au_sbi(sb);
22368+ err = 0;
22369+ opt_xino = NULL;
22370+ opt = opts->opt;
22371+ while (err >= 0 && opt->type != Opt_tail) {
22372+ err = au_opt_simple(sb, opt, opts);
22373+ if (!err)
22374+ err = au_opt_br(sb, opt, opts);
22375+ if (!err)
22376+ err = au_opt_xino(sb, opt, &opt_xino, opts);
22377+ opt++;
22378+ }
22379+ if (err > 0)
22380+ err = 0;
22381+ AuTraceErr(err);
22382+ /* go on even err */
22383+
22384+ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
22385+ if (unlikely(rerr && !err))
22386+ err = rerr;
22387+
22388+ if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
22389+ rerr = au_xib_trunc(sb);
22390+ if (unlikely(rerr && !err))
22391+ err = rerr;
22392+ }
22393+
22394+ /* will be handled by the caller */
027c5e7a 22395+ if (!au_ftest_opts(opts->flags, REFRESH)
1facf9fc 22396+ && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO)))
027c5e7a 22397+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 22398+
22399+ AuDbg("status 0x%x\n", opts->flags);
22400+ return err;
22401+}
22402+
22403+/* ---------------------------------------------------------------------- */
22404+
22405+unsigned int au_opt_udba(struct super_block *sb)
22406+{
22407+ return au_mntflags(sb) & AuOptMask_UDBA;
22408+}
7f207e10
AM
22409diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
22410--- /usr/share/empty/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100
392086de
AM
22411+++ linux/fs/aufs/opts.h 2013-10-26 16:51:32.276373845 +0200
22412@@ -0,0 +1,211 @@
1facf9fc 22413+/*
7a9e40b8 22414+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 22415+ *
22416+ * This program, aufs is free software; you can redistribute it and/or modify
22417+ * it under the terms of the GNU General Public License as published by
22418+ * the Free Software Foundation; either version 2 of the License, or
22419+ * (at your option) any later version.
dece6358
AM
22420+ *
22421+ * This program is distributed in the hope that it will be useful,
22422+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22423+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22424+ * GNU General Public License for more details.
22425+ *
22426+ * You should have received a copy of the GNU General Public License
22427+ * along with this program; if not, write to the Free Software
22428+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 22429+ */
22430+
22431+/*
22432+ * mount options/flags
22433+ */
22434+
22435+#ifndef __AUFS_OPTS_H__
22436+#define __AUFS_OPTS_H__
22437+
22438+#ifdef __KERNEL__
22439+
dece6358 22440+#include <linux/path.h>
1facf9fc 22441+
dece6358
AM
22442+struct file;
22443+struct super_block;
22444+
1facf9fc 22445+/* ---------------------------------------------------------------------- */
22446+
22447+/* mount flags */
22448+#define AuOpt_XINO 1 /* external inode number bitmap
22449+ and translation table */
22450+#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */
22451+#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */
22452+#define AuOpt_UDBA_REVAL (1 << 3)
4a4d8108 22453+#define AuOpt_UDBA_HNOTIFY (1 << 4)
dece6358
AM
22454+#define AuOpt_SHWH (1 << 5) /* show whiteout */
22455+#define AuOpt_PLINK (1 << 6) /* pseudo-link */
22456+#define AuOpt_DIRPERM1 (1 << 7) /* unimplemented */
22457+#define AuOpt_REFROF (1 << 8) /* unimplemented */
22458+#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */
22459+#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
22460+#define AuOpt_SUM_W (1 << 11) /* unimplemented */
22461+#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */
22462+#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */
4a4d8108 22463+#define AuOpt_DIO (1 << 14) /* direct io */
1facf9fc 22464+
4a4d8108
AM
22465+#ifndef CONFIG_AUFS_HNOTIFY
22466+#undef AuOpt_UDBA_HNOTIFY
22467+#define AuOpt_UDBA_HNOTIFY 0
1facf9fc 22468+#endif
dece6358
AM
22469+#ifndef CONFIG_AUFS_SHWH
22470+#undef AuOpt_SHWH
22471+#define AuOpt_SHWH 0
22472+#endif
1facf9fc 22473+
22474+#define AuOpt_Def (AuOpt_XINO \
22475+ | AuOpt_UDBA_REVAL \
22476+ | AuOpt_PLINK \
22477+ /* | AuOpt_DIRPERM1 */ \
22478+ | AuOpt_WARN_PERM)
22479+#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
22480+ | AuOpt_UDBA_REVAL \
4a4d8108 22481+ | AuOpt_UDBA_HNOTIFY)
1facf9fc 22482+
22483+#define au_opt_test(flags, name) (flags & AuOpt_##name)
22484+#define au_opt_set(flags, name) do { \
22485+ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
22486+ ((flags) |= AuOpt_##name); \
22487+} while (0)
22488+#define au_opt_set_udba(flags, name) do { \
22489+ (flags) &= ~AuOptMask_UDBA; \
22490+ ((flags) |= AuOpt_##name); \
22491+} while (0)
7f207e10
AM
22492+#define au_opt_clr(flags, name) do { \
22493+ ((flags) &= ~AuOpt_##name); \
22494+} while (0)
1facf9fc 22495+
e49829fe
JR
22496+static inline unsigned int au_opts_plink(unsigned int mntflags)
22497+{
22498+#ifdef CONFIG_PROC_FS
22499+ return mntflags;
22500+#else
22501+ return mntflags & ~AuOpt_PLINK;
22502+#endif
22503+}
22504+
1facf9fc 22505+/* ---------------------------------------------------------------------- */
22506+
22507+/* policies to select one among multiple writable branches */
22508+enum {
22509+ AuWbrCreate_TDP, /* top down parent */
22510+ AuWbrCreate_RR, /* round robin */
22511+ AuWbrCreate_MFS, /* most free space */
22512+ AuWbrCreate_MFSV, /* mfs with seconds */
22513+ AuWbrCreate_MFSRR, /* mfs then rr */
22514+ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */
22515+ AuWbrCreate_PMFS, /* parent and mfs */
22516+ AuWbrCreate_PMFSV, /* parent and mfs with seconds */
392086de
AM
22517+ AuWbrCreate_PMFSRR, /* parent, mfs and round-robin */
22518+ AuWbrCreate_PMFSRRV, /* plus seconds */
1facf9fc 22519+
22520+ AuWbrCreate_Def = AuWbrCreate_TDP
22521+};
22522+
22523+enum {
22524+ AuWbrCopyup_TDP, /* top down parent */
22525+ AuWbrCopyup_BUP, /* bottom up parent */
22526+ AuWbrCopyup_BU, /* bottom up */
22527+
22528+ AuWbrCopyup_Def = AuWbrCopyup_TDP
22529+};
22530+
22531+/* ---------------------------------------------------------------------- */
22532+
22533+struct au_opt_add {
22534+ aufs_bindex_t bindex;
22535+ char *pathname;
22536+ int perm;
22537+ struct path path;
22538+};
22539+
22540+struct au_opt_del {
22541+ char *pathname;
22542+ struct path h_path;
22543+};
22544+
22545+struct au_opt_mod {
22546+ char *path;
22547+ int perm;
22548+ struct dentry *h_root;
22549+};
22550+
22551+struct au_opt_xino {
22552+ char *path;
22553+ struct file *file;
22554+};
22555+
22556+struct au_opt_xino_itrunc {
22557+ aufs_bindex_t bindex;
22558+};
22559+
22560+struct au_opt_wbr_create {
22561+ int wbr_create;
22562+ int mfs_second;
22563+ unsigned long long mfsrr_watermark;
22564+};
22565+
22566+struct au_opt {
22567+ int type;
22568+ union {
22569+ struct au_opt_xino xino;
22570+ struct au_opt_xino_itrunc xino_itrunc;
22571+ struct au_opt_add add;
22572+ struct au_opt_del del;
22573+ struct au_opt_mod mod;
22574+ int dirwh;
22575+ int rdcache;
22576+ unsigned int rdblk;
22577+ unsigned int rdhash;
22578+ int udba;
22579+ struct au_opt_wbr_create wbr_create;
22580+ int wbr_copyup;
22581+ };
22582+};
22583+
22584+/* opts flags */
22585+#define AuOpts_REMOUNT 1
027c5e7a
AM
22586+#define AuOpts_REFRESH (1 << 1)
22587+#define AuOpts_TRUNC_XIB (1 << 2)
22588+#define AuOpts_REFRESH_DYAOP (1 << 3)
1facf9fc 22589+#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
7f207e10
AM
22590+#define au_fset_opts(flags, name) \
22591+ do { (flags) |= AuOpts_##name; } while (0)
22592+#define au_fclr_opts(flags, name) \
22593+ do { (flags) &= ~AuOpts_##name; } while (0)
1facf9fc 22594+
22595+struct au_opts {
22596+ struct au_opt *opt;
22597+ int max_opt;
22598+
22599+ unsigned int given_udba;
22600+ unsigned int flags;
22601+ unsigned long sb_flags;
22602+};
22603+
22604+/* ---------------------------------------------------------------------- */
22605+
1e00d052 22606+char *au_optstr_br_perm(int brperm);
1facf9fc 22607+const char *au_optstr_udba(int udba);
22608+const char *au_optstr_wbr_copyup(int wbr_copyup);
22609+const char *au_optstr_wbr_create(int wbr_create);
22610+
22611+void au_opts_free(struct au_opts *opts);
22612+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
22613+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
22614+ unsigned int pending);
22615+int au_opts_mount(struct super_block *sb, struct au_opts *opts);
22616+int au_opts_remount(struct super_block *sb, struct au_opts *opts);
22617+
22618+unsigned int au_opt_udba(struct super_block *sb);
22619+
22620+/* ---------------------------------------------------------------------- */
22621+
22622+#endif /* __KERNEL__ */
22623+#endif /* __AUFS_OPTS_H__ */
7f207e10
AM
22624diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
22625--- /usr/share/empty/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100
86dc4139
AM
22626+++ linux/fs/aufs/plink.c 2013-07-06 13:20:47.753531903 +0200
22627@@ -0,0 +1,520 @@
1facf9fc 22628+/*
7a9e40b8 22629+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 22630+ *
22631+ * This program, aufs is free software; you can redistribute it and/or modify
22632+ * it under the terms of the GNU General Public License as published by
22633+ * the Free Software Foundation; either version 2 of the License, or
22634+ * (at your option) any later version.
dece6358
AM
22635+ *
22636+ * This program is distributed in the hope that it will be useful,
22637+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22638+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22639+ * GNU General Public License for more details.
22640+ *
22641+ * You should have received a copy of the GNU General Public License
22642+ * along with this program; if not, write to the Free Software
22643+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 22644+ */
22645+
22646+/*
22647+ * pseudo-link
22648+ */
22649+
22650+#include "aufs.h"
22651+
22652+/*
e49829fe 22653+ * the pseudo-link maintenance mode.
1facf9fc 22654+ * during a user process maintains the pseudo-links,
22655+ * prohibit adding a new plink and branch manipulation.
e49829fe
JR
22656+ *
22657+ * Flags
22658+ * NOPLM:
22659+ * For entry functions which will handle plink, and i_mutex is already held
22660+ * in VFS.
22661+ * They cannot wait and should return an error at once.
22662+ * Callers has to check the error.
22663+ * NOPLMW:
22664+ * For entry functions which will handle plink, but i_mutex is not held
22665+ * in VFS.
22666+ * They can wait the plink maintenance mode to finish.
22667+ *
22668+ * They behave like F_SETLK and F_SETLKW.
22669+ * If the caller never handle plink, then both flags are unnecessary.
1facf9fc 22670+ */
e49829fe
JR
22671+
22672+int au_plink_maint(struct super_block *sb, int flags)
1facf9fc 22673+{
e49829fe
JR
22674+ int err;
22675+ pid_t pid, ppid;
22676+ struct au_sbinfo *sbi;
dece6358
AM
22677+
22678+ SiMustAnyLock(sb);
22679+
e49829fe
JR
22680+ err = 0;
22681+ if (!au_opt_test(au_mntflags(sb), PLINK))
22682+ goto out;
22683+
22684+ sbi = au_sbi(sb);
22685+ pid = sbi->si_plink_maint_pid;
22686+ if (!pid || pid == current->pid)
22687+ goto out;
22688+
22689+ /* todo: it highly depends upon /sbin/mount.aufs */
22690+ rcu_read_lock();
22691+ ppid = task_pid_vnr(rcu_dereference(current->real_parent));
22692+ rcu_read_unlock();
22693+ if (pid == ppid)
22694+ goto out;
22695+
22696+ if (au_ftest_lock(flags, NOPLMW)) {
027c5e7a
AM
22697+ /* if there is no i_mutex lock in VFS, we don't need to wait */
22698+ /* AuDebugOn(!lockdep_depth(current)); */
e49829fe
JR
22699+ while (sbi->si_plink_maint_pid) {
22700+ si_read_unlock(sb);
22701+ /* gave up wake_up_bit() */
22702+ wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
22703+
22704+ if (au_ftest_lock(flags, FLUSH))
22705+ au_nwt_flush(&sbi->si_nowait);
22706+ si_noflush_read_lock(sb);
22707+ }
22708+ } else if (au_ftest_lock(flags, NOPLM)) {
22709+ AuDbg("ppid %d, pid %d\n", ppid, pid);
22710+ err = -EAGAIN;
22711+ }
22712+
22713+out:
22714+ return err;
4a4d8108
AM
22715+}
22716+
e49829fe 22717+void au_plink_maint_leave(struct au_sbinfo *sbinfo)
4a4d8108 22718+{
4a4d8108 22719+ spin_lock(&sbinfo->si_plink_maint_lock);
027c5e7a 22720+ sbinfo->si_plink_maint_pid = 0;
4a4d8108 22721+ spin_unlock(&sbinfo->si_plink_maint_lock);
027c5e7a 22722+ wake_up_all(&sbinfo->si_plink_wq);
4a4d8108
AM
22723+}
22724+
e49829fe 22725+int au_plink_maint_enter(struct super_block *sb)
4a4d8108
AM
22726+{
22727+ int err;
4a4d8108
AM
22728+ struct au_sbinfo *sbinfo;
22729+
22730+ err = 0;
4a4d8108
AM
22731+ sbinfo = au_sbi(sb);
22732+ /* make sure i am the only one in this fs */
e49829fe
JR
22733+ si_write_lock(sb, AuLock_FLUSH);
22734+ if (au_opt_test(au_mntflags(sb), PLINK)) {
22735+ spin_lock(&sbinfo->si_plink_maint_lock);
22736+ if (!sbinfo->si_plink_maint_pid)
22737+ sbinfo->si_plink_maint_pid = current->pid;
22738+ else
22739+ err = -EBUSY;
22740+ spin_unlock(&sbinfo->si_plink_maint_lock);
22741+ }
4a4d8108
AM
22742+ si_write_unlock(sb);
22743+
22744+ return err;
1facf9fc 22745+}
22746+
22747+/* ---------------------------------------------------------------------- */
22748+
1facf9fc 22749+#ifdef CONFIG_AUFS_DEBUG
22750+void au_plink_list(struct super_block *sb)
22751+{
86dc4139 22752+ int i;
1facf9fc 22753+ struct au_sbinfo *sbinfo;
86dc4139 22754+ struct hlist_head *plink_hlist;
1facf9fc 22755+ struct pseudo_link *plink;
22756+
dece6358
AM
22757+ SiMustAnyLock(sb);
22758+
1facf9fc 22759+ sbinfo = au_sbi(sb);
22760+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 22761+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 22762+
86dc4139
AM
22763+ for (i = 0; i < AuPlink_NHASH; i++) {
22764+ plink_hlist = &sbinfo->si_plink[i].head;
22765+ rcu_read_lock();
22766+ hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
22767+ AuDbg("%lu\n", plink->inode->i_ino);
22768+ rcu_read_unlock();
22769+ }
1facf9fc 22770+}
22771+#endif
22772+
22773+/* is the inode pseudo-linked? */
22774+int au_plink_test(struct inode *inode)
22775+{
86dc4139 22776+ int found, i;
1facf9fc 22777+ struct au_sbinfo *sbinfo;
86dc4139 22778+ struct hlist_head *plink_hlist;
1facf9fc 22779+ struct pseudo_link *plink;
22780+
22781+ sbinfo = au_sbi(inode->i_sb);
dece6358 22782+ AuRwMustAnyLock(&sbinfo->si_rwsem);
1facf9fc 22783+ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
e49829fe 22784+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
1facf9fc 22785+
22786+ found = 0;
86dc4139
AM
22787+ i = au_plink_hash(inode->i_ino);
22788+ plink_hlist = &sbinfo->si_plink[i].head;
4a4d8108 22789+ rcu_read_lock();
86dc4139 22790+ hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
1facf9fc 22791+ if (plink->inode == inode) {
22792+ found = 1;
22793+ break;
22794+ }
4a4d8108 22795+ rcu_read_unlock();
1facf9fc 22796+ return found;
22797+}
22798+
22799+/* ---------------------------------------------------------------------- */
22800+
22801+/*
22802+ * generate a name for plink.
22803+ * the file will be stored under AUFS_WH_PLINKDIR.
22804+ */
22805+/* 20 is max digits length of ulong 64 */
22806+#define PLINK_NAME_LEN ((20 + 1) * 2)
22807+
22808+static int plink_name(char *name, int len, struct inode *inode,
22809+ aufs_bindex_t bindex)
22810+{
22811+ int rlen;
22812+ struct inode *h_inode;
22813+
22814+ h_inode = au_h_iptr(inode, bindex);
22815+ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
22816+ return rlen;
22817+}
22818+
7f207e10
AM
22819+struct au_do_plink_lkup_args {
22820+ struct dentry **errp;
22821+ struct qstr *tgtname;
22822+ struct dentry *h_parent;
22823+ struct au_branch *br;
22824+};
22825+
22826+static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
22827+ struct dentry *h_parent,
22828+ struct au_branch *br)
22829+{
22830+ struct dentry *h_dentry;
22831+ struct mutex *h_mtx;
22832+
22833+ h_mtx = &h_parent->d_inode->i_mutex;
22834+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
b4510431 22835+ h_dentry = vfsub_lkup_one(tgtname, h_parent);
7f207e10
AM
22836+ mutex_unlock(h_mtx);
22837+ return h_dentry;
22838+}
22839+
22840+static void au_call_do_plink_lkup(void *args)
22841+{
22842+ struct au_do_plink_lkup_args *a = args;
22843+ *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
22844+}
22845+
1facf9fc 22846+/* lookup the plink-ed @inode under the branch at @bindex */
22847+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
22848+{
22849+ struct dentry *h_dentry, *h_parent;
22850+ struct au_branch *br;
22851+ struct inode *h_dir;
7f207e10 22852+ int wkq_err;
1facf9fc 22853+ char a[PLINK_NAME_LEN];
0c3ec466 22854+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 22855+
e49829fe
JR
22856+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
22857+
1facf9fc 22858+ br = au_sbr(inode->i_sb, bindex);
22859+ h_parent = br->br_wbr->wbr_plink;
22860+ h_dir = h_parent->d_inode;
22861+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
22862+
2dfbb274 22863+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
7f207e10
AM
22864+ struct au_do_plink_lkup_args args = {
22865+ .errp = &h_dentry,
22866+ .tgtname = &tgtname,
22867+ .h_parent = h_parent,
22868+ .br = br
22869+ };
22870+
22871+ wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
22872+ if (unlikely(wkq_err))
22873+ h_dentry = ERR_PTR(wkq_err);
22874+ } else
22875+ h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
22876+
1facf9fc 22877+ return h_dentry;
22878+}
22879+
22880+/* create a pseudo-link */
22881+static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
22882+ struct dentry *h_dentry, struct au_branch *br)
22883+{
22884+ int err;
22885+ struct path h_path = {
86dc4139 22886+ .mnt = au_br_mnt(br)
1facf9fc 22887+ };
22888+ struct inode *h_dir;
22889+
22890+ h_dir = h_parent->d_inode;
7f207e10 22891+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
4f0767ce 22892+again:
b4510431 22893+ h_path.dentry = vfsub_lkup_one(tgt, h_parent);
1facf9fc 22894+ err = PTR_ERR(h_path.dentry);
22895+ if (IS_ERR(h_path.dentry))
22896+ goto out;
22897+
22898+ err = 0;
22899+ /* wh.plink dir is not monitored */
7f207e10 22900+ /* todo: is it really safe? */
1facf9fc 22901+ if (h_path.dentry->d_inode
22902+ && h_path.dentry->d_inode != h_dentry->d_inode) {
22903+ err = vfsub_unlink(h_dir, &h_path, /*force*/0);
22904+ dput(h_path.dentry);
22905+ h_path.dentry = NULL;
22906+ if (!err)
22907+ goto again;
22908+ }
22909+ if (!err && !h_path.dentry->d_inode)
22910+ err = vfsub_link(h_dentry, h_dir, &h_path);
22911+ dput(h_path.dentry);
22912+
4f0767ce 22913+out:
7f207e10 22914+ mutex_unlock(&h_dir->i_mutex);
1facf9fc 22915+ return err;
22916+}
22917+
22918+struct do_whplink_args {
22919+ int *errp;
22920+ struct qstr *tgt;
22921+ struct dentry *h_parent;
22922+ struct dentry *h_dentry;
22923+ struct au_branch *br;
22924+};
22925+
22926+static void call_do_whplink(void *args)
22927+{
22928+ struct do_whplink_args *a = args;
22929+ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
22930+}
22931+
22932+static int whplink(struct dentry *h_dentry, struct inode *inode,
22933+ aufs_bindex_t bindex, struct au_branch *br)
22934+{
22935+ int err, wkq_err;
22936+ struct au_wbr *wbr;
22937+ struct dentry *h_parent;
22938+ struct inode *h_dir;
22939+ char a[PLINK_NAME_LEN];
0c3ec466 22940+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 22941+
22942+ wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
22943+ h_parent = wbr->wbr_plink;
22944+ h_dir = h_parent->d_inode;
22945+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
22946+
22947+ /* always superio. */
2dfbb274 22948+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
1facf9fc 22949+ struct do_whplink_args args = {
22950+ .errp = &err,
22951+ .tgt = &tgtname,
22952+ .h_parent = h_parent,
22953+ .h_dentry = h_dentry,
22954+ .br = br
22955+ };
22956+ wkq_err = au_wkq_wait(call_do_whplink, &args);
22957+ if (unlikely(wkq_err))
22958+ err = wkq_err;
22959+ } else
22960+ err = do_whplink(&tgtname, h_parent, h_dentry, br);
1facf9fc 22961+
22962+ return err;
22963+}
22964+
22965+/* free a single plink */
22966+static void do_put_plink(struct pseudo_link *plink, int do_del)
22967+{
1facf9fc 22968+ if (do_del)
86dc4139 22969+ hlist_del(&plink->hlist);
4a4d8108
AM
22970+ iput(plink->inode);
22971+ kfree(plink);
22972+}
22973+
22974+static void do_put_plink_rcu(struct rcu_head *rcu)
22975+{
22976+ struct pseudo_link *plink;
22977+
22978+ plink = container_of(rcu, struct pseudo_link, rcu);
22979+ iput(plink->inode);
1facf9fc 22980+ kfree(plink);
22981+}
22982+
22983+/*
22984+ * create a new pseudo-link for @h_dentry on @bindex.
22985+ * the linked inode is held in aufs @inode.
22986+ */
22987+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
22988+ struct dentry *h_dentry)
22989+{
22990+ struct super_block *sb;
22991+ struct au_sbinfo *sbinfo;
86dc4139 22992+ struct hlist_head *plink_hlist;
4a4d8108 22993+ struct pseudo_link *plink, *tmp;
86dc4139
AM
22994+ struct au_sphlhead *sphl;
22995+ int found, err, cnt, i;
1facf9fc 22996+
22997+ sb = inode->i_sb;
22998+ sbinfo = au_sbi(sb);
22999+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 23000+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 23001+
86dc4139 23002+ found = au_plink_test(inode);
4a4d8108 23003+ if (found)
1facf9fc 23004+ return;
4a4d8108 23005+
86dc4139
AM
23006+ i = au_plink_hash(inode->i_ino);
23007+ sphl = sbinfo->si_plink + i;
23008+ plink_hlist = &sphl->head;
4a4d8108
AM
23009+ tmp = kmalloc(sizeof(*plink), GFP_NOFS);
23010+ if (tmp)
23011+ tmp->inode = au_igrab(inode);
23012+ else {
23013+ err = -ENOMEM;
23014+ goto out;
1facf9fc 23015+ }
23016+
86dc4139
AM
23017+ spin_lock(&sphl->spin);
23018+ hlist_for_each_entry(plink, plink_hlist, hlist) {
4a4d8108
AM
23019+ if (plink->inode == inode) {
23020+ found = 1;
23021+ break;
23022+ }
1facf9fc 23023+ }
4a4d8108 23024+ if (!found)
86dc4139
AM
23025+ hlist_add_head_rcu(&tmp->hlist, plink_hlist);
23026+ spin_unlock(&sphl->spin);
4a4d8108 23027+ if (!found) {
86dc4139
AM
23028+ cnt = au_sphl_count(sphl);
23029+#define msg "unexpectedly unblanced or too many pseudo-links"
23030+ if (cnt > AUFS_PLINK_WARN)
23031+ AuWarn1(msg ", %d\n", cnt);
23032+#undef msg
1facf9fc 23033+ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
4a4d8108
AM
23034+ } else {
23035+ do_put_plink(tmp, 0);
23036+ return;
1facf9fc 23037+ }
23038+
4a4d8108 23039+out:
1facf9fc 23040+ if (unlikely(err)) {
0c3ec466 23041+ pr_warn("err %d, damaged pseudo link.\n", err);
4a4d8108 23042+ if (tmp) {
86dc4139 23043+ au_sphl_del_rcu(&tmp->hlist, sphl);
4a4d8108
AM
23044+ call_rcu(&tmp->rcu, do_put_plink_rcu);
23045+ }
1facf9fc 23046+ }
23047+}
23048+
23049+/* free all plinks */
e49829fe 23050+void au_plink_put(struct super_block *sb, int verbose)
1facf9fc 23051+{
86dc4139 23052+ int i, warned;
1facf9fc 23053+ struct au_sbinfo *sbinfo;
86dc4139
AM
23054+ struct hlist_head *plink_hlist;
23055+ struct hlist_node *tmp;
23056+ struct pseudo_link *plink;
1facf9fc 23057+
dece6358
AM
23058+ SiMustWriteLock(sb);
23059+
1facf9fc 23060+ sbinfo = au_sbi(sb);
23061+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 23062+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 23063+
1facf9fc 23064+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
23065+ warned = 0;
23066+ for (i = 0; i < AuPlink_NHASH; i++) {
23067+ plink_hlist = &sbinfo->si_plink[i].head;
23068+ if (!warned && verbose && !hlist_empty(plink_hlist)) {
23069+ pr_warn("pseudo-link is not flushed");
23070+ warned = 1;
23071+ }
23072+ hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist)
23073+ do_put_plink(plink, 0);
23074+ INIT_HLIST_HEAD(plink_hlist);
23075+ }
1facf9fc 23076+}
23077+
e49829fe
JR
23078+void au_plink_clean(struct super_block *sb, int verbose)
23079+{
23080+ struct dentry *root;
23081+
23082+ root = sb->s_root;
23083+ aufs_write_lock(root);
23084+ if (au_opt_test(au_mntflags(sb), PLINK))
23085+ au_plink_put(sb, verbose);
23086+ aufs_write_unlock(root);
23087+}
23088+
86dc4139
AM
23089+static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id)
23090+{
23091+ int do_put;
23092+ aufs_bindex_t bstart, bend, bindex;
23093+
23094+ do_put = 0;
23095+ bstart = au_ibstart(inode);
23096+ bend = au_ibend(inode);
23097+ if (bstart >= 0) {
23098+ for (bindex = bstart; bindex <= bend; bindex++) {
23099+ if (!au_h_iptr(inode, bindex)
23100+ || au_ii_br_id(inode, bindex) != br_id)
23101+ continue;
23102+ au_set_h_iptr(inode, bindex, NULL, 0);
23103+ do_put = 1;
23104+ break;
23105+ }
23106+ if (do_put)
23107+ for (bindex = bstart; bindex <= bend; bindex++)
23108+ if (au_h_iptr(inode, bindex)) {
23109+ do_put = 0;
23110+ break;
23111+ }
23112+ } else
23113+ do_put = 1;
23114+
23115+ return do_put;
23116+}
23117+
1facf9fc 23118+/* free the plinks on a branch specified by @br_id */
23119+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
23120+{
23121+ struct au_sbinfo *sbinfo;
86dc4139
AM
23122+ struct hlist_head *plink_hlist;
23123+ struct hlist_node *tmp;
23124+ struct pseudo_link *plink;
1facf9fc 23125+ struct inode *inode;
86dc4139 23126+ int i, do_put;
1facf9fc 23127+
dece6358
AM
23128+ SiMustWriteLock(sb);
23129+
1facf9fc 23130+ sbinfo = au_sbi(sb);
23131+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 23132+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 23133+
1facf9fc 23134+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
23135+ for (i = 0; i < AuPlink_NHASH; i++) {
23136+ plink_hlist = &sbinfo->si_plink[i].head;
23137+ hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist) {
23138+ inode = au_igrab(plink->inode);
23139+ ii_write_lock_child(inode);
23140+ do_put = au_plink_do_half_refresh(inode, br_id);
dece6358
AM
23141+ if (do_put)
23142+ do_put_plink(plink, 1);
86dc4139
AM
23143+ ii_write_unlock(inode);
23144+ iput(inode);
dece6358 23145+ }
dece6358
AM
23146+ }
23147+}
7f207e10
AM
23148diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
23149--- /usr/share/empty/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100
86dc4139 23150+++ linux/fs/aufs/poll.c 2013-07-06 13:20:47.753531903 +0200
dece6358
AM
23151@@ -0,0 +1,56 @@
23152+/*
7a9e40b8 23153+ * Copyright (C) 2005-2013 Junjiro R. Okajima
dece6358
AM
23154+ *
23155+ * This program, aufs is free software; you can redistribute it and/or modify
23156+ * it under the terms of the GNU General Public License as published by
23157+ * the Free Software Foundation; either version 2 of the License, or
23158+ * (at your option) any later version.
23159+ *
23160+ * This program is distributed in the hope that it will be useful,
23161+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23162+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23163+ * GNU General Public License for more details.
23164+ *
23165+ * You should have received a copy of the GNU General Public License
23166+ * along with this program; if not, write to the Free Software
23167+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23168+ */
23169+
1308ab2a 23170+/*
23171+ * poll operation
23172+ * There is only one filesystem which implements ->poll operation, currently.
23173+ */
23174+
23175+#include "aufs.h"
23176+
23177+unsigned int aufs_poll(struct file *file, poll_table *wait)
23178+{
23179+ unsigned int mask;
23180+ int err;
23181+ struct file *h_file;
23182+ struct dentry *dentry;
23183+ struct super_block *sb;
23184+
23185+ /* We should pretend an error happened. */
23186+ mask = POLLERR /* | POLLIN | POLLOUT */;
23187+ dentry = file->f_dentry;
23188+ sb = dentry->d_sb;
e49829fe 23189+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
1308ab2a 23190+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
23191+ if (unlikely(err))
23192+ goto out;
23193+
23194+ /* it is not an error if h_file has no operation */
23195+ mask = DEFAULT_POLLMASK;
4a4d8108 23196+ h_file = au_hf_top(file);
1308ab2a 23197+ if (h_file->f_op && h_file->f_op->poll)
23198+ mask = h_file->f_op->poll(h_file, wait);
23199+
23200+ di_read_unlock(dentry, AuLock_IR);
23201+ fi_read_unlock(file);
23202+
4f0767ce 23203+out:
1308ab2a 23204+ si_read_unlock(sb);
23205+ AuTraceErr((int)mask);
23206+ return mask;
23207+}
7f207e10
AM
23208diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
23209--- /usr/share/empty/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100
86dc4139 23210+++ linux/fs/aufs/procfs.c 2013-07-06 13:20:47.753531903 +0200
53392da6 23211@@ -0,0 +1,170 @@
e49829fe 23212+/*
7a9e40b8 23213+ * Copyright (C) 2010-2013 Junjiro R. Okajima
e49829fe
JR
23214+ *
23215+ * This program, aufs is free software; you can redistribute it and/or modify
23216+ * it under the terms of the GNU General Public License as published by
23217+ * the Free Software Foundation; either version 2 of the License, or
23218+ * (at your option) any later version.
23219+ *
23220+ * This program is distributed in the hope that it will be useful,
23221+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23222+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23223+ * GNU General Public License for more details.
23224+ *
23225+ * You should have received a copy of the GNU General Public License
23226+ * along with this program; if not, write to the Free Software
23227+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23228+ */
23229+
23230+/*
23231+ * procfs interfaces
23232+ */
23233+
23234+#include <linux/proc_fs.h>
23235+#include "aufs.h"
23236+
23237+static int au_procfs_plm_release(struct inode *inode, struct file *file)
23238+{
23239+ struct au_sbinfo *sbinfo;
23240+
23241+ sbinfo = file->private_data;
23242+ if (sbinfo) {
23243+ au_plink_maint_leave(sbinfo);
23244+ kobject_put(&sbinfo->si_kobj);
23245+ }
23246+
23247+ return 0;
23248+}
23249+
23250+static void au_procfs_plm_write_clean(struct file *file)
23251+{
23252+ struct au_sbinfo *sbinfo;
23253+
23254+ sbinfo = file->private_data;
23255+ if (sbinfo)
23256+ au_plink_clean(sbinfo->si_sb, /*verbose*/0);
23257+}
23258+
23259+static int au_procfs_plm_write_si(struct file *file, unsigned long id)
23260+{
23261+ int err;
23262+ struct super_block *sb;
23263+ struct au_sbinfo *sbinfo;
23264+
23265+ err = -EBUSY;
23266+ if (unlikely(file->private_data))
23267+ goto out;
23268+
23269+ sb = NULL;
53392da6 23270+ /* don't use au_sbilist_lock() here */
e49829fe
JR
23271+ spin_lock(&au_sbilist.spin);
23272+ list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
23273+ if (id == sysaufs_si_id(sbinfo)) {
23274+ kobject_get(&sbinfo->si_kobj);
23275+ sb = sbinfo->si_sb;
23276+ break;
23277+ }
23278+ spin_unlock(&au_sbilist.spin);
23279+
23280+ err = -EINVAL;
23281+ if (unlikely(!sb))
23282+ goto out;
23283+
23284+ err = au_plink_maint_enter(sb);
23285+ if (!err)
23286+ /* keep kobject_get() */
23287+ file->private_data = sbinfo;
23288+ else
23289+ kobject_put(&sbinfo->si_kobj);
23290+out:
23291+ return err;
23292+}
23293+
23294+/*
23295+ * Accept a valid "si=xxxx" only.
23296+ * Once it is accepted successfully, accept "clean" too.
23297+ */
23298+static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf,
23299+ size_t count, loff_t *ppos)
23300+{
23301+ ssize_t err;
23302+ unsigned long id;
23303+ /* last newline is allowed */
23304+ char buf[3 + sizeof(unsigned long) * 2 + 1];
23305+
23306+ err = -EACCES;
23307+ if (unlikely(!capable(CAP_SYS_ADMIN)))
23308+ goto out;
23309+
23310+ err = -EINVAL;
23311+ if (unlikely(count > sizeof(buf)))
23312+ goto out;
23313+
23314+ err = copy_from_user(buf, ubuf, count);
23315+ if (unlikely(err)) {
23316+ err = -EFAULT;
23317+ goto out;
23318+ }
23319+ buf[count] = 0;
23320+
23321+ err = -EINVAL;
23322+ if (!strcmp("clean", buf)) {
23323+ au_procfs_plm_write_clean(file);
23324+ goto out_success;
23325+ } else if (unlikely(strncmp("si=", buf, 3)))
23326+ goto out;
23327+
9dbd164d 23328+ err = kstrtoul(buf + 3, 16, &id);
e49829fe
JR
23329+ if (unlikely(err))
23330+ goto out;
23331+
23332+ err = au_procfs_plm_write_si(file, id);
23333+ if (unlikely(err))
23334+ goto out;
23335+
23336+out_success:
23337+ err = count; /* success */
23338+out:
23339+ return err;
23340+}
23341+
23342+static const struct file_operations au_procfs_plm_fop = {
23343+ .write = au_procfs_plm_write,
23344+ .release = au_procfs_plm_release,
23345+ .owner = THIS_MODULE
23346+};
23347+
23348+/* ---------------------------------------------------------------------- */
23349+
23350+static struct proc_dir_entry *au_procfs_dir;
23351+
23352+void au_procfs_fin(void)
23353+{
23354+ remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir);
23355+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
23356+}
23357+
23358+int __init au_procfs_init(void)
23359+{
23360+ int err;
23361+ struct proc_dir_entry *entry;
23362+
23363+ err = -ENOMEM;
23364+ au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL);
23365+ if (unlikely(!au_procfs_dir))
23366+ goto out;
23367+
23368+ entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | S_IWUSR,
23369+ au_procfs_dir, &au_procfs_plm_fop);
23370+ if (unlikely(!entry))
23371+ goto out_dir;
23372+
23373+ err = 0;
23374+ goto out; /* success */
23375+
23376+
23377+out_dir:
23378+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
23379+out:
23380+ return err;
23381+}
7f207e10
AM
23382diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
23383--- /usr/share/empty/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
23384+++ linux/fs/aufs/rdu.c 2013-10-26 16:51:29.586298347 +0200
23385@@ -0,0 +1,389 @@
1308ab2a 23386+/*
7a9e40b8 23387+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1308ab2a 23388+ *
23389+ * This program, aufs is free software; you can redistribute it and/or modify
23390+ * it under the terms of the GNU General Public License as published by
23391+ * the Free Software Foundation; either version 2 of the License, or
23392+ * (at your option) any later version.
23393+ *
23394+ * This program is distributed in the hope that it will be useful,
23395+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23396+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23397+ * GNU General Public License for more details.
23398+ *
23399+ * You should have received a copy of the GNU General Public License
23400+ * along with this program; if not, write to the Free Software
23401+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23402+ */
23403+
23404+/*
23405+ * readdir in userspace.
23406+ */
23407+
b752ccd1 23408+#include <linux/compat.h>
4a4d8108 23409+#include <linux/fs_stack.h>
1308ab2a 23410+#include <linux/security.h>
1308ab2a 23411+#include "aufs.h"
23412+
23413+/* bits for struct aufs_rdu.flags */
23414+#define AuRdu_CALLED 1
23415+#define AuRdu_CONT (1 << 1)
23416+#define AuRdu_FULL (1 << 2)
23417+#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name)
7f207e10
AM
23418+#define au_fset_rdu(flags, name) \
23419+ do { (flags) |= AuRdu_##name; } while (0)
23420+#define au_fclr_rdu(flags, name) \
23421+ do { (flags) &= ~AuRdu_##name; } while (0)
1308ab2a 23422+
23423+struct au_rdu_arg {
392086de 23424+ struct dir_context ctx;
1308ab2a 23425+ struct aufs_rdu *rdu;
23426+ union au_rdu_ent_ul ent;
23427+ unsigned long end;
23428+
23429+ struct super_block *sb;
23430+ int err;
23431+};
23432+
392086de 23433+static int au_rdu_fill(struct dir_context *ctx, const char *name, int nlen,
1308ab2a 23434+ loff_t offset, u64 h_ino, unsigned int d_type)
23435+{
23436+ int err, len;
392086de 23437+ struct au_rdu_arg *arg = container_of(ctx, struct au_rdu_arg, ctx);
1308ab2a 23438+ struct aufs_rdu *rdu = arg->rdu;
23439+ struct au_rdu_ent ent;
23440+
23441+ err = 0;
23442+ arg->err = 0;
23443+ au_fset_rdu(rdu->cookie.flags, CALLED);
23444+ len = au_rdu_len(nlen);
23445+ if (arg->ent.ul + len < arg->end) {
23446+ ent.ino = h_ino;
23447+ ent.bindex = rdu->cookie.bindex;
23448+ ent.type = d_type;
23449+ ent.nlen = nlen;
4a4d8108
AM
23450+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
23451+ ent.type = DT_UNKNOWN;
1308ab2a 23452+
9dbd164d 23453+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 23454+ err = -EFAULT;
23455+ if (copy_to_user(arg->ent.e, &ent, sizeof(ent)))
23456+ goto out;
23457+ if (copy_to_user(arg->ent.e->name, name, nlen))
23458+ goto out;
23459+ /* the terminating NULL */
23460+ if (__put_user(0, arg->ent.e->name + nlen))
23461+ goto out;
23462+ err = 0;
23463+ /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */
23464+ arg->ent.ul += len;
23465+ rdu->rent++;
23466+ } else {
23467+ err = -EFAULT;
23468+ au_fset_rdu(rdu->cookie.flags, FULL);
23469+ rdu->full = 1;
23470+ rdu->tail = arg->ent;
23471+ }
23472+
4f0767ce 23473+out:
1308ab2a 23474+ /* AuTraceErr(err); */
23475+ return err;
23476+}
23477+
23478+static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg)
23479+{
23480+ int err;
23481+ loff_t offset;
23482+ struct au_rdu_cookie *cookie = &arg->rdu->cookie;
23483+
92d182d2 23484+ /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */
1308ab2a 23485+ offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET);
23486+ err = offset;
23487+ if (unlikely(offset != cookie->h_pos))
23488+ goto out;
23489+
23490+ err = 0;
23491+ do {
23492+ arg->err = 0;
23493+ au_fclr_rdu(cookie->flags, CALLED);
23494+ /* smp_mb(); */
392086de 23495+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1308ab2a 23496+ if (err >= 0)
23497+ err = arg->err;
23498+ } while (!err
23499+ && au_ftest_rdu(cookie->flags, CALLED)
23500+ && !au_ftest_rdu(cookie->flags, FULL));
23501+ cookie->h_pos = h_file->f_pos;
23502+
4f0767ce 23503+out:
1308ab2a 23504+ AuTraceErr(err);
23505+ return err;
23506+}
23507+
23508+static int au_rdu(struct file *file, struct aufs_rdu *rdu)
23509+{
23510+ int err;
23511+ aufs_bindex_t bend;
392086de
AM
23512+ struct au_rdu_arg arg = {
23513+ .ctx = {
23514+ .actor = au_diractor(au_rdu_fill)
23515+ }
23516+ };
1308ab2a 23517+ struct dentry *dentry;
23518+ struct inode *inode;
23519+ struct file *h_file;
23520+ struct au_rdu_cookie *cookie = &rdu->cookie;
23521+
23522+ err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz);
23523+ if (unlikely(err)) {
23524+ err = -EFAULT;
23525+ AuTraceErr(err);
23526+ goto out;
23527+ }
23528+ rdu->rent = 0;
23529+ rdu->tail = rdu->ent;
23530+ rdu->full = 0;
23531+ arg.rdu = rdu;
23532+ arg.ent = rdu->ent;
23533+ arg.end = arg.ent.ul;
23534+ arg.end += rdu->sz;
23535+
23536+ err = -ENOTDIR;
392086de 23537+ if (unlikely(!file->f_op || !file->f_op->iterate))
1308ab2a 23538+ goto out;
23539+
23540+ err = security_file_permission(file, MAY_READ);
23541+ AuTraceErr(err);
23542+ if (unlikely(err))
23543+ goto out;
23544+
23545+ dentry = file->f_dentry;
23546+ inode = dentry->d_inode;
23547+#if 1
23548+ mutex_lock(&inode->i_mutex);
23549+#else
23550+ err = mutex_lock_killable(&inode->i_mutex);
23551+ AuTraceErr(err);
23552+ if (unlikely(err))
23553+ goto out;
23554+#endif
1308ab2a 23555+
23556+ arg.sb = inode->i_sb;
e49829fe
JR
23557+ err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM);
23558+ if (unlikely(err))
23559+ goto out_mtx;
027c5e7a
AM
23560+ err = au_alive_dir(dentry);
23561+ if (unlikely(err))
23562+ goto out_si;
e49829fe 23563+ /* todo: reval? */
1308ab2a 23564+ fi_read_lock(file);
23565+
23566+ err = -EAGAIN;
23567+ if (unlikely(au_ftest_rdu(cookie->flags, CONT)
23568+ && cookie->generation != au_figen(file)))
23569+ goto out_unlock;
23570+
23571+ err = 0;
23572+ if (!rdu->blk) {
23573+ rdu->blk = au_sbi(arg.sb)->si_rdblk;
23574+ if (!rdu->blk)
23575+ rdu->blk = au_dir_size(file, /*dentry*/NULL);
23576+ }
23577+ bend = au_fbstart(file);
23578+ if (cookie->bindex < bend)
23579+ cookie->bindex = bend;
4a4d8108 23580+ bend = au_fbend_dir(file);
1308ab2a 23581+ /* AuDbg("b%d, b%d\n", cookie->bindex, bend); */
23582+ for (; !err && cookie->bindex <= bend;
23583+ cookie->bindex++, cookie->h_pos = 0) {
4a4d8108 23584+ h_file = au_hf_dir(file, cookie->bindex);
1308ab2a 23585+ if (!h_file)
23586+ continue;
23587+
23588+ au_fclr_rdu(cookie->flags, FULL);
23589+ err = au_rdu_do(h_file, &arg);
23590+ AuTraceErr(err);
23591+ if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err))
23592+ break;
23593+ }
23594+ AuDbg("rent %llu\n", rdu->rent);
23595+
23596+ if (!err && !au_ftest_rdu(cookie->flags, CONT)) {
23597+ rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH);
23598+ au_fset_rdu(cookie->flags, CONT);
23599+ cookie->generation = au_figen(file);
23600+ }
23601+
23602+ ii_read_lock_child(inode);
23603+ fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibstart(inode)));
23604+ ii_read_unlock(inode);
23605+
4f0767ce 23606+out_unlock:
1308ab2a 23607+ fi_read_unlock(file);
027c5e7a 23608+out_si:
1308ab2a 23609+ si_read_unlock(arg.sb);
4f0767ce 23610+out_mtx:
1308ab2a 23611+ mutex_unlock(&inode->i_mutex);
4f0767ce 23612+out:
1308ab2a 23613+ AuTraceErr(err);
23614+ return err;
23615+}
23616+
23617+static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu)
23618+{
23619+ int err;
23620+ ino_t ino;
23621+ unsigned long long nent;
23622+ union au_rdu_ent_ul *u;
23623+ struct au_rdu_ent ent;
23624+ struct super_block *sb;
23625+
23626+ err = 0;
23627+ nent = rdu->nent;
23628+ u = &rdu->ent;
23629+ sb = file->f_dentry->d_sb;
23630+ si_read_lock(sb, AuLock_FLUSH);
23631+ while (nent-- > 0) {
9dbd164d 23632+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 23633+ err = copy_from_user(&ent, u->e, sizeof(ent));
4a4d8108
AM
23634+ if (!err)
23635+ err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino));
1308ab2a 23636+ if (unlikely(err)) {
23637+ err = -EFAULT;
23638+ AuTraceErr(err);
23639+ break;
23640+ }
23641+
23642+ /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */
23643+ if (!ent.wh)
23644+ err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino);
23645+ else
23646+ err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type,
23647+ &ino);
23648+ if (unlikely(err)) {
23649+ AuTraceErr(err);
23650+ break;
23651+ }
23652+
23653+ err = __put_user(ino, &u->e->ino);
23654+ if (unlikely(err)) {
23655+ err = -EFAULT;
23656+ AuTraceErr(err);
23657+ break;
23658+ }
23659+ u->ul += au_rdu_len(ent.nlen);
23660+ }
23661+ si_read_unlock(sb);
23662+
23663+ return err;
23664+}
23665+
23666+/* ---------------------------------------------------------------------- */
23667+
23668+static int au_rdu_verify(struct aufs_rdu *rdu)
23669+{
b752ccd1 23670+ AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | "
1308ab2a 23671+ "%llu, b%d, 0x%x, g%u}\n",
b752ccd1 23672+ rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ],
1308ab2a 23673+ rdu->blk,
23674+ rdu->rent, rdu->shwh, rdu->full,
23675+ rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags,
23676+ rdu->cookie.generation);
dece6358 23677+
b752ccd1 23678+ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu))
1308ab2a 23679+ return 0;
dece6358 23680+
b752ccd1
AM
23681+ AuDbg("%u:%u\n",
23682+ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu));
1308ab2a 23683+ return -EINVAL;
23684+}
23685+
23686+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
dece6358 23687+{
1308ab2a 23688+ long err, e;
23689+ struct aufs_rdu rdu;
23690+ void __user *p = (void __user *)arg;
dece6358 23691+
1308ab2a 23692+ err = copy_from_user(&rdu, p, sizeof(rdu));
23693+ if (unlikely(err)) {
23694+ err = -EFAULT;
23695+ AuTraceErr(err);
23696+ goto out;
23697+ }
23698+ err = au_rdu_verify(&rdu);
dece6358
AM
23699+ if (unlikely(err))
23700+ goto out;
23701+
1308ab2a 23702+ switch (cmd) {
23703+ case AUFS_CTL_RDU:
23704+ err = au_rdu(file, &rdu);
23705+ if (unlikely(err))
23706+ break;
dece6358 23707+
1308ab2a 23708+ e = copy_to_user(p, &rdu, sizeof(rdu));
23709+ if (unlikely(e)) {
23710+ err = -EFAULT;
23711+ AuTraceErr(err);
23712+ }
23713+ break;
23714+ case AUFS_CTL_RDU_INO:
23715+ err = au_rdu_ino(file, &rdu);
23716+ break;
23717+
23718+ default:
4a4d8108 23719+ /* err = -ENOTTY; */
1308ab2a 23720+ err = -EINVAL;
23721+ }
dece6358 23722+
4f0767ce 23723+out:
1308ab2a 23724+ AuTraceErr(err);
23725+ return err;
1facf9fc 23726+}
b752ccd1
AM
23727+
23728+#ifdef CONFIG_COMPAT
23729+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
23730+{
23731+ long err, e;
23732+ struct aufs_rdu rdu;
23733+ void __user *p = compat_ptr(arg);
23734+
23735+ /* todo: get_user()? */
23736+ err = copy_from_user(&rdu, p, sizeof(rdu));
23737+ if (unlikely(err)) {
23738+ err = -EFAULT;
23739+ AuTraceErr(err);
23740+ goto out;
23741+ }
23742+ rdu.ent.e = compat_ptr(rdu.ent.ul);
23743+ err = au_rdu_verify(&rdu);
23744+ if (unlikely(err))
23745+ goto out;
23746+
23747+ switch (cmd) {
23748+ case AUFS_CTL_RDU:
23749+ err = au_rdu(file, &rdu);
23750+ if (unlikely(err))
23751+ break;
23752+
23753+ rdu.ent.ul = ptr_to_compat(rdu.ent.e);
23754+ rdu.tail.ul = ptr_to_compat(rdu.tail.e);
23755+ e = copy_to_user(p, &rdu, sizeof(rdu));
23756+ if (unlikely(e)) {
23757+ err = -EFAULT;
23758+ AuTraceErr(err);
23759+ }
23760+ break;
23761+ case AUFS_CTL_RDU_INO:
23762+ err = au_rdu_ino(file, &rdu);
23763+ break;
23764+
23765+ default:
23766+ /* err = -ENOTTY; */
23767+ err = -EINVAL;
23768+ }
23769+
4f0767ce 23770+out:
b752ccd1
AM
23771+ AuTraceErr(err);
23772+ return err;
23773+}
23774+#endif
7f207e10
AM
23775diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h
23776--- /usr/share/empty/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100
86dc4139 23777+++ linux/fs/aufs/rwsem.h 2013-07-06 13:20:47.753531903 +0200
f6c5ef8b 23778@@ -0,0 +1,188 @@
1facf9fc 23779+/*
7a9e40b8 23780+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 23781+ *
23782+ * This program, aufs is free software; you can redistribute it and/or modify
23783+ * it under the terms of the GNU General Public License as published by
23784+ * the Free Software Foundation; either version 2 of the License, or
23785+ * (at your option) any later version.
dece6358
AM
23786+ *
23787+ * This program is distributed in the hope that it will be useful,
23788+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23789+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23790+ * GNU General Public License for more details.
23791+ *
23792+ * You should have received a copy of the GNU General Public License
23793+ * along with this program; if not, write to the Free Software
23794+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 23795+ */
23796+
23797+/*
23798+ * simple read-write semaphore wrappers
23799+ */
23800+
23801+#ifndef __AUFS_RWSEM_H__
23802+#define __AUFS_RWSEM_H__
23803+
23804+#ifdef __KERNEL__
23805+
4a4d8108 23806+#include "debug.h"
dece6358
AM
23807+
23808+struct au_rwsem {
23809+ struct rw_semaphore rwsem;
23810+#ifdef CONFIG_AUFS_DEBUG
23811+ /* just for debugging, not almighty counter */
23812+ atomic_t rcnt, wcnt;
23813+#endif
23814+};
23815+
23816+#ifdef CONFIG_AUFS_DEBUG
23817+#define AuDbgCntInit(rw) do { \
23818+ atomic_set(&(rw)->rcnt, 0); \
23819+ atomic_set(&(rw)->wcnt, 0); \
23820+ smp_mb(); /* atomic set */ \
23821+} while (0)
23822+
e49829fe 23823+#define AuDbgRcntInc(rw) atomic_inc(&(rw)->rcnt)
dece6358 23824+#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0)
e49829fe 23825+#define AuDbgWcntInc(rw) atomic_inc(&(rw)->wcnt)
dece6358
AM
23826+#define AuDbgWcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->wcnt) < 0)
23827+#else
23828+#define AuDbgCntInit(rw) do {} while (0)
23829+#define AuDbgRcntInc(rw) do {} while (0)
23830+#define AuDbgRcntDec(rw) do {} while (0)
23831+#define AuDbgWcntInc(rw) do {} while (0)
23832+#define AuDbgWcntDec(rw) do {} while (0)
23833+#endif /* CONFIG_AUFS_DEBUG */
23834+
23835+/* to debug easier, do not make them inlined functions */
23836+#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->rwsem.wait_list))
23837+/* rwsem_is_locked() is unusable */
23838+#define AuRwMustReadLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0)
23839+#define AuRwMustWriteLock(rw) AuDebugOn(atomic_read(&(rw)->wcnt) <= 0)
23840+#define AuRwMustAnyLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0 \
23841+ && atomic_read(&(rw)->wcnt) <= 0)
23842+#define AuRwDestroy(rw) AuDebugOn(atomic_read(&(rw)->rcnt) \
23843+ || atomic_read(&(rw)->wcnt))
23844+
e49829fe
JR
23845+#define au_rw_class(rw, key) lockdep_set_class(&(rw)->rwsem, key)
23846+
dece6358
AM
23847+static inline void au_rw_init(struct au_rwsem *rw)
23848+{
23849+ AuDbgCntInit(rw);
23850+ init_rwsem(&rw->rwsem);
23851+}
23852+
23853+static inline void au_rw_init_wlock(struct au_rwsem *rw)
23854+{
23855+ au_rw_init(rw);
23856+ down_write(&rw->rwsem);
23857+ AuDbgWcntInc(rw);
23858+}
23859+
23860+static inline void au_rw_init_wlock_nested(struct au_rwsem *rw,
23861+ unsigned int lsc)
23862+{
23863+ au_rw_init(rw);
23864+ down_write_nested(&rw->rwsem, lsc);
23865+ AuDbgWcntInc(rw);
23866+}
23867+
23868+static inline void au_rw_read_lock(struct au_rwsem *rw)
23869+{
23870+ down_read(&rw->rwsem);
23871+ AuDbgRcntInc(rw);
23872+}
23873+
23874+static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc)
23875+{
23876+ down_read_nested(&rw->rwsem, lsc);
23877+ AuDbgRcntInc(rw);
23878+}
23879+
23880+static inline void au_rw_read_unlock(struct au_rwsem *rw)
23881+{
23882+ AuRwMustReadLock(rw);
23883+ AuDbgRcntDec(rw);
23884+ up_read(&rw->rwsem);
23885+}
23886+
23887+static inline void au_rw_dgrade_lock(struct au_rwsem *rw)
23888+{
23889+ AuRwMustWriteLock(rw);
23890+ AuDbgRcntInc(rw);
23891+ AuDbgWcntDec(rw);
23892+ downgrade_write(&rw->rwsem);
23893+}
23894+
23895+static inline void au_rw_write_lock(struct au_rwsem *rw)
23896+{
23897+ down_write(&rw->rwsem);
23898+ AuDbgWcntInc(rw);
23899+}
23900+
23901+static inline void au_rw_write_lock_nested(struct au_rwsem *rw,
23902+ unsigned int lsc)
23903+{
23904+ down_write_nested(&rw->rwsem, lsc);
23905+ AuDbgWcntInc(rw);
23906+}
1facf9fc 23907+
dece6358
AM
23908+static inline void au_rw_write_unlock(struct au_rwsem *rw)
23909+{
23910+ AuRwMustWriteLock(rw);
23911+ AuDbgWcntDec(rw);
23912+ up_write(&rw->rwsem);
23913+}
23914+
23915+/* why is not _nested version defined */
23916+static inline int au_rw_read_trylock(struct au_rwsem *rw)
23917+{
23918+ int ret = down_read_trylock(&rw->rwsem);
23919+ if (ret)
23920+ AuDbgRcntInc(rw);
23921+ return ret;
23922+}
23923+
23924+static inline int au_rw_write_trylock(struct au_rwsem *rw)
23925+{
23926+ int ret = down_write_trylock(&rw->rwsem);
23927+ if (ret)
23928+ AuDbgWcntInc(rw);
23929+ return ret;
23930+}
23931+
23932+#undef AuDbgCntInit
23933+#undef AuDbgRcntInc
23934+#undef AuDbgRcntDec
23935+#undef AuDbgWcntInc
23936+#undef AuDbgWcntDec
1facf9fc 23937+
23938+#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
23939+static inline void prefix##_read_lock(param) \
dece6358 23940+{ au_rw_read_lock(rwsem); } \
1facf9fc 23941+static inline void prefix##_write_lock(param) \
dece6358 23942+{ au_rw_write_lock(rwsem); } \
1facf9fc 23943+static inline int prefix##_read_trylock(param) \
dece6358 23944+{ return au_rw_read_trylock(rwsem); } \
1facf9fc 23945+static inline int prefix##_write_trylock(param) \
dece6358 23946+{ return au_rw_write_trylock(rwsem); }
1facf9fc 23947+/* why is not _nested version defined */
23948+/* static inline void prefix##_read_trylock_nested(param, lsc)
dece6358 23949+{ au_rw_read_trylock_nested(rwsem, lsc)); }
1facf9fc 23950+static inline void prefix##_write_trylock_nestd(param, lsc)
dece6358 23951+{ au_rw_write_trylock_nested(rwsem, lsc); } */
1facf9fc 23952+
23953+#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
23954+static inline void prefix##_read_unlock(param) \
dece6358 23955+{ au_rw_read_unlock(rwsem); } \
1facf9fc 23956+static inline void prefix##_write_unlock(param) \
dece6358 23957+{ au_rw_write_unlock(rwsem); } \
1facf9fc 23958+static inline void prefix##_downgrade_lock(param) \
dece6358 23959+{ au_rw_dgrade_lock(rwsem); }
1facf9fc 23960+
23961+#define AuSimpleRwsemFuncs(prefix, param, rwsem) \
23962+ AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
23963+ AuSimpleUnlockRwsemFuncs(prefix, param, rwsem)
23964+
23965+#endif /* __KERNEL__ */
23966+#endif /* __AUFS_RWSEM_H__ */
7f207e10
AM
23967diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
23968--- /usr/share/empty/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
23969+++ linux/fs/aufs/sbinfo.c 2013-10-26 16:51:32.276373845 +0200
23970@@ -0,0 +1,350 @@
1facf9fc 23971+/*
7a9e40b8 23972+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 23973+ *
23974+ * This program, aufs is free software; you can redistribute it and/or modify
23975+ * it under the terms of the GNU General Public License as published by
23976+ * the Free Software Foundation; either version 2 of the License, or
23977+ * (at your option) any later version.
dece6358
AM
23978+ *
23979+ * This program is distributed in the hope that it will be useful,
23980+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23981+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23982+ * GNU General Public License for more details.
23983+ *
23984+ * You should have received a copy of the GNU General Public License
23985+ * along with this program; if not, write to the Free Software
23986+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 23987+ */
23988+
23989+/*
23990+ * superblock private data
23991+ */
23992+
23993+#include "aufs.h"
23994+
23995+/*
23996+ * they are necessary regardless sysfs is disabled.
23997+ */
23998+void au_si_free(struct kobject *kobj)
23999+{
86dc4139 24000+ int i;
1facf9fc 24001+ struct au_sbinfo *sbinfo;
b752ccd1 24002+ char *locked __maybe_unused; /* debug only */
1facf9fc 24003+
24004+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
86dc4139
AM
24005+ for (i = 0; i < AuPlink_NHASH; i++)
24006+ AuDebugOn(!hlist_empty(&sbinfo->si_plink[i].head));
e49829fe 24007+ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
1facf9fc 24008+
e49829fe 24009+ au_rw_write_lock(&sbinfo->si_rwsem);
1facf9fc 24010+ au_br_free(sbinfo);
e49829fe 24011+ au_rw_write_unlock(&sbinfo->si_rwsem);
b752ccd1
AM
24012+
24013+ AuDebugOn(radix_tree_gang_lookup
24014+ (&sbinfo->au_si_pid.tree, (void **)&locked,
24015+ /*first_index*/PID_MAX_DEFAULT - 1,
24016+ /*max_items*/sizeof(locked)/sizeof(*locked)));
24017+
1facf9fc 24018+ kfree(sbinfo->si_branch);
b752ccd1 24019+ kfree(sbinfo->au_si_pid.bitmap);
1facf9fc 24020+ mutex_destroy(&sbinfo->si_xib_mtx);
dece6358 24021+ AuRwDestroy(&sbinfo->si_rwsem);
1facf9fc 24022+
24023+ kfree(sbinfo);
24024+}
24025+
24026+int au_si_alloc(struct super_block *sb)
24027+{
86dc4139 24028+ int err, i;
1facf9fc 24029+ struct au_sbinfo *sbinfo;
e49829fe 24030+ static struct lock_class_key aufs_si;
1facf9fc 24031+
24032+ err = -ENOMEM;
4a4d8108 24033+ sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS);
1facf9fc 24034+ if (unlikely(!sbinfo))
24035+ goto out;
24036+
b752ccd1
AM
24037+ BUILD_BUG_ON(sizeof(unsigned long) !=
24038+ sizeof(*sbinfo->au_si_pid.bitmap));
24039+ sbinfo->au_si_pid.bitmap = kcalloc(BITS_TO_LONGS(PID_MAX_DEFAULT),
24040+ sizeof(*sbinfo->au_si_pid.bitmap),
24041+ GFP_NOFS);
24042+ if (unlikely(!sbinfo->au_si_pid.bitmap))
24043+ goto out_sbinfo;
24044+
1facf9fc 24045+ /* will be reallocated separately */
24046+ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
24047+ if (unlikely(!sbinfo->si_branch))
b752ccd1 24048+ goto out_pidmap;
1facf9fc 24049+
1facf9fc 24050+ err = sysaufs_si_init(sbinfo);
24051+ if (unlikely(err))
24052+ goto out_br;
24053+
24054+ au_nwt_init(&sbinfo->si_nowait);
dece6358 24055+ au_rw_init_wlock(&sbinfo->si_rwsem);
e49829fe 24056+ au_rw_class(&sbinfo->si_rwsem, &aufs_si);
b752ccd1
AM
24057+ spin_lock_init(&sbinfo->au_si_pid.tree_lock);
24058+ INIT_RADIX_TREE(&sbinfo->au_si_pid.tree, GFP_ATOMIC | __GFP_NOFAIL);
24059+
7f207e10 24060+ atomic_long_set(&sbinfo->si_ninodes, 0);
7f207e10
AM
24061+ atomic_long_set(&sbinfo->si_nfiles, 0);
24062+
1facf9fc 24063+ sbinfo->si_bend = -1;
392086de 24064+ sbinfo->si_last_br_id = AUFS_BRANCH_MAX / 2;
1facf9fc 24065+
24066+ sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
24067+ sbinfo->si_wbr_create = AuWbrCreate_Def;
4a4d8108
AM
24068+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup;
24069+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create;
1facf9fc 24070+
e49829fe 24071+ sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
1facf9fc 24072+
392086de
AM
24073+ sbinfo->si_xino_jiffy = jiffies;
24074+ sbinfo->si_xino_expire
24075+ = msecs_to_jiffies(AUFS_XINO_DEF_SEC * MSEC_PER_SEC);
1facf9fc 24076+ mutex_init(&sbinfo->si_xib_mtx);
1facf9fc 24077+ sbinfo->si_xino_brid = -1;
24078+ /* leave si_xib_last_pindex and si_xib_next_bit */
24079+
e49829fe 24080+ sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
1facf9fc 24081+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
24082+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
24083+ sbinfo->si_dirwh = AUFS_DIRWH_DEF;
24084+
86dc4139
AM
24085+ for (i = 0; i < AuPlink_NHASH; i++)
24086+ au_sphl_init(sbinfo->si_plink + i);
1facf9fc 24087+ init_waitqueue_head(&sbinfo->si_plink_wq);
4a4d8108 24088+ spin_lock_init(&sbinfo->si_plink_maint_lock);
1facf9fc 24089+
24090+ /* leave other members for sysaufs and si_mnt. */
24091+ sbinfo->si_sb = sb;
24092+ sb->s_fs_info = sbinfo;
b752ccd1 24093+ si_pid_set(sb);
1facf9fc 24094+ au_debug_sbinfo_init(sbinfo);
24095+ return 0; /* success */
24096+
4f0767ce 24097+out_br:
1facf9fc 24098+ kfree(sbinfo->si_branch);
4f0767ce 24099+out_pidmap:
b752ccd1 24100+ kfree(sbinfo->au_si_pid.bitmap);
4f0767ce 24101+out_sbinfo:
1facf9fc 24102+ kfree(sbinfo);
4f0767ce 24103+out:
1facf9fc 24104+ return err;
24105+}
24106+
24107+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr)
24108+{
24109+ int err, sz;
24110+ struct au_branch **brp;
24111+
dece6358
AM
24112+ AuRwMustWriteLock(&sbinfo->si_rwsem);
24113+
1facf9fc 24114+ err = -ENOMEM;
24115+ sz = sizeof(*brp) * (sbinfo->si_bend + 1);
24116+ if (unlikely(!sz))
24117+ sz = sizeof(*brp);
24118+ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS);
24119+ if (brp) {
24120+ sbinfo->si_branch = brp;
24121+ err = 0;
24122+ }
24123+
24124+ return err;
24125+}
24126+
24127+/* ---------------------------------------------------------------------- */
24128+
24129+unsigned int au_sigen_inc(struct super_block *sb)
24130+{
24131+ unsigned int gen;
24132+
dece6358
AM
24133+ SiMustWriteLock(sb);
24134+
1facf9fc 24135+ gen = ++au_sbi(sb)->si_generation;
24136+ au_update_digen(sb->s_root);
537831f9 24137+ au_update_iigen(sb->s_root->d_inode, /*half*/0);
1facf9fc 24138+ sb->s_root->d_inode->i_version++;
24139+ return gen;
24140+}
24141+
24142+aufs_bindex_t au_new_br_id(struct super_block *sb)
24143+{
24144+ aufs_bindex_t br_id;
24145+ int i;
24146+ struct au_sbinfo *sbinfo;
24147+
dece6358
AM
24148+ SiMustWriteLock(sb);
24149+
1facf9fc 24150+ sbinfo = au_sbi(sb);
24151+ for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
24152+ br_id = ++sbinfo->si_last_br_id;
7f207e10 24153+ AuDebugOn(br_id < 0);
1facf9fc 24154+ if (br_id && au_br_index(sb, br_id) < 0)
24155+ return br_id;
24156+ }
24157+
24158+ return -1;
24159+}
24160+
24161+/* ---------------------------------------------------------------------- */
24162+
e49829fe
JR
24163+/* it is ok that new 'nwt' tasks are appended while we are sleeping */
24164+int si_read_lock(struct super_block *sb, int flags)
24165+{
24166+ int err;
24167+
24168+ err = 0;
24169+ if (au_ftest_lock(flags, FLUSH))
24170+ au_nwt_flush(&au_sbi(sb)->si_nowait);
24171+
24172+ si_noflush_read_lock(sb);
24173+ err = au_plink_maint(sb, flags);
24174+ if (unlikely(err))
24175+ si_read_unlock(sb);
24176+
24177+ return err;
24178+}
24179+
24180+int si_write_lock(struct super_block *sb, int flags)
24181+{
24182+ int err;
24183+
24184+ if (au_ftest_lock(flags, FLUSH))
24185+ au_nwt_flush(&au_sbi(sb)->si_nowait);
24186+
24187+ si_noflush_write_lock(sb);
24188+ err = au_plink_maint(sb, flags);
24189+ if (unlikely(err))
24190+ si_write_unlock(sb);
24191+
24192+ return err;
24193+}
24194+
1facf9fc 24195+/* dentry and super_block lock. call at entry point */
e49829fe 24196+int aufs_read_lock(struct dentry *dentry, int flags)
1facf9fc 24197+{
e49829fe 24198+ int err;
027c5e7a 24199+ struct super_block *sb;
e49829fe 24200+
027c5e7a
AM
24201+ sb = dentry->d_sb;
24202+ err = si_read_lock(sb, flags);
24203+ if (unlikely(err))
24204+ goto out;
24205+
24206+ if (au_ftest_lock(flags, DW))
24207+ di_write_lock_child(dentry);
24208+ else
24209+ di_read_lock_child(dentry, flags);
24210+
24211+ if (au_ftest_lock(flags, GEN)) {
24212+ err = au_digen_test(dentry, au_sigen(sb));
24213+ AuDebugOn(!err && au_dbrange_test(dentry));
24214+ if (unlikely(err))
24215+ aufs_read_unlock(dentry, flags);
e49829fe
JR
24216+ }
24217+
027c5e7a 24218+out:
e49829fe 24219+ return err;
1facf9fc 24220+}
24221+
24222+void aufs_read_unlock(struct dentry *dentry, int flags)
24223+{
24224+ if (au_ftest_lock(flags, DW))
24225+ di_write_unlock(dentry);
24226+ else
24227+ di_read_unlock(dentry, flags);
24228+ si_read_unlock(dentry->d_sb);
24229+}
24230+
24231+void aufs_write_lock(struct dentry *dentry)
24232+{
e49829fe 24233+ si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW);
1facf9fc 24234+ di_write_lock_child(dentry);
24235+}
24236+
24237+void aufs_write_unlock(struct dentry *dentry)
24238+{
24239+ di_write_unlock(dentry);
24240+ si_write_unlock(dentry->d_sb);
24241+}
24242+
e49829fe 24243+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
1facf9fc 24244+{
e49829fe 24245+ int err;
027c5e7a
AM
24246+ unsigned int sigen;
24247+ struct super_block *sb;
e49829fe 24248+
027c5e7a
AM
24249+ sb = d1->d_sb;
24250+ err = si_read_lock(sb, flags);
24251+ if (unlikely(err))
24252+ goto out;
24253+
24254+ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR));
24255+
24256+ if (au_ftest_lock(flags, GEN)) {
24257+ sigen = au_sigen(sb);
24258+ err = au_digen_test(d1, sigen);
24259+ AuDebugOn(!err && au_dbrange_test(d1));
24260+ if (!err) {
24261+ err = au_digen_test(d2, sigen);
24262+ AuDebugOn(!err && au_dbrange_test(d2));
24263+ }
24264+ if (unlikely(err))
24265+ aufs_read_and_write_unlock2(d1, d2);
24266+ }
24267+
24268+out:
e49829fe 24269+ return err;
1facf9fc 24270+}
24271+
24272+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
24273+{
24274+ di_write_unlock2(d1, d2);
24275+ si_read_unlock(d1->d_sb);
24276+}
b752ccd1
AM
24277+
24278+/* ---------------------------------------------------------------------- */
24279+
24280+int si_pid_test_slow(struct super_block *sb)
24281+{
24282+ void *p;
24283+
24284+ rcu_read_lock();
24285+ p = radix_tree_lookup(&au_sbi(sb)->au_si_pid.tree, current->pid);
24286+ rcu_read_unlock();
24287+
027c5e7a 24288+ return (long)!!p;
b752ccd1
AM
24289+}
24290+
24291+void si_pid_set_slow(struct super_block *sb)
24292+{
24293+ int err;
24294+ struct au_sbinfo *sbinfo;
24295+
24296+ AuDebugOn(si_pid_test_slow(sb));
24297+
24298+ sbinfo = au_sbi(sb);
24299+ err = radix_tree_preload(GFP_NOFS | __GFP_NOFAIL);
24300+ AuDebugOn(err);
24301+ spin_lock(&sbinfo->au_si_pid.tree_lock);
24302+ err = radix_tree_insert(&sbinfo->au_si_pid.tree, current->pid,
027c5e7a 24303+ /*any valid ptr*/sb);
b752ccd1
AM
24304+ spin_unlock(&sbinfo->au_si_pid.tree_lock);
24305+ AuDebugOn(err);
24306+ radix_tree_preload_end();
24307+}
24308+
24309+void si_pid_clr_slow(struct super_block *sb)
24310+{
24311+ void *p;
24312+ struct au_sbinfo *sbinfo;
24313+
24314+ AuDebugOn(!si_pid_test_slow(sb));
24315+
24316+ sbinfo = au_sbi(sb);
24317+ spin_lock(&sbinfo->au_si_pid.tree_lock);
24318+ p = radix_tree_delete(&sbinfo->au_si_pid.tree, current->pid);
24319+ spin_unlock(&sbinfo->au_si_pid.tree_lock);
b752ccd1 24320+}
7f207e10
AM
24321diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h
24322--- /usr/share/empty/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100
86dc4139
AM
24323+++ linux/fs/aufs/spl.h 2013-07-06 13:20:47.753531903 +0200
24324@@ -0,0 +1,112 @@
1facf9fc 24325+/*
7a9e40b8 24326+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 24327+ *
24328+ * This program, aufs is free software; you can redistribute it and/or modify
24329+ * it under the terms of the GNU General Public License as published by
24330+ * the Free Software Foundation; either version 2 of the License, or
24331+ * (at your option) any later version.
dece6358
AM
24332+ *
24333+ * This program is distributed in the hope that it will be useful,
24334+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24335+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24336+ * GNU General Public License for more details.
24337+ *
24338+ * You should have received a copy of the GNU General Public License
24339+ * along with this program; if not, write to the Free Software
24340+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 24341+ */
24342+
24343+/*
24344+ * simple list protected by a spinlock
24345+ */
24346+
24347+#ifndef __AUFS_SPL_H__
24348+#define __AUFS_SPL_H__
24349+
24350+#ifdef __KERNEL__
24351+
1facf9fc 24352+struct au_splhead {
24353+ spinlock_t spin;
24354+ struct list_head head;
24355+};
24356+
24357+static inline void au_spl_init(struct au_splhead *spl)
24358+{
24359+ spin_lock_init(&spl->spin);
24360+ INIT_LIST_HEAD(&spl->head);
24361+}
24362+
24363+static inline void au_spl_add(struct list_head *list, struct au_splhead *spl)
24364+{
24365+ spin_lock(&spl->spin);
24366+ list_add(list, &spl->head);
24367+ spin_unlock(&spl->spin);
24368+}
24369+
24370+static inline void au_spl_del(struct list_head *list, struct au_splhead *spl)
24371+{
24372+ spin_lock(&spl->spin);
24373+ list_del(list);
24374+ spin_unlock(&spl->spin);
24375+}
24376+
4a4d8108
AM
24377+static inline void au_spl_del_rcu(struct list_head *list,
24378+ struct au_splhead *spl)
24379+{
24380+ spin_lock(&spl->spin);
24381+ list_del_rcu(list);
24382+ spin_unlock(&spl->spin);
24383+}
24384+
86dc4139
AM
24385+/* ---------------------------------------------------------------------- */
24386+
24387+struct au_sphlhead {
24388+ spinlock_t spin;
24389+ struct hlist_head head;
24390+};
24391+
24392+static inline void au_sphl_init(struct au_sphlhead *sphl)
24393+{
24394+ spin_lock_init(&sphl->spin);
24395+ INIT_HLIST_HEAD(&sphl->head);
24396+}
24397+
24398+static inline void au_sphl_add(struct hlist_node *hlist,
24399+ struct au_sphlhead *sphl)
24400+{
24401+ spin_lock(&sphl->spin);
24402+ hlist_add_head(hlist, &sphl->head);
24403+ spin_unlock(&sphl->spin);
24404+}
24405+
24406+static inline void au_sphl_del(struct hlist_node *hlist,
24407+ struct au_sphlhead *sphl)
24408+{
24409+ spin_lock(&sphl->spin);
24410+ hlist_del(hlist);
24411+ spin_unlock(&sphl->spin);
24412+}
24413+
24414+static inline void au_sphl_del_rcu(struct hlist_node *hlist,
24415+ struct au_sphlhead *sphl)
24416+{
24417+ spin_lock(&sphl->spin);
24418+ hlist_del_rcu(hlist);
24419+ spin_unlock(&sphl->spin);
24420+}
24421+
24422+static inline unsigned long au_sphl_count(struct au_sphlhead *sphl)
24423+{
24424+ unsigned long cnt;
24425+ struct hlist_node *pos;
24426+
24427+ cnt = 0;
24428+ spin_lock(&sphl->spin);
24429+ hlist_for_each(pos, &sphl->head)
24430+ cnt++;
24431+ spin_unlock(&sphl->spin);
24432+ return cnt;
24433+}
24434+
1facf9fc 24435+#endif /* __KERNEL__ */
24436+#endif /* __AUFS_SPL_H__ */
7f207e10
AM
24437diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
24438--- /usr/share/empty/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
24439+++ linux/fs/aufs/super.c 2013-10-26 16:51:32.276373845 +0200
24440@@ -0,0 +1,1002 @@
1facf9fc 24441+/*
7a9e40b8 24442+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 24443+ *
24444+ * This program, aufs is free software; you can redistribute it and/or modify
24445+ * it under the terms of the GNU General Public License as published by
24446+ * the Free Software Foundation; either version 2 of the License, or
24447+ * (at your option) any later version.
dece6358
AM
24448+ *
24449+ * This program is distributed in the hope that it will be useful,
24450+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24451+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24452+ * GNU General Public License for more details.
24453+ *
24454+ * You should have received a copy of the GNU General Public License
24455+ * along with this program; if not, write to the Free Software
24456+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 24457+ */
24458+
24459+/*
24460+ * mount and super_block operations
24461+ */
24462+
f6c5ef8b 24463+#include <linux/mm.h>
dece6358 24464+#include <linux/module.h>
1facf9fc 24465+#include <linux/seq_file.h>
24466+#include <linux/statfs.h>
7f207e10
AM
24467+#include <linux/vmalloc.h>
24468+#include <linux/writeback.h>
1facf9fc 24469+#include "aufs.h"
24470+
24471+/*
24472+ * super_operations
24473+ */
24474+static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
24475+{
24476+ struct au_icntnr *c;
24477+
24478+ c = au_cache_alloc_icntnr();
24479+ if (c) {
027c5e7a 24480+ au_icntnr_init(c);
1facf9fc 24481+ c->vfs_inode.i_version = 1; /* sigen(sb); */
24482+ c->iinfo.ii_hinode = NULL;
24483+ return &c->vfs_inode;
24484+ }
24485+ return NULL;
24486+}
24487+
027c5e7a
AM
24488+static void aufs_destroy_inode_cb(struct rcu_head *head)
24489+{
24490+ struct inode *inode = container_of(head, struct inode, i_rcu);
24491+
b4510431 24492+ INIT_HLIST_HEAD(&inode->i_dentry);
027c5e7a
AM
24493+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
24494+}
24495+
1facf9fc 24496+static void aufs_destroy_inode(struct inode *inode)
24497+{
24498+ au_iinfo_fin(inode);
027c5e7a 24499+ call_rcu(&inode->i_rcu, aufs_destroy_inode_cb);
1facf9fc 24500+}
24501+
24502+struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
24503+{
24504+ struct inode *inode;
24505+ int err;
24506+
24507+ inode = iget_locked(sb, ino);
24508+ if (unlikely(!inode)) {
24509+ inode = ERR_PTR(-ENOMEM);
24510+ goto out;
24511+ }
24512+ if (!(inode->i_state & I_NEW))
24513+ goto out;
24514+
24515+ err = au_xigen_new(inode);
24516+ if (!err)
24517+ err = au_iinfo_init(inode);
24518+ if (!err)
24519+ inode->i_version++;
24520+ else {
24521+ iget_failed(inode);
24522+ inode = ERR_PTR(err);
24523+ }
24524+
4f0767ce 24525+out:
1facf9fc 24526+ /* never return NULL */
24527+ AuDebugOn(!inode);
24528+ AuTraceErrPtr(inode);
24529+ return inode;
24530+}
24531+
24532+/* lock free root dinfo */
24533+static int au_show_brs(struct seq_file *seq, struct super_block *sb)
24534+{
24535+ int err;
24536+ aufs_bindex_t bindex, bend;
24537+ struct path path;
4a4d8108 24538+ struct au_hdentry *hdp;
1facf9fc 24539+ struct au_branch *br;
1e00d052 24540+ char *perm;
1facf9fc 24541+
24542+ err = 0;
24543+ bend = au_sbend(sb);
4a4d8108 24544+ hdp = au_di(sb->s_root)->di_hdentry;
1facf9fc 24545+ for (bindex = 0; !err && bindex <= bend; bindex++) {
24546+ br = au_sbr(sb, bindex);
86dc4139 24547+ path.mnt = au_br_mnt(br);
4a4d8108 24548+ path.dentry = hdp[bindex].hd_dentry;
1facf9fc 24549+ err = au_seq_path(seq, &path);
1e00d052
AM
24550+ if (err > 0) {
24551+ perm = au_optstr_br_perm(br->br_perm);
24552+ if (perm) {
24553+ err = seq_printf(seq, "=%s", perm);
24554+ kfree(perm);
24555+ if (err == -1)
24556+ err = -E2BIG;
24557+ } else
24558+ err = -ENOMEM;
24559+ }
1facf9fc 24560+ if (!err && bindex != bend)
24561+ err = seq_putc(seq, ':');
24562+ }
24563+
24564+ return err;
24565+}
24566+
24567+static void au_show_wbr_create(struct seq_file *m, int v,
24568+ struct au_sbinfo *sbinfo)
24569+{
24570+ const char *pat;
24571+
dece6358
AM
24572+ AuRwMustAnyLock(&sbinfo->si_rwsem);
24573+
c2b27bf2 24574+ seq_puts(m, ",create=");
1facf9fc 24575+ pat = au_optstr_wbr_create(v);
24576+ switch (v) {
24577+ case AuWbrCreate_TDP:
24578+ case AuWbrCreate_RR:
24579+ case AuWbrCreate_MFS:
24580+ case AuWbrCreate_PMFS:
c2b27bf2 24581+ seq_puts(m, pat);
1facf9fc 24582+ break;
24583+ case AuWbrCreate_MFSV:
24584+ seq_printf(m, /*pat*/"mfs:%lu",
e49829fe
JR
24585+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
24586+ / MSEC_PER_SEC);
1facf9fc 24587+ break;
24588+ case AuWbrCreate_PMFSV:
24589+ seq_printf(m, /*pat*/"pmfs:%lu",
e49829fe
JR
24590+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
24591+ / MSEC_PER_SEC);
1facf9fc 24592+ break;
24593+ case AuWbrCreate_MFSRR:
24594+ seq_printf(m, /*pat*/"mfsrr:%llu",
24595+ sbinfo->si_wbr_mfs.mfsrr_watermark);
24596+ break;
24597+ case AuWbrCreate_MFSRRV:
24598+ seq_printf(m, /*pat*/"mfsrr:%llu:%lu",
24599+ sbinfo->si_wbr_mfs.mfsrr_watermark,
e49829fe
JR
24600+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
24601+ / MSEC_PER_SEC);
1facf9fc 24602+ break;
392086de
AM
24603+ case AuWbrCreate_PMFSRR:
24604+ seq_printf(m, /*pat*/"pmfsrr:%llu",
24605+ sbinfo->si_wbr_mfs.mfsrr_watermark);
24606+ break;
24607+ case AuWbrCreate_PMFSRRV:
24608+ seq_printf(m, /*pat*/"pmfsrr:%llu:%lu",
24609+ sbinfo->si_wbr_mfs.mfsrr_watermark,
24610+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
24611+ / MSEC_PER_SEC);
24612+ break;
1facf9fc 24613+ }
24614+}
24615+
7eafdf33 24616+static int au_show_xino(struct seq_file *seq, struct super_block *sb)
1facf9fc 24617+{
24618+#ifdef CONFIG_SYSFS
24619+ return 0;
24620+#else
24621+ int err;
24622+ const int len = sizeof(AUFS_XINO_FNAME) - 1;
24623+ aufs_bindex_t bindex, brid;
1facf9fc 24624+ struct qstr *name;
24625+ struct file *f;
24626+ struct dentry *d, *h_root;
4a4d8108 24627+ struct au_hdentry *hdp;
1facf9fc 24628+
dece6358
AM
24629+ AuRwMustAnyLock(&sbinfo->si_rwsem);
24630+
1facf9fc 24631+ err = 0;
1facf9fc 24632+ f = au_sbi(sb)->si_xib;
24633+ if (!f)
24634+ goto out;
24635+
24636+ /* stop printing the default xino path on the first writable branch */
24637+ h_root = NULL;
24638+ brid = au_xino_brid(sb);
24639+ if (brid >= 0) {
24640+ bindex = au_br_index(sb, brid);
4a4d8108
AM
24641+ hdp = au_di(sb->s_root)->di_hdentry;
24642+ h_root = hdp[0 + bindex].hd_dentry;
1facf9fc 24643+ }
24644+ d = f->f_dentry;
24645+ name = &d->d_name;
24646+ /* safe ->d_parent because the file is unlinked */
24647+ if (d->d_parent == h_root
24648+ && name->len == len
24649+ && !memcmp(name->name, AUFS_XINO_FNAME, len))
24650+ goto out;
24651+
24652+ seq_puts(seq, ",xino=");
24653+ err = au_xino_path(seq, f);
24654+
4f0767ce 24655+out:
1facf9fc 24656+ return err;
24657+#endif
24658+}
24659+
24660+/* seq_file will re-call me in case of too long string */
7eafdf33 24661+static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
1facf9fc 24662+{
027c5e7a 24663+ int err;
1facf9fc 24664+ unsigned int mnt_flags, v;
24665+ struct super_block *sb;
24666+ struct au_sbinfo *sbinfo;
24667+
24668+#define AuBool(name, str) do { \
24669+ v = au_opt_test(mnt_flags, name); \
24670+ if (v != au_opt_test(AuOpt_Def, name)) \
24671+ seq_printf(m, ",%s" #str, v ? "" : "no"); \
24672+} while (0)
24673+
24674+#define AuStr(name, str) do { \
24675+ v = mnt_flags & AuOptMask_##name; \
24676+ if (v != (AuOpt_Def & AuOptMask_##name)) \
24677+ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
24678+} while (0)
24679+
24680+#define AuUInt(name, str, val) do { \
24681+ if (val != AUFS_##name##_DEF) \
24682+ seq_printf(m, "," #str "=%u", val); \
24683+} while (0)
24684+
24685+ /* lock free root dinfo */
7eafdf33 24686+ sb = dentry->d_sb;
1facf9fc 24687+ si_noflush_read_lock(sb);
24688+ sbinfo = au_sbi(sb);
24689+ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
24690+
24691+ mnt_flags = au_mntflags(sb);
24692+ if (au_opt_test(mnt_flags, XINO)) {
7eafdf33 24693+ err = au_show_xino(m, sb);
1facf9fc 24694+ if (unlikely(err))
24695+ goto out;
24696+ } else
24697+ seq_puts(m, ",noxino");
24698+
24699+ AuBool(TRUNC_XINO, trunc_xino);
24700+ AuStr(UDBA, udba);
dece6358 24701+ AuBool(SHWH, shwh);
1facf9fc 24702+ AuBool(PLINK, plink);
4a4d8108 24703+ AuBool(DIO, dio);
1facf9fc 24704+ /* AuBool(DIRPERM1, dirperm1); */
24705+ /* AuBool(REFROF, refrof); */
24706+
24707+ v = sbinfo->si_wbr_create;
24708+ if (v != AuWbrCreate_Def)
24709+ au_show_wbr_create(m, v, sbinfo);
24710+
24711+ v = sbinfo->si_wbr_copyup;
24712+ if (v != AuWbrCopyup_Def)
24713+ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
24714+
24715+ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
24716+ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
24717+ seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
24718+
24719+ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
24720+
027c5e7a
AM
24721+ v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC;
24722+ AuUInt(RDCACHE, rdcache, v);
1facf9fc 24723+
24724+ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
24725+ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
24726+
24727+ AuBool(SUM, sum);
24728+ /* AuBool(SUM_W, wsum); */
24729+ AuBool(WARN_PERM, warn_perm);
24730+ AuBool(VERBOSE, verbose);
24731+
4f0767ce 24732+out:
1facf9fc 24733+ /* be sure to print "br:" last */
24734+ if (!sysaufs_brs) {
24735+ seq_puts(m, ",br:");
24736+ au_show_brs(m, sb);
24737+ }
24738+ si_read_unlock(sb);
24739+ return 0;
24740+
1facf9fc 24741+#undef AuBool
24742+#undef AuStr
4a4d8108 24743+#undef AuUInt
1facf9fc 24744+}
24745+
24746+/* ---------------------------------------------------------------------- */
24747+
24748+/* sum mode which returns the summation for statfs(2) */
24749+
24750+static u64 au_add_till_max(u64 a, u64 b)
24751+{
24752+ u64 old;
24753+
24754+ old = a;
24755+ a += b;
92d182d2
AM
24756+ if (old <= a)
24757+ return a;
24758+ return ULLONG_MAX;
24759+}
24760+
24761+static u64 au_mul_till_max(u64 a, long mul)
24762+{
24763+ u64 old;
24764+
24765+ old = a;
24766+ a *= mul;
24767+ if (old <= a)
1facf9fc 24768+ return a;
24769+ return ULLONG_MAX;
24770+}
24771+
24772+static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
24773+{
24774+ int err;
92d182d2 24775+ long bsize, factor;
1facf9fc 24776+ u64 blocks, bfree, bavail, files, ffree;
24777+ aufs_bindex_t bend, bindex, i;
24778+ unsigned char shared;
7f207e10 24779+ struct path h_path;
1facf9fc 24780+ struct super_block *h_sb;
24781+
92d182d2
AM
24782+ err = 0;
24783+ bsize = LONG_MAX;
24784+ files = 0;
24785+ ffree = 0;
1facf9fc 24786+ blocks = 0;
24787+ bfree = 0;
24788+ bavail = 0;
1facf9fc 24789+ bend = au_sbend(sb);
92d182d2 24790+ for (bindex = 0; bindex <= bend; bindex++) {
7f207e10
AM
24791+ h_path.mnt = au_sbr_mnt(sb, bindex);
24792+ h_sb = h_path.mnt->mnt_sb;
1facf9fc 24793+ shared = 0;
92d182d2 24794+ for (i = 0; !shared && i < bindex; i++)
1facf9fc 24795+ shared = (au_sbr_sb(sb, i) == h_sb);
24796+ if (shared)
24797+ continue;
24798+
24799+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
24800+ h_path.dentry = h_path.mnt->mnt_root;
24801+ err = vfs_statfs(&h_path, buf);
1facf9fc 24802+ if (unlikely(err))
24803+ goto out;
24804+
92d182d2
AM
24805+ if (bsize > buf->f_bsize) {
24806+ /*
24807+ * we will reduce bsize, so we have to expand blocks
24808+ * etc. to match them again
24809+ */
24810+ factor = (bsize / buf->f_bsize);
24811+ blocks = au_mul_till_max(blocks, factor);
24812+ bfree = au_mul_till_max(bfree, factor);
24813+ bavail = au_mul_till_max(bavail, factor);
24814+ bsize = buf->f_bsize;
24815+ }
24816+
24817+ factor = (buf->f_bsize / bsize);
24818+ blocks = au_add_till_max(blocks,
24819+ au_mul_till_max(buf->f_blocks, factor));
24820+ bfree = au_add_till_max(bfree,
24821+ au_mul_till_max(buf->f_bfree, factor));
24822+ bavail = au_add_till_max(bavail,
24823+ au_mul_till_max(buf->f_bavail, factor));
1facf9fc 24824+ files = au_add_till_max(files, buf->f_files);
24825+ ffree = au_add_till_max(ffree, buf->f_ffree);
24826+ }
24827+
92d182d2 24828+ buf->f_bsize = bsize;
1facf9fc 24829+ buf->f_blocks = blocks;
24830+ buf->f_bfree = bfree;
24831+ buf->f_bavail = bavail;
24832+ buf->f_files = files;
24833+ buf->f_ffree = ffree;
92d182d2 24834+ buf->f_frsize = 0;
1facf9fc 24835+
4f0767ce 24836+out:
1facf9fc 24837+ return err;
24838+}
24839+
24840+static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
24841+{
24842+ int err;
7f207e10 24843+ struct path h_path;
1facf9fc 24844+ struct super_block *sb;
24845+
24846+ /* lock free root dinfo */
24847+ sb = dentry->d_sb;
24848+ si_noflush_read_lock(sb);
7f207e10 24849+ if (!au_opt_test(au_mntflags(sb), SUM)) {
1facf9fc 24850+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
24851+ h_path.mnt = au_sbr_mnt(sb, 0);
24852+ h_path.dentry = h_path.mnt->mnt_root;
24853+ err = vfs_statfs(&h_path, buf);
24854+ } else
1facf9fc 24855+ err = au_statfs_sum(sb, buf);
24856+ si_read_unlock(sb);
24857+
24858+ if (!err) {
24859+ buf->f_type = AUFS_SUPER_MAGIC;
4a4d8108 24860+ buf->f_namelen = AUFS_MAX_NAMELEN;
1facf9fc 24861+ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
24862+ }
24863+ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
24864+
24865+ return err;
24866+}
24867+
24868+/* ---------------------------------------------------------------------- */
24869+
537831f9
AM
24870+static int aufs_sync_fs(struct super_block *sb, int wait)
24871+{
24872+ int err, e;
24873+ aufs_bindex_t bend, bindex;
24874+ struct au_branch *br;
24875+ struct super_block *h_sb;
24876+
24877+ err = 0;
24878+ si_noflush_read_lock(sb);
24879+ bend = au_sbend(sb);
24880+ for (bindex = 0; bindex <= bend; bindex++) {
24881+ br = au_sbr(sb, bindex);
24882+ if (!au_br_writable(br->br_perm))
24883+ continue;
24884+
24885+ h_sb = au_sbr_sb(sb, bindex);
24886+ if (h_sb->s_op->sync_fs) {
24887+ e = h_sb->s_op->sync_fs(h_sb, wait);
24888+ if (unlikely(e && !err))
24889+ err = e;
24890+ /* go on even if an error happens */
24891+ }
24892+ }
24893+ si_read_unlock(sb);
24894+
24895+ return err;
24896+}
24897+
24898+/* ---------------------------------------------------------------------- */
24899+
1facf9fc 24900+/* final actions when unmounting a file system */
24901+static void aufs_put_super(struct super_block *sb)
24902+{
24903+ struct au_sbinfo *sbinfo;
24904+
24905+ sbinfo = au_sbi(sb);
24906+ if (!sbinfo)
24907+ return;
24908+
1facf9fc 24909+ dbgaufs_si_fin(sbinfo);
24910+ kobject_put(&sbinfo->si_kobj);
24911+}
24912+
24913+/* ---------------------------------------------------------------------- */
24914+
7f207e10
AM
24915+void au_array_free(void *array)
24916+{
24917+ if (array) {
24918+ if (!is_vmalloc_addr(array))
24919+ kfree(array);
24920+ else
24921+ vfree(array);
24922+ }
24923+}
24924+
24925+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg)
24926+{
24927+ void *array;
24928+ unsigned long long n;
24929+
24930+ array = NULL;
24931+ n = 0;
24932+ if (!*hint)
24933+ goto out;
24934+
24935+ if (*hint > ULLONG_MAX / sizeof(array)) {
24936+ array = ERR_PTR(-EMFILE);
24937+ pr_err("hint %llu\n", *hint);
24938+ goto out;
24939+ }
24940+
24941+ array = kmalloc(sizeof(array) * *hint, GFP_NOFS);
24942+ if (unlikely(!array))
24943+ array = vmalloc(sizeof(array) * *hint);
24944+ if (unlikely(!array)) {
24945+ array = ERR_PTR(-ENOMEM);
24946+ goto out;
24947+ }
24948+
24949+ n = cb(array, *hint, arg);
24950+ AuDebugOn(n > *hint);
24951+
24952+out:
24953+ *hint = n;
24954+ return array;
24955+}
24956+
24957+static unsigned long long au_iarray_cb(void *a,
24958+ unsigned long long max __maybe_unused,
24959+ void *arg)
24960+{
24961+ unsigned long long n;
24962+ struct inode **p, *inode;
24963+ struct list_head *head;
24964+
24965+ n = 0;
24966+ p = a;
24967+ head = arg;
2cbb1c4b 24968+ spin_lock(&inode_sb_list_lock);
7f207e10
AM
24969+ list_for_each_entry(inode, head, i_sb_list) {
24970+ if (!is_bad_inode(inode)
24971+ && au_ii(inode)->ii_bstart >= 0) {
2cbb1c4b
JR
24972+ spin_lock(&inode->i_lock);
24973+ if (atomic_read(&inode->i_count)) {
24974+ au_igrab(inode);
24975+ *p++ = inode;
24976+ n++;
24977+ AuDebugOn(n > max);
24978+ }
24979+ spin_unlock(&inode->i_lock);
7f207e10
AM
24980+ }
24981+ }
2cbb1c4b 24982+ spin_unlock(&inode_sb_list_lock);
7f207e10
AM
24983+
24984+ return n;
24985+}
24986+
24987+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max)
24988+{
24989+ *max = atomic_long_read(&au_sbi(sb)->si_ninodes);
24990+ return au_array_alloc(max, au_iarray_cb, &sb->s_inodes);
24991+}
24992+
24993+void au_iarray_free(struct inode **a, unsigned long long max)
24994+{
24995+ unsigned long long ull;
24996+
24997+ for (ull = 0; ull < max; ull++)
24998+ iput(a[ull]);
24999+ au_array_free(a);
25000+}
25001+
25002+/* ---------------------------------------------------------------------- */
25003+
1facf9fc 25004+/*
25005+ * refresh dentry and inode at remount time.
25006+ */
027c5e7a
AM
25007+/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */
25008+static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags,
25009+ struct dentry *parent)
1facf9fc 25010+{
25011+ int err;
1facf9fc 25012+
25013+ di_write_lock_child(dentry);
1facf9fc 25014+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
25015+ err = au_refresh_dentry(dentry, parent);
25016+ if (!err && dir_flags)
25017+ au_hn_reset(dentry->d_inode, dir_flags);
1facf9fc 25018+ di_read_unlock(parent, AuLock_IR);
1facf9fc 25019+ di_write_unlock(dentry);
25020+
25021+ return err;
25022+}
25023+
027c5e7a
AM
25024+static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
25025+ struct au_sbinfo *sbinfo,
25026+ const unsigned int dir_flags)
1facf9fc 25027+{
027c5e7a
AM
25028+ int err;
25029+ struct dentry *parent;
25030+ struct inode *inode;
25031+
25032+ err = 0;
25033+ parent = dget_parent(dentry);
25034+ if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
25035+ inode = dentry->d_inode;
25036+ if (inode) {
25037+ if (!S_ISDIR(inode->i_mode))
25038+ err = au_do_refresh(dentry, /*dir_flags*/0,
25039+ parent);
25040+ else {
25041+ err = au_do_refresh(dentry, dir_flags, parent);
25042+ if (unlikely(err))
25043+ au_fset_si(sbinfo, FAILED_REFRESH_DIR);
25044+ }
25045+ } else
25046+ err = au_do_refresh(dentry, /*dir_flags*/0, parent);
25047+ AuDbgDentry(dentry);
25048+ }
25049+ dput(parent);
25050+
25051+ AuTraceErr(err);
25052+ return err;
1facf9fc 25053+}
25054+
027c5e7a 25055+static int au_refresh_d(struct super_block *sb)
1facf9fc 25056+{
25057+ int err, i, j, ndentry, e;
027c5e7a 25058+ unsigned int sigen;
1facf9fc 25059+ struct au_dcsub_pages dpages;
25060+ struct au_dpage *dpage;
027c5e7a
AM
25061+ struct dentry **dentries, *d;
25062+ struct au_sbinfo *sbinfo;
25063+ struct dentry *root = sb->s_root;
25064+ const unsigned int dir_flags = au_hi_flags(root->d_inode, /*isdir*/1);
1facf9fc 25065+
027c5e7a
AM
25066+ err = au_dpages_init(&dpages, GFP_NOFS);
25067+ if (unlikely(err))
1facf9fc 25068+ goto out;
027c5e7a
AM
25069+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
25070+ if (unlikely(err))
1facf9fc 25071+ goto out_dpages;
1facf9fc 25072+
027c5e7a
AM
25073+ sigen = au_sigen(sb);
25074+ sbinfo = au_sbi(sb);
25075+ for (i = 0; i < dpages.ndpage; i++) {
1facf9fc 25076+ dpage = dpages.dpages + i;
25077+ dentries = dpage->dentries;
25078+ ndentry = dpage->ndentry;
027c5e7a 25079+ for (j = 0; j < ndentry; j++) {
1facf9fc 25080+ d = dentries[j];
027c5e7a
AM
25081+ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags);
25082+ if (unlikely(e && !err))
25083+ err = e;
25084+ /* go on even err */
1facf9fc 25085+ }
25086+ }
25087+
4f0767ce 25088+out_dpages:
1facf9fc 25089+ au_dpages_free(&dpages);
4f0767ce 25090+out:
1facf9fc 25091+ return err;
25092+}
25093+
027c5e7a 25094+static int au_refresh_i(struct super_block *sb)
1facf9fc 25095+{
027c5e7a
AM
25096+ int err, e;
25097+ unsigned int sigen;
25098+ unsigned long long max, ull;
25099+ struct inode *inode, **array;
1facf9fc 25100+
027c5e7a
AM
25101+ array = au_iarray_alloc(sb, &max);
25102+ err = PTR_ERR(array);
25103+ if (IS_ERR(array))
25104+ goto out;
1facf9fc 25105+
25106+ err = 0;
027c5e7a
AM
25107+ sigen = au_sigen(sb);
25108+ for (ull = 0; ull < max; ull++) {
25109+ inode = array[ull];
537831f9 25110+ if (au_iigen(inode, NULL) != sigen) {
1facf9fc 25111+ ii_write_lock_child(inode);
027c5e7a 25112+ e = au_refresh_hinode_self(inode);
1facf9fc 25113+ ii_write_unlock(inode);
25114+ if (unlikely(e)) {
027c5e7a 25115+ pr_err("error %d, i%lu\n", e, inode->i_ino);
1facf9fc 25116+ if (!err)
25117+ err = e;
25118+ /* go on even if err */
25119+ }
25120+ }
1facf9fc 25121+ }
25122+
027c5e7a 25123+ au_iarray_free(array, max);
1facf9fc 25124+
4f0767ce 25125+out:
1facf9fc 25126+ return err;
25127+}
25128+
027c5e7a 25129+static void au_remount_refresh(struct super_block *sb)
1facf9fc 25130+{
027c5e7a
AM
25131+ int err, e;
25132+ unsigned int udba;
25133+ aufs_bindex_t bindex, bend;
1facf9fc 25134+ struct dentry *root;
25135+ struct inode *inode;
027c5e7a 25136+ struct au_branch *br;
1facf9fc 25137+
25138+ au_sigen_inc(sb);
027c5e7a 25139+ au_fclr_si(au_sbi(sb), FAILED_REFRESH_DIR);
1facf9fc 25140+
25141+ root = sb->s_root;
25142+ DiMustNoWaiters(root);
25143+ inode = root->d_inode;
25144+ IiMustNoWaiters(inode);
1facf9fc 25145+
027c5e7a
AM
25146+ udba = au_opt_udba(sb);
25147+ bend = au_sbend(sb);
25148+ for (bindex = 0; bindex <= bend; bindex++) {
25149+ br = au_sbr(sb, bindex);
25150+ err = au_hnotify_reset_br(udba, br, br->br_perm);
1facf9fc 25151+ if (unlikely(err))
027c5e7a
AM
25152+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
25153+ bindex, err);
25154+ /* go on even if err */
1facf9fc 25155+ }
027c5e7a 25156+ au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
1facf9fc 25157+
027c5e7a
AM
25158+ di_write_unlock(root);
25159+ err = au_refresh_d(sb);
25160+ e = au_refresh_i(sb);
25161+ if (unlikely(e && !err))
25162+ err = e;
1facf9fc 25163+ /* aufs_write_lock() calls ..._child() */
25164+ di_write_lock_child(root);
027c5e7a
AM
25165+
25166+ au_cpup_attr_all(inode, /*force*/1);
25167+
25168+ if (unlikely(err))
25169+ AuIOErr("refresh failed, ignored, %d\n", err);
1facf9fc 25170+}
25171+
25172+/* stop extra interpretation of errno in mount(8), and strange error messages */
25173+static int cvt_err(int err)
25174+{
25175+ AuTraceErr(err);
25176+
25177+ switch (err) {
25178+ case -ENOENT:
25179+ case -ENOTDIR:
25180+ case -EEXIST:
25181+ case -EIO:
25182+ err = -EINVAL;
25183+ }
25184+ return err;
25185+}
25186+
25187+static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
25188+{
4a4d8108
AM
25189+ int err, do_dx;
25190+ unsigned int mntflags;
1facf9fc 25191+ struct au_opts opts;
25192+ struct dentry *root;
25193+ struct inode *inode;
25194+ struct au_sbinfo *sbinfo;
25195+
25196+ err = 0;
25197+ root = sb->s_root;
25198+ if (!data || !*data) {
e49829fe
JR
25199+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
25200+ if (!err) {
25201+ di_write_lock_child(root);
25202+ err = au_opts_verify(sb, *flags, /*pending*/0);
25203+ aufs_write_unlock(root);
25204+ }
1facf9fc 25205+ goto out;
25206+ }
25207+
25208+ err = -ENOMEM;
25209+ memset(&opts, 0, sizeof(opts));
25210+ opts.opt = (void *)__get_free_page(GFP_NOFS);
25211+ if (unlikely(!opts.opt))
25212+ goto out;
25213+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
25214+ opts.flags = AuOpts_REMOUNT;
25215+ opts.sb_flags = *flags;
25216+
25217+ /* parse it before aufs lock */
25218+ err = au_opts_parse(sb, data, &opts);
25219+ if (unlikely(err))
25220+ goto out_opts;
25221+
25222+ sbinfo = au_sbi(sb);
25223+ inode = root->d_inode;
25224+ mutex_lock(&inode->i_mutex);
e49829fe
JR
25225+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
25226+ if (unlikely(err))
25227+ goto out_mtx;
25228+ di_write_lock_child(root);
1facf9fc 25229+
25230+ /* au_opts_remount() may return an error */
25231+ err = au_opts_remount(sb, &opts);
25232+ au_opts_free(&opts);
25233+
027c5e7a
AM
25234+ if (au_ftest_opts(opts.flags, REFRESH))
25235+ au_remount_refresh(sb);
1facf9fc 25236+
4a4d8108
AM
25237+ if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
25238+ mntflags = au_mntflags(sb);
25239+ do_dx = !!au_opt_test(mntflags, DIO);
25240+ au_dy_arefresh(do_dx);
25241+ }
25242+
1facf9fc 25243+ aufs_write_unlock(root);
953406b4 25244+
e49829fe
JR
25245+out_mtx:
25246+ mutex_unlock(&inode->i_mutex);
4f0767ce 25247+out_opts:
1facf9fc 25248+ free_page((unsigned long)opts.opt);
4f0767ce 25249+out:
1facf9fc 25250+ err = cvt_err(err);
25251+ AuTraceErr(err);
25252+ return err;
25253+}
25254+
4a4d8108 25255+static const struct super_operations aufs_sop = {
1facf9fc 25256+ .alloc_inode = aufs_alloc_inode,
25257+ .destroy_inode = aufs_destroy_inode,
b752ccd1 25258+ /* always deleting, no clearing */
1facf9fc 25259+ .drop_inode = generic_delete_inode,
25260+ .show_options = aufs_show_options,
25261+ .statfs = aufs_statfs,
25262+ .put_super = aufs_put_super,
537831f9 25263+ .sync_fs = aufs_sync_fs,
1facf9fc 25264+ .remount_fs = aufs_remount_fs
25265+};
25266+
25267+/* ---------------------------------------------------------------------- */
25268+
25269+static int alloc_root(struct super_block *sb)
25270+{
25271+ int err;
25272+ struct inode *inode;
25273+ struct dentry *root;
25274+
25275+ err = -ENOMEM;
25276+ inode = au_iget_locked(sb, AUFS_ROOT_INO);
25277+ err = PTR_ERR(inode);
25278+ if (IS_ERR(inode))
25279+ goto out;
25280+
25281+ inode->i_op = &aufs_dir_iop;
25282+ inode->i_fop = &aufs_dir_fop;
25283+ inode->i_mode = S_IFDIR;
9dbd164d 25284+ set_nlink(inode, 2);
1facf9fc 25285+ unlock_new_inode(inode);
25286+
92d182d2 25287+ root = d_make_root(inode);
1facf9fc 25288+ if (unlikely(!root))
92d182d2 25289+ goto out;
1facf9fc 25290+ err = PTR_ERR(root);
25291+ if (IS_ERR(root))
92d182d2 25292+ goto out;
1facf9fc 25293+
4a4d8108 25294+ err = au_di_init(root);
1facf9fc 25295+ if (!err) {
25296+ sb->s_root = root;
25297+ return 0; /* success */
25298+ }
25299+ dput(root);
1facf9fc 25300+
4f0767ce 25301+out:
1facf9fc 25302+ return err;
1facf9fc 25303+}
25304+
25305+static int aufs_fill_super(struct super_block *sb, void *raw_data,
25306+ int silent __maybe_unused)
25307+{
25308+ int err;
25309+ struct au_opts opts;
25310+ struct dentry *root;
25311+ struct inode *inode;
25312+ char *arg = raw_data;
25313+
25314+ if (unlikely(!arg || !*arg)) {
25315+ err = -EINVAL;
4a4d8108 25316+ pr_err("no arg\n");
1facf9fc 25317+ goto out;
25318+ }
25319+
25320+ err = -ENOMEM;
25321+ memset(&opts, 0, sizeof(opts));
25322+ opts.opt = (void *)__get_free_page(GFP_NOFS);
25323+ if (unlikely(!opts.opt))
25324+ goto out;
25325+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
25326+ opts.sb_flags = sb->s_flags;
25327+
25328+ err = au_si_alloc(sb);
25329+ if (unlikely(err))
25330+ goto out_opts;
25331+
25332+ /* all timestamps always follow the ones on the branch */
25333+ sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
25334+ sb->s_op = &aufs_sop;
027c5e7a 25335+ sb->s_d_op = &aufs_dop;
1facf9fc 25336+ sb->s_magic = AUFS_SUPER_MAGIC;
25337+ sb->s_maxbytes = 0;
25338+ au_export_init(sb);
25339+
25340+ err = alloc_root(sb);
25341+ if (unlikely(err)) {
25342+ si_write_unlock(sb);
25343+ goto out_info;
25344+ }
25345+ root = sb->s_root;
25346+ inode = root->d_inode;
25347+
25348+ /*
25349+ * actually we can parse options regardless aufs lock here.
25350+ * but at remount time, parsing must be done before aufs lock.
25351+ * so we follow the same rule.
25352+ */
25353+ ii_write_lock_parent(inode);
25354+ aufs_write_unlock(root);
25355+ err = au_opts_parse(sb, arg, &opts);
25356+ if (unlikely(err))
25357+ goto out_root;
25358+
25359+ /* lock vfs_inode first, then aufs. */
25360+ mutex_lock(&inode->i_mutex);
1facf9fc 25361+ aufs_write_lock(root);
25362+ err = au_opts_mount(sb, &opts);
25363+ au_opts_free(&opts);
1facf9fc 25364+ aufs_write_unlock(root);
25365+ mutex_unlock(&inode->i_mutex);
4a4d8108
AM
25366+ if (!err)
25367+ goto out_opts; /* success */
1facf9fc 25368+
4f0767ce 25369+out_root:
1facf9fc 25370+ dput(root);
25371+ sb->s_root = NULL;
4f0767ce 25372+out_info:
2cbb1c4b 25373+ dbgaufs_si_fin(au_sbi(sb));
1facf9fc 25374+ kobject_put(&au_sbi(sb)->si_kobj);
25375+ sb->s_fs_info = NULL;
4f0767ce 25376+out_opts:
1facf9fc 25377+ free_page((unsigned long)opts.opt);
4f0767ce 25378+out:
1facf9fc 25379+ AuTraceErr(err);
25380+ err = cvt_err(err);
25381+ AuTraceErr(err);
25382+ return err;
25383+}
25384+
25385+/* ---------------------------------------------------------------------- */
25386+
027c5e7a
AM
25387+static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags,
25388+ const char *dev_name __maybe_unused,
25389+ void *raw_data)
1facf9fc 25390+{
027c5e7a 25391+ struct dentry *root;
1facf9fc 25392+ struct super_block *sb;
25393+
25394+ /* all timestamps always follow the ones on the branch */
25395+ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
027c5e7a
AM
25396+ root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super);
25397+ if (IS_ERR(root))
25398+ goto out;
25399+
25400+ sb = root->d_sb;
25401+ si_write_lock(sb, !AuLock_FLUSH);
25402+ sysaufs_brs_add(sb, 0);
25403+ si_write_unlock(sb);
25404+ au_sbilist_add(sb);
25405+
25406+out:
25407+ return root;
1facf9fc 25408+}
25409+
e49829fe
JR
25410+static void aufs_kill_sb(struct super_block *sb)
25411+{
25412+ struct au_sbinfo *sbinfo;
25413+
25414+ sbinfo = au_sbi(sb);
25415+ if (sbinfo) {
25416+ au_sbilist_del(sb);
25417+ aufs_write_lock(sb->s_root);
25418+ if (sbinfo->si_wbr_create_ops->fin)
25419+ sbinfo->si_wbr_create_ops->fin(sb);
25420+ if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
25421+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
027c5e7a 25422+ au_remount_refresh(sb);
e49829fe
JR
25423+ }
25424+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
25425+ au_plink_put(sb, /*verbose*/1);
25426+ au_xino_clr(sb);
1e00d052 25427+ sbinfo->si_sb = NULL;
e49829fe 25428+ aufs_write_unlock(sb->s_root);
e49829fe
JR
25429+ au_nwt_flush(&sbinfo->si_nowait);
25430+ }
25431+ generic_shutdown_super(sb);
25432+}
25433+
1facf9fc 25434+struct file_system_type aufs_fs_type = {
25435+ .name = AUFS_FSTYPE,
c06a8ce3
AM
25436+ /* a race between rename and others */
25437+ .fs_flags = FS_RENAME_DOES_D_MOVE,
027c5e7a 25438+ .mount = aufs_mount,
e49829fe 25439+ .kill_sb = aufs_kill_sb,
1facf9fc 25440+ /* no need to __module_get() and module_put(). */
25441+ .owner = THIS_MODULE,
25442+};
7f207e10
AM
25443diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
25444--- /usr/share/empty/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100
392086de
AM
25445+++ linux/fs/aufs/super.h 2013-10-26 16:51:32.276373845 +0200
25446@@ -0,0 +1,568 @@
1facf9fc 25447+/*
7a9e40b8 25448+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 25449+ *
25450+ * This program, aufs is free software; you can redistribute it and/or modify
25451+ * it under the terms of the GNU General Public License as published by
25452+ * the Free Software Foundation; either version 2 of the License, or
25453+ * (at your option) any later version.
dece6358
AM
25454+ *
25455+ * This program is distributed in the hope that it will be useful,
25456+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25457+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25458+ * GNU General Public License for more details.
25459+ *
25460+ * You should have received a copy of the GNU General Public License
25461+ * along with this program; if not, write to the Free Software
25462+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 25463+ */
25464+
25465+/*
25466+ * super_block operations
25467+ */
25468+
25469+#ifndef __AUFS_SUPER_H__
25470+#define __AUFS_SUPER_H__
25471+
25472+#ifdef __KERNEL__
25473+
25474+#include <linux/fs.h>
1facf9fc 25475+#include "rwsem.h"
25476+#include "spl.h"
25477+#include "wkq.h"
25478+
25479+typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *);
25480+typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t,
25481+ loff_t *);
25482+
25483+/* policies to select one among multiple writable branches */
25484+struct au_wbr_copyup_operations {
25485+ int (*copyup)(struct dentry *dentry);
25486+};
25487+
392086de
AM
25488+#define AuWbr_DIR 1 /* target is a dir */
25489+#define AuWbr_PARENT (1 << 1) /* always require a parent */
25490+
25491+#define au_ftest_wbr(flags, name) ((flags) & AuWbr_##name)
25492+#define au_fset_wbr(flags, name) { (flags) |= AuWbr_##name; }
25493+#define au_fclr_wbr(flags, name) { (flags) &= ~AuWbr_##name; }
25494+
1facf9fc 25495+struct au_wbr_create_operations {
392086de 25496+ int (*create)(struct dentry *dentry, unsigned int flags);
1facf9fc 25497+ int (*init)(struct super_block *sb);
25498+ int (*fin)(struct super_block *sb);
25499+};
25500+
25501+struct au_wbr_mfs {
25502+ struct mutex mfs_lock; /* protect this structure */
25503+ unsigned long mfs_jiffy;
25504+ unsigned long mfs_expire;
25505+ aufs_bindex_t mfs_bindex;
25506+
25507+ unsigned long long mfsrr_bytes;
25508+ unsigned long long mfsrr_watermark;
25509+};
25510+
86dc4139
AM
25511+struct pseudo_link {
25512+ union {
25513+ struct hlist_node hlist;
25514+ struct rcu_head rcu;
25515+ };
25516+ struct inode *inode;
25517+};
25518+
25519+#define AuPlink_NHASH 100
25520+static inline int au_plink_hash(ino_t ino)
25521+{
25522+ return ino % AuPlink_NHASH;
25523+}
25524+
1facf9fc 25525+struct au_branch;
25526+struct au_sbinfo {
25527+ /* nowait tasks in the system-wide workqueue */
25528+ struct au_nowait_tasks si_nowait;
25529+
b752ccd1
AM
25530+ /*
25531+ * tried sb->s_umount, but failed due to the dependecy between i_mutex.
25532+ * rwsem for au_sbinfo is necessary.
25533+ */
dece6358 25534+ struct au_rwsem si_rwsem;
1facf9fc 25535+
b752ccd1
AM
25536+ /* prevent recursive locking in deleting inode */
25537+ struct {
25538+ unsigned long *bitmap;
25539+ spinlock_t tree_lock;
25540+ struct radix_tree_root tree;
25541+ } au_si_pid;
25542+
7f207e10
AM
25543+ /*
25544+ * dirty approach to protect sb->sb_inodes and ->s_files from remount.
25545+ */
25546+ atomic_long_t si_ninodes, si_nfiles;
25547+
1facf9fc 25548+ /* branch management */
25549+ unsigned int si_generation;
25550+
25551+ /* see above flags */
25552+ unsigned char au_si_status;
25553+
25554+ aufs_bindex_t si_bend;
7f207e10
AM
25555+
25556+ /* dirty trick to keep br_id plus */
25557+ unsigned int si_last_br_id :
25558+ sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1;
1facf9fc 25559+ struct au_branch **si_branch;
25560+
25561+ /* policy to select a writable branch */
25562+ unsigned char si_wbr_copyup;
25563+ unsigned char si_wbr_create;
25564+ struct au_wbr_copyup_operations *si_wbr_copyup_ops;
25565+ struct au_wbr_create_operations *si_wbr_create_ops;
25566+
25567+ /* round robin */
25568+ atomic_t si_wbr_rr_next;
25569+
25570+ /* most free space */
25571+ struct au_wbr_mfs si_wbr_mfs;
25572+
25573+ /* mount flags */
25574+ /* include/asm-ia64/siginfo.h defines a macro named si_flags */
25575+ unsigned int si_mntflags;
25576+
25577+ /* external inode number (bitmap and translation table) */
25578+ au_readf_t si_xread;
25579+ au_writef_t si_xwrite;
25580+ struct file *si_xib;
25581+ struct mutex si_xib_mtx; /* protect xib members */
25582+ unsigned long *si_xib_buf;
25583+ unsigned long si_xib_last_pindex;
25584+ int si_xib_next_bit;
25585+ aufs_bindex_t si_xino_brid;
392086de
AM
25586+ unsigned long si_xino_jiffy;
25587+ unsigned long si_xino_expire;
1facf9fc 25588+ /* reserved for future use */
25589+ /* unsigned long long si_xib_limit; */ /* Max xib file size */
25590+
25591+#ifdef CONFIG_AUFS_EXPORT
25592+ /* i_generation */
25593+ struct file *si_xigen;
25594+ atomic_t si_xigen_next;
25595+#endif
25596+
25597+ /* vdir parameters */
e49829fe 25598+ unsigned long si_rdcache; /* max cache time in jiffies */
1facf9fc 25599+ unsigned int si_rdblk; /* deblk size */
25600+ unsigned int si_rdhash; /* hash size */
25601+
25602+ /*
25603+ * If the number of whiteouts are larger than si_dirwh, leave all of
25604+ * them after au_whtmp_ren to reduce the cost of rmdir(2).
25605+ * future fsck.aufs or kernel thread will remove them later.
25606+ * Otherwise, remove all whiteouts and the dir in rmdir(2).
25607+ */
25608+ unsigned int si_dirwh;
25609+
25610+ /*
25611+ * rename(2) a directory with all children.
25612+ */
25613+ /* reserved for future use */
25614+ /* int si_rendir; */
25615+
25616+ /* pseudo_link list */
86dc4139 25617+ struct au_sphlhead si_plink[AuPlink_NHASH];
1facf9fc 25618+ wait_queue_head_t si_plink_wq;
4a4d8108 25619+ spinlock_t si_plink_maint_lock;
e49829fe 25620+ pid_t si_plink_maint_pid;
1facf9fc 25621+
25622+ /*
25623+ * sysfs and lifetime management.
25624+ * this is not a small structure and it may be a waste of memory in case
25625+ * of sysfs is disabled, particulary when many aufs-es are mounted.
25626+ * but using sysfs is majority.
25627+ */
25628+ struct kobject si_kobj;
25629+#ifdef CONFIG_DEBUG_FS
86dc4139
AM
25630+ struct dentry *si_dbgaufs;
25631+ struct dentry *si_dbgaufs_plink;
25632+ struct dentry *si_dbgaufs_xib;
1facf9fc 25633+#ifdef CONFIG_AUFS_EXPORT
25634+ struct dentry *si_dbgaufs_xigen;
25635+#endif
25636+#endif
25637+
e49829fe
JR
25638+#ifdef CONFIG_AUFS_SBILIST
25639+ struct list_head si_list;
25640+#endif
25641+
1facf9fc 25642+ /* dirty, necessary for unmounting, sysfs and sysrq */
25643+ struct super_block *si_sb;
25644+};
25645+
dece6358
AM
25646+/* sbinfo status flags */
25647+/*
25648+ * set true when refresh_dirs() failed at remount time.
25649+ * then try refreshing dirs at access time again.
25650+ * if it is false, refreshing dirs at access time is unnecesary
25651+ */
027c5e7a 25652+#define AuSi_FAILED_REFRESH_DIR 1
dece6358
AM
25653+static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
25654+ unsigned int flag)
25655+{
25656+ AuRwMustAnyLock(&sbi->si_rwsem);
25657+ return sbi->au_si_status & flag;
25658+}
25659+#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name)
25660+#define au_fset_si(sbinfo, name) do { \
25661+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
25662+ (sbinfo)->au_si_status |= AuSi_##name; \
25663+} while (0)
25664+#define au_fclr_si(sbinfo, name) do { \
25665+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
25666+ (sbinfo)->au_si_status &= ~AuSi_##name; \
25667+} while (0)
25668+
1facf9fc 25669+/* ---------------------------------------------------------------------- */
25670+
25671+/* policy to select one among writable branches */
4a4d8108
AM
25672+#define AuWbrCopyup(sbinfo, ...) \
25673+ ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__))
25674+#define AuWbrCreate(sbinfo, ...) \
25675+ ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__))
1facf9fc 25676+
25677+/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
25678+#define AuLock_DW 1 /* write-lock dentry */
25679+#define AuLock_IR (1 << 1) /* read-lock inode */
25680+#define AuLock_IW (1 << 2) /* write-lock inode */
25681+#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
25682+#define AuLock_DIR (1 << 4) /* target is a dir */
e49829fe
JR
25683+#define AuLock_NOPLM (1 << 5) /* return err in plm mode */
25684+#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */
027c5e7a 25685+#define AuLock_GEN (1 << 7) /* test digen/iigen */
1facf9fc 25686+#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
7f207e10
AM
25687+#define au_fset_lock(flags, name) \
25688+ do { (flags) |= AuLock_##name; } while (0)
25689+#define au_fclr_lock(flags, name) \
25690+ do { (flags) &= ~AuLock_##name; } while (0)
1facf9fc 25691+
25692+/* ---------------------------------------------------------------------- */
25693+
25694+/* super.c */
25695+extern struct file_system_type aufs_fs_type;
25696+struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
7f207e10
AM
25697+typedef unsigned long long (*au_arraycb_t)(void *array, unsigned long long max,
25698+ void *arg);
25699+void au_array_free(void *array);
25700+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg);
25701+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
25702+void au_iarray_free(struct inode **a, unsigned long long max);
1facf9fc 25703+
25704+/* sbinfo.c */
25705+void au_si_free(struct kobject *kobj);
25706+int au_si_alloc(struct super_block *sb);
25707+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr);
25708+
25709+unsigned int au_sigen_inc(struct super_block *sb);
25710+aufs_bindex_t au_new_br_id(struct super_block *sb);
25711+
e49829fe
JR
25712+int si_read_lock(struct super_block *sb, int flags);
25713+int si_write_lock(struct super_block *sb, int flags);
25714+int aufs_read_lock(struct dentry *dentry, int flags);
1facf9fc 25715+void aufs_read_unlock(struct dentry *dentry, int flags);
25716+void aufs_write_lock(struct dentry *dentry);
25717+void aufs_write_unlock(struct dentry *dentry);
e49829fe 25718+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
1facf9fc 25719+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
25720+
b752ccd1
AM
25721+int si_pid_test_slow(struct super_block *sb);
25722+void si_pid_set_slow(struct super_block *sb);
25723+void si_pid_clr_slow(struct super_block *sb);
25724+
1facf9fc 25725+/* wbr_policy.c */
25726+extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
25727+extern struct au_wbr_create_operations au_wbr_create_ops[];
25728+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
c2b27bf2
AM
25729+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex);
25730+
25731+/* mvdown.c */
25732+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *arg);
1facf9fc 25733+
25734+/* ---------------------------------------------------------------------- */
25735+
25736+static inline struct au_sbinfo *au_sbi(struct super_block *sb)
25737+{
25738+ return sb->s_fs_info;
25739+}
25740+
25741+/* ---------------------------------------------------------------------- */
25742+
25743+#ifdef CONFIG_AUFS_EXPORT
a2a7ad62 25744+int au_test_nfsd(void);
1facf9fc 25745+void au_export_init(struct super_block *sb);
b752ccd1 25746+void au_xigen_inc(struct inode *inode);
1facf9fc 25747+int au_xigen_new(struct inode *inode);
25748+int au_xigen_set(struct super_block *sb, struct file *base);
25749+void au_xigen_clr(struct super_block *sb);
25750+
25751+static inline int au_busy_or_stale(void)
25752+{
b752ccd1 25753+ if (!au_test_nfsd())
1facf9fc 25754+ return -EBUSY;
25755+ return -ESTALE;
25756+}
25757+#else
b752ccd1 25758+AuStubInt0(au_test_nfsd, void)
a2a7ad62 25759+AuStubVoid(au_export_init, struct super_block *sb)
b752ccd1 25760+AuStubVoid(au_xigen_inc, struct inode *inode)
4a4d8108
AM
25761+AuStubInt0(au_xigen_new, struct inode *inode)
25762+AuStubInt0(au_xigen_set, struct super_block *sb, struct file *base)
25763+AuStubVoid(au_xigen_clr, struct super_block *sb)
1facf9fc 25764+static inline int au_busy_or_stale(void)
25765+{
25766+ return -EBUSY;
25767+}
25768+#endif /* CONFIG_AUFS_EXPORT */
25769+
25770+/* ---------------------------------------------------------------------- */
25771+
e49829fe
JR
25772+#ifdef CONFIG_AUFS_SBILIST
25773+/* module.c */
25774+extern struct au_splhead au_sbilist;
25775+
25776+static inline void au_sbilist_init(void)
25777+{
25778+ au_spl_init(&au_sbilist);
25779+}
25780+
25781+static inline void au_sbilist_add(struct super_block *sb)
25782+{
25783+ au_spl_add(&au_sbi(sb)->si_list, &au_sbilist);
25784+}
25785+
25786+static inline void au_sbilist_del(struct super_block *sb)
25787+{
25788+ au_spl_del(&au_sbi(sb)->si_list, &au_sbilist);
25789+}
53392da6
AM
25790+
25791+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
25792+static inline void au_sbilist_lock(void)
25793+{
25794+ spin_lock(&au_sbilist.spin);
25795+}
25796+
25797+static inline void au_sbilist_unlock(void)
25798+{
25799+ spin_unlock(&au_sbilist.spin);
25800+}
25801+#define AuGFP_SBILIST GFP_ATOMIC
25802+#else
25803+AuStubVoid(au_sbilist_lock, void)
25804+AuStubVoid(au_sbilist_unlock, void)
25805+#define AuGFP_SBILIST GFP_NOFS
25806+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
e49829fe
JR
25807+#else
25808+AuStubVoid(au_sbilist_init, void)
25809+AuStubVoid(au_sbilist_add, struct super_block*)
25810+AuStubVoid(au_sbilist_del, struct super_block*)
53392da6
AM
25811+AuStubVoid(au_sbilist_lock, void)
25812+AuStubVoid(au_sbilist_unlock, void)
25813+#define AuGFP_SBILIST GFP_NOFS
e49829fe
JR
25814+#endif
25815+
25816+/* ---------------------------------------------------------------------- */
25817+
1facf9fc 25818+static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
25819+{
dece6358
AM
25820+ /*
25821+ * This function is a dynamic '__init' fucntion actually,
25822+ * so the tiny check for si_rwsem is unnecessary.
25823+ */
25824+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
1facf9fc 25825+#ifdef CONFIG_DEBUG_FS
25826+ sbinfo->si_dbgaufs = NULL;
86dc4139 25827+ sbinfo->si_dbgaufs_plink = NULL;
1facf9fc 25828+ sbinfo->si_dbgaufs_xib = NULL;
25829+#ifdef CONFIG_AUFS_EXPORT
25830+ sbinfo->si_dbgaufs_xigen = NULL;
25831+#endif
25832+#endif
25833+}
25834+
25835+/* ---------------------------------------------------------------------- */
25836+
b752ccd1
AM
25837+static inline pid_t si_pid_bit(void)
25838+{
25839+ /* the origin of pid is 1, but the bitmap's is 0 */
25840+ return current->pid - 1;
25841+}
25842+
25843+static inline int si_pid_test(struct super_block *sb)
25844+{
25845+ pid_t bit = si_pid_bit();
25846+ if (bit < PID_MAX_DEFAULT)
25847+ return test_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
25848+ else
25849+ return si_pid_test_slow(sb);
25850+}
25851+
25852+static inline void si_pid_set(struct super_block *sb)
25853+{
25854+ pid_t bit = si_pid_bit();
25855+ if (bit < PID_MAX_DEFAULT) {
25856+ AuDebugOn(test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
25857+ set_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
25858+ /* smp_mb(); */
25859+ } else
25860+ si_pid_set_slow(sb);
25861+}
25862+
25863+static inline void si_pid_clr(struct super_block *sb)
25864+{
25865+ pid_t bit = si_pid_bit();
25866+ if (bit < PID_MAX_DEFAULT) {
25867+ AuDebugOn(!test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
25868+ clear_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
25869+ /* smp_mb(); */
25870+ } else
25871+ si_pid_clr_slow(sb);
25872+}
25873+
25874+/* ---------------------------------------------------------------------- */
25875+
1facf9fc 25876+/* lock superblock. mainly for entry point functions */
25877+/*
b752ccd1
AM
25878+ * __si_read_lock, __si_write_lock,
25879+ * __si_read_unlock, __si_write_unlock, __si_downgrade_lock
1facf9fc 25880+ */
b752ccd1 25881+AuSimpleRwsemFuncs(__si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
1facf9fc 25882+
dece6358
AM
25883+#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
25884+#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
25885+#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
25886+
b752ccd1
AM
25887+static inline void si_noflush_read_lock(struct super_block *sb)
25888+{
25889+ __si_read_lock(sb);
25890+ si_pid_set(sb);
25891+}
25892+
25893+static inline int si_noflush_read_trylock(struct super_block *sb)
25894+{
25895+ int locked = __si_read_trylock(sb);
25896+ if (locked)
25897+ si_pid_set(sb);
25898+ return locked;
25899+}
25900+
25901+static inline void si_noflush_write_lock(struct super_block *sb)
25902+{
25903+ __si_write_lock(sb);
25904+ si_pid_set(sb);
25905+}
25906+
25907+static inline int si_noflush_write_trylock(struct super_block *sb)
25908+{
25909+ int locked = __si_write_trylock(sb);
25910+ if (locked)
25911+ si_pid_set(sb);
25912+ return locked;
25913+}
25914+
e49829fe 25915+#if 0 /* unused */
1facf9fc 25916+static inline int si_read_trylock(struct super_block *sb, int flags)
25917+{
25918+ if (au_ftest_lock(flags, FLUSH))
25919+ au_nwt_flush(&au_sbi(sb)->si_nowait);
25920+ return si_noflush_read_trylock(sb);
25921+}
e49829fe 25922+#endif
1facf9fc 25923+
b752ccd1
AM
25924+static inline void si_read_unlock(struct super_block *sb)
25925+{
25926+ si_pid_clr(sb);
25927+ __si_read_unlock(sb);
25928+}
25929+
b752ccd1 25930+#if 0 /* unused */
1facf9fc 25931+static inline int si_write_trylock(struct super_block *sb, int flags)
25932+{
25933+ if (au_ftest_lock(flags, FLUSH))
25934+ au_nwt_flush(&au_sbi(sb)->si_nowait);
25935+ return si_noflush_write_trylock(sb);
25936+}
b752ccd1
AM
25937+#endif
25938+
25939+static inline void si_write_unlock(struct super_block *sb)
25940+{
25941+ si_pid_clr(sb);
25942+ __si_write_unlock(sb);
25943+}
25944+
25945+#if 0 /* unused */
25946+static inline void si_downgrade_lock(struct super_block *sb)
25947+{
25948+ __si_downgrade_lock(sb);
25949+}
25950+#endif
1facf9fc 25951+
25952+/* ---------------------------------------------------------------------- */
25953+
25954+static inline aufs_bindex_t au_sbend(struct super_block *sb)
25955+{
dece6358 25956+ SiMustAnyLock(sb);
1facf9fc 25957+ return au_sbi(sb)->si_bend;
25958+}
25959+
25960+static inline unsigned int au_mntflags(struct super_block *sb)
25961+{
dece6358 25962+ SiMustAnyLock(sb);
1facf9fc 25963+ return au_sbi(sb)->si_mntflags;
25964+}
25965+
25966+static inline unsigned int au_sigen(struct super_block *sb)
25967+{
dece6358 25968+ SiMustAnyLock(sb);
1facf9fc 25969+ return au_sbi(sb)->si_generation;
25970+}
25971+
7f207e10
AM
25972+static inline void au_ninodes_inc(struct super_block *sb)
25973+{
25974+ atomic_long_inc(&au_sbi(sb)->si_ninodes);
25975+}
25976+
25977+static inline void au_ninodes_dec(struct super_block *sb)
25978+{
25979+ AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_ninodes));
25980+ atomic_long_dec(&au_sbi(sb)->si_ninodes);
25981+}
25982+
25983+static inline void au_nfiles_inc(struct super_block *sb)
25984+{
25985+ atomic_long_inc(&au_sbi(sb)->si_nfiles);
25986+}
25987+
25988+static inline void au_nfiles_dec(struct super_block *sb)
25989+{
25990+ AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_nfiles));
25991+ atomic_long_dec(&au_sbi(sb)->si_nfiles);
25992+}
25993+
1facf9fc 25994+static inline struct au_branch *au_sbr(struct super_block *sb,
25995+ aufs_bindex_t bindex)
25996+{
dece6358 25997+ SiMustAnyLock(sb);
1facf9fc 25998+ return au_sbi(sb)->si_branch[0 + bindex];
25999+}
26000+
26001+static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid)
26002+{
dece6358 26003+ SiMustWriteLock(sb);
1facf9fc 26004+ au_sbi(sb)->si_xino_brid = brid;
26005+}
26006+
26007+static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
26008+{
dece6358 26009+ SiMustAnyLock(sb);
1facf9fc 26010+ return au_sbi(sb)->si_xino_brid;
26011+}
26012+
26013+#endif /* __KERNEL__ */
26014+#endif /* __AUFS_SUPER_H__ */
7f207e10
AM
26015diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c
26016--- /usr/share/empty/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
86dc4139 26017+++ linux/fs/aufs/sysaufs.c 2013-07-06 13:20:47.753531903 +0200
f6c5ef8b 26018@@ -0,0 +1,105 @@
1facf9fc 26019+/*
7a9e40b8 26020+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 26021+ *
26022+ * This program, aufs is free software; you can redistribute it and/or modify
26023+ * it under the terms of the GNU General Public License as published by
26024+ * the Free Software Foundation; either version 2 of the License, or
26025+ * (at your option) any later version.
dece6358
AM
26026+ *
26027+ * This program is distributed in the hope that it will be useful,
26028+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26029+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26030+ * GNU General Public License for more details.
26031+ *
26032+ * You should have received a copy of the GNU General Public License
26033+ * along with this program; if not, write to the Free Software
26034+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 26035+ */
26036+
26037+/*
26038+ * sysfs interface and lifetime management
26039+ * they are necessary regardless sysfs is disabled.
26040+ */
26041+
1facf9fc 26042+#include <linux/random.h>
1facf9fc 26043+#include "aufs.h"
26044+
26045+unsigned long sysaufs_si_mask;
e49829fe 26046+struct kset *sysaufs_kset;
1facf9fc 26047+
26048+#define AuSiAttr(_name) { \
26049+ .attr = { .name = __stringify(_name), .mode = 0444 }, \
26050+ .show = sysaufs_si_##_name, \
26051+}
26052+
26053+static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
26054+struct attribute *sysaufs_si_attrs[] = {
26055+ &sysaufs_si_attr_xi_path.attr,
26056+ NULL,
26057+};
26058+
4a4d8108 26059+static const struct sysfs_ops au_sbi_ops = {
1facf9fc 26060+ .show = sysaufs_si_show
26061+};
26062+
26063+static struct kobj_type au_sbi_ktype = {
26064+ .release = au_si_free,
26065+ .sysfs_ops = &au_sbi_ops,
26066+ .default_attrs = sysaufs_si_attrs
26067+};
26068+
26069+/* ---------------------------------------------------------------------- */
26070+
26071+int sysaufs_si_init(struct au_sbinfo *sbinfo)
26072+{
26073+ int err;
26074+
e49829fe 26075+ sbinfo->si_kobj.kset = sysaufs_kset;
1facf9fc 26076+ /* cf. sysaufs_name() */
26077+ err = kobject_init_and_add
e49829fe 26078+ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL,
1facf9fc 26079+ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
26080+
26081+ dbgaufs_si_null(sbinfo);
26082+ if (!err) {
26083+ err = dbgaufs_si_init(sbinfo);
26084+ if (unlikely(err))
26085+ kobject_put(&sbinfo->si_kobj);
26086+ }
26087+ return err;
26088+}
26089+
26090+void sysaufs_fin(void)
26091+{
26092+ dbgaufs_fin();
e49829fe
JR
26093+ sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group);
26094+ kset_unregister(sysaufs_kset);
1facf9fc 26095+}
26096+
26097+int __init sysaufs_init(void)
26098+{
26099+ int err;
26100+
26101+ do {
26102+ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
26103+ } while (!sysaufs_si_mask);
26104+
4a4d8108 26105+ err = -EINVAL;
e49829fe
JR
26106+ sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
26107+ if (unlikely(!sysaufs_kset))
4a4d8108 26108+ goto out;
e49829fe
JR
26109+ err = PTR_ERR(sysaufs_kset);
26110+ if (IS_ERR(sysaufs_kset))
1facf9fc 26111+ goto out;
e49829fe 26112+ err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group);
1facf9fc 26113+ if (unlikely(err)) {
e49829fe 26114+ kset_unregister(sysaufs_kset);
1facf9fc 26115+ goto out;
26116+ }
26117+
26118+ err = dbgaufs_init();
26119+ if (unlikely(err))
26120+ sysaufs_fin();
4f0767ce 26121+out:
1facf9fc 26122+ return err;
26123+}
7f207e10
AM
26124diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h
26125--- /usr/share/empty/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
86dc4139 26126+++ linux/fs/aufs/sysaufs.h 2013-07-06 13:20:47.753531903 +0200
f6c5ef8b 26127@@ -0,0 +1,104 @@
1facf9fc 26128+/*
7a9e40b8 26129+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 26130+ *
26131+ * This program, aufs is free software; you can redistribute it and/or modify
26132+ * it under the terms of the GNU General Public License as published by
26133+ * the Free Software Foundation; either version 2 of the License, or
26134+ * (at your option) any later version.
dece6358
AM
26135+ *
26136+ * This program is distributed in the hope that it will be useful,
26137+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26138+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26139+ * GNU General Public License for more details.
26140+ *
26141+ * You should have received a copy of the GNU General Public License
26142+ * along with this program; if not, write to the Free Software
26143+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 26144+ */
26145+
26146+/*
26147+ * sysfs interface and mount lifetime management
26148+ */
26149+
26150+#ifndef __SYSAUFS_H__
26151+#define __SYSAUFS_H__
26152+
26153+#ifdef __KERNEL__
26154+
1facf9fc 26155+#include <linux/sysfs.h>
1facf9fc 26156+#include "module.h"
26157+
dece6358
AM
26158+struct super_block;
26159+struct au_sbinfo;
26160+
1facf9fc 26161+struct sysaufs_si_attr {
26162+ struct attribute attr;
26163+ int (*show)(struct seq_file *seq, struct super_block *sb);
26164+};
26165+
26166+/* ---------------------------------------------------------------------- */
26167+
26168+/* sysaufs.c */
26169+extern unsigned long sysaufs_si_mask;
e49829fe 26170+extern struct kset *sysaufs_kset;
1facf9fc 26171+extern struct attribute *sysaufs_si_attrs[];
26172+int sysaufs_si_init(struct au_sbinfo *sbinfo);
26173+int __init sysaufs_init(void);
26174+void sysaufs_fin(void);
26175+
26176+/* ---------------------------------------------------------------------- */
26177+
26178+/* some people doesn't like to show a pointer in kernel */
26179+static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
26180+{
26181+ return sysaufs_si_mask ^ (unsigned long)sbinfo;
26182+}
26183+
26184+#define SysaufsSiNamePrefix "si_"
26185+#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16)
26186+static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
26187+{
26188+ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
26189+ sysaufs_si_id(sbinfo));
26190+}
26191+
26192+struct au_branch;
26193+#ifdef CONFIG_SYSFS
26194+/* sysfs.c */
26195+extern struct attribute_group *sysaufs_attr_group;
26196+
26197+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
26198+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
26199+ char *buf);
26200+
26201+void sysaufs_br_init(struct au_branch *br);
26202+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
26203+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
26204+
26205+#define sysaufs_brs_init() do {} while (0)
26206+
26207+#else
26208+#define sysaufs_attr_group NULL
26209+
4a4d8108 26210+AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb)
1facf9fc 26211+
26212+static inline
26213+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
26214+ char *buf)
26215+{
26216+ return 0;
26217+}
26218+
4a4d8108
AM
26219+AuStubVoid(sysaufs_br_init, struct au_branch *br)
26220+AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
26221+AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
1facf9fc 26222+
26223+static inline void sysaufs_brs_init(void)
26224+{
26225+ sysaufs_brs = 0;
26226+}
26227+
26228+#endif /* CONFIG_SYSFS */
26229+
26230+#endif /* __KERNEL__ */
26231+#endif /* __SYSAUFS_H__ */
7f207e10
AM
26232diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
26233--- /usr/share/empty/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
26234+++ linux/fs/aufs/sysfs.c 2013-10-26 16:51:32.276373845 +0200
26235@@ -0,0 +1,297 @@
1facf9fc 26236+/*
7a9e40b8 26237+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 26238+ *
26239+ * This program, aufs is free software; you can redistribute it and/or modify
26240+ * it under the terms of the GNU General Public License as published by
26241+ * the Free Software Foundation; either version 2 of the License, or
26242+ * (at your option) any later version.
dece6358
AM
26243+ *
26244+ * This program is distributed in the hope that it will be useful,
26245+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26246+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26247+ * GNU General Public License for more details.
26248+ *
26249+ * You should have received a copy of the GNU General Public License
26250+ * along with this program; if not, write to the Free Software
26251+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 26252+ */
26253+
26254+/*
26255+ * sysfs interface
26256+ */
26257+
1facf9fc 26258+#include <linux/seq_file.h>
1facf9fc 26259+#include "aufs.h"
26260+
4a4d8108
AM
26261+#ifdef CONFIG_AUFS_FS_MODULE
26262+/* this entry violates the "one line per file" policy of sysfs */
26263+static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr,
26264+ char *buf)
26265+{
26266+ ssize_t err;
26267+ static char *conf =
26268+/* this file is generated at compiling */
26269+#include "conf.str"
26270+ ;
26271+
26272+ err = snprintf(buf, PAGE_SIZE, conf);
26273+ if (unlikely(err >= PAGE_SIZE))
26274+ err = -EFBIG;
26275+ return err;
26276+}
26277+
26278+static struct kobj_attribute au_config_attr = __ATTR_RO(config);
26279+#endif
26280+
1facf9fc 26281+static struct attribute *au_attr[] = {
4a4d8108
AM
26282+#ifdef CONFIG_AUFS_FS_MODULE
26283+ &au_config_attr.attr,
26284+#endif
1facf9fc 26285+ NULL, /* need to NULL terminate the list of attributes */
26286+};
26287+
26288+static struct attribute_group sysaufs_attr_group_body = {
26289+ .attrs = au_attr
26290+};
26291+
26292+struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
26293+
26294+/* ---------------------------------------------------------------------- */
26295+
26296+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
26297+{
26298+ int err;
26299+
dece6358
AM
26300+ SiMustAnyLock(sb);
26301+
1facf9fc 26302+ err = 0;
26303+ if (au_opt_test(au_mntflags(sb), XINO)) {
26304+ err = au_xino_path(seq, au_sbi(sb)->si_xib);
26305+ seq_putc(seq, '\n');
26306+ }
26307+ return err;
26308+}
26309+
26310+/*
26311+ * the lifetime of branch is independent from the entry under sysfs.
26312+ * sysfs handles the lifetime of the entry, and never call ->show() after it is
26313+ * unlinked.
26314+ */
26315+static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
392086de 26316+ aufs_bindex_t bindex, int idx)
1facf9fc 26317+{
1e00d052 26318+ int err;
1facf9fc 26319+ struct path path;
26320+ struct dentry *root;
26321+ struct au_branch *br;
1e00d052 26322+ char *perm;
1facf9fc 26323+
26324+ AuDbg("b%d\n", bindex);
26325+
1e00d052 26326+ err = 0;
1facf9fc 26327+ root = sb->s_root;
26328+ di_read_lock_parent(root, !AuLock_IR);
26329+ br = au_sbr(sb, bindex);
392086de
AM
26330+
26331+ switch (idx) {
26332+ case AuBrSysfs_BR:
26333+ path.mnt = au_br_mnt(br);
26334+ path.dentry = au_h_dptr(root, bindex);
26335+ au_seq_path(seq, &path);
26336+ di_read_unlock(root, !AuLock_IR);
26337+ perm = au_optstr_br_perm(br->br_perm);
26338+ if (perm) {
26339+ err = seq_printf(seq, "=%s\n", perm);
26340+ kfree(perm);
26341+ if (err == -1)
26342+ err = -E2BIG;
26343+ } else
26344+ err = -ENOMEM;
26345+ break;
26346+ case AuBrSysfs_BRID:
26347+ err = seq_printf(seq, "%d\n", br->br_id);
26348+ di_read_unlock(root, !AuLock_IR);
1e00d052
AM
26349+ if (err == -1)
26350+ err = -E2BIG;
392086de
AM
26351+ break;
26352+ }
26353+
1e00d052 26354+ return err;
1facf9fc 26355+}
26356+
26357+/* ---------------------------------------------------------------------- */
26358+
26359+static struct seq_file *au_seq(char *p, ssize_t len)
26360+{
26361+ struct seq_file *seq;
26362+
26363+ seq = kzalloc(sizeof(*seq), GFP_NOFS);
26364+ if (seq) {
26365+ /* mutex_init(&seq.lock); */
26366+ seq->buf = p;
26367+ seq->size = len;
26368+ return seq; /* success */
26369+ }
26370+
26371+ seq = ERR_PTR(-ENOMEM);
26372+ return seq;
26373+}
26374+
392086de
AM
26375+#define SysaufsBr_PREFIX "br"
26376+#define SysaufsBrid_PREFIX "brid"
1facf9fc 26377+
26378+/* todo: file size may exceed PAGE_SIZE */
26379+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
1308ab2a 26380+ char *buf)
1facf9fc 26381+{
26382+ ssize_t err;
392086de 26383+ int idx;
1facf9fc 26384+ long l;
26385+ aufs_bindex_t bend;
26386+ struct au_sbinfo *sbinfo;
26387+ struct super_block *sb;
26388+ struct seq_file *seq;
26389+ char *name;
26390+ struct attribute **cattr;
26391+
26392+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
26393+ sb = sbinfo->si_sb;
1308ab2a 26394+
26395+ /*
26396+ * prevent a race condition between sysfs and aufs.
26397+ * for instance, sysfs_file_read() calls sysfs_get_active_two() which
26398+ * prohibits maintaining the sysfs entries.
26399+ * hew we acquire read lock after sysfs_get_active_two().
26400+ * on the other hand, the remount process may maintain the sysfs/aufs
26401+ * entries after acquiring write lock.
26402+ * it can cause a deadlock.
26403+ * simply we gave up processing read here.
26404+ */
26405+ err = -EBUSY;
26406+ if (unlikely(!si_noflush_read_trylock(sb)))
26407+ goto out;
1facf9fc 26408+
26409+ seq = au_seq(buf, PAGE_SIZE);
26410+ err = PTR_ERR(seq);
26411+ if (IS_ERR(seq))
1308ab2a 26412+ goto out_unlock;
1facf9fc 26413+
26414+ name = (void *)attr->name;
26415+ cattr = sysaufs_si_attrs;
26416+ while (*cattr) {
26417+ if (!strcmp(name, (*cattr)->name)) {
26418+ err = container_of(*cattr, struct sysaufs_si_attr, attr)
26419+ ->show(seq, sb);
26420+ goto out_seq;
26421+ }
26422+ cattr++;
26423+ }
26424+
392086de
AM
26425+ if (!strncmp(name, SysaufsBrid_PREFIX,
26426+ sizeof(SysaufsBrid_PREFIX) - 1)) {
26427+ idx = AuBrSysfs_BRID;
26428+ name += sizeof(SysaufsBrid_PREFIX) - 1;
26429+ } else if (!strncmp(name, SysaufsBr_PREFIX,
26430+ sizeof(SysaufsBr_PREFIX) - 1)) {
26431+ idx = AuBrSysfs_BR;
1facf9fc 26432+ name += sizeof(SysaufsBr_PREFIX) - 1;
392086de
AM
26433+ } else
26434+ BUG();
26435+
26436+ err = kstrtol(name, 10, &l);
26437+ if (!err) {
26438+ bend = au_sbend(sb);
26439+ if (l <= bend)
26440+ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l, idx);
26441+ else
26442+ err = -ENOENT;
1facf9fc 26443+ }
1facf9fc 26444+
4f0767ce 26445+out_seq:
1facf9fc 26446+ if (!err) {
26447+ err = seq->count;
26448+ /* sysfs limit */
26449+ if (unlikely(err == PAGE_SIZE))
26450+ err = -EFBIG;
26451+ }
26452+ kfree(seq);
4f0767ce 26453+out_unlock:
1facf9fc 26454+ si_read_unlock(sb);
4f0767ce 26455+out:
1facf9fc 26456+ return err;
26457+}
26458+
26459+/* ---------------------------------------------------------------------- */
26460+
26461+void sysaufs_br_init(struct au_branch *br)
26462+{
392086de
AM
26463+ int i;
26464+ struct au_brsysfs *br_sysfs;
26465+ struct attribute *attr;
4a4d8108 26466+
392086de
AM
26467+ br_sysfs = br->br_sysfs;
26468+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
26469+ attr = &br_sysfs->attr;
26470+ sysfs_attr_init(attr);
26471+ attr->name = br_sysfs->name;
26472+ attr->mode = S_IRUGO;
26473+ br_sysfs++;
26474+ }
1facf9fc 26475+}
26476+
26477+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
26478+{
26479+ struct au_branch *br;
26480+ struct kobject *kobj;
392086de
AM
26481+ struct au_brsysfs *br_sysfs;
26482+ int i;
1facf9fc 26483+ aufs_bindex_t bend;
26484+
26485+ dbgaufs_brs_del(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+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
26496+ sysfs_remove_file(kobj, &br_sysfs->attr);
26497+ br_sysfs++;
26498+ }
1facf9fc 26499+ }
26500+}
26501+
26502+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
26503+{
392086de 26504+ int err, i;
1facf9fc 26505+ aufs_bindex_t bend;
26506+ struct kobject *kobj;
26507+ struct au_branch *br;
392086de 26508+ struct au_brsysfs *br_sysfs;
1facf9fc 26509+
26510+ dbgaufs_brs_add(sb, bindex);
26511+
26512+ if (!sysaufs_brs)
26513+ return;
26514+
26515+ kobj = &au_sbi(sb)->si_kobj;
26516+ bend = au_sbend(sb);
26517+ for (; bindex <= bend; bindex++) {
26518+ br = au_sbr(sb, bindex);
392086de
AM
26519+ br_sysfs = br->br_sysfs;
26520+ snprintf(br_sysfs[AuBrSysfs_BR].name, sizeof(br_sysfs->name),
26521+ SysaufsBr_PREFIX "%d", bindex);
26522+ snprintf(br_sysfs[AuBrSysfs_BRID].name, sizeof(br_sysfs->name),
26523+ SysaufsBrid_PREFIX "%d", bindex);
26524+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
26525+ err = sysfs_create_file(kobj, &br_sysfs->attr);
26526+ if (unlikely(err))
26527+ pr_warn("failed %s under sysfs(%d)\n",
26528+ br_sysfs->name, err);
26529+ br_sysfs++;
26530+ }
1facf9fc 26531+ }
26532+}
7f207e10
AM
26533diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
26534--- /usr/share/empty/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100
86dc4139 26535+++ linux/fs/aufs/sysrq.c 2013-07-06 13:20:47.753531903 +0200
c06a8ce3 26536@@ -0,0 +1,151 @@
1facf9fc 26537+/*
7a9e40b8 26538+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 26539+ *
26540+ * This program, aufs is free software; you can redistribute it and/or modify
26541+ * it under the terms of the GNU General Public License as published by
26542+ * the Free Software Foundation; either version 2 of the License, or
26543+ * (at your option) any later version.
dece6358
AM
26544+ *
26545+ * This program is distributed in the hope that it will be useful,
26546+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26547+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26548+ * GNU General Public License for more details.
26549+ *
26550+ * You should have received a copy of the GNU General Public License
26551+ * along with this program; if not, write to the Free Software
26552+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 26553+ */
26554+
26555+/*
26556+ * magic sysrq hanlder
26557+ */
26558+
1facf9fc 26559+/* #include <linux/sysrq.h> */
027c5e7a 26560+#include <linux/writeback.h>
1facf9fc 26561+#include "aufs.h"
26562+
26563+/* ---------------------------------------------------------------------- */
26564+
26565+static void sysrq_sb(struct super_block *sb)
26566+{
26567+ char *plevel;
26568+ struct au_sbinfo *sbinfo;
26569+ struct file *file;
26570+
26571+ plevel = au_plevel;
26572+ au_plevel = KERN_WARNING;
1facf9fc 26573+
4a4d8108 26574+ /* since we define pr_fmt, call printk directly */
c06a8ce3
AM
26575+#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str)
26576+
26577+ sbinfo = au_sbi(sb);
4a4d8108 26578+ printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo));
c06a8ce3 26579+ pr("superblock\n");
1facf9fc 26580+ au_dpri_sb(sb);
027c5e7a
AM
26581+
26582+#if 0
c06a8ce3 26583+ pr("root dentry\n");
1facf9fc 26584+ au_dpri_dentry(sb->s_root);
c06a8ce3 26585+ pr("root inode\n");
1facf9fc 26586+ au_dpri_inode(sb->s_root->d_inode);
027c5e7a
AM
26587+#endif
26588+
1facf9fc 26589+#if 0
027c5e7a
AM
26590+ do {
26591+ int err, i, j, ndentry;
26592+ struct au_dcsub_pages dpages;
26593+ struct au_dpage *dpage;
26594+
26595+ err = au_dpages_init(&dpages, GFP_ATOMIC);
26596+ if (unlikely(err))
26597+ break;
26598+ err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL);
26599+ if (!err)
26600+ for (i = 0; i < dpages.ndpage; i++) {
26601+ dpage = dpages.dpages + i;
26602+ ndentry = dpage->ndentry;
26603+ for (j = 0; j < ndentry; j++)
26604+ au_dpri_dentry(dpage->dentries[j]);
26605+ }
26606+ au_dpages_free(&dpages);
26607+ } while (0);
26608+#endif
26609+
26610+#if 1
26611+ {
26612+ struct inode *i;
c06a8ce3 26613+ pr("isolated inode\n");
2cbb1c4b
JR
26614+ spin_lock(&inode_sb_list_lock);
26615+ list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
26616+ spin_lock(&i->i_lock);
b4510431 26617+ if (1 || hlist_empty(&i->i_dentry))
027c5e7a 26618+ au_dpri_inode(i);
2cbb1c4b
JR
26619+ spin_unlock(&i->i_lock);
26620+ }
26621+ spin_unlock(&inode_sb_list_lock);
027c5e7a 26622+ }
1facf9fc 26623+#endif
c06a8ce3 26624+ pr("files\n");
0c3ec466 26625+ lg_global_lock(&files_lglock);
0c5527e5 26626+ do_file_list_for_each_entry(sb, file) {
4a4d8108 26627+ umode_t mode;
c06a8ce3 26628+ mode = file_inode(file)->i_mode;
4a4d8108 26629+ if (!special_file(mode) || au_special_file(mode))
1facf9fc 26630+ au_dpri_file(file);
0c5527e5 26631+ } while_file_list_for_each_entry;
0c3ec466 26632+ lg_global_unlock(&files_lglock);
c06a8ce3 26633+ pr("done\n");
1facf9fc 26634+
c06a8ce3 26635+#undef pr
1facf9fc 26636+ au_plevel = plevel;
1facf9fc 26637+}
26638+
26639+/* ---------------------------------------------------------------------- */
26640+
26641+/* module parameter */
26642+static char *aufs_sysrq_key = "a";
26643+module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO);
26644+MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
26645+
0c5527e5 26646+static void au_sysrq(int key __maybe_unused)
1facf9fc 26647+{
1facf9fc 26648+ struct au_sbinfo *sbinfo;
26649+
027c5e7a 26650+ lockdep_off();
53392da6 26651+ au_sbilist_lock();
e49829fe 26652+ list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
1facf9fc 26653+ sysrq_sb(sbinfo->si_sb);
53392da6 26654+ au_sbilist_unlock();
027c5e7a 26655+ lockdep_on();
1facf9fc 26656+}
26657+
26658+static struct sysrq_key_op au_sysrq_op = {
26659+ .handler = au_sysrq,
26660+ .help_msg = "Aufs",
26661+ .action_msg = "Aufs",
26662+ .enable_mask = SYSRQ_ENABLE_DUMP
26663+};
26664+
26665+/* ---------------------------------------------------------------------- */
26666+
26667+int __init au_sysrq_init(void)
26668+{
26669+ int err;
26670+ char key;
26671+
26672+ err = -1;
26673+ key = *aufs_sysrq_key;
26674+ if ('a' <= key && key <= 'z')
26675+ err = register_sysrq_key(key, &au_sysrq_op);
26676+ if (unlikely(err))
4a4d8108 26677+ pr_err("err %d, sysrq=%c\n", err, key);
1facf9fc 26678+ return err;
26679+}
26680+
26681+void au_sysrq_fin(void)
26682+{
26683+ int err;
26684+ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
26685+ if (unlikely(err))
4a4d8108 26686+ pr_err("err %d (ignored)\n", err);
1facf9fc 26687+}
7f207e10
AM
26688diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
26689--- /usr/share/empty/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
26690+++ linux/fs/aufs/vdir.c 2013-10-26 16:51:29.586298347 +0200
26691@@ -0,0 +1,888 @@
1facf9fc 26692+/*
7a9e40b8 26693+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 26694+ *
26695+ * This program, aufs is free software; you can redistribute it and/or modify
26696+ * it under the terms of the GNU General Public License as published by
26697+ * the Free Software Foundation; either version 2 of the License, or
26698+ * (at your option) any later version.
dece6358
AM
26699+ *
26700+ * This program is distributed in the hope that it will be useful,
26701+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26702+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26703+ * GNU General Public License for more details.
26704+ *
26705+ * You should have received a copy of the GNU General Public License
26706+ * along with this program; if not, write to the Free Software
26707+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 26708+ */
26709+
26710+/*
26711+ * virtual or vertical directory
26712+ */
26713+
26714+#include "aufs.h"
26715+
dece6358 26716+static unsigned int calc_size(int nlen)
1facf9fc 26717+{
dece6358 26718+ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
1facf9fc 26719+}
26720+
26721+static int set_deblk_end(union au_vdir_deblk_p *p,
26722+ union au_vdir_deblk_p *deblk_end)
26723+{
26724+ if (calc_size(0) <= deblk_end->deblk - p->deblk) {
26725+ p->de->de_str.len = 0;
26726+ /* smp_mb(); */
26727+ return 0;
26728+ }
26729+ return -1; /* error */
26730+}
26731+
26732+/* returns true or false */
26733+static int is_deblk_end(union au_vdir_deblk_p *p,
26734+ union au_vdir_deblk_p *deblk_end)
26735+{
26736+ if (calc_size(0) <= deblk_end->deblk - p->deblk)
26737+ return !p->de->de_str.len;
26738+ return 1;
26739+}
26740+
26741+static unsigned char *last_deblk(struct au_vdir *vdir)
26742+{
26743+ return vdir->vd_deblk[vdir->vd_nblk - 1];
26744+}
26745+
26746+/* ---------------------------------------------------------------------- */
26747+
1308ab2a 26748+/* estimate the apropriate size for name hash table */
26749+unsigned int au_rdhash_est(loff_t sz)
26750+{
26751+ unsigned int n;
26752+
26753+ n = UINT_MAX;
26754+ sz >>= 10;
26755+ if (sz < n)
26756+ n = sz;
26757+ if (sz < AUFS_RDHASH_DEF)
26758+ n = AUFS_RDHASH_DEF;
4a4d8108 26759+ /* pr_info("n %u\n", n); */
1308ab2a 26760+ return n;
26761+}
26762+
1facf9fc 26763+/*
26764+ * the allocated memory has to be freed by
dece6358 26765+ * au_nhash_wh_free() or au_nhash_de_free().
1facf9fc 26766+ */
dece6358 26767+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
1facf9fc 26768+{
1facf9fc 26769+ struct hlist_head *head;
dece6358 26770+ unsigned int u;
1facf9fc 26771+
dece6358
AM
26772+ head = kmalloc(sizeof(*nhash->nh_head) * num_hash, gfp);
26773+ if (head) {
26774+ nhash->nh_num = num_hash;
26775+ nhash->nh_head = head;
26776+ for (u = 0; u < num_hash; u++)
1facf9fc 26777+ INIT_HLIST_HEAD(head++);
dece6358 26778+ return 0; /* success */
1facf9fc 26779+ }
1facf9fc 26780+
dece6358 26781+ return -ENOMEM;
1facf9fc 26782+}
26783+
dece6358
AM
26784+static void nhash_count(struct hlist_head *head)
26785+{
26786+#if 0
26787+ unsigned long n;
26788+ struct hlist_node *pos;
26789+
26790+ n = 0;
26791+ hlist_for_each(pos, head)
26792+ n++;
4a4d8108 26793+ pr_info("%lu\n", n);
dece6358
AM
26794+#endif
26795+}
26796+
26797+static void au_nhash_wh_do_free(struct hlist_head *head)
1facf9fc 26798+{
c06a8ce3
AM
26799+ struct au_vdir_wh *pos;
26800+ struct hlist_node *node;
1facf9fc 26801+
c06a8ce3
AM
26802+ hlist_for_each_entry_safe(pos, node, head, wh_hash)
26803+ kfree(pos);
1facf9fc 26804+}
26805+
dece6358 26806+static void au_nhash_de_do_free(struct hlist_head *head)
1facf9fc 26807+{
c06a8ce3
AM
26808+ struct au_vdir_dehstr *pos;
26809+ struct hlist_node *node;
1facf9fc 26810+
c06a8ce3
AM
26811+ hlist_for_each_entry_safe(pos, node, head, hash)
26812+ au_cache_free_vdir_dehstr(pos);
1facf9fc 26813+}
26814+
dece6358
AM
26815+static void au_nhash_do_free(struct au_nhash *nhash,
26816+ void (*free)(struct hlist_head *head))
1facf9fc 26817+{
1308ab2a 26818+ unsigned int n;
1facf9fc 26819+ struct hlist_head *head;
1facf9fc 26820+
dece6358 26821+ n = nhash->nh_num;
1308ab2a 26822+ if (!n)
26823+ return;
26824+
dece6358 26825+ head = nhash->nh_head;
1308ab2a 26826+ while (n-- > 0) {
dece6358
AM
26827+ nhash_count(head);
26828+ free(head++);
1facf9fc 26829+ }
dece6358 26830+ kfree(nhash->nh_head);
1facf9fc 26831+}
26832+
dece6358 26833+void au_nhash_wh_free(struct au_nhash *whlist)
1facf9fc 26834+{
dece6358
AM
26835+ au_nhash_do_free(whlist, au_nhash_wh_do_free);
26836+}
1facf9fc 26837+
dece6358
AM
26838+static void au_nhash_de_free(struct au_nhash *delist)
26839+{
26840+ au_nhash_do_free(delist, au_nhash_de_do_free);
1facf9fc 26841+}
26842+
26843+/* ---------------------------------------------------------------------- */
26844+
26845+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
26846+ int limit)
26847+{
26848+ int num;
26849+ unsigned int u, n;
26850+ struct hlist_head *head;
c06a8ce3 26851+ struct au_vdir_wh *pos;
1facf9fc 26852+
26853+ num = 0;
26854+ n = whlist->nh_num;
26855+ head = whlist->nh_head;
1308ab2a 26856+ for (u = 0; u < n; u++, head++)
c06a8ce3
AM
26857+ hlist_for_each_entry(pos, head, wh_hash)
26858+ if (pos->wh_bindex == btgt && ++num > limit)
1facf9fc 26859+ return 1;
1facf9fc 26860+ return 0;
26861+}
26862+
26863+static struct hlist_head *au_name_hash(struct au_nhash *nhash,
dece6358 26864+ unsigned char *name,
1facf9fc 26865+ unsigned int len)
26866+{
dece6358
AM
26867+ unsigned int v;
26868+ /* const unsigned int magic_bit = 12; */
26869+
1308ab2a 26870+ AuDebugOn(!nhash->nh_num || !nhash->nh_head);
26871+
dece6358
AM
26872+ v = 0;
26873+ while (len--)
26874+ v += *name++;
26875+ /* v = hash_long(v, magic_bit); */
26876+ v %= nhash->nh_num;
26877+ return nhash->nh_head + v;
26878+}
26879+
26880+static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
26881+ int nlen)
26882+{
26883+ return str->len == nlen && !memcmp(str->name, name, nlen);
1facf9fc 26884+}
26885+
26886+/* returns found or not */
dece6358 26887+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
1facf9fc 26888+{
26889+ struct hlist_head *head;
c06a8ce3 26890+ struct au_vdir_wh *pos;
1facf9fc 26891+ struct au_vdir_destr *str;
26892+
dece6358 26893+ head = au_name_hash(whlist, name, nlen);
c06a8ce3
AM
26894+ hlist_for_each_entry(pos, head, wh_hash) {
26895+ str = &pos->wh_str;
1facf9fc 26896+ AuDbg("%.*s\n", str->len, str->name);
dece6358
AM
26897+ if (au_nhash_test_name(str, name, nlen))
26898+ return 1;
26899+ }
26900+ return 0;
26901+}
26902+
26903+/* returns found(true) or not */
26904+static int test_known(struct au_nhash *delist, char *name, int nlen)
26905+{
26906+ struct hlist_head *head;
c06a8ce3 26907+ struct au_vdir_dehstr *pos;
dece6358
AM
26908+ struct au_vdir_destr *str;
26909+
26910+ head = au_name_hash(delist, name, nlen);
c06a8ce3
AM
26911+ hlist_for_each_entry(pos, head, hash) {
26912+ str = pos->str;
dece6358
AM
26913+ AuDbg("%.*s\n", str->len, str->name);
26914+ if (au_nhash_test_name(str, name, nlen))
1facf9fc 26915+ return 1;
26916+ }
26917+ return 0;
26918+}
26919+
dece6358
AM
26920+static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
26921+ unsigned char d_type)
26922+{
26923+#ifdef CONFIG_AUFS_SHWH
26924+ wh->wh_ino = ino;
26925+ wh->wh_type = d_type;
26926+#endif
26927+}
26928+
26929+/* ---------------------------------------------------------------------- */
26930+
26931+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
26932+ unsigned int d_type, aufs_bindex_t bindex,
26933+ unsigned char shwh)
1facf9fc 26934+{
26935+ int err;
26936+ struct au_vdir_destr *str;
26937+ struct au_vdir_wh *wh;
26938+
dece6358 26939+ AuDbg("%.*s\n", nlen, name);
1308ab2a 26940+ AuDebugOn(!whlist->nh_num || !whlist->nh_head);
26941+
1facf9fc 26942+ err = -ENOMEM;
dece6358 26943+ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
1facf9fc 26944+ if (unlikely(!wh))
26945+ goto out;
26946+
26947+ err = 0;
26948+ wh->wh_bindex = bindex;
dece6358
AM
26949+ if (shwh)
26950+ au_shwh_init_wh(wh, ino, d_type);
1facf9fc 26951+ str = &wh->wh_str;
dece6358
AM
26952+ str->len = nlen;
26953+ memcpy(str->name, name, nlen);
26954+ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
1facf9fc 26955+ /* smp_mb(); */
26956+
4f0767ce 26957+out:
1facf9fc 26958+ return err;
26959+}
26960+
1facf9fc 26961+static int append_deblk(struct au_vdir *vdir)
26962+{
26963+ int err;
dece6358 26964+ unsigned long ul;
1facf9fc 26965+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
26966+ union au_vdir_deblk_p p, deblk_end;
26967+ unsigned char **o;
26968+
26969+ err = -ENOMEM;
dece6358
AM
26970+ o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
26971+ GFP_NOFS);
1facf9fc 26972+ if (unlikely(!o))
26973+ goto out;
26974+
26975+ vdir->vd_deblk = o;
26976+ p.deblk = kmalloc(deblk_sz, GFP_NOFS);
26977+ if (p.deblk) {
26978+ ul = vdir->vd_nblk++;
26979+ vdir->vd_deblk[ul] = p.deblk;
26980+ vdir->vd_last.ul = ul;
26981+ vdir->vd_last.p.deblk = p.deblk;
26982+ deblk_end.deblk = p.deblk + deblk_sz;
26983+ err = set_deblk_end(&p, &deblk_end);
26984+ }
26985+
4f0767ce 26986+out:
1facf9fc 26987+ return err;
26988+}
26989+
dece6358
AM
26990+static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
26991+ unsigned int d_type, struct au_nhash *delist)
26992+{
26993+ int err;
26994+ unsigned int sz;
26995+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
26996+ union au_vdir_deblk_p p, *room, deblk_end;
26997+ struct au_vdir_dehstr *dehstr;
26998+
26999+ p.deblk = last_deblk(vdir);
27000+ deblk_end.deblk = p.deblk + deblk_sz;
27001+ room = &vdir->vd_last.p;
27002+ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
27003+ || !is_deblk_end(room, &deblk_end));
27004+
27005+ sz = calc_size(nlen);
27006+ if (unlikely(sz > deblk_end.deblk - room->deblk)) {
27007+ err = append_deblk(vdir);
27008+ if (unlikely(err))
27009+ goto out;
27010+
27011+ p.deblk = last_deblk(vdir);
27012+ deblk_end.deblk = p.deblk + deblk_sz;
27013+ /* smp_mb(); */
27014+ AuDebugOn(room->deblk != p.deblk);
27015+ }
27016+
27017+ err = -ENOMEM;
4a4d8108 27018+ dehstr = au_cache_alloc_vdir_dehstr();
dece6358
AM
27019+ if (unlikely(!dehstr))
27020+ goto out;
27021+
27022+ dehstr->str = &room->de->de_str;
27023+ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
27024+ room->de->de_ino = ino;
27025+ room->de->de_type = d_type;
27026+ room->de->de_str.len = nlen;
27027+ memcpy(room->de->de_str.name, name, nlen);
27028+
27029+ err = 0;
27030+ room->deblk += sz;
27031+ if (unlikely(set_deblk_end(room, &deblk_end)))
27032+ err = append_deblk(vdir);
27033+ /* smp_mb(); */
27034+
4f0767ce 27035+out:
dece6358
AM
27036+ return err;
27037+}
27038+
27039+/* ---------------------------------------------------------------------- */
27040+
27041+void au_vdir_free(struct au_vdir *vdir)
27042+{
27043+ unsigned char **deblk;
27044+
27045+ deblk = vdir->vd_deblk;
27046+ while (vdir->vd_nblk--)
27047+ kfree(*deblk++);
27048+ kfree(vdir->vd_deblk);
27049+ au_cache_free_vdir(vdir);
27050+}
27051+
1308ab2a 27052+static struct au_vdir *alloc_vdir(struct file *file)
1facf9fc 27053+{
27054+ struct au_vdir *vdir;
1308ab2a 27055+ struct super_block *sb;
1facf9fc 27056+ int err;
27057+
1308ab2a 27058+ sb = file->f_dentry->d_sb;
dece6358
AM
27059+ SiMustAnyLock(sb);
27060+
1facf9fc 27061+ err = -ENOMEM;
27062+ vdir = au_cache_alloc_vdir();
27063+ if (unlikely(!vdir))
27064+ goto out;
27065+
27066+ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
27067+ if (unlikely(!vdir->vd_deblk))
27068+ goto out_free;
27069+
27070+ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
1308ab2a 27071+ if (!vdir->vd_deblk_sz) {
27072+ /* estimate the apropriate size for deblk */
27073+ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
4a4d8108 27074+ /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
1308ab2a 27075+ }
1facf9fc 27076+ vdir->vd_nblk = 0;
27077+ vdir->vd_version = 0;
27078+ vdir->vd_jiffy = 0;
27079+ err = append_deblk(vdir);
27080+ if (!err)
27081+ return vdir; /* success */
27082+
27083+ kfree(vdir->vd_deblk);
27084+
4f0767ce 27085+out_free:
1facf9fc 27086+ au_cache_free_vdir(vdir);
4f0767ce 27087+out:
1facf9fc 27088+ vdir = ERR_PTR(err);
27089+ return vdir;
27090+}
27091+
27092+static int reinit_vdir(struct au_vdir *vdir)
27093+{
27094+ int err;
27095+ union au_vdir_deblk_p p, deblk_end;
27096+
27097+ while (vdir->vd_nblk > 1) {
27098+ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
27099+ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
27100+ vdir->vd_nblk--;
27101+ }
27102+ p.deblk = vdir->vd_deblk[0];
27103+ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
27104+ err = set_deblk_end(&p, &deblk_end);
27105+ /* keep vd_dblk_sz */
27106+ vdir->vd_last.ul = 0;
27107+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
27108+ vdir->vd_version = 0;
27109+ vdir->vd_jiffy = 0;
27110+ /* smp_mb(); */
27111+ return err;
27112+}
27113+
27114+/* ---------------------------------------------------------------------- */
27115+
1facf9fc 27116+#define AuFillVdir_CALLED 1
27117+#define AuFillVdir_WHABLE (1 << 1)
dece6358 27118+#define AuFillVdir_SHWH (1 << 2)
1facf9fc 27119+#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
7f207e10
AM
27120+#define au_fset_fillvdir(flags, name) \
27121+ do { (flags) |= AuFillVdir_##name; } while (0)
27122+#define au_fclr_fillvdir(flags, name) \
27123+ do { (flags) &= ~AuFillVdir_##name; } while (0)
1facf9fc 27124+
dece6358
AM
27125+#ifndef CONFIG_AUFS_SHWH
27126+#undef AuFillVdir_SHWH
27127+#define AuFillVdir_SHWH 0
27128+#endif
27129+
1facf9fc 27130+struct fillvdir_arg {
392086de 27131+ struct dir_context ctx;
1facf9fc 27132+ struct file *file;
27133+ struct au_vdir *vdir;
dece6358
AM
27134+ struct au_nhash delist;
27135+ struct au_nhash whlist;
1facf9fc 27136+ aufs_bindex_t bindex;
27137+ unsigned int flags;
27138+ int err;
27139+};
27140+
392086de 27141+static int fillvdir(struct dir_context *ctx, const char *__name, int nlen,
1facf9fc 27142+ loff_t offset __maybe_unused, u64 h_ino,
27143+ unsigned int d_type)
27144+{
392086de 27145+ struct fillvdir_arg *arg = container_of(ctx, struct fillvdir_arg, ctx);
1facf9fc 27146+ char *name = (void *)__name;
27147+ struct super_block *sb;
1facf9fc 27148+ ino_t ino;
dece6358 27149+ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
1facf9fc 27150+
1facf9fc 27151+ arg->err = 0;
dece6358 27152+ sb = arg->file->f_dentry->d_sb;
1facf9fc 27153+ au_fset_fillvdir(arg->flags, CALLED);
27154+ /* smp_mb(); */
dece6358 27155+ if (nlen <= AUFS_WH_PFX_LEN
1facf9fc 27156+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
dece6358
AM
27157+ if (test_known(&arg->delist, name, nlen)
27158+ || au_nhash_test_known_wh(&arg->whlist, name, nlen))
27159+ goto out; /* already exists or whiteouted */
1facf9fc 27160+
27161+ sb = arg->file->f_dentry->d_sb;
dece6358 27162+ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
4a4d8108
AM
27163+ if (!arg->err) {
27164+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
27165+ d_type = DT_UNKNOWN;
dece6358
AM
27166+ arg->err = append_de(arg->vdir, name, nlen, ino,
27167+ d_type, &arg->delist);
4a4d8108 27168+ }
1facf9fc 27169+ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
27170+ name += AUFS_WH_PFX_LEN;
dece6358
AM
27171+ nlen -= AUFS_WH_PFX_LEN;
27172+ if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
27173+ goto out; /* already whiteouted */
1facf9fc 27174+
dece6358
AM
27175+ if (shwh)
27176+ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
27177+ &ino);
4a4d8108
AM
27178+ if (!arg->err) {
27179+ if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
27180+ d_type = DT_UNKNOWN;
1facf9fc 27181+ arg->err = au_nhash_append_wh
dece6358
AM
27182+ (&arg->whlist, name, nlen, ino, d_type,
27183+ arg->bindex, shwh);
4a4d8108 27184+ }
1facf9fc 27185+ }
27186+
4f0767ce 27187+out:
1facf9fc 27188+ if (!arg->err)
27189+ arg->vdir->vd_jiffy = jiffies;
27190+ /* smp_mb(); */
27191+ AuTraceErr(arg->err);
27192+ return arg->err;
27193+}
27194+
dece6358
AM
27195+static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
27196+ struct au_nhash *whlist, struct au_nhash *delist)
27197+{
27198+#ifdef CONFIG_AUFS_SHWH
27199+ int err;
27200+ unsigned int nh, u;
27201+ struct hlist_head *head;
c06a8ce3
AM
27202+ struct au_vdir_wh *pos;
27203+ struct hlist_node *n;
dece6358
AM
27204+ char *p, *o;
27205+ struct au_vdir_destr *destr;
27206+
27207+ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
27208+
27209+ err = -ENOMEM;
537831f9 27210+ o = p = (void *)__get_free_page(GFP_NOFS);
dece6358
AM
27211+ if (unlikely(!p))
27212+ goto out;
27213+
27214+ err = 0;
27215+ nh = whlist->nh_num;
27216+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
27217+ p += AUFS_WH_PFX_LEN;
27218+ for (u = 0; u < nh; u++) {
27219+ head = whlist->nh_head + u;
c06a8ce3
AM
27220+ hlist_for_each_entry_safe(pos, n, head, wh_hash) {
27221+ destr = &pos->wh_str;
dece6358
AM
27222+ memcpy(p, destr->name, destr->len);
27223+ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
c06a8ce3 27224+ pos->wh_ino, pos->wh_type, delist);
dece6358
AM
27225+ if (unlikely(err))
27226+ break;
27227+ }
27228+ }
27229+
537831f9 27230+ free_page((unsigned long)o);
dece6358 27231+
4f0767ce 27232+out:
dece6358
AM
27233+ AuTraceErr(err);
27234+ return err;
27235+#else
27236+ return 0;
27237+#endif
27238+}
27239+
1facf9fc 27240+static int au_do_read_vdir(struct fillvdir_arg *arg)
27241+{
27242+ int err;
dece6358 27243+ unsigned int rdhash;
1facf9fc 27244+ loff_t offset;
dece6358
AM
27245+ aufs_bindex_t bend, bindex, bstart;
27246+ unsigned char shwh;
1facf9fc 27247+ struct file *hf, *file;
27248+ struct super_block *sb;
27249+
1facf9fc 27250+ file = arg->file;
27251+ sb = file->f_dentry->d_sb;
dece6358
AM
27252+ SiMustAnyLock(sb);
27253+
27254+ rdhash = au_sbi(sb)->si_rdhash;
1308ab2a 27255+ if (!rdhash)
27256+ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
dece6358
AM
27257+ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
27258+ if (unlikely(err))
1facf9fc 27259+ goto out;
dece6358
AM
27260+ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
27261+ if (unlikely(err))
1facf9fc 27262+ goto out_delist;
27263+
27264+ err = 0;
27265+ arg->flags = 0;
dece6358
AM
27266+ shwh = 0;
27267+ if (au_opt_test(au_mntflags(sb), SHWH)) {
27268+ shwh = 1;
27269+ au_fset_fillvdir(arg->flags, SHWH);
27270+ }
27271+ bstart = au_fbstart(file);
4a4d8108 27272+ bend = au_fbend_dir(file);
dece6358 27273+ for (bindex = bstart; !err && bindex <= bend; bindex++) {
4a4d8108 27274+ hf = au_hf_dir(file, bindex);
1facf9fc 27275+ if (!hf)
27276+ continue;
27277+
27278+ offset = vfsub_llseek(hf, 0, SEEK_SET);
27279+ err = offset;
27280+ if (unlikely(offset))
27281+ break;
27282+
27283+ arg->bindex = bindex;
27284+ au_fclr_fillvdir(arg->flags, WHABLE);
dece6358
AM
27285+ if (shwh
27286+ || (bindex != bend
27287+ && au_br_whable(au_sbr_perm(sb, bindex))))
1facf9fc 27288+ au_fset_fillvdir(arg->flags, WHABLE);
27289+ do {
27290+ arg->err = 0;
27291+ au_fclr_fillvdir(arg->flags, CALLED);
27292+ /* smp_mb(); */
392086de 27293+ err = vfsub_iterate_dir(hf, &arg->ctx);
1facf9fc 27294+ if (err >= 0)
27295+ err = arg->err;
27296+ } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
392086de
AM
27297+
27298+ /*
27299+ * dir_relax() may be good for concurrency, but aufs should not
27300+ * use it since it will cause a lockdep problem.
27301+ */
1facf9fc 27302+ }
dece6358
AM
27303+
27304+ if (!err && shwh)
27305+ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
27306+
27307+ au_nhash_wh_free(&arg->whlist);
1facf9fc 27308+
4f0767ce 27309+out_delist:
dece6358 27310+ au_nhash_de_free(&arg->delist);
4f0767ce 27311+out:
1facf9fc 27312+ return err;
27313+}
27314+
27315+static int read_vdir(struct file *file, int may_read)
27316+{
27317+ int err;
27318+ unsigned long expire;
27319+ unsigned char do_read;
392086de
AM
27320+ struct fillvdir_arg arg = {
27321+ .ctx = {
27322+ .actor = au_diractor(fillvdir)
27323+ }
27324+ };
1facf9fc 27325+ struct inode *inode;
27326+ struct au_vdir *vdir, *allocated;
27327+
27328+ err = 0;
c06a8ce3 27329+ inode = file_inode(file);
1facf9fc 27330+ IMustLock(inode);
dece6358
AM
27331+ SiMustAnyLock(inode->i_sb);
27332+
1facf9fc 27333+ allocated = NULL;
27334+ do_read = 0;
27335+ expire = au_sbi(inode->i_sb)->si_rdcache;
27336+ vdir = au_ivdir(inode);
27337+ if (!vdir) {
27338+ do_read = 1;
1308ab2a 27339+ vdir = alloc_vdir(file);
1facf9fc 27340+ err = PTR_ERR(vdir);
27341+ if (IS_ERR(vdir))
27342+ goto out;
27343+ err = 0;
27344+ allocated = vdir;
27345+ } else if (may_read
27346+ && (inode->i_version != vdir->vd_version
27347+ || time_after(jiffies, vdir->vd_jiffy + expire))) {
27348+ do_read = 1;
27349+ err = reinit_vdir(vdir);
27350+ if (unlikely(err))
27351+ goto out;
27352+ }
27353+
27354+ if (!do_read)
27355+ return 0; /* success */
27356+
27357+ arg.file = file;
27358+ arg.vdir = vdir;
27359+ err = au_do_read_vdir(&arg);
27360+ if (!err) {
392086de 27361+ /* file->f_pos = 0; */ /* todo: ctx->pos? */
1facf9fc 27362+ vdir->vd_version = inode->i_version;
27363+ vdir->vd_last.ul = 0;
27364+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
27365+ if (allocated)
27366+ au_set_ivdir(inode, allocated);
27367+ } else if (allocated)
27368+ au_vdir_free(allocated);
27369+
4f0767ce 27370+out:
1facf9fc 27371+ return err;
27372+}
27373+
27374+static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
27375+{
27376+ int err, rerr;
27377+ unsigned long ul, n;
27378+ const unsigned int deblk_sz = src->vd_deblk_sz;
27379+
27380+ AuDebugOn(tgt->vd_nblk != 1);
27381+
27382+ err = -ENOMEM;
27383+ if (tgt->vd_nblk < src->vd_nblk) {
27384+ unsigned char **p;
27385+
dece6358
AM
27386+ p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
27387+ GFP_NOFS);
1facf9fc 27388+ if (unlikely(!p))
27389+ goto out;
27390+ tgt->vd_deblk = p;
27391+ }
27392+
1308ab2a 27393+ if (tgt->vd_deblk_sz != deblk_sz) {
27394+ unsigned char *p;
27395+
27396+ tgt->vd_deblk_sz = deblk_sz;
27397+ p = krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS);
27398+ if (unlikely(!p))
27399+ goto out;
27400+ tgt->vd_deblk[0] = p;
27401+ }
1facf9fc 27402+ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
1facf9fc 27403+ tgt->vd_version = src->vd_version;
27404+ tgt->vd_jiffy = src->vd_jiffy;
27405+
27406+ n = src->vd_nblk;
27407+ for (ul = 1; ul < n; ul++) {
dece6358
AM
27408+ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
27409+ GFP_NOFS);
27410+ if (unlikely(!tgt->vd_deblk[ul]))
1facf9fc 27411+ goto out;
1308ab2a 27412+ tgt->vd_nblk++;
1facf9fc 27413+ }
1308ab2a 27414+ tgt->vd_nblk = n;
27415+ tgt->vd_last.ul = tgt->vd_last.ul;
27416+ tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul];
27417+ tgt->vd_last.p.deblk += src->vd_last.p.deblk
27418+ - src->vd_deblk[src->vd_last.ul];
1facf9fc 27419+ /* smp_mb(); */
27420+ return 0; /* success */
27421+
4f0767ce 27422+out:
1facf9fc 27423+ rerr = reinit_vdir(tgt);
27424+ BUG_ON(rerr);
27425+ return err;
27426+}
27427+
27428+int au_vdir_init(struct file *file)
27429+{
27430+ int err;
27431+ struct inode *inode;
27432+ struct au_vdir *vdir_cache, *allocated;
27433+
392086de 27434+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 27435+ err = read_vdir(file, !file->f_pos);
27436+ if (unlikely(err))
27437+ goto out;
27438+
27439+ allocated = NULL;
27440+ vdir_cache = au_fvdir_cache(file);
27441+ if (!vdir_cache) {
1308ab2a 27442+ vdir_cache = alloc_vdir(file);
1facf9fc 27443+ err = PTR_ERR(vdir_cache);
27444+ if (IS_ERR(vdir_cache))
27445+ goto out;
27446+ allocated = vdir_cache;
27447+ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
392086de 27448+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 27449+ err = reinit_vdir(vdir_cache);
27450+ if (unlikely(err))
27451+ goto out;
27452+ } else
27453+ return 0; /* success */
27454+
c06a8ce3 27455+ inode = file_inode(file);
1facf9fc 27456+ err = copy_vdir(vdir_cache, au_ivdir(inode));
27457+ if (!err) {
27458+ file->f_version = inode->i_version;
27459+ if (allocated)
27460+ au_set_fvdir_cache(file, allocated);
27461+ } else if (allocated)
27462+ au_vdir_free(allocated);
27463+
4f0767ce 27464+out:
1facf9fc 27465+ return err;
27466+}
27467+
27468+static loff_t calc_offset(struct au_vdir *vdir)
27469+{
27470+ loff_t offset;
27471+ union au_vdir_deblk_p p;
27472+
27473+ p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
27474+ offset = vdir->vd_last.p.deblk - p.deblk;
27475+ offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
27476+ return offset;
27477+}
27478+
27479+/* returns true or false */
392086de 27480+static int seek_vdir(struct file *file, struct dir_context *ctx)
1facf9fc 27481+{
27482+ int valid;
27483+ unsigned int deblk_sz;
27484+ unsigned long ul, n;
27485+ loff_t offset;
27486+ union au_vdir_deblk_p p, deblk_end;
27487+ struct au_vdir *vdir_cache;
27488+
27489+ valid = 1;
27490+ vdir_cache = au_fvdir_cache(file);
27491+ offset = calc_offset(vdir_cache);
27492+ AuDbg("offset %lld\n", offset);
392086de 27493+ if (ctx->pos == offset)
1facf9fc 27494+ goto out;
27495+
27496+ vdir_cache->vd_last.ul = 0;
27497+ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
392086de 27498+ if (!ctx->pos)
1facf9fc 27499+ goto out;
27500+
27501+ valid = 0;
27502+ deblk_sz = vdir_cache->vd_deblk_sz;
392086de 27503+ ul = div64_u64(ctx->pos, deblk_sz);
1facf9fc 27504+ AuDbg("ul %lu\n", ul);
27505+ if (ul >= vdir_cache->vd_nblk)
27506+ goto out;
27507+
27508+ n = vdir_cache->vd_nblk;
27509+ for (; ul < n; ul++) {
27510+ p.deblk = vdir_cache->vd_deblk[ul];
27511+ deblk_end.deblk = p.deblk + deblk_sz;
27512+ offset = ul;
27513+ offset *= deblk_sz;
392086de 27514+ while (!is_deblk_end(&p, &deblk_end) && offset < ctx->pos) {
1facf9fc 27515+ unsigned int l;
27516+
27517+ l = calc_size(p.de->de_str.len);
27518+ offset += l;
27519+ p.deblk += l;
27520+ }
27521+ if (!is_deblk_end(&p, &deblk_end)) {
27522+ valid = 1;
27523+ vdir_cache->vd_last.ul = ul;
27524+ vdir_cache->vd_last.p = p;
27525+ break;
27526+ }
27527+ }
27528+
4f0767ce 27529+out:
1facf9fc 27530+ /* smp_mb(); */
27531+ AuTraceErr(!valid);
27532+ return valid;
27533+}
27534+
392086de 27535+int au_vdir_fill_de(struct file *file, struct dir_context *ctx)
1facf9fc 27536+{
1facf9fc 27537+ unsigned int l, deblk_sz;
27538+ union au_vdir_deblk_p deblk_end;
27539+ struct au_vdir *vdir_cache;
27540+ struct au_vdir_de *de;
27541+
27542+ vdir_cache = au_fvdir_cache(file);
392086de 27543+ if (!seek_vdir(file, ctx))
1facf9fc 27544+ return 0;
27545+
27546+ deblk_sz = vdir_cache->vd_deblk_sz;
27547+ while (1) {
27548+ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
27549+ deblk_end.deblk += deblk_sz;
27550+ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
27551+ de = vdir_cache->vd_last.p.de;
27552+ AuDbg("%.*s, off%lld, i%lu, dt%d\n",
392086de 27553+ de->de_str.len, de->de_str.name, ctx->pos,
1facf9fc 27554+ (unsigned long)de->de_ino, de->de_type);
392086de
AM
27555+ if (unlikely(!dir_emit(ctx, de->de_str.name,
27556+ de->de_str.len, de->de_ino,
27557+ de->de_type))) {
1facf9fc 27558+ /* todo: ignore the error caused by udba? */
27559+ /* return err; */
27560+ return 0;
27561+ }
27562+
27563+ l = calc_size(de->de_str.len);
27564+ vdir_cache->vd_last.p.deblk += l;
392086de 27565+ ctx->pos += l;
1facf9fc 27566+ }
27567+ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
27568+ vdir_cache->vd_last.ul++;
27569+ vdir_cache->vd_last.p.deblk
27570+ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
392086de 27571+ ctx->pos = deblk_sz * vdir_cache->vd_last.ul;
1facf9fc 27572+ continue;
27573+ }
27574+ break;
27575+ }
27576+
27577+ /* smp_mb(); */
27578+ return 0;
27579+}
7f207e10
AM
27580diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
27581--- /usr/share/empty/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
27582+++ linux/fs/aufs/vfsub.c 2013-10-26 16:51:29.586298347 +0200
27583@@ -0,0 +1,772 @@
1facf9fc 27584+/*
7a9e40b8 27585+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 27586+ *
27587+ * This program, aufs is free software; you can redistribute it and/or modify
27588+ * it under the terms of the GNU General Public License as published by
27589+ * the Free Software Foundation; either version 2 of the License, or
27590+ * (at your option) any later version.
dece6358
AM
27591+ *
27592+ * This program is distributed in the hope that it will be useful,
27593+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27594+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27595+ * GNU General Public License for more details.
27596+ *
27597+ * You should have received a copy of the GNU General Public License
27598+ * along with this program; if not, write to the Free Software
27599+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 27600+ */
27601+
27602+/*
27603+ * sub-routines for VFS
27604+ */
27605+
1308ab2a 27606+#include <linux/ima.h>
dece6358
AM
27607+#include <linux/namei.h>
27608+#include <linux/security.h>
27609+#include <linux/splice.h>
1facf9fc 27610+#include "aufs.h"
27611+
27612+int vfsub_update_h_iattr(struct path *h_path, int *did)
27613+{
27614+ int err;
27615+ struct kstat st;
27616+ struct super_block *h_sb;
27617+
27618+ /* for remote fs, leave work for its getattr or d_revalidate */
27619+ /* for bad i_attr fs, handle them in aufs_getattr() */
27620+ /* still some fs may acquire i_mutex. we need to skip them */
27621+ err = 0;
27622+ if (!did)
27623+ did = &err;
27624+ h_sb = h_path->dentry->d_sb;
27625+ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
27626+ if (*did)
c06a8ce3 27627+ err = vfs_getattr(h_path, &st);
1facf9fc 27628+
27629+ return err;
27630+}
27631+
27632+/* ---------------------------------------------------------------------- */
27633+
4a4d8108 27634+struct file *vfsub_dentry_open(struct path *path, int flags)
1308ab2a 27635+{
27636+ struct file *file;
27637+
b4510431 27638+ file = dentry_open(path, flags /* | __FMODE_NONOTIFY */,
7f207e10 27639+ current_cred());
2cbb1c4b
JR
27640+ if (!IS_ERR_OR_NULL(file)
27641+ && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
27642+ i_readcount_inc(path->dentry->d_inode);
4a4d8108 27643+
1308ab2a 27644+ return file;
27645+}
27646+
1facf9fc 27647+struct file *vfsub_filp_open(const char *path, int oflags, int mode)
27648+{
27649+ struct file *file;
27650+
2cbb1c4b 27651+ lockdep_off();
7f207e10 27652+ file = filp_open(path,
2cbb1c4b 27653+ oflags /* | __FMODE_NONOTIFY */,
7f207e10 27654+ mode);
2cbb1c4b 27655+ lockdep_on();
1facf9fc 27656+ if (IS_ERR(file))
27657+ goto out;
27658+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
27659+
4f0767ce 27660+out:
1facf9fc 27661+ return file;
27662+}
27663+
27664+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
27665+{
27666+ int err;
27667+
1facf9fc 27668+ err = kern_path(name, flags, path);
1facf9fc 27669+ if (!err && path->dentry->d_inode)
27670+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
27671+ return err;
27672+}
27673+
27674+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
27675+ int len)
27676+{
27677+ struct path path = {
27678+ .mnt = NULL
27679+ };
27680+
1308ab2a 27681+ /* VFS checks it too, but by WARN_ON_ONCE() */
1facf9fc 27682+ IMustLock(parent->d_inode);
27683+
27684+ path.dentry = lookup_one_len(name, parent, len);
27685+ if (IS_ERR(path.dentry))
27686+ goto out;
27687+ if (path.dentry->d_inode)
27688+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
27689+
4f0767ce 27690+out:
4a4d8108 27691+ AuTraceErrPtr(path.dentry);
1facf9fc 27692+ return path.dentry;
27693+}
27694+
b4510431 27695+void vfsub_call_lkup_one(void *args)
2cbb1c4b 27696+{
b4510431
AM
27697+ struct vfsub_lkup_one_args *a = args;
27698+ *a->errp = vfsub_lkup_one(a->name, a->parent);
2cbb1c4b
JR
27699+}
27700+
1facf9fc 27701+/* ---------------------------------------------------------------------- */
27702+
27703+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
27704+ struct dentry *d2, struct au_hinode *hdir2)
27705+{
27706+ struct dentry *d;
27707+
2cbb1c4b 27708+ lockdep_off();
1facf9fc 27709+ d = lock_rename(d1, d2);
2cbb1c4b 27710+ lockdep_on();
4a4d8108 27711+ au_hn_suspend(hdir1);
1facf9fc 27712+ if (hdir1 != hdir2)
4a4d8108 27713+ au_hn_suspend(hdir2);
1facf9fc 27714+
27715+ return d;
27716+}
27717+
27718+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
27719+ struct dentry *d2, struct au_hinode *hdir2)
27720+{
4a4d8108 27721+ au_hn_resume(hdir1);
1facf9fc 27722+ if (hdir1 != hdir2)
4a4d8108 27723+ au_hn_resume(hdir2);
2cbb1c4b 27724+ lockdep_off();
1facf9fc 27725+ unlock_rename(d1, d2);
2cbb1c4b 27726+ lockdep_on();
1facf9fc 27727+}
27728+
27729+/* ---------------------------------------------------------------------- */
27730+
b4510431 27731+int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl)
1facf9fc 27732+{
27733+ int err;
27734+ struct dentry *d;
27735+
27736+ IMustLock(dir);
27737+
27738+ d = path->dentry;
27739+ path->dentry = d->d_parent;
b752ccd1 27740+ err = security_path_mknod(path, d, mode, 0);
1facf9fc 27741+ path->dentry = d;
27742+ if (unlikely(err))
27743+ goto out;
27744+
b4510431 27745+ err = vfs_create(dir, path->dentry, mode, want_excl);
1facf9fc 27746+ if (!err) {
27747+ struct path tmp = *path;
27748+ int did;
27749+
27750+ vfsub_update_h_iattr(&tmp, &did);
27751+ if (did) {
27752+ tmp.dentry = path->dentry->d_parent;
27753+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
27754+ }
27755+ /*ignore*/
27756+ }
27757+
4f0767ce 27758+out:
1facf9fc 27759+ return err;
27760+}
27761+
27762+int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
27763+{
27764+ int err;
27765+ struct dentry *d;
27766+
27767+ IMustLock(dir);
27768+
27769+ d = path->dentry;
27770+ path->dentry = d->d_parent;
b752ccd1 27771+ err = security_path_symlink(path, d, symname);
1facf9fc 27772+ path->dentry = d;
27773+ if (unlikely(err))
27774+ goto out;
27775+
27776+ err = vfs_symlink(dir, path->dentry, symname);
27777+ if (!err) {
27778+ struct path tmp = *path;
27779+ int did;
27780+
27781+ vfsub_update_h_iattr(&tmp, &did);
27782+ if (did) {
27783+ tmp.dentry = path->dentry->d_parent;
27784+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
27785+ }
27786+ /*ignore*/
27787+ }
27788+
4f0767ce 27789+out:
1facf9fc 27790+ return err;
27791+}
27792+
27793+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
27794+{
27795+ int err;
27796+ struct dentry *d;
27797+
27798+ IMustLock(dir);
27799+
27800+ d = path->dentry;
27801+ path->dentry = d->d_parent;
027c5e7a 27802+ err = security_path_mknod(path, d, mode, new_encode_dev(dev));
1facf9fc 27803+ path->dentry = d;
27804+ if (unlikely(err))
27805+ goto out;
27806+
27807+ err = vfs_mknod(dir, path->dentry, mode, dev);
27808+ if (!err) {
27809+ struct path tmp = *path;
27810+ int did;
27811+
27812+ vfsub_update_h_iattr(&tmp, &did);
27813+ if (did) {
27814+ tmp.dentry = path->dentry->d_parent;
27815+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
27816+ }
27817+ /*ignore*/
27818+ }
27819+
4f0767ce 27820+out:
1facf9fc 27821+ return err;
27822+}
27823+
27824+static int au_test_nlink(struct inode *inode)
27825+{
27826+ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
27827+
27828+ if (!au_test_fs_no_limit_nlink(inode->i_sb)
27829+ || inode->i_nlink < link_max)
27830+ return 0;
27831+ return -EMLINK;
27832+}
27833+
27834+int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path)
27835+{
27836+ int err;
27837+ struct dentry *d;
27838+
27839+ IMustLock(dir);
27840+
27841+ err = au_test_nlink(src_dentry->d_inode);
27842+ if (unlikely(err))
27843+ return err;
27844+
b4510431 27845+ /* we don't call may_linkat() */
1facf9fc 27846+ d = path->dentry;
27847+ path->dentry = d->d_parent;
b752ccd1 27848+ err = security_path_link(src_dentry, path, d);
1facf9fc 27849+ path->dentry = d;
27850+ if (unlikely(err))
27851+ goto out;
27852+
2cbb1c4b 27853+ lockdep_off();
1facf9fc 27854+ err = vfs_link(src_dentry, dir, path->dentry);
2cbb1c4b 27855+ lockdep_on();
1facf9fc 27856+ if (!err) {
27857+ struct path tmp = *path;
27858+ int did;
27859+
27860+ /* fuse has different memory inode for the same inumber */
27861+ vfsub_update_h_iattr(&tmp, &did);
27862+ if (did) {
27863+ tmp.dentry = path->dentry->d_parent;
27864+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
27865+ tmp.dentry = src_dentry;
27866+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
27867+ }
27868+ /*ignore*/
27869+ }
27870+
4f0767ce 27871+out:
1facf9fc 27872+ return err;
27873+}
27874+
27875+int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
27876+ struct inode *dir, struct path *path)
27877+{
27878+ int err;
27879+ struct path tmp = {
27880+ .mnt = path->mnt
27881+ };
27882+ struct dentry *d;
27883+
27884+ IMustLock(dir);
27885+ IMustLock(src_dir);
27886+
27887+ d = path->dentry;
27888+ path->dentry = d->d_parent;
27889+ tmp.dentry = src_dentry->d_parent;
b752ccd1 27890+ err = security_path_rename(&tmp, src_dentry, path, d);
1facf9fc 27891+ path->dentry = d;
27892+ if (unlikely(err))
27893+ goto out;
27894+
2cbb1c4b 27895+ lockdep_off();
1facf9fc 27896+ err = vfs_rename(src_dir, src_dentry, dir, path->dentry);
2cbb1c4b 27897+ lockdep_on();
1facf9fc 27898+ if (!err) {
27899+ int did;
27900+
27901+ tmp.dentry = d->d_parent;
27902+ vfsub_update_h_iattr(&tmp, &did);
27903+ if (did) {
27904+ tmp.dentry = src_dentry;
27905+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
27906+ tmp.dentry = src_dentry->d_parent;
27907+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
27908+ }
27909+ /*ignore*/
27910+ }
27911+
4f0767ce 27912+out:
1facf9fc 27913+ return err;
27914+}
27915+
27916+int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
27917+{
27918+ int err;
27919+ struct dentry *d;
27920+
27921+ IMustLock(dir);
27922+
27923+ d = path->dentry;
27924+ path->dentry = d->d_parent;
b752ccd1 27925+ err = security_path_mkdir(path, d, mode);
1facf9fc 27926+ path->dentry = d;
27927+ if (unlikely(err))
27928+ goto out;
27929+
27930+ err = vfs_mkdir(dir, path->dentry, mode);
27931+ if (!err) {
27932+ struct path tmp = *path;
27933+ int did;
27934+
27935+ vfsub_update_h_iattr(&tmp, &did);
27936+ if (did) {
27937+ tmp.dentry = path->dentry->d_parent;
27938+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
27939+ }
27940+ /*ignore*/
27941+ }
27942+
4f0767ce 27943+out:
1facf9fc 27944+ return err;
27945+}
27946+
27947+int vfsub_rmdir(struct inode *dir, struct path *path)
27948+{
27949+ int err;
27950+ struct dentry *d;
27951+
27952+ IMustLock(dir);
27953+
27954+ d = path->dentry;
27955+ path->dentry = d->d_parent;
b752ccd1 27956+ err = security_path_rmdir(path, d);
1facf9fc 27957+ path->dentry = d;
27958+ if (unlikely(err))
27959+ goto out;
27960+
2cbb1c4b 27961+ lockdep_off();
1facf9fc 27962+ err = vfs_rmdir(dir, path->dentry);
2cbb1c4b 27963+ lockdep_on();
1facf9fc 27964+ if (!err) {
27965+ struct path tmp = {
27966+ .dentry = path->dentry->d_parent,
27967+ .mnt = path->mnt
27968+ };
27969+
27970+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
27971+ }
27972+
4f0767ce 27973+out:
1facf9fc 27974+ return err;
27975+}
27976+
27977+/* ---------------------------------------------------------------------- */
27978+
9dbd164d 27979+/* todo: support mmap_sem? */
1facf9fc 27980+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
27981+ loff_t *ppos)
27982+{
27983+ ssize_t err;
27984+
2cbb1c4b 27985+ lockdep_off();
1facf9fc 27986+ err = vfs_read(file, ubuf, count, ppos);
2cbb1c4b 27987+ lockdep_on();
1facf9fc 27988+ if (err >= 0)
27989+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
27990+ return err;
27991+}
27992+
27993+/* todo: kernel_read()? */
27994+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
27995+ loff_t *ppos)
27996+{
27997+ ssize_t err;
27998+ mm_segment_t oldfs;
b752ccd1
AM
27999+ union {
28000+ void *k;
28001+ char __user *u;
28002+ } buf;
1facf9fc 28003+
b752ccd1 28004+ buf.k = kbuf;
1facf9fc 28005+ oldfs = get_fs();
28006+ set_fs(KERNEL_DS);
b752ccd1 28007+ err = vfsub_read_u(file, buf.u, count, ppos);
1facf9fc 28008+ set_fs(oldfs);
28009+ return err;
28010+}
28011+
28012+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
28013+ loff_t *ppos)
28014+{
28015+ ssize_t err;
28016+
2cbb1c4b 28017+ lockdep_off();
1facf9fc 28018+ err = vfs_write(file, ubuf, count, ppos);
2cbb1c4b 28019+ lockdep_on();
1facf9fc 28020+ if (err >= 0)
28021+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
28022+ return err;
28023+}
28024+
28025+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
28026+{
28027+ ssize_t err;
28028+ mm_segment_t oldfs;
b752ccd1
AM
28029+ union {
28030+ void *k;
28031+ const char __user *u;
28032+ } buf;
1facf9fc 28033+
b752ccd1 28034+ buf.k = kbuf;
1facf9fc 28035+ oldfs = get_fs();
28036+ set_fs(KERNEL_DS);
b752ccd1 28037+ err = vfsub_write_u(file, buf.u, count, ppos);
1facf9fc 28038+ set_fs(oldfs);
28039+ return err;
28040+}
28041+
4a4d8108
AM
28042+int vfsub_flush(struct file *file, fl_owner_t id)
28043+{
28044+ int err;
28045+
28046+ err = 0;
28047+ if (file->f_op && file->f_op->flush) {
2cbb1c4b
JR
28048+ if (!au_test_nfs(file->f_dentry->d_sb))
28049+ err = file->f_op->flush(file, id);
28050+ else {
28051+ lockdep_off();
28052+ err = file->f_op->flush(file, id);
28053+ lockdep_on();
28054+ }
4a4d8108
AM
28055+ if (!err)
28056+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
28057+ /*ignore*/
28058+ }
28059+ return err;
28060+}
28061+
392086de 28062+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx)
1facf9fc 28063+{
28064+ int err;
28065+
392086de
AM
28066+ AuDbg("%.*s, ctx{%pf, %llu}\n",
28067+ AuDLNPair(file->f_dentry), ctx->actor, ctx->pos);
28068+
2cbb1c4b 28069+ lockdep_off();
392086de 28070+ err = iterate_dir(file, ctx);
2cbb1c4b 28071+ lockdep_on();
1facf9fc 28072+ if (err >= 0)
28073+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
28074+ return err;
28075+}
28076+
28077+long vfsub_splice_to(struct file *in, loff_t *ppos,
28078+ struct pipe_inode_info *pipe, size_t len,
28079+ unsigned int flags)
28080+{
28081+ long err;
28082+
2cbb1c4b 28083+ lockdep_off();
0fc653ad 28084+ err = do_splice_to(in, ppos, pipe, len, flags);
2cbb1c4b 28085+ lockdep_on();
4a4d8108 28086+ file_accessed(in);
1facf9fc 28087+ if (err >= 0)
28088+ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
28089+ return err;
28090+}
28091+
28092+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
28093+ loff_t *ppos, size_t len, unsigned int flags)
28094+{
28095+ long err;
28096+
2cbb1c4b 28097+ lockdep_off();
0fc653ad 28098+ err = do_splice_from(pipe, out, ppos, len, flags);
2cbb1c4b 28099+ lockdep_on();
1facf9fc 28100+ if (err >= 0)
28101+ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
28102+ return err;
28103+}
28104+
53392da6
AM
28105+int vfsub_fsync(struct file *file, struct path *path, int datasync)
28106+{
28107+ int err;
28108+
28109+ /* file can be NULL */
28110+ lockdep_off();
28111+ err = vfs_fsync(file, datasync);
28112+ lockdep_on();
28113+ if (!err) {
28114+ if (!path) {
28115+ AuDebugOn(!file);
28116+ path = &file->f_path;
28117+ }
28118+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
28119+ }
28120+ return err;
28121+}
28122+
1facf9fc 28123+/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
28124+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
28125+ struct file *h_file)
28126+{
28127+ int err;
28128+ struct inode *h_inode;
c06a8ce3 28129+ struct super_block *h_sb;
1facf9fc 28130+
1facf9fc 28131+ if (!h_file) {
c06a8ce3
AM
28132+ err = vfsub_truncate(h_path, length);
28133+ goto out;
1facf9fc 28134+ }
28135+
c06a8ce3
AM
28136+ h_inode = h_path->dentry->d_inode;
28137+ h_sb = h_inode->i_sb;
28138+ lockdep_off();
28139+ sb_start_write(h_sb);
28140+ lockdep_on();
1facf9fc 28141+ err = locks_verify_truncate(h_inode, h_file, length);
28142+ if (!err)
953406b4 28143+ err = security_path_truncate(h_path);
2cbb1c4b
JR
28144+ if (!err) {
28145+ lockdep_off();
1facf9fc 28146+ err = do_truncate(h_path->dentry, length, attr, h_file);
2cbb1c4b
JR
28147+ lockdep_on();
28148+ }
c06a8ce3
AM
28149+ lockdep_off();
28150+ sb_end_write(h_sb);
28151+ lockdep_on();
1facf9fc 28152+
4f0767ce 28153+out:
1facf9fc 28154+ return err;
28155+}
28156+
28157+/* ---------------------------------------------------------------------- */
28158+
28159+struct au_vfsub_mkdir_args {
28160+ int *errp;
28161+ struct inode *dir;
28162+ struct path *path;
28163+ int mode;
28164+};
28165+
28166+static void au_call_vfsub_mkdir(void *args)
28167+{
28168+ struct au_vfsub_mkdir_args *a = args;
28169+ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
28170+}
28171+
28172+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
28173+{
28174+ int err, do_sio, wkq_err;
28175+
28176+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
28177+ if (!do_sio)
28178+ err = vfsub_mkdir(dir, path, mode);
28179+ else {
28180+ struct au_vfsub_mkdir_args args = {
28181+ .errp = &err,
28182+ .dir = dir,
28183+ .path = path,
28184+ .mode = mode
28185+ };
28186+ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
28187+ if (unlikely(wkq_err))
28188+ err = wkq_err;
28189+ }
28190+
28191+ return err;
28192+}
28193+
28194+struct au_vfsub_rmdir_args {
28195+ int *errp;
28196+ struct inode *dir;
28197+ struct path *path;
28198+};
28199+
28200+static void au_call_vfsub_rmdir(void *args)
28201+{
28202+ struct au_vfsub_rmdir_args *a = args;
28203+ *a->errp = vfsub_rmdir(a->dir, a->path);
28204+}
28205+
28206+int vfsub_sio_rmdir(struct inode *dir, struct path *path)
28207+{
28208+ int err, do_sio, wkq_err;
28209+
28210+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
28211+ if (!do_sio)
28212+ err = vfsub_rmdir(dir, path);
28213+ else {
28214+ struct au_vfsub_rmdir_args args = {
28215+ .errp = &err,
28216+ .dir = dir,
28217+ .path = path
28218+ };
28219+ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
28220+ if (unlikely(wkq_err))
28221+ err = wkq_err;
28222+ }
28223+
28224+ return err;
28225+}
28226+
28227+/* ---------------------------------------------------------------------- */
28228+
28229+struct notify_change_args {
28230+ int *errp;
28231+ struct path *path;
28232+ struct iattr *ia;
28233+};
28234+
28235+static void call_notify_change(void *args)
28236+{
28237+ struct notify_change_args *a = args;
28238+ struct inode *h_inode;
28239+
28240+ h_inode = a->path->dentry->d_inode;
28241+ IMustLock(h_inode);
28242+
28243+ *a->errp = -EPERM;
28244+ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
1facf9fc 28245+ *a->errp = notify_change(a->path->dentry, a->ia);
1facf9fc 28246+ if (!*a->errp)
28247+ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
28248+ }
28249+ AuTraceErr(*a->errp);
28250+}
28251+
28252+int vfsub_notify_change(struct path *path, struct iattr *ia)
28253+{
28254+ int err;
28255+ struct notify_change_args args = {
28256+ .errp = &err,
28257+ .path = path,
28258+ .ia = ia
28259+ };
28260+
28261+ call_notify_change(&args);
28262+
28263+ return err;
28264+}
28265+
28266+int vfsub_sio_notify_change(struct path *path, struct iattr *ia)
28267+{
28268+ int err, wkq_err;
28269+ struct notify_change_args args = {
28270+ .errp = &err,
28271+ .path = path,
28272+ .ia = ia
28273+ };
28274+
28275+ wkq_err = au_wkq_wait(call_notify_change, &args);
28276+ if (unlikely(wkq_err))
28277+ err = wkq_err;
28278+
28279+ return err;
28280+}
28281+
28282+/* ---------------------------------------------------------------------- */
28283+
28284+struct unlink_args {
28285+ int *errp;
28286+ struct inode *dir;
28287+ struct path *path;
28288+};
28289+
28290+static void call_unlink(void *args)
28291+{
28292+ struct unlink_args *a = args;
28293+ struct dentry *d = a->path->dentry;
28294+ struct inode *h_inode;
28295+ const int stop_sillyrename = (au_test_nfs(d->d_sb)
392086de 28296+ && d_count(d) == 1);
1facf9fc 28297+
28298+ IMustLock(a->dir);
28299+
28300+ a->path->dentry = d->d_parent;
28301+ *a->errp = security_path_unlink(a->path, d);
28302+ a->path->dentry = d;
28303+ if (unlikely(*a->errp))
28304+ return;
28305+
28306+ if (!stop_sillyrename)
28307+ dget(d);
28308+ h_inode = d->d_inode;
28309+ if (h_inode)
027c5e7a 28310+ ihold(h_inode);
1facf9fc 28311+
2cbb1c4b 28312+ lockdep_off();
1facf9fc 28313+ *a->errp = vfs_unlink(a->dir, d);
2cbb1c4b 28314+ lockdep_on();
1facf9fc 28315+ if (!*a->errp) {
28316+ struct path tmp = {
28317+ .dentry = d->d_parent,
28318+ .mnt = a->path->mnt
28319+ };
28320+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
28321+ }
28322+
28323+ if (!stop_sillyrename)
28324+ dput(d);
28325+ if (h_inode)
28326+ iput(h_inode);
28327+
28328+ AuTraceErr(*a->errp);
28329+}
28330+
28331+/*
28332+ * @dir: must be locked.
28333+ * @dentry: target dentry.
28334+ */
28335+int vfsub_unlink(struct inode *dir, struct path *path, int force)
28336+{
28337+ int err;
28338+ struct unlink_args args = {
28339+ .errp = &err,
28340+ .dir = dir,
28341+ .path = path
28342+ };
28343+
28344+ if (!force)
28345+ call_unlink(&args);
28346+ else {
28347+ int wkq_err;
28348+
28349+ wkq_err = au_wkq_wait(call_unlink, &args);
28350+ if (unlikely(wkq_err))
28351+ err = wkq_err;
28352+ }
28353+
28354+ return err;
28355+}
7f207e10
AM
28356diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
28357--- /usr/share/empty/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
392086de
AM
28358+++ linux/fs/aufs/vfsub.h 2013-10-26 16:51:32.276373845 +0200
28359@@ -0,0 +1,312 @@
1facf9fc 28360+/*
7a9e40b8 28361+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 28362+ *
28363+ * This program, aufs is free software; you can redistribute it and/or modify
28364+ * it under the terms of the GNU General Public License as published by
28365+ * the Free Software Foundation; either version 2 of the License, or
28366+ * (at your option) any later version.
dece6358
AM
28367+ *
28368+ * This program is distributed in the hope that it will be useful,
28369+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28370+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28371+ * GNU General Public License for more details.
28372+ *
28373+ * You should have received a copy of the GNU General Public License
28374+ * along with this program; if not, write to the Free Software
28375+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 28376+ */
28377+
28378+/*
28379+ * sub-routines for VFS
28380+ */
28381+
28382+#ifndef __AUFS_VFSUB_H__
28383+#define __AUFS_VFSUB_H__
28384+
28385+#ifdef __KERNEL__
28386+
28387+#include <linux/fs.h>
0c5527e5 28388+#include <linux/lglock.h>
b4510431 28389+#include <linux/mount.h>
7f207e10 28390+#include "debug.h"
1facf9fc 28391+
7f207e10 28392+/* copied from linux/fs/internal.h */
2cbb1c4b 28393+/* todo: BAD approach!! */
0c3ec466 28394+extern struct lglock vfsmount_lock;
c06a8ce3 28395+extern void __mnt_drop_write(struct vfsmount *);
2cbb1c4b 28396+extern spinlock_t inode_sb_list_lock;
392086de 28397+void __file_sb_list_add(struct file *file, struct super_block *sb);
0c5527e5 28398+
7f207e10 28399+/* copied from linux/fs/file_table.c */
0c3ec466 28400+extern struct lglock files_lglock;
0c5527e5
AM
28401+#ifdef CONFIG_SMP
28402+/*
28403+ * These macros iterate all files on all CPUs for a given superblock.
28404+ * files_lglock must be held globally.
28405+ */
28406+#define do_file_list_for_each_entry(__sb, __file) \
28407+{ \
28408+ int i; \
28409+ for_each_possible_cpu(i) { \
28410+ struct list_head *list; \
28411+ list = per_cpu_ptr((__sb)->s_files, i); \
28412+ list_for_each_entry((__file), list, f_u.fu_list)
28413+
28414+#define while_file_list_for_each_entry \
28415+ } \
28416+}
28417+
28418+#else
28419+
28420+#define do_file_list_for_each_entry(__sb, __file) \
28421+{ \
28422+ struct list_head *list; \
28423+ list = &(sb)->s_files; \
28424+ list_for_each_entry((__file), list, f_u.fu_list)
28425+
28426+#define while_file_list_for_each_entry \
28427+}
7f207e10
AM
28428+#endif
28429+
28430+/* ---------------------------------------------------------------------- */
1facf9fc 28431+
28432+/* lock subclass for lower inode */
28433+/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
28434+/* reduce? gave up. */
28435+enum {
28436+ AuLsc_I_Begin = I_MUTEX_QUOTA, /* 4 */
28437+ AuLsc_I_PARENT, /* lower inode, parent first */
28438+ AuLsc_I_PARENT2, /* copyup dirs */
dece6358 28439+ AuLsc_I_PARENT3, /* copyup wh */
1facf9fc 28440+ AuLsc_I_CHILD,
28441+ AuLsc_I_CHILD2,
28442+ AuLsc_I_End
28443+};
28444+
28445+/* to debug easier, do not make them inlined functions */
28446+#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
28447+#define IMustLock(i) MtxMustLock(&(i)->i_mutex)
28448+
28449+/* ---------------------------------------------------------------------- */
28450+
7f207e10
AM
28451+static inline void vfsub_drop_nlink(struct inode *inode)
28452+{
28453+ AuDebugOn(!inode->i_nlink);
28454+ drop_nlink(inode);
28455+}
28456+
027c5e7a
AM
28457+static inline void vfsub_dead_dir(struct inode *inode)
28458+{
28459+ AuDebugOn(!S_ISDIR(inode->i_mode));
28460+ inode->i_flags |= S_DEAD;
28461+ clear_nlink(inode);
28462+}
28463+
392086de
AM
28464+static inline int vfsub_native_ro(struct inode *inode)
28465+{
28466+ return (inode->i_sb->s_flags & MS_RDONLY)
28467+ || IS_RDONLY(inode)
28468+ /* || IS_APPEND(inode) */
28469+ || IS_IMMUTABLE(inode);
28470+}
28471+
7f207e10
AM
28472+/* ---------------------------------------------------------------------- */
28473+
28474+int vfsub_update_h_iattr(struct path *h_path, int *did);
28475+struct file *vfsub_dentry_open(struct path *path, int flags);
28476+struct file *vfsub_filp_open(const char *path, int oflags, int mode);
1facf9fc 28477+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
b4510431 28478+
1facf9fc 28479+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
28480+ int len);
b4510431
AM
28481+
28482+struct vfsub_lkup_one_args {
28483+ struct dentry **errp;
28484+ struct qstr *name;
28485+ struct dentry *parent;
28486+};
28487+
28488+static inline struct dentry *vfsub_lkup_one(struct qstr *name,
28489+ struct dentry *parent)
28490+{
28491+ return vfsub_lookup_one_len(name->name, parent, name->len);
28492+}
28493+
28494+void vfsub_call_lkup_one(void *args);
28495+
28496+/* ---------------------------------------------------------------------- */
28497+
28498+static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
28499+{
28500+ int err;
28501+ lockdep_off();
28502+ err = mnt_want_write(mnt);
28503+ lockdep_on();
28504+ return err;
28505+}
28506+
28507+static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
28508+{
28509+ lockdep_off();
28510+ mnt_drop_write(mnt);
28511+ lockdep_on();
28512+}
1facf9fc 28513+
c06a8ce3
AM
28514+static inline void vfsub_mnt_drop_write_file(struct file *file)
28515+{
28516+ lockdep_off();
28517+ mnt_drop_write_file(file);
28518+ lockdep_on();
28519+}
28520+
1facf9fc 28521+/* ---------------------------------------------------------------------- */
28522+
28523+struct au_hinode;
28524+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
28525+ struct dentry *d2, struct au_hinode *hdir2);
28526+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
28527+ struct dentry *d2, struct au_hinode *hdir2);
28528+
537831f9
AM
28529+int vfsub_create(struct inode *dir, struct path *path, int mode,
28530+ bool want_excl);
1facf9fc 28531+int vfsub_symlink(struct inode *dir, struct path *path,
28532+ const char *symname);
28533+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
28534+int vfsub_link(struct dentry *src_dentry, struct inode *dir,
28535+ struct path *path);
28536+int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
28537+ struct inode *hdir, struct path *path);
28538+int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
28539+int vfsub_rmdir(struct inode *dir, struct path *path);
28540+
28541+/* ---------------------------------------------------------------------- */
28542+
28543+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
28544+ loff_t *ppos);
28545+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
28546+ loff_t *ppos);
28547+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
28548+ loff_t *ppos);
28549+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
28550+ loff_t *ppos);
4a4d8108 28551+int vfsub_flush(struct file *file, fl_owner_t id);
392086de
AM
28552+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx);
28553+
28554+/* just for type-check */
28555+static inline filldir_t au_diractor(int (*func)(struct dir_context *,
28556+ const char *, int, loff_t, u64,
28557+ unsigned))
28558+{
28559+ return (filldir_t)func;
28560+}
28561+
1facf9fc 28562+
c06a8ce3
AM
28563+static inline loff_t vfsub_f_size_read(struct file *file)
28564+{
28565+ return i_size_read(file_inode(file));
28566+}
28567+
4a4d8108
AM
28568+static inline unsigned int vfsub_file_flags(struct file *file)
28569+{
28570+ unsigned int flags;
28571+
28572+ spin_lock(&file->f_lock);
28573+ flags = file->f_flags;
28574+ spin_unlock(&file->f_lock);
28575+
28576+ return flags;
28577+}
1308ab2a 28578+
1facf9fc 28579+static inline void vfsub_file_accessed(struct file *h_file)
28580+{
28581+ file_accessed(h_file);
28582+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
28583+}
28584+
28585+static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
28586+ struct dentry *h_dentry)
28587+{
28588+ struct path h_path = {
28589+ .dentry = h_dentry,
28590+ .mnt = h_mnt
28591+ };
92d182d2 28592+ touch_atime(&h_path);
1facf9fc 28593+ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
28594+}
28595+
0c3ec466
AM
28596+static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts,
28597+ int flags)
28598+{
28599+ return update_time(h_inode, ts, flags);
28600+ /* no vfsub_update_h_iattr() since we don't have struct path */
28601+}
28602+
4a4d8108
AM
28603+long vfsub_splice_to(struct file *in, loff_t *ppos,
28604+ struct pipe_inode_info *pipe, size_t len,
28605+ unsigned int flags);
28606+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
28607+ loff_t *ppos, size_t len, unsigned int flags);
c06a8ce3
AM
28608+
28609+static inline long vfsub_truncate(struct path *path, loff_t length)
28610+{
28611+ long err;
28612+ lockdep_off();
28613+ err = vfs_truncate(path, length);
28614+ lockdep_on();
28615+ return err;
28616+}
28617+
4a4d8108
AM
28618+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
28619+ struct file *h_file);
53392da6 28620+int vfsub_fsync(struct file *file, struct path *path, int datasync);
4a4d8108 28621+
1facf9fc 28622+/* ---------------------------------------------------------------------- */
28623+
28624+static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
28625+{
28626+ loff_t err;
28627+
2cbb1c4b 28628+ lockdep_off();
1facf9fc 28629+ err = vfs_llseek(file, offset, origin);
2cbb1c4b 28630+ lockdep_on();
1facf9fc 28631+ return err;
28632+}
28633+
28634+/* ---------------------------------------------------------------------- */
28635+
28636+/* dirty workaround for strict type of fmode_t */
28637+union vfsub_fmu {
28638+ fmode_t fm;
28639+ unsigned int ui;
28640+};
28641+
28642+static inline unsigned int vfsub_fmode_to_uint(fmode_t fm)
28643+{
28644+ union vfsub_fmu u = {
28645+ .fm = fm
28646+ };
28647+
28648+ BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui));
28649+
28650+ return u.ui;
28651+}
28652+
28653+static inline fmode_t vfsub_uint_to_fmode(unsigned int ui)
28654+{
28655+ union vfsub_fmu u = {
28656+ .ui = ui
28657+ };
28658+
28659+ return u.fm;
28660+}
28661+
4a4d8108
AM
28662+/* ---------------------------------------------------------------------- */
28663+
28664+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
28665+int vfsub_sio_rmdir(struct inode *dir, struct path *path);
28666+int vfsub_sio_notify_change(struct path *path, struct iattr *ia);
28667+int vfsub_notify_change(struct path *path, struct iattr *ia);
28668+int vfsub_unlink(struct inode *dir, struct path *path, int force);
28669+
1facf9fc 28670+#endif /* __KERNEL__ */
28671+#endif /* __AUFS_VFSUB_H__ */
7f207e10
AM
28672diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
28673--- /usr/share/empty/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
28674+++ linux/fs/aufs/wbr_policy.c 2013-10-26 16:51:32.276373845 +0200
28675@@ -0,0 +1,756 @@
1facf9fc 28676+/*
7a9e40b8 28677+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 28678+ *
28679+ * This program, aufs is free software; you can redistribute it and/or modify
28680+ * it under the terms of the GNU General Public License as published by
28681+ * the Free Software Foundation; either version 2 of the License, or
28682+ * (at your option) any later version.
dece6358
AM
28683+ *
28684+ * This program is distributed in the hope that it will be useful,
28685+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28686+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28687+ * GNU General Public License for more details.
28688+ *
28689+ * You should have received a copy of the GNU General Public License
28690+ * along with this program; if not, write to the Free Software
28691+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 28692+ */
28693+
28694+/*
28695+ * policies for selecting one among multiple writable branches
28696+ */
28697+
28698+#include <linux/statfs.h>
28699+#include "aufs.h"
28700+
28701+/* subset of cpup_attr() */
28702+static noinline_for_stack
28703+int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
28704+{
28705+ int err, sbits;
28706+ struct iattr ia;
28707+ struct inode *h_isrc;
28708+
28709+ h_isrc = h_src->d_inode;
28710+ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
28711+ ia.ia_mode = h_isrc->i_mode;
28712+ ia.ia_uid = h_isrc->i_uid;
28713+ ia.ia_gid = h_isrc->i_gid;
28714+ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
86dc4139 28715+ au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc->i_flags);
1facf9fc 28716+ err = vfsub_sio_notify_change(h_path, &ia);
28717+
28718+ /* is this nfs only? */
28719+ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
28720+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
28721+ ia.ia_mode = h_isrc->i_mode;
28722+ err = vfsub_sio_notify_change(h_path, &ia);
28723+ }
28724+
28725+ return err;
28726+}
28727+
28728+#define AuCpdown_PARENT_OPQ 1
28729+#define AuCpdown_WHED (1 << 1)
28730+#define AuCpdown_MADE_DIR (1 << 2)
28731+#define AuCpdown_DIROPQ (1 << 3)
28732+#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name)
7f207e10
AM
28733+#define au_fset_cpdown(flags, name) \
28734+ do { (flags) |= AuCpdown_##name; } while (0)
28735+#define au_fclr_cpdown(flags, name) \
28736+ do { (flags) &= ~AuCpdown_##name; } while (0)
1facf9fc 28737+
1facf9fc 28738+static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
c2b27bf2 28739+ unsigned int *flags)
1facf9fc 28740+{
28741+ int err;
28742+ struct dentry *opq_dentry;
28743+
28744+ opq_dentry = au_diropq_create(dentry, bdst);
28745+ err = PTR_ERR(opq_dentry);
28746+ if (IS_ERR(opq_dentry))
28747+ goto out;
28748+ dput(opq_dentry);
c2b27bf2 28749+ au_fset_cpdown(*flags, DIROPQ);
1facf9fc 28750+
4f0767ce 28751+out:
1facf9fc 28752+ return err;
28753+}
28754+
28755+static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
28756+ struct inode *dir, aufs_bindex_t bdst)
28757+{
28758+ int err;
28759+ struct path h_path;
28760+ struct au_branch *br;
28761+
28762+ br = au_sbr(dentry->d_sb, bdst);
28763+ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
28764+ err = PTR_ERR(h_path.dentry);
28765+ if (IS_ERR(h_path.dentry))
28766+ goto out;
28767+
28768+ err = 0;
28769+ if (h_path.dentry->d_inode) {
86dc4139 28770+ h_path.mnt = au_br_mnt(br);
1facf9fc 28771+ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
28772+ dentry);
28773+ }
28774+ dput(h_path.dentry);
28775+
4f0767ce 28776+out:
1facf9fc 28777+ return err;
28778+}
28779+
28780+static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 28781+ struct au_pin *pin,
1facf9fc 28782+ struct dentry *h_parent, void *arg)
28783+{
28784+ int err, rerr;
4a4d8108 28785+ aufs_bindex_t bopq, bstart;
1facf9fc 28786+ struct path h_path;
28787+ struct dentry *parent;
28788+ struct inode *h_dir, *h_inode, *inode, *dir;
c2b27bf2 28789+ unsigned int *flags = arg;
1facf9fc 28790+
28791+ bstart = au_dbstart(dentry);
28792+ /* dentry is di-locked */
28793+ parent = dget_parent(dentry);
28794+ dir = parent->d_inode;
28795+ h_dir = h_parent->d_inode;
28796+ AuDebugOn(h_dir != au_h_iptr(dir, bdst));
28797+ IMustLock(h_dir);
28798+
86dc4139 28799+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
1facf9fc 28800+ if (unlikely(err < 0))
28801+ goto out;
28802+ h_path.dentry = au_h_dptr(dentry, bdst);
28803+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
28804+ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path,
28805+ S_IRWXU | S_IRUGO | S_IXUGO);
28806+ if (unlikely(err))
28807+ goto out_put;
c2b27bf2 28808+ au_fset_cpdown(*flags, MADE_DIR);
1facf9fc 28809+
1facf9fc 28810+ bopq = au_dbdiropq(dentry);
c2b27bf2
AM
28811+ au_fclr_cpdown(*flags, WHED);
28812+ au_fclr_cpdown(*flags, DIROPQ);
1facf9fc 28813+ if (au_dbwh(dentry) == bdst)
c2b27bf2
AM
28814+ au_fset_cpdown(*flags, WHED);
28815+ if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst)
28816+ au_fset_cpdown(*flags, PARENT_OPQ);
1facf9fc 28817+ h_inode = h_path.dentry->d_inode;
28818+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
c2b27bf2
AM
28819+ if (au_ftest_cpdown(*flags, WHED)) {
28820+ err = au_cpdown_dir_opq(dentry, bdst, flags);
1facf9fc 28821+ if (unlikely(err)) {
28822+ mutex_unlock(&h_inode->i_mutex);
28823+ goto out_dir;
28824+ }
28825+ }
28826+
28827+ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart));
28828+ mutex_unlock(&h_inode->i_mutex);
28829+ if (unlikely(err))
28830+ goto out_opq;
28831+
c2b27bf2 28832+ if (au_ftest_cpdown(*flags, WHED)) {
1facf9fc 28833+ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
28834+ if (unlikely(err))
28835+ goto out_opq;
28836+ }
28837+
28838+ inode = dentry->d_inode;
28839+ if (au_ibend(inode) < bdst)
28840+ au_set_ibend(inode, bdst);
28841+ au_set_h_iptr(inode, bdst, au_igrab(h_inode),
28842+ au_hi_flags(inode, /*isdir*/1));
28843+ goto out; /* success */
28844+
28845+ /* revert */
4f0767ce 28846+out_opq:
c2b27bf2 28847+ if (au_ftest_cpdown(*flags, DIROPQ)) {
1facf9fc 28848+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
28849+ rerr = au_diropq_remove(dentry, bdst);
28850+ mutex_unlock(&h_inode->i_mutex);
28851+ if (unlikely(rerr)) {
28852+ AuIOErr("failed removing diropq for %.*s b%d (%d)\n",
28853+ AuDLNPair(dentry), bdst, rerr);
28854+ err = -EIO;
28855+ goto out;
28856+ }
28857+ }
4f0767ce 28858+out_dir:
c2b27bf2 28859+ if (au_ftest_cpdown(*flags, MADE_DIR)) {
1facf9fc 28860+ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
28861+ if (unlikely(rerr)) {
28862+ AuIOErr("failed removing %.*s b%d (%d)\n",
28863+ AuDLNPair(dentry), bdst, rerr);
28864+ err = -EIO;
28865+ }
28866+ }
4f0767ce 28867+out_put:
1facf9fc 28868+ au_set_h_dptr(dentry, bdst, NULL);
28869+ if (au_dbend(dentry) == bdst)
28870+ au_update_dbend(dentry);
4f0767ce 28871+out:
1facf9fc 28872+ dput(parent);
28873+ return err;
28874+}
28875+
28876+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
28877+{
28878+ int err;
c2b27bf2 28879+ unsigned int flags;
1facf9fc 28880+
c2b27bf2
AM
28881+ flags = 0;
28882+ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &flags);
1facf9fc 28883+
28884+ return err;
28885+}
28886+
28887+/* ---------------------------------------------------------------------- */
28888+
28889+/* policies for create */
28890+
c2b27bf2 28891+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex)
4a4d8108
AM
28892+{
28893+ int err, i, j, ndentry;
28894+ aufs_bindex_t bopq;
28895+ struct au_dcsub_pages dpages;
28896+ struct au_dpage *dpage;
28897+ struct dentry **dentries, *parent, *d;
28898+
28899+ err = au_dpages_init(&dpages, GFP_NOFS);
28900+ if (unlikely(err))
28901+ goto out;
28902+ parent = dget_parent(dentry);
027c5e7a 28903+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0);
4a4d8108
AM
28904+ if (unlikely(err))
28905+ goto out_free;
28906+
28907+ err = bindex;
28908+ for (i = 0; i < dpages.ndpage; i++) {
28909+ dpage = dpages.dpages + i;
28910+ dentries = dpage->dentries;
28911+ ndentry = dpage->ndentry;
28912+ for (j = 0; j < ndentry; j++) {
28913+ d = dentries[j];
28914+ di_read_lock_parent2(d, !AuLock_IR);
28915+ bopq = au_dbdiropq(d);
28916+ di_read_unlock(d, !AuLock_IR);
28917+ if (bopq >= 0 && bopq < err)
28918+ err = bopq;
28919+ }
28920+ }
28921+
28922+out_free:
28923+ dput(parent);
28924+ au_dpages_free(&dpages);
28925+out:
28926+ return err;
28927+}
28928+
1facf9fc 28929+static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
28930+{
28931+ for (; bindex >= 0; bindex--)
28932+ if (!au_br_rdonly(au_sbr(sb, bindex)))
28933+ return bindex;
28934+ return -EROFS;
28935+}
28936+
28937+/* top down parent */
392086de
AM
28938+static int au_wbr_create_tdp(struct dentry *dentry,
28939+ unsigned int flags __maybe_unused)
1facf9fc 28940+{
28941+ int err;
28942+ aufs_bindex_t bstart, bindex;
28943+ struct super_block *sb;
28944+ struct dentry *parent, *h_parent;
28945+
28946+ sb = dentry->d_sb;
28947+ bstart = au_dbstart(dentry);
28948+ err = bstart;
28949+ if (!au_br_rdonly(au_sbr(sb, bstart)))
28950+ goto out;
28951+
28952+ err = -EROFS;
28953+ parent = dget_parent(dentry);
28954+ for (bindex = au_dbstart(parent); bindex < bstart; bindex++) {
28955+ h_parent = au_h_dptr(parent, bindex);
28956+ if (!h_parent || !h_parent->d_inode)
28957+ continue;
28958+
28959+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
28960+ err = bindex;
28961+ break;
28962+ }
28963+ }
28964+ dput(parent);
28965+
28966+ /* bottom up here */
4a4d8108 28967+ if (unlikely(err < 0)) {
1facf9fc 28968+ err = au_wbr_bu(sb, bstart - 1);
4a4d8108
AM
28969+ if (err >= 0)
28970+ err = au_wbr_nonopq(dentry, err);
28971+ }
1facf9fc 28972+
4f0767ce 28973+out:
1facf9fc 28974+ AuDbg("b%d\n", err);
28975+ return err;
28976+}
28977+
28978+/* ---------------------------------------------------------------------- */
28979+
28980+/* an exception for the policy other than tdp */
28981+static int au_wbr_create_exp(struct dentry *dentry)
28982+{
28983+ int err;
28984+ aufs_bindex_t bwh, bdiropq;
28985+ struct dentry *parent;
28986+
28987+ err = -1;
28988+ bwh = au_dbwh(dentry);
28989+ parent = dget_parent(dentry);
28990+ bdiropq = au_dbdiropq(parent);
28991+ if (bwh >= 0) {
28992+ if (bdiropq >= 0)
28993+ err = min(bdiropq, bwh);
28994+ else
28995+ err = bwh;
28996+ AuDbg("%d\n", err);
28997+ } else if (bdiropq >= 0) {
28998+ err = bdiropq;
28999+ AuDbg("%d\n", err);
29000+ }
29001+ dput(parent);
29002+
4a4d8108
AM
29003+ if (err >= 0)
29004+ err = au_wbr_nonopq(dentry, err);
29005+
1facf9fc 29006+ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
29007+ err = -1;
29008+
29009+ AuDbg("%d\n", err);
29010+ return err;
29011+}
29012+
29013+/* ---------------------------------------------------------------------- */
29014+
29015+/* round robin */
29016+static int au_wbr_create_init_rr(struct super_block *sb)
29017+{
29018+ int err;
29019+
29020+ err = au_wbr_bu(sb, au_sbend(sb));
29021+ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
dece6358 29022+ /* smp_mb(); */
1facf9fc 29023+
29024+ AuDbg("b%d\n", err);
29025+ return err;
29026+}
29027+
392086de 29028+static int au_wbr_create_rr(struct dentry *dentry, unsigned int flags)
1facf9fc 29029+{
29030+ int err, nbr;
29031+ unsigned int u;
29032+ aufs_bindex_t bindex, bend;
29033+ struct super_block *sb;
29034+ atomic_t *next;
29035+
29036+ err = au_wbr_create_exp(dentry);
29037+ if (err >= 0)
29038+ goto out;
29039+
29040+ sb = dentry->d_sb;
29041+ next = &au_sbi(sb)->si_wbr_rr_next;
29042+ bend = au_sbend(sb);
29043+ nbr = bend + 1;
29044+ for (bindex = 0; bindex <= bend; bindex++) {
392086de 29045+ if (!au_ftest_wbr(flags, DIR)) {
1facf9fc 29046+ err = atomic_dec_return(next) + 1;
29047+ /* modulo for 0 is meaningless */
29048+ if (unlikely(!err))
29049+ err = atomic_dec_return(next) + 1;
29050+ } else
29051+ err = atomic_read(next);
29052+ AuDbg("%d\n", err);
29053+ u = err;
29054+ err = u % nbr;
29055+ AuDbg("%d\n", err);
29056+ if (!au_br_rdonly(au_sbr(sb, err)))
29057+ break;
29058+ err = -EROFS;
29059+ }
29060+
4a4d8108
AM
29061+ if (err >= 0)
29062+ err = au_wbr_nonopq(dentry, err);
29063+
4f0767ce 29064+out:
1facf9fc 29065+ AuDbg("%d\n", err);
29066+ return err;
29067+}
29068+
29069+/* ---------------------------------------------------------------------- */
29070+
29071+/* most free space */
392086de 29072+static void au_mfs(struct dentry *dentry, struct dentry *parent)
1facf9fc 29073+{
29074+ struct super_block *sb;
29075+ struct au_branch *br;
29076+ struct au_wbr_mfs *mfs;
392086de 29077+ struct dentry *h_parent;
1facf9fc 29078+ aufs_bindex_t bindex, bend;
29079+ int err;
29080+ unsigned long long b, bavail;
7f207e10 29081+ struct path h_path;
1facf9fc 29082+ /* reduce the stack usage */
29083+ struct kstatfs *st;
29084+
29085+ st = kmalloc(sizeof(*st), GFP_NOFS);
29086+ if (unlikely(!st)) {
29087+ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
29088+ return;
29089+ }
29090+
29091+ bavail = 0;
29092+ sb = dentry->d_sb;
29093+ mfs = &au_sbi(sb)->si_wbr_mfs;
dece6358 29094+ MtxMustLock(&mfs->mfs_lock);
1facf9fc 29095+ mfs->mfs_bindex = -EROFS;
29096+ mfs->mfsrr_bytes = 0;
392086de
AM
29097+ if (!parent) {
29098+ bindex = 0;
29099+ bend = au_sbend(sb);
29100+ } else {
29101+ bindex = au_dbstart(parent);
29102+ bend = au_dbtaildir(parent);
29103+ }
29104+
29105+ for (; bindex <= bend; bindex++) {
29106+ if (parent) {
29107+ h_parent = au_h_dptr(parent, bindex);
29108+ if (!h_parent || !h_parent->d_inode)
29109+ continue;
29110+ }
1facf9fc 29111+ br = au_sbr(sb, bindex);
29112+ if (au_br_rdonly(br))
29113+ continue;
29114+
29115+ /* sb->s_root for NFS is unreliable */
86dc4139 29116+ h_path.mnt = au_br_mnt(br);
7f207e10
AM
29117+ h_path.dentry = h_path.mnt->mnt_root;
29118+ err = vfs_statfs(&h_path, st);
1facf9fc 29119+ if (unlikely(err)) {
29120+ AuWarn1("failed statfs, b%d, %d\n", bindex, err);
29121+ continue;
29122+ }
29123+
29124+ /* when the available size is equal, select the lower one */
29125+ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
29126+ || sizeof(b) < sizeof(st->f_bsize));
29127+ b = st->f_bavail * st->f_bsize;
29128+ br->br_wbr->wbr_bytes = b;
29129+ if (b >= bavail) {
29130+ bavail = b;
29131+ mfs->mfs_bindex = bindex;
29132+ mfs->mfs_jiffy = jiffies;
29133+ }
29134+ }
29135+
29136+ mfs->mfsrr_bytes = bavail;
29137+ AuDbg("b%d\n", mfs->mfs_bindex);
29138+ kfree(st);
29139+}
29140+
392086de 29141+static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags)
1facf9fc 29142+{
29143+ int err;
392086de 29144+ struct dentry *parent;
1facf9fc 29145+ struct super_block *sb;
29146+ struct au_wbr_mfs *mfs;
29147+
29148+ err = au_wbr_create_exp(dentry);
29149+ if (err >= 0)
29150+ goto out;
29151+
29152+ sb = dentry->d_sb;
392086de
AM
29153+ parent = NULL;
29154+ if (au_ftest_wbr(flags, PARENT))
29155+ parent = dget_parent(dentry);
1facf9fc 29156+ mfs = &au_sbi(sb)->si_wbr_mfs;
29157+ mutex_lock(&mfs->mfs_lock);
29158+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
29159+ || mfs->mfs_bindex < 0
29160+ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
392086de 29161+ au_mfs(dentry, parent);
1facf9fc 29162+ mutex_unlock(&mfs->mfs_lock);
29163+ err = mfs->mfs_bindex;
392086de 29164+ dput(parent);
1facf9fc 29165+
4a4d8108
AM
29166+ if (err >= 0)
29167+ err = au_wbr_nonopq(dentry, err);
29168+
4f0767ce 29169+out:
1facf9fc 29170+ AuDbg("b%d\n", err);
29171+ return err;
29172+}
29173+
29174+static int au_wbr_create_init_mfs(struct super_block *sb)
29175+{
29176+ struct au_wbr_mfs *mfs;
29177+
29178+ mfs = &au_sbi(sb)->si_wbr_mfs;
29179+ mutex_init(&mfs->mfs_lock);
29180+ mfs->mfs_jiffy = 0;
29181+ mfs->mfs_bindex = -EROFS;
29182+
29183+ return 0;
29184+}
29185+
29186+static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
29187+{
29188+ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
29189+ return 0;
29190+}
29191+
29192+/* ---------------------------------------------------------------------- */
29193+
29194+/* most free space and then round robin */
392086de 29195+static int au_wbr_create_mfsrr(struct dentry *dentry, unsigned int flags)
1facf9fc 29196+{
29197+ int err;
29198+ struct au_wbr_mfs *mfs;
29199+
392086de 29200+ err = au_wbr_create_mfs(dentry, flags);
1facf9fc 29201+ if (err >= 0) {
29202+ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
dece6358 29203+ mutex_lock(&mfs->mfs_lock);
1facf9fc 29204+ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
392086de 29205+ err = au_wbr_create_rr(dentry, flags);
dece6358 29206+ mutex_unlock(&mfs->mfs_lock);
1facf9fc 29207+ }
29208+
29209+ AuDbg("b%d\n", err);
29210+ return err;
29211+}
29212+
29213+static int au_wbr_create_init_mfsrr(struct super_block *sb)
29214+{
29215+ int err;
29216+
29217+ au_wbr_create_init_mfs(sb); /* ignore */
29218+ err = au_wbr_create_init_rr(sb);
29219+
29220+ return err;
29221+}
29222+
29223+/* ---------------------------------------------------------------------- */
29224+
29225+/* top down parent and most free space */
392086de 29226+static int au_wbr_create_pmfs(struct dentry *dentry, unsigned int flags)
1facf9fc 29227+{
29228+ int err, e2;
29229+ unsigned long long b;
29230+ aufs_bindex_t bindex, bstart, bend;
29231+ struct super_block *sb;
29232+ struct dentry *parent, *h_parent;
29233+ struct au_branch *br;
29234+
392086de 29235+ err = au_wbr_create_tdp(dentry, flags);
1facf9fc 29236+ if (unlikely(err < 0))
29237+ goto out;
29238+ parent = dget_parent(dentry);
29239+ bstart = au_dbstart(parent);
29240+ bend = au_dbtaildir(parent);
29241+ if (bstart == bend)
29242+ goto out_parent; /* success */
29243+
392086de 29244+ e2 = au_wbr_create_mfs(dentry, flags);
1facf9fc 29245+ if (e2 < 0)
29246+ goto out_parent; /* success */
29247+
29248+ /* when the available size is equal, select upper one */
29249+ sb = dentry->d_sb;
29250+ br = au_sbr(sb, err);
29251+ b = br->br_wbr->wbr_bytes;
29252+ AuDbg("b%d, %llu\n", err, b);
29253+
29254+ for (bindex = bstart; bindex <= bend; bindex++) {
29255+ h_parent = au_h_dptr(parent, bindex);
29256+ if (!h_parent || !h_parent->d_inode)
29257+ continue;
29258+
29259+ br = au_sbr(sb, bindex);
29260+ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
29261+ b = br->br_wbr->wbr_bytes;
29262+ err = bindex;
29263+ AuDbg("b%d, %llu\n", err, b);
29264+ }
29265+ }
29266+
4a4d8108
AM
29267+ if (err >= 0)
29268+ err = au_wbr_nonopq(dentry, err);
29269+
4f0767ce 29270+out_parent:
1facf9fc 29271+ dput(parent);
4f0767ce 29272+out:
1facf9fc 29273+ AuDbg("b%d\n", err);
29274+ return err;
29275+}
29276+
29277+/* ---------------------------------------------------------------------- */
29278+
392086de
AM
29279+/*
29280+ * - top down parent
29281+ * - most free space with parent
29282+ * - most free space round-robin regardless parent
29283+ */
29284+static int au_wbr_create_pmfsrr(struct dentry *dentry, unsigned int flags)
29285+{
29286+ int err;
29287+ unsigned long long watermark;
29288+ struct super_block *sb;
29289+ struct au_branch *br;
29290+ struct au_wbr_mfs *mfs;
29291+
29292+ err = au_wbr_create_pmfs(dentry, flags | AuWbr_PARENT);
29293+ if (unlikely(err < 0))
29294+ goto out;
29295+
29296+ sb = dentry->d_sb;
29297+ br = au_sbr(sb, err);
29298+ mfs = &au_sbi(sb)->si_wbr_mfs;
29299+ mutex_lock(&mfs->mfs_lock);
29300+ watermark = mfs->mfsrr_watermark;
29301+ mutex_unlock(&mfs->mfs_lock);
29302+ if (br->br_wbr->wbr_bytes < watermark)
29303+ /* regardless the parent dir */
29304+ err = au_wbr_create_mfsrr(dentry, flags);
29305+
29306+out:
29307+ AuDbg("b%d\n", err);
29308+ return err;
29309+}
29310+
29311+/* ---------------------------------------------------------------------- */
29312+
1facf9fc 29313+/* policies for copyup */
29314+
29315+/* top down parent */
29316+static int au_wbr_copyup_tdp(struct dentry *dentry)
29317+{
392086de 29318+ return au_wbr_create_tdp(dentry, /*flags, anything is ok*/0);
1facf9fc 29319+}
29320+
29321+/* bottom up parent */
29322+static int au_wbr_copyup_bup(struct dentry *dentry)
29323+{
29324+ int err;
29325+ aufs_bindex_t bindex, bstart;
29326+ struct dentry *parent, *h_parent;
29327+ struct super_block *sb;
29328+
29329+ err = -EROFS;
29330+ sb = dentry->d_sb;
29331+ parent = dget_parent(dentry);
29332+ bstart = au_dbstart(parent);
29333+ for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) {
29334+ h_parent = au_h_dptr(parent, bindex);
29335+ if (!h_parent || !h_parent->d_inode)
29336+ continue;
29337+
29338+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
29339+ err = bindex;
29340+ break;
29341+ }
29342+ }
29343+ dput(parent);
29344+
29345+ /* bottom up here */
29346+ if (unlikely(err < 0))
29347+ err = au_wbr_bu(sb, bstart - 1);
29348+
29349+ AuDbg("b%d\n", err);
29350+ return err;
29351+}
29352+
29353+/* bottom up */
29354+static int au_wbr_copyup_bu(struct dentry *dentry)
29355+{
29356+ int err;
4a4d8108 29357+ aufs_bindex_t bstart;
1facf9fc 29358+
4a4d8108
AM
29359+ bstart = au_dbstart(dentry);
29360+ err = au_wbr_bu(dentry->d_sb, bstart);
29361+ AuDbg("b%d\n", err);
29362+ if (err > bstart)
29363+ err = au_wbr_nonopq(dentry, err);
1facf9fc 29364+
29365+ AuDbg("b%d\n", err);
29366+ return err;
29367+}
29368+
29369+/* ---------------------------------------------------------------------- */
29370+
29371+struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
29372+ [AuWbrCopyup_TDP] = {
29373+ .copyup = au_wbr_copyup_tdp
29374+ },
29375+ [AuWbrCopyup_BUP] = {
29376+ .copyup = au_wbr_copyup_bup
29377+ },
29378+ [AuWbrCopyup_BU] = {
29379+ .copyup = au_wbr_copyup_bu
29380+ }
29381+};
29382+
29383+struct au_wbr_create_operations au_wbr_create_ops[] = {
29384+ [AuWbrCreate_TDP] = {
29385+ .create = au_wbr_create_tdp
29386+ },
29387+ [AuWbrCreate_RR] = {
29388+ .create = au_wbr_create_rr,
29389+ .init = au_wbr_create_init_rr
29390+ },
29391+ [AuWbrCreate_MFS] = {
29392+ .create = au_wbr_create_mfs,
29393+ .init = au_wbr_create_init_mfs,
29394+ .fin = au_wbr_create_fin_mfs
29395+ },
29396+ [AuWbrCreate_MFSV] = {
29397+ .create = au_wbr_create_mfs,
29398+ .init = au_wbr_create_init_mfs,
29399+ .fin = au_wbr_create_fin_mfs
29400+ },
29401+ [AuWbrCreate_MFSRR] = {
29402+ .create = au_wbr_create_mfsrr,
29403+ .init = au_wbr_create_init_mfsrr,
29404+ .fin = au_wbr_create_fin_mfs
29405+ },
29406+ [AuWbrCreate_MFSRRV] = {
29407+ .create = au_wbr_create_mfsrr,
29408+ .init = au_wbr_create_init_mfsrr,
29409+ .fin = au_wbr_create_fin_mfs
29410+ },
29411+ [AuWbrCreate_PMFS] = {
29412+ .create = au_wbr_create_pmfs,
29413+ .init = au_wbr_create_init_mfs,
29414+ .fin = au_wbr_create_fin_mfs
29415+ },
29416+ [AuWbrCreate_PMFSV] = {
29417+ .create = au_wbr_create_pmfs,
29418+ .init = au_wbr_create_init_mfs,
29419+ .fin = au_wbr_create_fin_mfs
392086de
AM
29420+ },
29421+ [AuWbrCreate_PMFSRR] = {
29422+ .create = au_wbr_create_pmfsrr,
29423+ .init = au_wbr_create_init_mfsrr,
29424+ .fin = au_wbr_create_fin_mfs
29425+ },
29426+ [AuWbrCreate_PMFSRRV] = {
29427+ .create = au_wbr_create_pmfsrr,
29428+ .init = au_wbr_create_init_mfsrr,
29429+ .fin = au_wbr_create_fin_mfs
1facf9fc 29430+ }
29431+};
7f207e10
AM
29432diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
29433--- /usr/share/empty/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100
86dc4139
AM
29434+++ linux/fs/aufs/whout.c 2013-07-06 13:20:47.760198800 +0200
29435@@ -0,0 +1,1022 @@
1facf9fc 29436+/*
7a9e40b8 29437+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 29438+ *
29439+ * This program, aufs is free software; you can redistribute it and/or modify
29440+ * it under the terms of the GNU General Public License as published by
29441+ * the Free Software Foundation; either version 2 of the License, or
29442+ * (at your option) any later version.
dece6358
AM
29443+ *
29444+ * This program is distributed in the hope that it will be useful,
29445+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29446+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29447+ * GNU General Public License for more details.
29448+ *
29449+ * You should have received a copy of the GNU General Public License
29450+ * along with this program; if not, write to the Free Software
29451+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 29452+ */
29453+
29454+/*
29455+ * whiteout for logical deletion and opaque directory
29456+ */
29457+
1facf9fc 29458+#include "aufs.h"
29459+
29460+#define WH_MASK S_IRUGO
29461+
29462+/*
29463+ * If a directory contains this file, then it is opaque. We start with the
29464+ * .wh. flag so that it is blocked by lookup.
29465+ */
0c3ec466
AM
29466+static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ,
29467+ sizeof(AUFS_WH_DIROPQ) - 1);
1facf9fc 29468+
29469+/*
29470+ * generate whiteout name, which is NOT terminated by NULL.
29471+ * @name: original d_name.name
29472+ * @len: original d_name.len
29473+ * @wh: whiteout qstr
29474+ * returns zero when succeeds, otherwise error.
29475+ * succeeded value as wh->name should be freed by kfree().
29476+ */
29477+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
29478+{
29479+ char *p;
29480+
29481+ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
29482+ return -ENAMETOOLONG;
29483+
29484+ wh->len = name->len + AUFS_WH_PFX_LEN;
29485+ p = kmalloc(wh->len, GFP_NOFS);
29486+ wh->name = p;
29487+ if (p) {
29488+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
29489+ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
29490+ /* smp_mb(); */
29491+ return 0;
29492+ }
29493+ return -ENOMEM;
29494+}
29495+
29496+/* ---------------------------------------------------------------------- */
29497+
29498+/*
29499+ * test if the @wh_name exists under @h_parent.
29500+ * @try_sio specifies the necessary of super-io.
29501+ */
29502+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
29503+ struct au_branch *br, int try_sio)
29504+{
29505+ int err;
29506+ struct dentry *wh_dentry;
1facf9fc 29507+
1facf9fc 29508+ if (!try_sio)
b4510431 29509+ wh_dentry = vfsub_lkup_one(wh_name, h_parent);
1facf9fc 29510+ else
29511+ wh_dentry = au_sio_lkup_one(wh_name, h_parent, br);
29512+ err = PTR_ERR(wh_dentry);
29513+ if (IS_ERR(wh_dentry))
29514+ goto out;
29515+
29516+ err = 0;
29517+ if (!wh_dentry->d_inode)
29518+ goto out_wh; /* success */
29519+
29520+ err = 1;
29521+ if (S_ISREG(wh_dentry->d_inode->i_mode))
29522+ goto out_wh; /* success */
29523+
29524+ err = -EIO;
29525+ AuIOErr("%.*s Invalid whiteout entry type 0%o.\n",
29526+ AuDLNPair(wh_dentry), wh_dentry->d_inode->i_mode);
29527+
4f0767ce 29528+out_wh:
1facf9fc 29529+ dput(wh_dentry);
4f0767ce 29530+out:
1facf9fc 29531+ return err;
29532+}
29533+
29534+/*
29535+ * test if the @h_dentry sets opaque or not.
29536+ */
29537+int au_diropq_test(struct dentry *h_dentry, struct au_branch *br)
29538+{
29539+ int err;
29540+ struct inode *h_dir;
29541+
29542+ h_dir = h_dentry->d_inode;
29543+ err = au_wh_test(h_dentry, &diropq_name, br,
29544+ au_test_h_perm_sio(h_dir, MAY_EXEC));
29545+ return err;
29546+}
29547+
29548+/*
29549+ * returns a negative dentry whose name is unique and temporary.
29550+ */
29551+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
29552+ struct qstr *prefix)
29553+{
1facf9fc 29554+ struct dentry *dentry;
29555+ int i;
027c5e7a 29556+ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
4a4d8108 29557+ *name, *p;
027c5e7a 29558+ /* strict atomic_t is unnecessary here */
1facf9fc 29559+ static unsigned short cnt;
29560+ struct qstr qs;
29561+
4a4d8108
AM
29562+ BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
29563+
1facf9fc 29564+ name = defname;
027c5e7a
AM
29565+ qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
29566+ if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
1facf9fc 29567+ dentry = ERR_PTR(-ENAMETOOLONG);
4a4d8108 29568+ if (unlikely(qs.len > NAME_MAX))
1facf9fc 29569+ goto out;
29570+ dentry = ERR_PTR(-ENOMEM);
29571+ name = kmalloc(qs.len + 1, GFP_NOFS);
29572+ if (unlikely(!name))
29573+ goto out;
29574+ }
29575+
29576+ /* doubly whiteout-ed */
29577+ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
29578+ p = name + AUFS_WH_PFX_LEN * 2;
29579+ memcpy(p, prefix->name, prefix->len);
29580+ p += prefix->len;
29581+ *p++ = '.';
4a4d8108 29582+ AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
1facf9fc 29583+
29584+ qs.name = name;
29585+ for (i = 0; i < 3; i++) {
b752ccd1 29586+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
1facf9fc 29587+ dentry = au_sio_lkup_one(&qs, h_parent, br);
29588+ if (IS_ERR(dentry) || !dentry->d_inode)
29589+ goto out_name;
29590+ dput(dentry);
29591+ }
0c3ec466 29592+ /* pr_warn("could not get random name\n"); */
1facf9fc 29593+ dentry = ERR_PTR(-EEXIST);
29594+ AuDbg("%.*s\n", AuLNPair(&qs));
29595+ BUG();
29596+
4f0767ce 29597+out_name:
1facf9fc 29598+ if (name != defname)
29599+ kfree(name);
4f0767ce 29600+out:
4a4d8108 29601+ AuTraceErrPtr(dentry);
1facf9fc 29602+ return dentry;
1facf9fc 29603+}
29604+
29605+/*
29606+ * rename the @h_dentry on @br to the whiteouted temporary name.
29607+ */
29608+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
29609+{
29610+ int err;
29611+ struct path h_path = {
86dc4139 29612+ .mnt = au_br_mnt(br)
1facf9fc 29613+ };
29614+ struct inode *h_dir;
29615+ struct dentry *h_parent;
29616+
29617+ h_parent = h_dentry->d_parent; /* dir inode is locked */
29618+ h_dir = h_parent->d_inode;
29619+ IMustLock(h_dir);
29620+
29621+ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
29622+ err = PTR_ERR(h_path.dentry);
29623+ if (IS_ERR(h_path.dentry))
29624+ goto out;
29625+
29626+ /* under the same dir, no need to lock_rename() */
29627+ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path);
29628+ AuTraceErr(err);
29629+ dput(h_path.dentry);
29630+
4f0767ce 29631+out:
4a4d8108 29632+ AuTraceErr(err);
1facf9fc 29633+ return err;
29634+}
29635+
29636+/* ---------------------------------------------------------------------- */
29637+/*
29638+ * functions for removing a whiteout
29639+ */
29640+
29641+static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
29642+{
29643+ int force;
29644+
29645+ /*
29646+ * forces superio when the dir has a sticky bit.
29647+ * this may be a violation of unix fs semantics.
29648+ */
29649+ force = (h_dir->i_mode & S_ISVTX)
0c3ec466 29650+ && !uid_eq(current_fsuid(), h_path->dentry->d_inode->i_uid);
1facf9fc 29651+ return vfsub_unlink(h_dir, h_path, force);
29652+}
29653+
29654+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
29655+ struct dentry *dentry)
29656+{
29657+ int err;
29658+
29659+ err = do_unlink_wh(h_dir, h_path);
29660+ if (!err && dentry)
29661+ au_set_dbwh(dentry, -1);
29662+
29663+ return err;
29664+}
29665+
29666+static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
29667+ struct au_branch *br)
29668+{
29669+ int err;
29670+ struct path h_path = {
86dc4139 29671+ .mnt = au_br_mnt(br)
1facf9fc 29672+ };
29673+
29674+ err = 0;
b4510431 29675+ h_path.dentry = vfsub_lkup_one(wh, h_parent);
1facf9fc 29676+ if (IS_ERR(h_path.dentry))
29677+ err = PTR_ERR(h_path.dentry);
29678+ else {
29679+ if (h_path.dentry->d_inode
29680+ && S_ISREG(h_path.dentry->d_inode->i_mode))
29681+ err = do_unlink_wh(h_parent->d_inode, &h_path);
29682+ dput(h_path.dentry);
29683+ }
29684+
29685+ return err;
29686+}
29687+
29688+/* ---------------------------------------------------------------------- */
29689+/*
29690+ * initialize/clean whiteout for a branch
29691+ */
29692+
29693+static void au_wh_clean(struct inode *h_dir, struct path *whpath,
29694+ const int isdir)
29695+{
29696+ int err;
29697+
29698+ if (!whpath->dentry->d_inode)
29699+ return;
29700+
86dc4139
AM
29701+ if (isdir)
29702+ err = vfsub_rmdir(h_dir, whpath);
29703+ else
29704+ err = vfsub_unlink(h_dir, whpath, /*force*/0);
1facf9fc 29705+ if (unlikely(err))
0c3ec466
AM
29706+ pr_warn("failed removing %.*s (%d), ignored.\n",
29707+ AuDLNPair(whpath->dentry), err);
1facf9fc 29708+}
29709+
29710+static int test_linkable(struct dentry *h_root)
29711+{
29712+ struct inode *h_dir = h_root->d_inode;
29713+
29714+ if (h_dir->i_op->link)
29715+ return 0;
29716+
4a4d8108
AM
29717+ pr_err("%.*s (%s) doesn't support link(2), use noplink and rw+nolwh\n",
29718+ AuDLNPair(h_root), au_sbtype(h_root->d_sb));
1facf9fc 29719+ return -ENOSYS;
29720+}
29721+
29722+/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
29723+static int au_whdir(struct inode *h_dir, struct path *path)
29724+{
29725+ int err;
29726+
29727+ err = -EEXIST;
29728+ if (!path->dentry->d_inode) {
29729+ int mode = S_IRWXU;
29730+
29731+ if (au_test_nfs(path->dentry->d_sb))
29732+ mode |= S_IXUGO;
86dc4139 29733+ err = vfsub_mkdir(h_dir, path, mode);
1facf9fc 29734+ } else if (S_ISDIR(path->dentry->d_inode->i_mode))
29735+ err = 0;
29736+ else
4a4d8108 29737+ pr_err("unknown %.*s exists\n", AuDLNPair(path->dentry));
1facf9fc 29738+
29739+ return err;
29740+}
29741+
29742+struct au_wh_base {
29743+ const struct qstr *name;
29744+ struct dentry *dentry;
29745+};
29746+
29747+static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
29748+ struct path *h_path)
29749+{
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+ au_wh_clean(h_dir, h_path, /*isdir*/1);
29754+ h_path->dentry = base[AuBrWh_ORPH].dentry;
29755+ au_wh_clean(h_dir, h_path, /*isdir*/1);
29756+}
29757+
29758+/*
29759+ * returns tri-state,
29760+ * minus: error, caller should print the mesage
29761+ * zero: succuess
29762+ * plus: error, caller should NOT print the mesage
29763+ */
29764+static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
29765+ int do_plink, struct au_wh_base base[],
29766+ struct path *h_path)
29767+{
29768+ int err;
29769+ struct inode *h_dir;
29770+
29771+ h_dir = h_root->d_inode;
29772+ h_path->dentry = base[AuBrWh_BASE].dentry;
29773+ au_wh_clean(h_dir, h_path, /*isdir*/0);
29774+ h_path->dentry = base[AuBrWh_PLINK].dentry;
29775+ if (do_plink) {
29776+ err = test_linkable(h_root);
29777+ if (unlikely(err)) {
29778+ err = 1;
29779+ goto out;
29780+ }
29781+
29782+ err = au_whdir(h_dir, h_path);
29783+ if (unlikely(err))
29784+ goto out;
29785+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
29786+ } else
29787+ au_wh_clean(h_dir, h_path, /*isdir*/1);
29788+ h_path->dentry = base[AuBrWh_ORPH].dentry;
29789+ err = au_whdir(h_dir, h_path);
29790+ if (unlikely(err))
29791+ goto out;
29792+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
29793+
4f0767ce 29794+out:
1facf9fc 29795+ return err;
29796+}
29797+
29798+/*
29799+ * for the moment, aufs supports the branch filesystem which does not support
29800+ * link(2). testing on FAT which does not support i_op->setattr() fully either,
29801+ * copyup failed. finally, such filesystem will not be used as the writable
29802+ * branch.
29803+ *
29804+ * returns tri-state, see above.
29805+ */
29806+static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
29807+ int do_plink, struct au_wh_base base[],
29808+ struct path *h_path)
29809+{
29810+ int err;
29811+ struct inode *h_dir;
29812+
1308ab2a 29813+ WbrWhMustWriteLock(wbr);
29814+
1facf9fc 29815+ err = test_linkable(h_root);
29816+ if (unlikely(err)) {
29817+ err = 1;
29818+ goto out;
29819+ }
29820+
29821+ /*
29822+ * todo: should this create be done in /sbin/mount.aufs helper?
29823+ */
29824+ err = -EEXIST;
29825+ h_dir = h_root->d_inode;
29826+ if (!base[AuBrWh_BASE].dentry->d_inode) {
86dc4139
AM
29827+ h_path->dentry = base[AuBrWh_BASE].dentry;
29828+ err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true);
1facf9fc 29829+ } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode))
29830+ err = 0;
29831+ else
4a4d8108
AM
29832+ pr_err("unknown %.*s/%.*s exists\n",
29833+ AuDLNPair(h_root), AuDLNPair(base[AuBrWh_BASE].dentry));
1facf9fc 29834+ if (unlikely(err))
29835+ goto out;
29836+
29837+ h_path->dentry = base[AuBrWh_PLINK].dentry;
29838+ if (do_plink) {
29839+ err = au_whdir(h_dir, h_path);
29840+ if (unlikely(err))
29841+ goto out;
29842+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
29843+ } else
29844+ au_wh_clean(h_dir, h_path, /*isdir*/1);
29845+ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
29846+
29847+ h_path->dentry = base[AuBrWh_ORPH].dentry;
29848+ err = au_whdir(h_dir, h_path);
29849+ if (unlikely(err))
29850+ goto out;
29851+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
29852+
4f0767ce 29853+out:
1facf9fc 29854+ return err;
29855+}
29856+
29857+/*
29858+ * initialize the whiteout base file/dir for @br.
29859+ */
86dc4139 29860+int au_wh_init(struct au_branch *br, struct super_block *sb)
1facf9fc 29861+{
29862+ int err, i;
29863+ const unsigned char do_plink
29864+ = !!au_opt_test(au_mntflags(sb), PLINK);
1facf9fc 29865+ struct inode *h_dir;
86dc4139
AM
29866+ struct path path = br->br_path;
29867+ struct dentry *h_root = path.dentry;
1facf9fc 29868+ struct au_wbr *wbr = br->br_wbr;
29869+ static const struct qstr base_name[] = {
0c3ec466
AM
29870+ [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME,
29871+ sizeof(AUFS_BASE_NAME) - 1),
29872+ [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME,
29873+ sizeof(AUFS_PLINKDIR_NAME) - 1),
29874+ [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME,
29875+ sizeof(AUFS_ORPHDIR_NAME) - 1)
1facf9fc 29876+ };
29877+ struct au_wh_base base[] = {
29878+ [AuBrWh_BASE] = {
29879+ .name = base_name + AuBrWh_BASE,
29880+ .dentry = NULL
29881+ },
29882+ [AuBrWh_PLINK] = {
29883+ .name = base_name + AuBrWh_PLINK,
29884+ .dentry = NULL
29885+ },
29886+ [AuBrWh_ORPH] = {
29887+ .name = base_name + AuBrWh_ORPH,
29888+ .dentry = NULL
29889+ }
29890+ };
29891+
1308ab2a 29892+ if (wbr)
29893+ WbrWhMustWriteLock(wbr);
1facf9fc 29894+
1facf9fc 29895+ for (i = 0; i < AuBrWh_Last; i++) {
29896+ /* doubly whiteouted */
29897+ struct dentry *d;
29898+
29899+ d = au_wh_lkup(h_root, (void *)base[i].name, br);
29900+ err = PTR_ERR(d);
29901+ if (IS_ERR(d))
29902+ goto out;
29903+
29904+ base[i].dentry = d;
29905+ AuDebugOn(wbr
29906+ && wbr->wbr_wh[i]
29907+ && wbr->wbr_wh[i] != base[i].dentry);
29908+ }
29909+
29910+ if (wbr)
29911+ for (i = 0; i < AuBrWh_Last; i++) {
29912+ dput(wbr->wbr_wh[i]);
29913+ wbr->wbr_wh[i] = NULL;
29914+ }
29915+
29916+ err = 0;
1e00d052 29917+ if (!au_br_writable(br->br_perm)) {
4a4d8108 29918+ h_dir = h_root->d_inode;
1facf9fc 29919+ au_wh_init_ro(h_dir, base, &path);
1e00d052 29920+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 29921+ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
29922+ if (err > 0)
29923+ goto out;
29924+ else if (err)
29925+ goto out_err;
1e00d052 29926+ } else {
1facf9fc 29927+ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
29928+ if (err > 0)
29929+ goto out;
29930+ else if (err)
29931+ goto out_err;
1facf9fc 29932+ }
29933+ goto out; /* success */
29934+
4f0767ce 29935+out_err:
4a4d8108
AM
29936+ pr_err("an error(%d) on the writable branch %.*s(%s)\n",
29937+ err, AuDLNPair(h_root), au_sbtype(h_root->d_sb));
4f0767ce 29938+out:
1facf9fc 29939+ for (i = 0; i < AuBrWh_Last; i++)
29940+ dput(base[i].dentry);
29941+ return err;
29942+}
29943+
29944+/* ---------------------------------------------------------------------- */
29945+/*
29946+ * whiteouts are all hard-linked usually.
29947+ * when its link count reaches a ceiling, we create a new whiteout base
29948+ * asynchronously.
29949+ */
29950+
29951+struct reinit_br_wh {
29952+ struct super_block *sb;
29953+ struct au_branch *br;
29954+};
29955+
29956+static void reinit_br_wh(void *arg)
29957+{
29958+ int err;
29959+ aufs_bindex_t bindex;
29960+ struct path h_path;
29961+ struct reinit_br_wh *a = arg;
29962+ struct au_wbr *wbr;
29963+ struct inode *dir;
29964+ struct dentry *h_root;
29965+ struct au_hinode *hdir;
29966+
29967+ err = 0;
29968+ wbr = a->br->br_wbr;
29969+ /* big aufs lock */
29970+ si_noflush_write_lock(a->sb);
29971+ if (!au_br_writable(a->br->br_perm))
29972+ goto out;
29973+ bindex = au_br_index(a->sb, a->br->br_id);
29974+ if (unlikely(bindex < 0))
29975+ goto out;
29976+
1308ab2a 29977+ di_read_lock_parent(a->sb->s_root, AuLock_IR);
1facf9fc 29978+ dir = a->sb->s_root->d_inode;
1facf9fc 29979+ hdir = au_hi(dir, bindex);
29980+ h_root = au_h_dptr(a->sb->s_root, bindex);
86dc4139 29981+ AuDebugOn(h_root != au_br_dentry(a->br));
1facf9fc 29982+
4a4d8108 29983+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 29984+ wbr_wh_write_lock(wbr);
29985+ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
29986+ h_root, a->br);
29987+ if (!err) {
86dc4139
AM
29988+ h_path.dentry = wbr->wbr_whbase;
29989+ h_path.mnt = au_br_mnt(a->br);
29990+ err = vfsub_unlink(hdir->hi_inode, &h_path, /*force*/0);
1facf9fc 29991+ } else {
0c3ec466
AM
29992+ pr_warn("%.*s is moved, ignored\n",
29993+ AuDLNPair(wbr->wbr_whbase));
1facf9fc 29994+ err = 0;
29995+ }
29996+ dput(wbr->wbr_whbase);
29997+ wbr->wbr_whbase = NULL;
29998+ if (!err)
86dc4139 29999+ err = au_wh_init(a->br, a->sb);
1facf9fc 30000+ wbr_wh_write_unlock(wbr);
4a4d8108 30001+ au_hn_imtx_unlock(hdir);
1308ab2a 30002+ di_read_unlock(a->sb->s_root, AuLock_IR);
1facf9fc 30003+
4f0767ce 30004+out:
1facf9fc 30005+ if (wbr)
30006+ atomic_dec(&wbr->wbr_wh_running);
30007+ atomic_dec(&a->br->br_count);
1facf9fc 30008+ si_write_unlock(a->sb);
027c5e7a 30009+ au_nwt_done(&au_sbi(a->sb)->si_nowait);
1facf9fc 30010+ kfree(arg);
30011+ if (unlikely(err))
30012+ AuIOErr("err %d\n", err);
30013+}
30014+
30015+static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
30016+{
30017+ int do_dec, wkq_err;
30018+ struct reinit_br_wh *arg;
30019+
30020+ do_dec = 1;
30021+ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
30022+ goto out;
30023+
30024+ /* ignore ENOMEM */
30025+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
30026+ if (arg) {
30027+ /*
30028+ * dec(wh_running), kfree(arg) and dec(br_count)
30029+ * in reinit function
30030+ */
30031+ arg->sb = sb;
30032+ arg->br = br;
30033+ atomic_inc(&br->br_count);
53392da6 30034+ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0);
1facf9fc 30035+ if (unlikely(wkq_err)) {
30036+ atomic_dec(&br->br_wbr->wbr_wh_running);
30037+ atomic_dec(&br->br_count);
30038+ kfree(arg);
30039+ }
30040+ do_dec = 0;
30041+ }
30042+
4f0767ce 30043+out:
1facf9fc 30044+ if (do_dec)
30045+ atomic_dec(&br->br_wbr->wbr_wh_running);
30046+}
30047+
30048+/* ---------------------------------------------------------------------- */
30049+
30050+/*
30051+ * create the whiteout @wh.
30052+ */
30053+static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
30054+ struct dentry *wh)
30055+{
30056+ int err;
30057+ struct path h_path = {
30058+ .dentry = wh
30059+ };
30060+ struct au_branch *br;
30061+ struct au_wbr *wbr;
30062+ struct dentry *h_parent;
30063+ struct inode *h_dir;
30064+
30065+ h_parent = wh->d_parent; /* dir inode is locked */
30066+ h_dir = h_parent->d_inode;
30067+ IMustLock(h_dir);
30068+
30069+ br = au_sbr(sb, bindex);
86dc4139 30070+ h_path.mnt = au_br_mnt(br);
1facf9fc 30071+ wbr = br->br_wbr;
30072+ wbr_wh_read_lock(wbr);
30073+ if (wbr->wbr_whbase) {
30074+ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path);
30075+ if (!err || err != -EMLINK)
30076+ goto out;
30077+
30078+ /* link count full. re-initialize br_whbase. */
30079+ kick_reinit_br_wh(sb, br);
30080+ }
30081+
30082+ /* return this error in this context */
b4510431 30083+ err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true);
1facf9fc 30084+
4f0767ce 30085+out:
1facf9fc 30086+ wbr_wh_read_unlock(wbr);
30087+ return err;
30088+}
30089+
30090+/* ---------------------------------------------------------------------- */
30091+
30092+/*
30093+ * create or remove the diropq.
30094+ */
30095+static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
30096+ unsigned int flags)
30097+{
30098+ struct dentry *opq_dentry, *h_dentry;
30099+ struct super_block *sb;
30100+ struct au_branch *br;
30101+ int err;
30102+
30103+ sb = dentry->d_sb;
30104+ br = au_sbr(sb, bindex);
30105+ h_dentry = au_h_dptr(dentry, bindex);
b4510431 30106+ opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry);
1facf9fc 30107+ if (IS_ERR(opq_dentry))
30108+ goto out;
30109+
30110+ if (au_ftest_diropq(flags, CREATE)) {
30111+ err = link_or_create_wh(sb, bindex, opq_dentry);
30112+ if (!err) {
30113+ au_set_dbdiropq(dentry, bindex);
30114+ goto out; /* success */
30115+ }
30116+ } else {
30117+ struct path tmp = {
30118+ .dentry = opq_dentry,
86dc4139 30119+ .mnt = au_br_mnt(br)
1facf9fc 30120+ };
30121+ err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp);
30122+ if (!err)
30123+ au_set_dbdiropq(dentry, -1);
30124+ }
30125+ dput(opq_dentry);
30126+ opq_dentry = ERR_PTR(err);
30127+
4f0767ce 30128+out:
1facf9fc 30129+ return opq_dentry;
30130+}
30131+
30132+struct do_diropq_args {
30133+ struct dentry **errp;
30134+ struct dentry *dentry;
30135+ aufs_bindex_t bindex;
30136+ unsigned int flags;
30137+};
30138+
30139+static void call_do_diropq(void *args)
30140+{
30141+ struct do_diropq_args *a = args;
30142+ *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
30143+}
30144+
30145+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
30146+ unsigned int flags)
30147+{
30148+ struct dentry *diropq, *h_dentry;
30149+
30150+ h_dentry = au_h_dptr(dentry, bindex);
30151+ if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE))
30152+ diropq = do_diropq(dentry, bindex, flags);
30153+ else {
30154+ int wkq_err;
30155+ struct do_diropq_args args = {
30156+ .errp = &diropq,
30157+ .dentry = dentry,
30158+ .bindex = bindex,
30159+ .flags = flags
30160+ };
30161+
30162+ wkq_err = au_wkq_wait(call_do_diropq, &args);
30163+ if (unlikely(wkq_err))
30164+ diropq = ERR_PTR(wkq_err);
30165+ }
30166+
30167+ return diropq;
30168+}
30169+
30170+/* ---------------------------------------------------------------------- */
30171+
30172+/*
30173+ * lookup whiteout dentry.
30174+ * @h_parent: lower parent dentry which must exist and be locked
30175+ * @base_name: name of dentry which will be whiteouted
30176+ * returns dentry for whiteout.
30177+ */
30178+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
30179+ struct au_branch *br)
30180+{
30181+ int err;
30182+ struct qstr wh_name;
30183+ struct dentry *wh_dentry;
30184+
30185+ err = au_wh_name_alloc(&wh_name, base_name);
30186+ wh_dentry = ERR_PTR(err);
30187+ if (!err) {
b4510431 30188+ wh_dentry = vfsub_lkup_one(&wh_name, h_parent);
1facf9fc 30189+ kfree(wh_name.name);
30190+ }
30191+ return wh_dentry;
30192+}
30193+
30194+/*
30195+ * link/create a whiteout for @dentry on @bindex.
30196+ */
30197+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
30198+ struct dentry *h_parent)
30199+{
30200+ struct dentry *wh_dentry;
30201+ struct super_block *sb;
30202+ int err;
30203+
30204+ sb = dentry->d_sb;
30205+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
30206+ if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) {
30207+ err = link_or_create_wh(sb, bindex, wh_dentry);
30208+ if (!err)
30209+ au_set_dbwh(dentry, bindex);
30210+ else {
30211+ dput(wh_dentry);
30212+ wh_dentry = ERR_PTR(err);
30213+ }
30214+ }
30215+
30216+ return wh_dentry;
30217+}
30218+
30219+/* ---------------------------------------------------------------------- */
30220+
30221+/* Delete all whiteouts in this directory on branch bindex. */
30222+static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
30223+ aufs_bindex_t bindex, struct au_branch *br)
30224+{
30225+ int err;
30226+ unsigned long ul, n;
30227+ struct qstr wh_name;
30228+ char *p;
30229+ struct hlist_head *head;
c06a8ce3 30230+ struct au_vdir_wh *pos;
1facf9fc 30231+ struct au_vdir_destr *str;
30232+
30233+ err = -ENOMEM;
537831f9 30234+ p = (void *)__get_free_page(GFP_NOFS);
1facf9fc 30235+ wh_name.name = p;
30236+ if (unlikely(!wh_name.name))
30237+ goto out;
30238+
30239+ err = 0;
30240+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
30241+ p += AUFS_WH_PFX_LEN;
30242+ n = whlist->nh_num;
30243+ head = whlist->nh_head;
30244+ for (ul = 0; !err && ul < n; ul++, head++) {
c06a8ce3
AM
30245+ hlist_for_each_entry(pos, head, wh_hash) {
30246+ if (pos->wh_bindex != bindex)
1facf9fc 30247+ continue;
30248+
c06a8ce3 30249+ str = &pos->wh_str;
1facf9fc 30250+ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
30251+ memcpy(p, str->name, str->len);
30252+ wh_name.len = AUFS_WH_PFX_LEN + str->len;
30253+ err = unlink_wh_name(h_dentry, &wh_name, br);
30254+ if (!err)
30255+ continue;
30256+ break;
30257+ }
30258+ AuIOErr("whiteout name too long %.*s\n",
30259+ str->len, str->name);
30260+ err = -EIO;
30261+ break;
30262+ }
30263+ }
537831f9 30264+ free_page((unsigned long)wh_name.name);
1facf9fc 30265+
4f0767ce 30266+out:
1facf9fc 30267+ return err;
30268+}
30269+
30270+struct del_wh_children_args {
30271+ int *errp;
30272+ struct dentry *h_dentry;
1308ab2a 30273+ struct au_nhash *whlist;
1facf9fc 30274+ aufs_bindex_t bindex;
30275+ struct au_branch *br;
30276+};
30277+
30278+static void call_del_wh_children(void *args)
30279+{
30280+ struct del_wh_children_args *a = args;
1308ab2a 30281+ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
1facf9fc 30282+}
30283+
30284+/* ---------------------------------------------------------------------- */
30285+
30286+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
30287+{
30288+ struct au_whtmp_rmdir *whtmp;
dece6358 30289+ int err;
1308ab2a 30290+ unsigned int rdhash;
dece6358
AM
30291+
30292+ SiMustAnyLock(sb);
1facf9fc 30293+
30294+ whtmp = kmalloc(sizeof(*whtmp), gfp);
dece6358
AM
30295+ if (unlikely(!whtmp)) {
30296+ whtmp = ERR_PTR(-ENOMEM);
1facf9fc 30297+ goto out;
dece6358 30298+ }
1facf9fc 30299+
30300+ whtmp->dir = NULL;
027c5e7a 30301+ whtmp->br = NULL;
1facf9fc 30302+ whtmp->wh_dentry = NULL;
1308ab2a 30303+ /* no estimation for dir size */
30304+ rdhash = au_sbi(sb)->si_rdhash;
30305+ if (!rdhash)
30306+ rdhash = AUFS_RDHASH_DEF;
30307+ err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
30308+ if (unlikely(err)) {
30309+ kfree(whtmp);
30310+ whtmp = ERR_PTR(err);
30311+ }
dece6358 30312+
4f0767ce 30313+out:
dece6358 30314+ return whtmp;
1facf9fc 30315+}
30316+
30317+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
30318+{
027c5e7a
AM
30319+ if (whtmp->br)
30320+ atomic_dec(&whtmp->br->br_count);
1facf9fc 30321+ dput(whtmp->wh_dentry);
30322+ iput(whtmp->dir);
dece6358 30323+ au_nhash_wh_free(&whtmp->whlist);
1facf9fc 30324+ kfree(whtmp);
30325+}
30326+
30327+/*
30328+ * rmdir the whiteouted temporary named dir @h_dentry.
30329+ * @whlist: whiteouted children.
30330+ */
30331+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
30332+ struct dentry *wh_dentry, struct au_nhash *whlist)
30333+{
30334+ int err;
30335+ struct path h_tmp;
30336+ struct inode *wh_inode, *h_dir;
30337+ struct au_branch *br;
30338+
30339+ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
30340+ IMustLock(h_dir);
30341+
30342+ br = au_sbr(dir->i_sb, bindex);
30343+ wh_inode = wh_dentry->d_inode;
30344+ mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
30345+
30346+ /*
30347+ * someone else might change some whiteouts while we were sleeping.
30348+ * it means this whlist may have an obsoleted entry.
30349+ */
30350+ if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
30351+ err = del_wh_children(wh_dentry, whlist, bindex, br);
30352+ else {
30353+ int wkq_err;
30354+ struct del_wh_children_args args = {
30355+ .errp = &err,
30356+ .h_dentry = wh_dentry,
1308ab2a 30357+ .whlist = whlist,
1facf9fc 30358+ .bindex = bindex,
30359+ .br = br
30360+ };
30361+
30362+ wkq_err = au_wkq_wait(call_del_wh_children, &args);
30363+ if (unlikely(wkq_err))
30364+ err = wkq_err;
30365+ }
30366+ mutex_unlock(&wh_inode->i_mutex);
30367+
30368+ if (!err) {
30369+ h_tmp.dentry = wh_dentry;
86dc4139 30370+ h_tmp.mnt = au_br_mnt(br);
1facf9fc 30371+ err = vfsub_rmdir(h_dir, &h_tmp);
1facf9fc 30372+ }
30373+
30374+ if (!err) {
30375+ if (au_ibstart(dir) == bindex) {
7f207e10 30376+ /* todo: dir->i_mutex is necessary */
1facf9fc 30377+ au_cpup_attr_timesizes(dir);
7f207e10 30378+ vfsub_drop_nlink(dir);
1facf9fc 30379+ }
30380+ return 0; /* success */
30381+ }
30382+
0c3ec466
AM
30383+ pr_warn("failed removing %.*s(%d), ignored\n",
30384+ AuDLNPair(wh_dentry), err);
1facf9fc 30385+ return err;
30386+}
30387+
30388+static void call_rmdir_whtmp(void *args)
30389+{
30390+ int err;
e49829fe 30391+ aufs_bindex_t bindex;
1facf9fc 30392+ struct au_whtmp_rmdir *a = args;
30393+ struct super_block *sb;
30394+ struct dentry *h_parent;
30395+ struct inode *h_dir;
1facf9fc 30396+ struct au_hinode *hdir;
30397+
30398+ /* rmdir by nfsd may cause deadlock with this i_mutex */
30399+ /* mutex_lock(&a->dir->i_mutex); */
e49829fe 30400+ err = -EROFS;
1facf9fc 30401+ sb = a->dir->i_sb;
e49829fe
JR
30402+ si_read_lock(sb, !AuLock_FLUSH);
30403+ if (!au_br_writable(a->br->br_perm))
30404+ goto out;
30405+ bindex = au_br_index(sb, a->br->br_id);
30406+ if (unlikely(bindex < 0))
1facf9fc 30407+ goto out;
30408+
30409+ err = -EIO;
1facf9fc 30410+ ii_write_lock_parent(a->dir);
30411+ h_parent = dget_parent(a->wh_dentry);
30412+ h_dir = h_parent->d_inode;
e49829fe 30413+ hdir = au_hi(a->dir, bindex);
86dc4139
AM
30414+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
30415+ if (unlikely(err))
30416+ goto out_mnt;
4a4d8108 30417+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
e49829fe
JR
30418+ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
30419+ a->br);
86dc4139
AM
30420+ if (!err)
30421+ err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist);
4a4d8108 30422+ au_hn_imtx_unlock(hdir);
86dc4139
AM
30423+ vfsub_mnt_drop_write(au_br_mnt(a->br));
30424+
30425+out_mnt:
1facf9fc 30426+ dput(h_parent);
30427+ ii_write_unlock(a->dir);
4f0767ce 30428+out:
1facf9fc 30429+ /* mutex_unlock(&a->dir->i_mutex); */
1facf9fc 30430+ au_whtmp_rmdir_free(a);
027c5e7a
AM
30431+ si_read_unlock(sb);
30432+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 30433+ if (unlikely(err))
30434+ AuIOErr("err %d\n", err);
30435+}
30436+
30437+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
30438+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
30439+{
30440+ int wkq_err;
e49829fe 30441+ struct super_block *sb;
1facf9fc 30442+
30443+ IMustLock(dir);
30444+
30445+ /* all post-process will be done in do_rmdir_whtmp(). */
e49829fe 30446+ sb = dir->i_sb;
1facf9fc 30447+ args->dir = au_igrab(dir);
e49829fe
JR
30448+ args->br = au_sbr(sb, bindex);
30449+ atomic_inc(&args->br->br_count);
1facf9fc 30450+ args->wh_dentry = dget(wh_dentry);
53392da6 30451+ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0);
1facf9fc 30452+ if (unlikely(wkq_err)) {
0c3ec466
AM
30453+ pr_warn("rmdir error %.*s (%d), ignored\n",
30454+ AuDLNPair(wh_dentry), wkq_err);
1facf9fc 30455+ au_whtmp_rmdir_free(args);
30456+ }
30457+}
7f207e10
AM
30458diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h
30459--- /usr/share/empty/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100
86dc4139
AM
30460+++ linux/fs/aufs/whout.h 2013-07-06 13:20:47.760198800 +0200
30461@@ -0,0 +1,87 @@
1facf9fc 30462+/*
7a9e40b8 30463+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 30464+ *
30465+ * This program, aufs is free software; you can redistribute it and/or modify
30466+ * it under the terms of the GNU General Public License as published by
30467+ * the Free Software Foundation; either version 2 of the License, or
30468+ * (at your option) any later version.
dece6358
AM
30469+ *
30470+ * This program is distributed in the hope that it will be useful,
30471+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30472+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30473+ * GNU General Public License for more details.
30474+ *
30475+ * You should have received a copy of the GNU General Public License
30476+ * along with this program; if not, write to the Free Software
30477+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 30478+ */
30479+
30480+/*
30481+ * whiteout for logical deletion and opaque directory
30482+ */
30483+
30484+#ifndef __AUFS_WHOUT_H__
30485+#define __AUFS_WHOUT_H__
30486+
30487+#ifdef __KERNEL__
30488+
1facf9fc 30489+#include "dir.h"
30490+
30491+/* whout.c */
30492+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
30493+struct au_branch;
30494+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
30495+ struct au_branch *br, int try_sio);
30496+int au_diropq_test(struct dentry *h_dentry, struct au_branch *br);
30497+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
30498+ struct qstr *prefix);
30499+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
30500+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
30501+ struct dentry *dentry);
86dc4139 30502+int au_wh_init(struct au_branch *br, struct super_block *sb);
1facf9fc 30503+
30504+/* diropq flags */
30505+#define AuDiropq_CREATE 1
30506+#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name)
7f207e10
AM
30507+#define au_fset_diropq(flags, name) \
30508+ do { (flags) |= AuDiropq_##name; } while (0)
30509+#define au_fclr_diropq(flags, name) \
30510+ do { (flags) &= ~AuDiropq_##name; } while (0)
1facf9fc 30511+
30512+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
30513+ unsigned int flags);
30514+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
30515+ struct au_branch *br);
30516+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
30517+ struct dentry *h_parent);
30518+
30519+/* real rmdir for the whiteout-ed dir */
30520+struct au_whtmp_rmdir {
30521+ struct inode *dir;
e49829fe 30522+ struct au_branch *br;
1facf9fc 30523+ struct dentry *wh_dentry;
dece6358 30524+ struct au_nhash whlist;
1facf9fc 30525+};
30526+
30527+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
30528+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
30529+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
30530+ struct dentry *wh_dentry, struct au_nhash *whlist);
30531+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
30532+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
30533+
30534+/* ---------------------------------------------------------------------- */
30535+
30536+static inline struct dentry *au_diropq_create(struct dentry *dentry,
30537+ aufs_bindex_t bindex)
30538+{
30539+ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
30540+}
30541+
30542+static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
30543+{
30544+ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
30545+}
30546+
30547+#endif /* __KERNEL__ */
30548+#endif /* __AUFS_WHOUT_H__ */
7f207e10
AM
30549diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
30550--- /usr/share/empty/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100
392086de 30551+++ linux/fs/aufs/wkq.c 2013-10-26 16:51:32.276373845 +0200
86dc4139 30552@@ -0,0 +1,213 @@
1facf9fc 30553+/*
7a9e40b8 30554+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 30555+ *
30556+ * This program, aufs is free software; you can redistribute it and/or modify
30557+ * it under the terms of the GNU General Public License as published by
30558+ * the Free Software Foundation; either version 2 of the License, or
30559+ * (at your option) any later version.
dece6358
AM
30560+ *
30561+ * This program is distributed in the hope that it will be useful,
30562+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30563+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30564+ * GNU General Public License for more details.
30565+ *
30566+ * You should have received a copy of the GNU General Public License
30567+ * along with this program; if not, write to the Free Software
30568+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 30569+ */
30570+
30571+/*
30572+ * workqueue for asynchronous/super-io operations
30573+ * todo: try new dredential scheme
30574+ */
30575+
dece6358 30576+#include <linux/module.h>
1facf9fc 30577+#include "aufs.h"
30578+
9dbd164d 30579+/* internal workqueue named AUFS_WKQ_NAME */
b752ccd1 30580+
9dbd164d 30581+static struct workqueue_struct *au_wkq;
1facf9fc 30582+
30583+struct au_wkinfo {
30584+ struct work_struct wk;
7f207e10 30585+ struct kobject *kobj;
1facf9fc 30586+
30587+ unsigned int flags; /* see wkq.h */
30588+
30589+ au_wkq_func_t func;
30590+ void *args;
30591+
1facf9fc 30592+ struct completion *comp;
30593+};
30594+
30595+/* ---------------------------------------------------------------------- */
30596+
1facf9fc 30597+static void wkq_func(struct work_struct *wk)
30598+{
30599+ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
30600+
2dfbb274 30601+ AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID));
7f207e10
AM
30602+ AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY);
30603+
1facf9fc 30604+ wkinfo->func(wkinfo->args);
1facf9fc 30605+ if (au_ftest_wkq(wkinfo->flags, WAIT))
30606+ complete(wkinfo->comp);
30607+ else {
7f207e10 30608+ kobject_put(wkinfo->kobj);
9dbd164d 30609+ module_put(THIS_MODULE); /* todo: ?? */
1facf9fc 30610+ kfree(wkinfo);
30611+ }
30612+}
30613+
30614+/*
30615+ * Since struct completion is large, try allocating it dynamically.
30616+ */
c2b27bf2 30617+#if 1 /* defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) */
1facf9fc 30618+#define AuWkqCompDeclare(name) struct completion *comp = NULL
30619+
30620+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
30621+{
30622+ *comp = kmalloc(sizeof(**comp), GFP_NOFS);
30623+ if (*comp) {
30624+ init_completion(*comp);
30625+ wkinfo->comp = *comp;
30626+ return 0;
30627+ }
30628+ return -ENOMEM;
30629+}
30630+
30631+static void au_wkq_comp_free(struct completion *comp)
30632+{
30633+ kfree(comp);
30634+}
30635+
30636+#else
30637+
30638+/* no braces */
30639+#define AuWkqCompDeclare(name) \
30640+ DECLARE_COMPLETION_ONSTACK(_ ## name); \
30641+ struct completion *comp = &_ ## name
30642+
30643+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
30644+{
30645+ wkinfo->comp = *comp;
30646+ return 0;
30647+}
30648+
30649+static void au_wkq_comp_free(struct completion *comp __maybe_unused)
30650+{
30651+ /* empty */
30652+}
30653+#endif /* 4KSTACKS */
30654+
53392da6 30655+static void au_wkq_run(struct au_wkinfo *wkinfo)
1facf9fc 30656+{
53392da6
AM
30657+ if (au_ftest_wkq(wkinfo->flags, NEST)) {
30658+ if (au_wkq_test()) {
30659+ AuWarn1("wkq from wkq, due to a dead dir by UDBA?\n");
30660+ AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT));
30661+ }
30662+ } else
30663+ au_dbg_verify_kthread();
30664+
30665+ if (au_ftest_wkq(wkinfo->flags, WAIT)) {
a1f66529 30666+ INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func);
9dbd164d 30667+ queue_work(au_wkq, &wkinfo->wk);
4a4d8108
AM
30668+ } else {
30669+ INIT_WORK(&wkinfo->wk, wkq_func);
30670+ schedule_work(&wkinfo->wk);
30671+ }
1facf9fc 30672+}
30673+
7f207e10
AM
30674+/*
30675+ * Be careful. It is easy to make deadlock happen.
30676+ * processA: lock, wkq and wait
30677+ * processB: wkq and wait, lock in wkq
30678+ * --> deadlock
30679+ */
b752ccd1 30680+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args)
1facf9fc 30681+{
30682+ int err;
30683+ AuWkqCompDeclare(comp);
30684+ struct au_wkinfo wkinfo = {
b752ccd1 30685+ .flags = flags,
1facf9fc 30686+ .func = func,
30687+ .args = args
30688+ };
30689+
30690+ err = au_wkq_comp_alloc(&wkinfo, &comp);
30691+ if (!err) {
53392da6 30692+ au_wkq_run(&wkinfo);
1facf9fc 30693+ /* no timeout, no interrupt */
30694+ wait_for_completion(wkinfo.comp);
30695+ au_wkq_comp_free(comp);
4a4d8108 30696+ destroy_work_on_stack(&wkinfo.wk);
1facf9fc 30697+ }
30698+
30699+ return err;
30700+
30701+}
30702+
027c5e7a
AM
30703+/*
30704+ * Note: dget/dput() in func for aufs dentries are not supported. It will be a
30705+ * problem in a concurrent umounting.
30706+ */
53392da6
AM
30707+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
30708+ unsigned int flags)
1facf9fc 30709+{
30710+ int err;
30711+ struct au_wkinfo *wkinfo;
30712+
30713+ atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
30714+
30715+ /*
30716+ * wkq_func() must free this wkinfo.
30717+ * it highly depends upon the implementation of workqueue.
30718+ */
30719+ err = 0;
30720+ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
30721+ if (wkinfo) {
7f207e10 30722+ wkinfo->kobj = &au_sbi(sb)->si_kobj;
53392da6 30723+ wkinfo->flags = flags & ~AuWkq_WAIT;
1facf9fc 30724+ wkinfo->func = func;
30725+ wkinfo->args = args;
30726+ wkinfo->comp = NULL;
7f207e10 30727+ kobject_get(wkinfo->kobj);
9dbd164d 30728+ __module_get(THIS_MODULE); /* todo: ?? */
1facf9fc 30729+
53392da6 30730+ au_wkq_run(wkinfo);
1facf9fc 30731+ } else {
30732+ err = -ENOMEM;
e49829fe 30733+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 30734+ }
30735+
30736+ return err;
30737+}
30738+
30739+/* ---------------------------------------------------------------------- */
30740+
30741+void au_nwt_init(struct au_nowait_tasks *nwt)
30742+{
30743+ atomic_set(&nwt->nw_len, 0);
4a4d8108 30744+ /* smp_mb(); */ /* atomic_set */
1facf9fc 30745+ init_waitqueue_head(&nwt->nw_wq);
30746+}
30747+
30748+void au_wkq_fin(void)
30749+{
9dbd164d 30750+ destroy_workqueue(au_wkq);
1facf9fc 30751+}
30752+
30753+int __init au_wkq_init(void)
30754+{
9dbd164d 30755+ int err;
b752ccd1
AM
30756+
30757+ err = 0;
86dc4139 30758+ au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE);
9dbd164d
AM
30759+ if (IS_ERR(au_wkq))
30760+ err = PTR_ERR(au_wkq);
30761+ else if (!au_wkq)
30762+ err = -ENOMEM;
b752ccd1
AM
30763+
30764+ return err;
1facf9fc 30765+}
7f207e10
AM
30766diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
30767--- /usr/share/empty/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100
86dc4139 30768+++ linux/fs/aufs/wkq.h 2013-07-06 13:20:47.760198800 +0200
f6c5ef8b 30769@@ -0,0 +1,92 @@
1facf9fc 30770+/*
7a9e40b8 30771+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 30772+ *
30773+ * This program, aufs is free software; you can redistribute it and/or modify
30774+ * it under the terms of the GNU General Public License as published by
30775+ * the Free Software Foundation; either version 2 of the License, or
30776+ * (at your option) any later version.
dece6358
AM
30777+ *
30778+ * This program is distributed in the hope that it will be useful,
30779+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30780+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30781+ * GNU General Public License for more details.
30782+ *
30783+ * You should have received a copy of the GNU General Public License
30784+ * along with this program; if not, write to the Free Software
30785+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 30786+ */
30787+
30788+/*
30789+ * workqueue for asynchronous/super-io operations
30790+ * todo: try new credentials management scheme
30791+ */
30792+
30793+#ifndef __AUFS_WKQ_H__
30794+#define __AUFS_WKQ_H__
30795+
30796+#ifdef __KERNEL__
30797+
dece6358
AM
30798+struct super_block;
30799+
1facf9fc 30800+/* ---------------------------------------------------------------------- */
30801+
30802+/*
30803+ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
30804+ */
30805+struct au_nowait_tasks {
30806+ atomic_t nw_len;
30807+ wait_queue_head_t nw_wq;
30808+};
30809+
30810+/* ---------------------------------------------------------------------- */
30811+
30812+typedef void (*au_wkq_func_t)(void *args);
30813+
30814+/* wkq flags */
30815+#define AuWkq_WAIT 1
9dbd164d 30816+#define AuWkq_NEST (1 << 1)
1facf9fc 30817+#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name)
7f207e10
AM
30818+#define au_fset_wkq(flags, name) \
30819+ do { (flags) |= AuWkq_##name; } while (0)
30820+#define au_fclr_wkq(flags, name) \
30821+ do { (flags) &= ~AuWkq_##name; } while (0)
1facf9fc 30822+
9dbd164d
AM
30823+#ifndef CONFIG_AUFS_HNOTIFY
30824+#undef AuWkq_NEST
30825+#define AuWkq_NEST 0
30826+#endif
30827+
1facf9fc 30828+/* wkq.c */
b752ccd1 30829+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args);
53392da6
AM
30830+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
30831+ unsigned int flags);
1facf9fc 30832+void au_nwt_init(struct au_nowait_tasks *nwt);
30833+int __init au_wkq_init(void);
30834+void au_wkq_fin(void);
30835+
30836+/* ---------------------------------------------------------------------- */
30837+
53392da6
AM
30838+static inline int au_wkq_test(void)
30839+{
30840+ return current->flags & PF_WQ_WORKER;
30841+}
30842+
b752ccd1 30843+static inline int au_wkq_wait(au_wkq_func_t func, void *args)
1facf9fc 30844+{
b752ccd1 30845+ return au_wkq_do_wait(AuWkq_WAIT, func, args);
1facf9fc 30846+}
30847+
30848+static inline void au_nwt_done(struct au_nowait_tasks *nwt)
30849+{
e49829fe 30850+ if (atomic_dec_and_test(&nwt->nw_len))
1facf9fc 30851+ wake_up_all(&nwt->nw_wq);
30852+}
30853+
30854+static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
30855+{
30856+ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
30857+ return 0;
30858+}
30859+
30860+#endif /* __KERNEL__ */
30861+#endif /* __AUFS_WKQ_H__ */
7f207e10
AM
30862diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
30863--- /usr/share/empty/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100
392086de
AM
30864+++ linux/fs/aufs/xino.c 2013-10-26 16:51:32.276373845 +0200
30865@@ -0,0 +1,1312 @@
1facf9fc 30866+/*
7a9e40b8 30867+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 30868+ *
30869+ * This program, aufs is free software; you can redistribute it and/or modify
30870+ * it under the terms of the GNU General Public License as published by
30871+ * the Free Software Foundation; either version 2 of the License, or
30872+ * (at your option) any later version.
dece6358
AM
30873+ *
30874+ * This program is distributed in the hope that it will be useful,
30875+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30876+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30877+ * GNU General Public License for more details.
30878+ *
30879+ * You should have received a copy of the GNU General Public License
30880+ * along with this program; if not, write to the Free Software
30881+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1facf9fc 30882+ */
30883+
30884+/*
30885+ * external inode number translation table and bitmap
30886+ */
30887+
30888+#include <linux/seq_file.h>
392086de 30889+#include <linux/statfs.h>
1facf9fc 30890+#include "aufs.h"
30891+
9dbd164d 30892+/* todo: unnecessary to support mmap_sem since kernel-space? */
b752ccd1 30893+ssize_t xino_fread(au_readf_t func, struct file *file, void *kbuf, size_t size,
1facf9fc 30894+ loff_t *pos)
30895+{
30896+ ssize_t err;
30897+ mm_segment_t oldfs;
b752ccd1
AM
30898+ union {
30899+ void *k;
30900+ char __user *u;
30901+ } buf;
1facf9fc 30902+
b752ccd1 30903+ buf.k = kbuf;
1facf9fc 30904+ oldfs = get_fs();
30905+ set_fs(KERNEL_DS);
30906+ do {
30907+ /* todo: signal_pending? */
b752ccd1 30908+ err = func(file, buf.u, size, pos);
1facf9fc 30909+ } while (err == -EAGAIN || err == -EINTR);
30910+ set_fs(oldfs);
30911+
30912+#if 0 /* reserved for future use */
30913+ if (err > 0)
30914+ fsnotify_access(file->f_dentry);
30915+#endif
30916+
30917+ return err;
30918+}
30919+
30920+/* ---------------------------------------------------------------------- */
30921+
b752ccd1 30922+static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *kbuf,
1facf9fc 30923+ size_t size, loff_t *pos)
30924+{
30925+ ssize_t err;
30926+ mm_segment_t oldfs;
b752ccd1
AM
30927+ union {
30928+ void *k;
30929+ const char __user *u;
30930+ } buf;
1facf9fc 30931+
b752ccd1 30932+ buf.k = kbuf;
1facf9fc 30933+ oldfs = get_fs();
30934+ set_fs(KERNEL_DS);
1facf9fc 30935+ do {
30936+ /* todo: signal_pending? */
b752ccd1 30937+ err = func(file, buf.u, size, pos);
1facf9fc 30938+ } while (err == -EAGAIN || err == -EINTR);
1facf9fc 30939+ set_fs(oldfs);
30940+
30941+#if 0 /* reserved for future use */
30942+ if (err > 0)
30943+ fsnotify_modify(file->f_dentry);
30944+#endif
30945+
30946+ return err;
30947+}
30948+
30949+struct do_xino_fwrite_args {
30950+ ssize_t *errp;
30951+ au_writef_t func;
30952+ struct file *file;
30953+ void *buf;
30954+ size_t size;
30955+ loff_t *pos;
30956+};
30957+
30958+static void call_do_xino_fwrite(void *args)
30959+{
30960+ struct do_xino_fwrite_args *a = args;
30961+ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
30962+}
30963+
30964+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
30965+ loff_t *pos)
30966+{
30967+ ssize_t err;
30968+
30969+ /* todo: signal block and no wkq? */
b752ccd1
AM
30970+ if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
30971+ lockdep_off();
30972+ err = do_xino_fwrite(func, file, buf, size, pos);
30973+ lockdep_on();
30974+ } else {
30975+ /*
30976+ * it breaks RLIMIT_FSIZE and normal user's limit,
30977+ * users should care about quota and real 'filesystem full.'
30978+ */
1facf9fc 30979+ int wkq_err;
30980+ struct do_xino_fwrite_args args = {
30981+ .errp = &err,
30982+ .func = func,
30983+ .file = file,
30984+ .buf = buf,
30985+ .size = size,
30986+ .pos = pos
30987+ };
30988+
30989+ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
30990+ if (unlikely(wkq_err))
30991+ err = wkq_err;
b752ccd1 30992+ }
1facf9fc 30993+
30994+ return err;
30995+}
30996+
30997+/* ---------------------------------------------------------------------- */
30998+
30999+/*
31000+ * create a new xinofile at the same place/path as @base_file.
31001+ */
31002+struct file *au_xino_create2(struct file *base_file, struct file *copy_src)
31003+{
31004+ struct file *file;
4a4d8108 31005+ struct dentry *base, *parent;
1facf9fc 31006+ struct inode *dir;
31007+ struct qstr *name;
1308ab2a 31008+ struct path path;
4a4d8108 31009+ int err;
1facf9fc 31010+
31011+ base = base_file->f_dentry;
31012+ parent = base->d_parent; /* dir inode is locked */
31013+ dir = parent->d_inode;
31014+ IMustLock(dir);
31015+
31016+ file = ERR_PTR(-EINVAL);
31017+ name = &base->d_name;
4a4d8108
AM
31018+ path.dentry = vfsub_lookup_one_len(name->name, parent, name->len);
31019+ if (IS_ERR(path.dentry)) {
31020+ file = (void *)path.dentry;
31021+ pr_err("%.*s lookup err %ld\n",
31022+ AuLNPair(name), PTR_ERR(path.dentry));
1facf9fc 31023+ goto out;
31024+ }
31025+
31026+ /* no need to mnt_want_write() since we call dentry_open() later */
4a4d8108 31027+ err = vfs_create(dir, path.dentry, S_IRUGO | S_IWUGO, NULL);
1facf9fc 31028+ if (unlikely(err)) {
31029+ file = ERR_PTR(err);
4a4d8108 31030+ pr_err("%.*s create err %d\n", AuLNPair(name), err);
1facf9fc 31031+ goto out_dput;
31032+ }
31033+
c06a8ce3 31034+ path.mnt = base_file->f_path.mnt;
4a4d8108 31035+ file = vfsub_dentry_open(&path,
7f207e10 31036+ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 31037+ /* | __FMODE_NONOTIFY */);
1facf9fc 31038+ if (IS_ERR(file)) {
4a4d8108 31039+ pr_err("%.*s open err %ld\n", AuLNPair(name), PTR_ERR(file));
1facf9fc 31040+ goto out_dput;
31041+ }
31042+
31043+ err = vfsub_unlink(dir, &file->f_path, /*force*/0);
31044+ if (unlikely(err)) {
4a4d8108 31045+ pr_err("%.*s unlink err %d\n", AuLNPair(name), err);
1facf9fc 31046+ goto out_fput;
31047+ }
31048+
31049+ if (copy_src) {
31050+ /* no one can touch copy_src xino */
c06a8ce3 31051+ err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src));
1facf9fc 31052+ if (unlikely(err)) {
4a4d8108 31053+ pr_err("%.*s copy err %d\n", AuLNPair(name), err);
1facf9fc 31054+ goto out_fput;
31055+ }
31056+ }
31057+ goto out_dput; /* success */
31058+
4f0767ce 31059+out_fput:
1facf9fc 31060+ fput(file);
31061+ file = ERR_PTR(err);
4f0767ce 31062+out_dput:
4a4d8108 31063+ dput(path.dentry);
4f0767ce 31064+out:
1facf9fc 31065+ return file;
31066+}
31067+
31068+struct au_xino_lock_dir {
31069+ struct au_hinode *hdir;
31070+ struct dentry *parent;
31071+ struct mutex *mtx;
31072+};
31073+
31074+static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
31075+ struct au_xino_lock_dir *ldir)
31076+{
31077+ aufs_bindex_t brid, bindex;
31078+
31079+ ldir->hdir = NULL;
31080+ bindex = -1;
31081+ brid = au_xino_brid(sb);
31082+ if (brid >= 0)
31083+ bindex = au_br_index(sb, brid);
31084+ if (bindex >= 0) {
31085+ ldir->hdir = au_hi(sb->s_root->d_inode, bindex);
4a4d8108 31086+ au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
1facf9fc 31087+ } else {
31088+ ldir->parent = dget_parent(xino->f_dentry);
31089+ ldir->mtx = &ldir->parent->d_inode->i_mutex;
31090+ mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT);
31091+ }
31092+}
31093+
31094+static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
31095+{
31096+ if (ldir->hdir)
4a4d8108 31097+ au_hn_imtx_unlock(ldir->hdir);
1facf9fc 31098+ else {
31099+ mutex_unlock(ldir->mtx);
31100+ dput(ldir->parent);
31101+ }
31102+}
31103+
31104+/* ---------------------------------------------------------------------- */
31105+
31106+/* trucate xino files asynchronously */
31107+
31108+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex)
31109+{
31110+ int err;
392086de
AM
31111+ unsigned long jiffy;
31112+ blkcnt_t blocks;
1facf9fc 31113+ aufs_bindex_t bi, bend;
392086de 31114+ struct kstatfs *st;
1facf9fc 31115+ struct au_branch *br;
31116+ struct file *new_xino, *file;
31117+ struct super_block *h_sb;
31118+ struct au_xino_lock_dir ldir;
31119+
392086de
AM
31120+ err = -ENOMEM;
31121+ st = kzalloc(sizeof(*st), GFP_NOFS);
31122+ if (unlikely(!st))
31123+ goto out;
31124+
1facf9fc 31125+ err = -EINVAL;
31126+ bend = au_sbend(sb);
31127+ if (unlikely(bindex < 0 || bend < bindex))
392086de 31128+ goto out_st;
1facf9fc 31129+ br = au_sbr(sb, bindex);
31130+ file = br->br_xino.xi_file;
31131+ if (!file)
392086de
AM
31132+ goto out_st;
31133+
31134+ err = vfs_statfs(&file->f_path, st);
31135+ if (unlikely(err))
31136+ AuErr1("statfs err %d, ignored\n", err);
31137+ jiffy = jiffies;
31138+ blocks = file_inode(file)->i_blocks;
31139+ pr_info("begin truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
31140+ bindex, (u64)blocks, st->f_bfree, st->f_blocks);
1facf9fc 31141+
31142+ au_xino_lock_dir(sb, file, &ldir);
31143+ /* mnt_want_write() is unnecessary here */
31144+ new_xino = au_xino_create2(file, file);
31145+ au_xino_unlock_dir(&ldir);
31146+ err = PTR_ERR(new_xino);
392086de
AM
31147+ if (IS_ERR(new_xino)) {
31148+ pr_err("err %d, ignored\n", err);
31149+ goto out_st;
31150+ }
1facf9fc 31151+ err = 0;
31152+ fput(file);
31153+ br->br_xino.xi_file = new_xino;
31154+
86dc4139 31155+ h_sb = au_br_sb(br);
1facf9fc 31156+ for (bi = 0; bi <= bend; bi++) {
31157+ if (unlikely(bi == bindex))
31158+ continue;
31159+ br = au_sbr(sb, bi);
86dc4139 31160+ if (au_br_sb(br) != h_sb)
1facf9fc 31161+ continue;
31162+
31163+ fput(br->br_xino.xi_file);
31164+ br->br_xino.xi_file = new_xino;
31165+ get_file(new_xino);
31166+ }
31167+
392086de
AM
31168+ err = vfs_statfs(&new_xino->f_path, st);
31169+ if (!err) {
31170+ pr_info("end truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
31171+ bindex, (u64)file_inode(new_xino)->i_blocks,
31172+ st->f_bfree, st->f_blocks);
31173+ if (file_inode(new_xino)->i_blocks < blocks)
31174+ au_sbi(sb)->si_xino_jiffy = jiffy;
31175+ } else
31176+ AuErr1("statfs err %d, ignored\n", err);
31177+
31178+out_st:
31179+ kfree(st);
4f0767ce 31180+out:
1facf9fc 31181+ return err;
31182+}
31183+
31184+struct xino_do_trunc_args {
31185+ struct super_block *sb;
31186+ struct au_branch *br;
31187+};
31188+
31189+static void xino_do_trunc(void *_args)
31190+{
31191+ struct xino_do_trunc_args *args = _args;
31192+ struct super_block *sb;
31193+ struct au_branch *br;
31194+ struct inode *dir;
31195+ int err;
31196+ aufs_bindex_t bindex;
31197+
31198+ err = 0;
31199+ sb = args->sb;
31200+ dir = sb->s_root->d_inode;
31201+ br = args->br;
31202+
31203+ si_noflush_write_lock(sb);
31204+ ii_read_lock_parent(dir);
31205+ bindex = au_br_index(sb, br->br_id);
31206+ err = au_xino_trunc(sb, bindex);
1facf9fc 31207+ ii_read_unlock(dir);
31208+ if (unlikely(err))
392086de 31209+ pr_warn("err b%d, (%d)\n", bindex, err);
1facf9fc 31210+ atomic_dec(&br->br_xino_running);
31211+ atomic_dec(&br->br_count);
1facf9fc 31212+ si_write_unlock(sb);
027c5e7a 31213+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 31214+ kfree(args);
31215+}
31216+
392086de
AM
31217+static int xino_trunc_test(struct super_block *sb, struct au_branch *br)
31218+{
31219+ int err;
31220+ struct kstatfs st;
31221+ struct au_sbinfo *sbinfo;
31222+
31223+ /* todo: si_xino_expire and the ratio should be customizable */
31224+ sbinfo = au_sbi(sb);
31225+ if (time_before(jiffies,
31226+ sbinfo->si_xino_jiffy + sbinfo->si_xino_expire))
31227+ return 0;
31228+
31229+ /* truncation border */
31230+ err = vfs_statfs(&br->br_xino.xi_file->f_path, &st);
31231+ if (unlikely(err)) {
31232+ AuErr1("statfs err %d, ignored\n", err);
31233+ return 0;
31234+ }
31235+ if (div64_u64(st.f_bfree * 100, st.f_blocks) >= AUFS_XINO_DEF_TRUNC)
31236+ return 0;
31237+
31238+ return 1;
31239+}
31240+
1facf9fc 31241+static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
31242+{
31243+ struct xino_do_trunc_args *args;
31244+ int wkq_err;
31245+
392086de 31246+ if (!xino_trunc_test(sb, br))
1facf9fc 31247+ return;
31248+
31249+ if (atomic_inc_return(&br->br_xino_running) > 1)
31250+ goto out;
31251+
31252+ /* lock and kfree() will be called in trunc_xino() */
31253+ args = kmalloc(sizeof(*args), GFP_NOFS);
31254+ if (unlikely(!args)) {
31255+ AuErr1("no memory\n");
31256+ goto out_args;
31257+ }
31258+
e49829fe 31259+ atomic_inc(&br->br_count);
1facf9fc 31260+ args->sb = sb;
31261+ args->br = br;
53392da6 31262+ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0);
1facf9fc 31263+ if (!wkq_err)
31264+ return; /* success */
31265+
4a4d8108 31266+ pr_err("wkq %d\n", wkq_err);
e49829fe 31267+ atomic_dec(&br->br_count);
1facf9fc 31268+
4f0767ce 31269+out_args:
1facf9fc 31270+ kfree(args);
4f0767ce 31271+out:
e49829fe 31272+ atomic_dec(&br->br_xino_running);
1facf9fc 31273+}
31274+
31275+/* ---------------------------------------------------------------------- */
31276+
31277+static int au_xino_do_write(au_writef_t write, struct file *file,
31278+ ino_t h_ino, ino_t ino)
31279+{
31280+ loff_t pos;
31281+ ssize_t sz;
31282+
31283+ pos = h_ino;
31284+ if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) {
31285+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
31286+ return -EFBIG;
31287+ }
31288+ pos *= sizeof(ino);
31289+ sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos);
31290+ if (sz == sizeof(ino))
31291+ return 0; /* success */
31292+
31293+ AuIOErr("write failed (%zd)\n", sz);
31294+ return -EIO;
31295+}
31296+
31297+/*
31298+ * write @ino to the xinofile for the specified branch{@sb, @bindex}
31299+ * at the position of @h_ino.
31300+ * even if @ino is zero, it is written to the xinofile and means no entry.
31301+ * if the size of the xino file on a specific filesystem exceeds the watermark,
31302+ * try truncating it.
31303+ */
31304+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
31305+ ino_t ino)
31306+{
31307+ int err;
31308+ unsigned int mnt_flags;
31309+ struct au_branch *br;
31310+
31311+ BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max)
31312+ || ((loff_t)-1) > 0);
dece6358 31313+ SiMustAnyLock(sb);
1facf9fc 31314+
31315+ mnt_flags = au_mntflags(sb);
31316+ if (!au_opt_test(mnt_flags, XINO))
31317+ return 0;
31318+
31319+ br = au_sbr(sb, bindex);
31320+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
31321+ h_ino, ino);
31322+ if (!err) {
31323+ if (au_opt_test(mnt_flags, TRUNC_XINO)
86dc4139 31324+ && au_test_fs_trunc_xino(au_br_sb(br)))
1facf9fc 31325+ xino_try_trunc(sb, br);
31326+ return 0; /* success */
31327+ }
31328+
31329+ AuIOErr("write failed (%d)\n", err);
31330+ return -EIO;
31331+}
31332+
31333+/* ---------------------------------------------------------------------- */
31334+
31335+/* aufs inode number bitmap */
31336+
31337+static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
31338+static ino_t xib_calc_ino(unsigned long pindex, int bit)
31339+{
31340+ ino_t ino;
31341+
31342+ AuDebugOn(bit < 0 || page_bits <= bit);
31343+ ino = AUFS_FIRST_INO + pindex * page_bits + bit;
31344+ return ino;
31345+}
31346+
31347+static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
31348+{
31349+ AuDebugOn(ino < AUFS_FIRST_INO);
31350+ ino -= AUFS_FIRST_INO;
31351+ *pindex = ino / page_bits;
31352+ *bit = ino % page_bits;
31353+}
31354+
31355+static int xib_pindex(struct super_block *sb, unsigned long pindex)
31356+{
31357+ int err;
31358+ loff_t pos;
31359+ ssize_t sz;
31360+ struct au_sbinfo *sbinfo;
31361+ struct file *xib;
31362+ unsigned long *p;
31363+
31364+ sbinfo = au_sbi(sb);
31365+ MtxMustLock(&sbinfo->si_xib_mtx);
31366+ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
31367+ || !au_opt_test(sbinfo->si_mntflags, XINO));
31368+
31369+ if (pindex == sbinfo->si_xib_last_pindex)
31370+ return 0;
31371+
31372+ xib = sbinfo->si_xib;
31373+ p = sbinfo->si_xib_buf;
31374+ pos = sbinfo->si_xib_last_pindex;
31375+ pos *= PAGE_SIZE;
31376+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
31377+ if (unlikely(sz != PAGE_SIZE))
31378+ goto out;
31379+
31380+ pos = pindex;
31381+ pos *= PAGE_SIZE;
c06a8ce3 31382+ if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE)
1facf9fc 31383+ sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
31384+ else {
31385+ memset(p, 0, PAGE_SIZE);
31386+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
31387+ }
31388+ if (sz == PAGE_SIZE) {
31389+ sbinfo->si_xib_last_pindex = pindex;
31390+ return 0; /* success */
31391+ }
31392+
4f0767ce 31393+out:
b752ccd1
AM
31394+ AuIOErr1("write failed (%zd)\n", sz);
31395+ err = sz;
31396+ if (sz >= 0)
31397+ err = -EIO;
31398+ return err;
31399+}
31400+
31401+/* ---------------------------------------------------------------------- */
31402+
31403+static void au_xib_clear_bit(struct inode *inode)
31404+{
31405+ int err, bit;
31406+ unsigned long pindex;
31407+ struct super_block *sb;
31408+ struct au_sbinfo *sbinfo;
31409+
31410+ AuDebugOn(inode->i_nlink);
31411+
31412+ sb = inode->i_sb;
31413+ xib_calc_bit(inode->i_ino, &pindex, &bit);
31414+ AuDebugOn(page_bits <= bit);
31415+ sbinfo = au_sbi(sb);
31416+ mutex_lock(&sbinfo->si_xib_mtx);
31417+ err = xib_pindex(sb, pindex);
31418+ if (!err) {
31419+ clear_bit(bit, sbinfo->si_xib_buf);
31420+ sbinfo->si_xib_next_bit = bit;
31421+ }
31422+ mutex_unlock(&sbinfo->si_xib_mtx);
31423+}
31424+
31425+/* for s_op->delete_inode() */
31426+void au_xino_delete_inode(struct inode *inode, const int unlinked)
31427+{
31428+ int err;
31429+ unsigned int mnt_flags;
31430+ aufs_bindex_t bindex, bend, bi;
31431+ unsigned char try_trunc;
31432+ struct au_iinfo *iinfo;
31433+ struct super_block *sb;
31434+ struct au_hinode *hi;
31435+ struct inode *h_inode;
31436+ struct au_branch *br;
31437+ au_writef_t xwrite;
31438+
31439+ sb = inode->i_sb;
31440+ mnt_flags = au_mntflags(sb);
31441+ if (!au_opt_test(mnt_flags, XINO)
31442+ || inode->i_ino == AUFS_ROOT_INO)
31443+ return;
31444+
31445+ if (unlinked) {
31446+ au_xigen_inc(inode);
31447+ au_xib_clear_bit(inode);
31448+ }
31449+
31450+ iinfo = au_ii(inode);
31451+ if (!iinfo)
31452+ return;
1facf9fc 31453+
b752ccd1
AM
31454+ bindex = iinfo->ii_bstart;
31455+ if (bindex < 0)
31456+ return;
1facf9fc 31457+
b752ccd1
AM
31458+ xwrite = au_sbi(sb)->si_xwrite;
31459+ try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO);
31460+ hi = iinfo->ii_hinode + bindex;
31461+ bend = iinfo->ii_bend;
31462+ for (; bindex <= bend; bindex++, hi++) {
31463+ h_inode = hi->hi_inode;
31464+ if (!h_inode
31465+ || (!unlinked && h_inode->i_nlink))
31466+ continue;
1facf9fc 31467+
b752ccd1
AM
31468+ /* inode may not be revalidated */
31469+ bi = au_br_index(sb, hi->hi_id);
31470+ if (bi < 0)
31471+ continue;
1facf9fc 31472+
b752ccd1
AM
31473+ br = au_sbr(sb, bi);
31474+ err = au_xino_do_write(xwrite, br->br_xino.xi_file,
31475+ h_inode->i_ino, /*ino*/0);
31476+ if (!err && try_trunc
86dc4139 31477+ && au_test_fs_trunc_xino(au_br_sb(br)))
b752ccd1 31478+ xino_try_trunc(sb, br);
1facf9fc 31479+ }
1facf9fc 31480+}
31481+
31482+/* get an unused inode number from bitmap */
31483+ino_t au_xino_new_ino(struct super_block *sb)
31484+{
31485+ ino_t ino;
31486+ unsigned long *p, pindex, ul, pend;
31487+ struct au_sbinfo *sbinfo;
31488+ struct file *file;
31489+ int free_bit, err;
31490+
31491+ if (!au_opt_test(au_mntflags(sb), XINO))
31492+ return iunique(sb, AUFS_FIRST_INO);
31493+
31494+ sbinfo = au_sbi(sb);
31495+ mutex_lock(&sbinfo->si_xib_mtx);
31496+ p = sbinfo->si_xib_buf;
31497+ free_bit = sbinfo->si_xib_next_bit;
31498+ if (free_bit < page_bits && !test_bit(free_bit, p))
31499+ goto out; /* success */
31500+ free_bit = find_first_zero_bit(p, page_bits);
31501+ if (free_bit < page_bits)
31502+ goto out; /* success */
31503+
31504+ pindex = sbinfo->si_xib_last_pindex;
31505+ for (ul = pindex - 1; ul < ULONG_MAX; 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+
31514+ file = sbinfo->si_xib;
c06a8ce3 31515+ pend = vfsub_f_size_read(file) / PAGE_SIZE;
1facf9fc 31516+ for (ul = pindex + 1; ul <= pend; ul++) {
31517+ err = xib_pindex(sb, ul);
31518+ if (unlikely(err))
31519+ goto out_err;
31520+ free_bit = find_first_zero_bit(p, page_bits);
31521+ if (free_bit < page_bits)
31522+ goto out; /* success */
31523+ }
31524+ BUG();
31525+
4f0767ce 31526+out:
1facf9fc 31527+ set_bit(free_bit, p);
7f207e10 31528+ sbinfo->si_xib_next_bit = free_bit + 1;
1facf9fc 31529+ pindex = sbinfo->si_xib_last_pindex;
31530+ mutex_unlock(&sbinfo->si_xib_mtx);
31531+ ino = xib_calc_ino(pindex, free_bit);
31532+ AuDbg("i%lu\n", (unsigned long)ino);
31533+ return ino;
4f0767ce 31534+out_err:
1facf9fc 31535+ mutex_unlock(&sbinfo->si_xib_mtx);
31536+ AuDbg("i0\n");
31537+ return 0;
31538+}
31539+
31540+/*
31541+ * read @ino from xinofile for the specified branch{@sb, @bindex}
31542+ * at the position of @h_ino.
31543+ * if @ino does not exist and @do_new is true, get new one.
31544+ */
31545+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
31546+ ino_t *ino)
31547+{
31548+ int err;
31549+ ssize_t sz;
31550+ loff_t pos;
31551+ struct file *file;
31552+ struct au_sbinfo *sbinfo;
31553+
31554+ *ino = 0;
31555+ if (!au_opt_test(au_mntflags(sb), XINO))
31556+ return 0; /* no xino */
31557+
31558+ err = 0;
31559+ sbinfo = au_sbi(sb);
31560+ pos = h_ino;
31561+ if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) {
31562+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
31563+ return -EFBIG;
31564+ }
31565+ pos *= sizeof(*ino);
31566+
31567+ file = au_sbr(sb, bindex)->br_xino.xi_file;
c06a8ce3 31568+ if (vfsub_f_size_read(file) < pos + sizeof(*ino))
1facf9fc 31569+ return 0; /* no ino */
31570+
31571+ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos);
31572+ if (sz == sizeof(*ino))
31573+ return 0; /* success */
31574+
31575+ err = sz;
31576+ if (unlikely(sz >= 0)) {
31577+ err = -EIO;
31578+ AuIOErr("xino read error (%zd)\n", sz);
31579+ }
31580+
31581+ return err;
31582+}
31583+
31584+/* ---------------------------------------------------------------------- */
31585+
31586+/* create and set a new xino file */
31587+
31588+struct file *au_xino_create(struct super_block *sb, char *fname, int silent)
31589+{
31590+ struct file *file;
31591+ struct dentry *h_parent, *d;
31592+ struct inode *h_dir;
31593+ int err;
31594+
31595+ /*
31596+ * at mount-time, and the xino file is the default path,
4a4d8108 31597+ * hnotify is disabled so we have no notify events to ignore.
1facf9fc 31598+ * when a user specified the xino, we cannot get au_hdir to be ignored.
31599+ */
7f207e10 31600+ file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 31601+ /* | __FMODE_NONOTIFY */,
1facf9fc 31602+ S_IRUGO | S_IWUGO);
31603+ if (IS_ERR(file)) {
31604+ if (!silent)
4a4d8108 31605+ pr_err("open %s(%ld)\n", fname, PTR_ERR(file));
1facf9fc 31606+ return file;
31607+ }
31608+
31609+ /* keep file count */
31610+ h_parent = dget_parent(file->f_dentry);
31611+ h_dir = h_parent->d_inode;
31612+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
31613+ /* mnt_want_write() is unnecessary here */
31614+ err = vfsub_unlink(h_dir, &file->f_path, /*force*/0);
31615+ mutex_unlock(&h_dir->i_mutex);
31616+ dput(h_parent);
31617+ if (unlikely(err)) {
31618+ if (!silent)
4a4d8108 31619+ pr_err("unlink %s(%d)\n", fname, err);
1facf9fc 31620+ goto out;
31621+ }
31622+
31623+ err = -EINVAL;
31624+ d = file->f_dentry;
31625+ if (unlikely(sb == d->d_sb)) {
31626+ if (!silent)
4a4d8108 31627+ pr_err("%s must be outside\n", fname);
1facf9fc 31628+ goto out;
31629+ }
31630+ if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
31631+ if (!silent)
4a4d8108
AM
31632+ pr_err("xino doesn't support %s(%s)\n",
31633+ fname, au_sbtype(d->d_sb));
1facf9fc 31634+ goto out;
31635+ }
31636+ return file; /* success */
31637+
4f0767ce 31638+out:
1facf9fc 31639+ fput(file);
31640+ file = ERR_PTR(err);
31641+ return file;
31642+}
31643+
31644+/*
31645+ * find another branch who is on the same filesystem of the specified
31646+ * branch{@btgt}. search until @bend.
31647+ */
31648+static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
31649+ aufs_bindex_t bend)
31650+{
31651+ aufs_bindex_t bindex;
31652+ struct super_block *tgt_sb = au_sbr_sb(sb, btgt);
31653+
31654+ for (bindex = 0; bindex < btgt; bindex++)
31655+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
31656+ return bindex;
31657+ for (bindex++; bindex <= bend; bindex++)
31658+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
31659+ return bindex;
31660+ return -1;
31661+}
31662+
31663+/* ---------------------------------------------------------------------- */
31664+
31665+/*
31666+ * initialize the xinofile for the specified branch @br
31667+ * at the place/path where @base_file indicates.
31668+ * test whether another branch is on the same filesystem or not,
31669+ * if @do_test is true.
31670+ */
31671+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
31672+ struct file *base_file, int do_test)
31673+{
31674+ int err;
31675+ ino_t ino;
31676+ aufs_bindex_t bend, bindex;
31677+ struct au_branch *shared_br, *b;
31678+ struct file *file;
31679+ struct super_block *tgt_sb;
31680+
31681+ shared_br = NULL;
31682+ bend = au_sbend(sb);
31683+ if (do_test) {
86dc4139 31684+ tgt_sb = au_br_sb(br);
1facf9fc 31685+ for (bindex = 0; bindex <= bend; bindex++) {
31686+ b = au_sbr(sb, bindex);
86dc4139 31687+ if (tgt_sb == au_br_sb(b)) {
1facf9fc 31688+ shared_br = b;
31689+ break;
31690+ }
31691+ }
31692+ }
31693+
31694+ if (!shared_br || !shared_br->br_xino.xi_file) {
31695+ struct au_xino_lock_dir ldir;
31696+
31697+ au_xino_lock_dir(sb, base_file, &ldir);
31698+ /* mnt_want_write() is unnecessary here */
31699+ file = au_xino_create2(base_file, NULL);
31700+ au_xino_unlock_dir(&ldir);
31701+ err = PTR_ERR(file);
31702+ if (IS_ERR(file))
31703+ goto out;
31704+ br->br_xino.xi_file = file;
31705+ } else {
31706+ br->br_xino.xi_file = shared_br->br_xino.xi_file;
31707+ get_file(br->br_xino.xi_file);
31708+ }
31709+
31710+ ino = AUFS_ROOT_INO;
31711+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
31712+ h_ino, ino);
b752ccd1
AM
31713+ if (unlikely(err)) {
31714+ fput(br->br_xino.xi_file);
31715+ br->br_xino.xi_file = NULL;
31716+ }
1facf9fc 31717+
4f0767ce 31718+out:
1facf9fc 31719+ return err;
31720+}
31721+
31722+/* ---------------------------------------------------------------------- */
31723+
31724+/* trucate a xino bitmap file */
31725+
31726+/* todo: slow */
31727+static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
31728+{
31729+ int err, bit;
31730+ ssize_t sz;
31731+ unsigned long pindex;
31732+ loff_t pos, pend;
31733+ struct au_sbinfo *sbinfo;
31734+ au_readf_t func;
31735+ ino_t *ino;
31736+ unsigned long *p;
31737+
31738+ err = 0;
31739+ sbinfo = au_sbi(sb);
dece6358 31740+ MtxMustLock(&sbinfo->si_xib_mtx);
1facf9fc 31741+ p = sbinfo->si_xib_buf;
31742+ func = sbinfo->si_xread;
c06a8ce3 31743+ pend = vfsub_f_size_read(file);
1facf9fc 31744+ pos = 0;
31745+ while (pos < pend) {
31746+ sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
31747+ err = sz;
31748+ if (unlikely(sz <= 0))
31749+ goto out;
31750+
31751+ err = 0;
31752+ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
31753+ if (unlikely(*ino < AUFS_FIRST_INO))
31754+ continue;
31755+
31756+ xib_calc_bit(*ino, &pindex, &bit);
31757+ AuDebugOn(page_bits <= bit);
31758+ err = xib_pindex(sb, pindex);
31759+ if (!err)
31760+ set_bit(bit, p);
31761+ else
31762+ goto out;
31763+ }
31764+ }
31765+
4f0767ce 31766+out:
1facf9fc 31767+ return err;
31768+}
31769+
31770+static int xib_restore(struct super_block *sb)
31771+{
31772+ int err;
31773+ aufs_bindex_t bindex, bend;
31774+ void *page;
31775+
31776+ err = -ENOMEM;
31777+ page = (void *)__get_free_page(GFP_NOFS);
31778+ if (unlikely(!page))
31779+ goto out;
31780+
31781+ err = 0;
31782+ bend = au_sbend(sb);
31783+ for (bindex = 0; !err && bindex <= bend; bindex++)
31784+ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0)
31785+ err = do_xib_restore
31786+ (sb, au_sbr(sb, bindex)->br_xino.xi_file, page);
31787+ else
31788+ AuDbg("b%d\n", bindex);
31789+ free_page((unsigned long)page);
31790+
4f0767ce 31791+out:
1facf9fc 31792+ return err;
31793+}
31794+
31795+int au_xib_trunc(struct super_block *sb)
31796+{
31797+ int err;
31798+ ssize_t sz;
31799+ loff_t pos;
31800+ struct au_xino_lock_dir ldir;
31801+ struct au_sbinfo *sbinfo;
31802+ unsigned long *p;
31803+ struct file *file;
31804+
dece6358
AM
31805+ SiMustWriteLock(sb);
31806+
1facf9fc 31807+ err = 0;
31808+ sbinfo = au_sbi(sb);
31809+ if (!au_opt_test(sbinfo->si_mntflags, XINO))
31810+ goto out;
31811+
31812+ file = sbinfo->si_xib;
c06a8ce3 31813+ if (vfsub_f_size_read(file) <= PAGE_SIZE)
1facf9fc 31814+ goto out;
31815+
31816+ au_xino_lock_dir(sb, file, &ldir);
31817+ /* mnt_want_write() is unnecessary here */
31818+ file = au_xino_create2(sbinfo->si_xib, NULL);
31819+ au_xino_unlock_dir(&ldir);
31820+ err = PTR_ERR(file);
31821+ if (IS_ERR(file))
31822+ goto out;
31823+ fput(sbinfo->si_xib);
31824+ sbinfo->si_xib = file;
31825+
31826+ p = sbinfo->si_xib_buf;
31827+ memset(p, 0, PAGE_SIZE);
31828+ pos = 0;
31829+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
31830+ if (unlikely(sz != PAGE_SIZE)) {
31831+ err = sz;
31832+ AuIOErr("err %d\n", err);
31833+ if (sz >= 0)
31834+ err = -EIO;
31835+ goto out;
31836+ }
31837+
31838+ mutex_lock(&sbinfo->si_xib_mtx);
31839+ /* mnt_want_write() is unnecessary here */
31840+ err = xib_restore(sb);
31841+ mutex_unlock(&sbinfo->si_xib_mtx);
31842+
31843+out:
31844+ return err;
31845+}
31846+
31847+/* ---------------------------------------------------------------------- */
31848+
31849+/*
31850+ * xino mount option handlers
31851+ */
31852+static au_readf_t find_readf(struct file *h_file)
31853+{
31854+ const struct file_operations *fop = h_file->f_op;
31855+
31856+ if (fop) {
31857+ if (fop->read)
31858+ return fop->read;
31859+ if (fop->aio_read)
31860+ return do_sync_read;
31861+ }
31862+ return ERR_PTR(-ENOSYS);
31863+}
31864+
31865+static au_writef_t find_writef(struct file *h_file)
31866+{
31867+ const struct file_operations *fop = h_file->f_op;
31868+
31869+ if (fop) {
31870+ if (fop->write)
31871+ return fop->write;
31872+ if (fop->aio_write)
31873+ return do_sync_write;
31874+ }
31875+ return ERR_PTR(-ENOSYS);
31876+}
31877+
31878+/* xino bitmap */
31879+static void xino_clear_xib(struct super_block *sb)
31880+{
31881+ struct au_sbinfo *sbinfo;
31882+
dece6358
AM
31883+ SiMustWriteLock(sb);
31884+
1facf9fc 31885+ sbinfo = au_sbi(sb);
31886+ sbinfo->si_xread = NULL;
31887+ sbinfo->si_xwrite = NULL;
31888+ if (sbinfo->si_xib)
31889+ fput(sbinfo->si_xib);
31890+ sbinfo->si_xib = NULL;
31891+ free_page((unsigned long)sbinfo->si_xib_buf);
31892+ sbinfo->si_xib_buf = NULL;
31893+}
31894+
31895+static int au_xino_set_xib(struct super_block *sb, struct file *base)
31896+{
31897+ int err;
31898+ loff_t pos;
31899+ struct au_sbinfo *sbinfo;
31900+ struct file *file;
31901+
dece6358
AM
31902+ SiMustWriteLock(sb);
31903+
1facf9fc 31904+ sbinfo = au_sbi(sb);
31905+ file = au_xino_create2(base, sbinfo->si_xib);
31906+ err = PTR_ERR(file);
31907+ if (IS_ERR(file))
31908+ goto out;
31909+ if (sbinfo->si_xib)
31910+ fput(sbinfo->si_xib);
31911+ sbinfo->si_xib = file;
31912+ sbinfo->si_xread = find_readf(file);
31913+ sbinfo->si_xwrite = find_writef(file);
31914+
31915+ err = -ENOMEM;
31916+ if (!sbinfo->si_xib_buf)
31917+ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
31918+ if (unlikely(!sbinfo->si_xib_buf))
31919+ goto out_unset;
31920+
31921+ sbinfo->si_xib_last_pindex = 0;
31922+ sbinfo->si_xib_next_bit = 0;
c06a8ce3 31923+ if (vfsub_f_size_read(file) < PAGE_SIZE) {
1facf9fc 31924+ pos = 0;
31925+ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
31926+ PAGE_SIZE, &pos);
31927+ if (unlikely(err != PAGE_SIZE))
31928+ goto out_free;
31929+ }
31930+ err = 0;
31931+ goto out; /* success */
31932+
4f0767ce 31933+out_free:
1facf9fc 31934+ free_page((unsigned long)sbinfo->si_xib_buf);
b752ccd1
AM
31935+ sbinfo->si_xib_buf = NULL;
31936+ if (err >= 0)
31937+ err = -EIO;
4f0767ce 31938+out_unset:
b752ccd1
AM
31939+ fput(sbinfo->si_xib);
31940+ sbinfo->si_xib = NULL;
31941+ sbinfo->si_xread = NULL;
31942+ sbinfo->si_xwrite = NULL;
4f0767ce 31943+out:
b752ccd1 31944+ return err;
1facf9fc 31945+}
31946+
b752ccd1
AM
31947+/* xino for each branch */
31948+static void xino_clear_br(struct super_block *sb)
31949+{
31950+ aufs_bindex_t bindex, bend;
31951+ struct au_branch *br;
1facf9fc 31952+
b752ccd1
AM
31953+ bend = au_sbend(sb);
31954+ for (bindex = 0; bindex <= bend; bindex++) {
31955+ br = au_sbr(sb, bindex);
31956+ if (!br || !br->br_xino.xi_file)
31957+ continue;
31958+
31959+ fput(br->br_xino.xi_file);
31960+ br->br_xino.xi_file = NULL;
31961+ }
31962+}
31963+
31964+static int au_xino_set_br(struct super_block *sb, struct file *base)
1facf9fc 31965+{
31966+ int err;
b752ccd1
AM
31967+ ino_t ino;
31968+ aufs_bindex_t bindex, bend, bshared;
31969+ struct {
31970+ struct file *old, *new;
31971+ } *fpair, *p;
31972+ struct au_branch *br;
31973+ struct inode *inode;
31974+ au_writef_t writef;
1facf9fc 31975+
b752ccd1
AM
31976+ SiMustWriteLock(sb);
31977+
31978+ err = -ENOMEM;
31979+ bend = au_sbend(sb);
31980+ fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS);
31981+ if (unlikely(!fpair))
1facf9fc 31982+ goto out;
31983+
b752ccd1
AM
31984+ inode = sb->s_root->d_inode;
31985+ ino = AUFS_ROOT_INO;
31986+ writef = au_sbi(sb)->si_xwrite;
31987+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
31988+ br = au_sbr(sb, bindex);
31989+ bshared = is_sb_shared(sb, bindex, bindex - 1);
31990+ if (bshared >= 0) {
31991+ /* shared xino */
31992+ *p = fpair[bshared];
31993+ get_file(p->new);
31994+ }
31995+
31996+ if (!p->new) {
31997+ /* new xino */
31998+ p->old = br->br_xino.xi_file;
31999+ p->new = au_xino_create2(base, br->br_xino.xi_file);
32000+ err = PTR_ERR(p->new);
32001+ if (IS_ERR(p->new)) {
32002+ p->new = NULL;
32003+ goto out_pair;
32004+ }
32005+ }
32006+
32007+ err = au_xino_do_write(writef, p->new,
32008+ au_h_iptr(inode, bindex)->i_ino, ino);
32009+ if (unlikely(err))
32010+ goto out_pair;
32011+ }
32012+
32013+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
32014+ br = au_sbr(sb, bindex);
32015+ if (br->br_xino.xi_file)
32016+ fput(br->br_xino.xi_file);
32017+ get_file(p->new);
32018+ br->br_xino.xi_file = p->new;
32019+ }
1facf9fc 32020+
4f0767ce 32021+out_pair:
b752ccd1
AM
32022+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++)
32023+ if (p->new)
32024+ fput(p->new);
32025+ else
32026+ break;
32027+ kfree(fpair);
4f0767ce 32028+out:
1facf9fc 32029+ return err;
32030+}
b752ccd1
AM
32031+
32032+void au_xino_clr(struct super_block *sb)
32033+{
32034+ struct au_sbinfo *sbinfo;
32035+
32036+ au_xigen_clr(sb);
32037+ xino_clear_xib(sb);
32038+ xino_clear_br(sb);
32039+ sbinfo = au_sbi(sb);
32040+ /* lvalue, do not call au_mntflags() */
32041+ au_opt_clr(sbinfo->si_mntflags, XINO);
32042+}
32043+
32044+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount)
32045+{
32046+ int err, skip;
32047+ struct dentry *parent, *cur_parent;
32048+ struct qstr *dname, *cur_name;
32049+ struct file *cur_xino;
32050+ struct inode *dir;
32051+ struct au_sbinfo *sbinfo;
32052+
32053+ SiMustWriteLock(sb);
32054+
32055+ err = 0;
32056+ sbinfo = au_sbi(sb);
32057+ parent = dget_parent(xino->file->f_dentry);
32058+ if (remount) {
32059+ skip = 0;
32060+ dname = &xino->file->f_dentry->d_name;
32061+ cur_xino = sbinfo->si_xib;
32062+ if (cur_xino) {
32063+ cur_parent = dget_parent(cur_xino->f_dentry);
32064+ cur_name = &cur_xino->f_dentry->d_name;
32065+ skip = (cur_parent == parent
32066+ && dname->len == cur_name->len
32067+ && !memcmp(dname->name, cur_name->name,
32068+ dname->len));
32069+ dput(cur_parent);
32070+ }
32071+ if (skip)
32072+ goto out;
32073+ }
32074+
32075+ au_opt_set(sbinfo->si_mntflags, XINO);
32076+ dir = parent->d_inode;
32077+ mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT);
32078+ /* mnt_want_write() is unnecessary here */
32079+ err = au_xino_set_xib(sb, xino->file);
32080+ if (!err)
32081+ err = au_xigen_set(sb, xino->file);
32082+ if (!err)
32083+ err = au_xino_set_br(sb, xino->file);
32084+ mutex_unlock(&dir->i_mutex);
32085+ if (!err)
32086+ goto out; /* success */
32087+
32088+ /* reset all */
32089+ AuIOErr("failed creating xino(%d).\n", err);
32090+
4f0767ce 32091+out:
b752ccd1
AM
32092+ dput(parent);
32093+ return err;
32094+}
32095+
32096+/* ---------------------------------------------------------------------- */
32097+
32098+/*
32099+ * create a xinofile at the default place/path.
32100+ */
32101+struct file *au_xino_def(struct super_block *sb)
32102+{
32103+ struct file *file;
32104+ char *page, *p;
32105+ struct au_branch *br;
32106+ struct super_block *h_sb;
32107+ struct path path;
32108+ aufs_bindex_t bend, bindex, bwr;
32109+
32110+ br = NULL;
32111+ bend = au_sbend(sb);
32112+ bwr = -1;
32113+ for (bindex = 0; bindex <= bend; bindex++) {
32114+ br = au_sbr(sb, bindex);
32115+ if (au_br_writable(br->br_perm)
86dc4139 32116+ && !au_test_fs_bad_xino(au_br_sb(br))) {
b752ccd1
AM
32117+ bwr = bindex;
32118+ break;
32119+ }
32120+ }
32121+
7f207e10
AM
32122+ if (bwr >= 0) {
32123+ file = ERR_PTR(-ENOMEM);
537831f9 32124+ page = (void *)__get_free_page(GFP_NOFS);
7f207e10
AM
32125+ if (unlikely(!page))
32126+ goto out;
86dc4139 32127+ path.mnt = au_br_mnt(br);
7f207e10
AM
32128+ path.dentry = au_h_dptr(sb->s_root, bwr);
32129+ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
32130+ file = (void *)p;
32131+ if (!IS_ERR(p)) {
32132+ strcat(p, "/" AUFS_XINO_FNAME);
32133+ AuDbg("%s\n", p);
32134+ file = au_xino_create(sb, p, /*silent*/0);
32135+ if (!IS_ERR(file))
32136+ au_xino_brid_set(sb, br->br_id);
32137+ }
537831f9 32138+ free_page((unsigned long)page);
7f207e10
AM
32139+ } else {
32140+ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
32141+ if (IS_ERR(file))
32142+ goto out;
32143+ h_sb = file->f_dentry->d_sb;
32144+ if (unlikely(au_test_fs_bad_xino(h_sb))) {
32145+ pr_err("xino doesn't support %s(%s)\n",
32146+ AUFS_XINO_DEFPATH, au_sbtype(h_sb));
32147+ fput(file);
32148+ file = ERR_PTR(-EINVAL);
32149+ }
32150+ if (!IS_ERR(file))
32151+ au_xino_brid_set(sb, -1);
32152+ }
0c5527e5 32153+
7f207e10
AM
32154+out:
32155+ return file;
32156+}
32157+
32158+/* ---------------------------------------------------------------------- */
32159+
32160+int au_xino_path(struct seq_file *seq, struct file *file)
32161+{
32162+ int err;
32163+
32164+ err = au_seq_path(seq, &file->f_path);
32165+ if (unlikely(err < 0))
32166+ goto out;
32167+
32168+ err = 0;
32169+#define Deleted "\\040(deleted)"
32170+ seq->count -= sizeof(Deleted) - 1;
32171+ AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
32172+ sizeof(Deleted) - 1));
32173+#undef Deleted
32174+
32175+out:
32176+ return err;
32177+}
32178diff -urN /usr/share/empty/include/linux/aufs_type.h linux/include/linux/aufs_type.h
32179--- /usr/share/empty/include/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
86dc4139 32180+++ linux/include/linux/aufs_type.h 2013-07-06 13:20:47.760198800 +0200
537831f9
AM
32181@@ -0,0 +1,19 @@
32182+/*
7a9e40b8 32183+ * Copyright (C) 2012-2013 Junjiro R. Okajima
537831f9
AM
32184+ *
32185+ * This program, aufs is free software; you can redistribute it and/or modify
32186+ * it under the terms of the GNU General Public License as published by
32187+ * the Free Software Foundation; either version 2 of the License, or
32188+ * (at your option) any later version.
32189+ *
32190+ * This program is distributed in the hope that it will be useful,
32191+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32192+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32193+ * GNU General Public License for more details.
32194+ *
32195+ * You should have received a copy of the GNU General Public License
32196+ * along with this program; if not, write to the Free Software
32197+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32198+ */
32199+
32200+#include <uapi/linux/aufs_type.h>
32201diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h
32202--- /usr/share/empty/include/uapi/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
392086de
AM
32203+++ linux/include/uapi/linux/aufs_type.h 2013-10-26 16:51:32.276373845 +0200
32204@@ -0,0 +1,282 @@
7f207e10 32205+/*
7a9e40b8 32206+ * Copyright (C) 2005-2013 Junjiro R. Okajima
7f207e10
AM
32207+ *
32208+ * This program, aufs is free software; you can redistribute it and/or modify
32209+ * it under the terms of the GNU General Public License as published by
32210+ * the Free Software Foundation; either version 2 of the License, or
32211+ * (at your option) any later version.
32212+ *
32213+ * This program is distributed in the hope that it will be useful,
32214+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32215+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32216+ * GNU General Public License for more details.
32217+ *
32218+ * You should have received a copy of the GNU General Public License
32219+ * along with this program; if not, write to the Free Software
32220+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32221+ */
32222+
32223+#ifndef __AUFS_TYPE_H__
32224+#define __AUFS_TYPE_H__
32225+
f6c5ef8b
AM
32226+#define AUFS_NAME "aufs"
32227+
9dbd164d 32228+#ifdef __KERNEL__
f6c5ef8b
AM
32229+/*
32230+ * define it before including all other headers.
32231+ * sched.h may use pr_* macros before defining "current", so define the
32232+ * no-current version first, and re-define later.
32233+ */
32234+#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__
32235+#include <linux/sched.h>
32236+#undef pr_fmt
a2a7ad62
AM
32237+#define pr_fmt(fmt) \
32238+ AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \
32239+ (int)sizeof(current->comm), current->comm, current->pid
9dbd164d
AM
32240+#else
32241+#include <stdint.h>
32242+#include <sys/types.h>
f6c5ef8b 32243+#endif /* __KERNEL__ */
7f207e10 32244+
f6c5ef8b
AM
32245+#include <linux/limits.h>
32246+
392086de 32247+#define AUFS_VERSION "3.x-rcN-20131014"
7f207e10
AM
32248+
32249+/* todo? move this to linux-2.6.19/include/magic.h */
32250+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
32251+
32252+/* ---------------------------------------------------------------------- */
32253+
32254+#ifdef CONFIG_AUFS_BRANCH_MAX_127
9dbd164d 32255+typedef int8_t aufs_bindex_t;
7f207e10
AM
32256+#define AUFS_BRANCH_MAX 127
32257+#else
9dbd164d 32258+typedef int16_t aufs_bindex_t;
7f207e10
AM
32259+#ifdef CONFIG_AUFS_BRANCH_MAX_511
32260+#define AUFS_BRANCH_MAX 511
32261+#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
32262+#define AUFS_BRANCH_MAX 1023
32263+#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
32264+#define AUFS_BRANCH_MAX 32767
32265+#endif
32266+#endif
32267+
32268+#ifdef __KERNEL__
32269+#ifndef AUFS_BRANCH_MAX
32270+#error unknown CONFIG_AUFS_BRANCH_MAX value
32271+#endif
32272+#endif /* __KERNEL__ */
32273+
32274+/* ---------------------------------------------------------------------- */
32275+
7f207e10
AM
32276+#define AUFS_FSTYPE AUFS_NAME
32277+
32278+#define AUFS_ROOT_INO 2
32279+#define AUFS_FIRST_INO 11
32280+
32281+#define AUFS_WH_PFX ".wh."
32282+#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1)
32283+#define AUFS_WH_TMP_LEN 4
86dc4139 32284+/* a limit for rmdir/rename a dir and copyup */
7f207e10
AM
32285+#define AUFS_MAX_NAMELEN (NAME_MAX \
32286+ - AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\
32287+ - 1 /* dot */\
32288+ - AUFS_WH_TMP_LEN) /* hex */
32289+#define AUFS_XINO_FNAME "." AUFS_NAME ".xino"
32290+#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME
392086de
AM
32291+#define AUFS_XINO_DEF_SEC 30 /* seconds */
32292+#define AUFS_XINO_DEF_TRUNC 45 /* percentage */
7f207e10
AM
32293+#define AUFS_DIRWH_DEF 3
32294+#define AUFS_RDCACHE_DEF 10 /* seconds */
027c5e7a 32295+#define AUFS_RDCACHE_MAX 3600 /* seconds */
7f207e10
AM
32296+#define AUFS_RDBLK_DEF 512 /* bytes */
32297+#define AUFS_RDHASH_DEF 32
32298+#define AUFS_WKQ_NAME AUFS_NAME "d"
027c5e7a
AM
32299+#define AUFS_MFS_DEF_SEC 30 /* seconds */
32300+#define AUFS_MFS_MAX_SEC 3600 /* seconds */
86dc4139 32301+#define AUFS_PLINK_WARN 50 /* number of plinks in a single bucket */
7f207e10
AM
32302+
32303+/* pseudo-link maintenace under /proc */
32304+#define AUFS_PLINK_MAINT_NAME "plink_maint"
32305+#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME
32306+#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME
32307+
32308+#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */
32309+#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME
32310+
32311+#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME
32312+#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk"
32313+#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph"
32314+
32315+/* doubly whiteouted */
32316+#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME
32317+#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME
32318+#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME
32319+
1e00d052 32320+/* branch permissions and attributes */
7f207e10
AM
32321+#define AUFS_BRPERM_RW "rw"
32322+#define AUFS_BRPERM_RO "ro"
32323+#define AUFS_BRPERM_RR "rr"
1e00d052
AM
32324+#define AUFS_BRRATTR_WH "wh"
32325+#define AUFS_BRWATTR_NLWH "nolwh"
86dc4139 32326+#define AUFS_BRATTR_UNPIN "unpin"
7f207e10
AM
32327+
32328+/* ---------------------------------------------------------------------- */
32329+
32330+/* ioctl */
32331+enum {
32332+ /* readdir in userspace */
32333+ AuCtl_RDU,
32334+ AuCtl_RDU_INO,
32335+
32336+ /* pathconf wrapper */
027c5e7a
AM
32337+ AuCtl_WBR_FD,
32338+
32339+ /* busy inode */
c2b27bf2
AM
32340+ AuCtl_IBUSY,
32341+
32342+ /* move-down */
32343+ AuCtl_MVDOWN
7f207e10
AM
32344+};
32345+
32346+/* borrowed from linux/include/linux/kernel.h */
32347+#ifndef ALIGN
32348+#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1)
32349+#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
32350+#endif
32351+
32352+/* borrowed from linux/include/linux/compiler-gcc3.h */
32353+#ifndef __aligned
32354+#define __aligned(x) __attribute__((aligned(x)))
53392da6
AM
32355+#endif
32356+
32357+#ifdef __KERNEL__
32358+#ifndef __packed
7f207e10
AM
32359+#define __packed __attribute__((packed))
32360+#endif
53392da6 32361+#endif
7f207e10
AM
32362+
32363+struct au_rdu_cookie {
9dbd164d
AM
32364+ uint64_t h_pos;
32365+ int16_t bindex;
32366+ uint8_t flags;
32367+ uint8_t pad;
32368+ uint32_t generation;
7f207e10
AM
32369+} __aligned(8);
32370+
32371+struct au_rdu_ent {
9dbd164d
AM
32372+ uint64_t ino;
32373+ int16_t bindex;
32374+ uint8_t type;
32375+ uint8_t nlen;
32376+ uint8_t wh;
7f207e10
AM
32377+ char name[0];
32378+} __aligned(8);
32379+
32380+static inline int au_rdu_len(int nlen)
32381+{
32382+ /* include the terminating NULL */
32383+ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1,
9dbd164d 32384+ sizeof(uint64_t));
7f207e10
AM
32385+}
32386+
32387+union au_rdu_ent_ul {
32388+ struct au_rdu_ent __user *e;
9dbd164d 32389+ uint64_t ul;
7f207e10
AM
32390+};
32391+
32392+enum {
32393+ AufsCtlRduV_SZ,
32394+ AufsCtlRduV_End
32395+};
32396+
32397+struct aufs_rdu {
32398+ /* input */
32399+ union {
9dbd164d
AM
32400+ uint64_t sz; /* AuCtl_RDU */
32401+ uint64_t nent; /* AuCtl_RDU_INO */
7f207e10
AM
32402+ };
32403+ union au_rdu_ent_ul ent;
9dbd164d 32404+ uint16_t verify[AufsCtlRduV_End];
7f207e10
AM
32405+
32406+ /* input/output */
9dbd164d 32407+ uint32_t blk;
7f207e10
AM
32408+
32409+ /* output */
32410+ union au_rdu_ent_ul tail;
32411+ /* number of entries which were added in a single call */
9dbd164d
AM
32412+ uint64_t rent;
32413+ uint8_t full;
32414+ uint8_t shwh;
7f207e10
AM
32415+
32416+ struct au_rdu_cookie cookie;
32417+} __aligned(8);
32418+
1e00d052
AM
32419+/* ---------------------------------------------------------------------- */
32420+
32421+struct aufs_wbr_fd {
9dbd164d
AM
32422+ uint32_t oflags;
32423+ int16_t brid;
1e00d052
AM
32424+} __aligned(8);
32425+
32426+/* ---------------------------------------------------------------------- */
32427+
027c5e7a 32428+struct aufs_ibusy {
9dbd164d
AM
32429+ uint64_t ino, h_ino;
32430+ int16_t bindex;
027c5e7a
AM
32431+} __aligned(8);
32432+
1e00d052
AM
32433+/* ---------------------------------------------------------------------- */
32434+
392086de
AM
32435+/* error code for move-down */
32436+/* the actual message strings are implemented in aufs-util.git */
32437+enum {
32438+ EAU_MVDOWN_OPAQUE = 1,
32439+ EAU_MVDOWN_WHITEOUT,
32440+ EAU_MVDOWN_UPPER,
32441+ EAU_MVDOWN_BOTTOM,
32442+ EAU_MVDOWN_NOUPPER,
32443+ EAU_MVDOWN_NOLOWERBR,
32444+ EAU_Last
32445+};
32446+
c2b27bf2 32447+/* flags for move-down */
392086de
AM
32448+#define AUFS_MVDOWN_DMSG 1
32449+#define AUFS_MVDOWN_OWLOWER (1 << 1) /* overwrite lower */
32450+#define AUFS_MVDOWN_KUPPER (1 << 2) /* keep upper */
32451+#define AUFS_MVDOWN_ROLOWER (1 << 3) /* do even if lower is RO */
32452+#define AUFS_MVDOWN_ROLOWER_R (1 << 4) /* did on lower RO */
32453+#define AUFS_MVDOWN_ROUPPER (1 << 5) /* do even if upper is RO */
32454+#define AUFS_MVDOWN_ROUPPER_R (1 << 6) /* did on upper RO */
32455+#define AUFS_MVDOWN_BRID_UPPER (1 << 7) /* upper brid */
32456+#define AUFS_MVDOWN_BRID_LOWER (1 << 8) /* lower brid */
c2b27bf2
AM
32457+/* will be added more */
32458+
392086de
AM
32459+enum {
32460+ AUFS_MVDOWN_UPPER,
32461+ AUFS_MVDOWN_LOWER,
32462+ AUFS_MVDOWN_NARRAY
32463+};
32464+
c2b27bf2 32465+struct aufs_mvdown {
392086de
AM
32466+ uint32_t flags;
32467+ struct {
32468+ int16_t bindex;
32469+ int16_t brid;
32470+ } a[AUFS_MVDOWN_NARRAY];
32471+ int8_t au_errno;
c2b27bf2
AM
32472+ /* will be added more */
32473+} __aligned(8);
32474+
32475+/* ---------------------------------------------------------------------- */
32476+
7f207e10
AM
32477+#define AuCtlType 'A'
32478+#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu)
32479+#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu)
1e00d052
AM
32480+#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \
32481+ struct aufs_wbr_fd)
027c5e7a 32482+#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
392086de
AM
32483+#define AUFS_CTL_MVDOWN _IOWR(AuCtlType, AuCtl_MVDOWN, \
32484+ struct aufs_mvdown)
7f207e10
AM
32485+
32486+#endif /* __AUFS_TYPE_H__ */
This page took 5.340183 seconds and 4 git commands to generate.