]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-aufs4.patch
- 4.9.168
[packages/kernel.git] / kernel-aufs4.patch
CommitLineData
f2c43d5f 1aufs4.9 kbuild patch
7f207e10
AM
2
3diff --git a/fs/Kconfig b/fs/Kconfig
f2c43d5f 4index 4bd03a2..620e01b 100644
7f207e10
AM
5--- a/fs/Kconfig
6+++ b/fs/Kconfig
f2c43d5f 7@@ -249,6 +249,7 @@ source "fs/pstore/Kconfig"
5527c038 8 source "fs/sysv/Kconfig"
7e9cd9fe 9 source "fs/ufs/Kconfig"
7f207e10
AM
10 source "fs/exofs/Kconfig"
11+source "fs/aufs/Kconfig"
12
13 endif # MISC_FILESYSTEMS
14
15diff --git a/fs/Makefile b/fs/Makefile
e2f27e51 16index ed2b632..aa6d14b 100644
7f207e10
AM
17--- a/fs/Makefile
18+++ b/fs/Makefile
e2f27e51 19@@ -129,3 +129,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
f2c43d5f 25index cd2be1c..78f3c68 100644
c06a8ce3
AM
26--- a/include/uapi/linux/Kbuild
27+++ b/include/uapi/linux/Kbuild
5527c038 28@@ -59,6 +59,7 @@ header-y += atmsvc.h
03673fb0
JR
29 header-y += atm_tcp.h
30 header-y += atm_zatm.h
c06a8ce3
AM
31 header-y += audit.h
32+header-y += aufs_type.h
c06a8ce3 33 header-y += auto_fs4.h
03673fb0 34 header-y += auto_fs.h
c06a8ce3 35 header-y += auxvec.h
f2c43d5f 36aufs4.9 base patch
7f207e10 37
c1595e42 38diff --git a/MAINTAINERS b/MAINTAINERS
f2c43d5f 39index 63cefa6..d78b954 100644
c1595e42
JR
40--- a/MAINTAINERS
41+++ b/MAINTAINERS
f2c43d5f 42@@ -2293,6 +2293,19 @@ F: include/linux/audit.h
c1595e42
JR
43 F: include/uapi/linux/audit.h
44 F: kernel/audit*
45
46+AUFS (advanced multi layered unification filesystem) FILESYSTEM
47+M: "J. R. Okajima" <hooanon05g@gmail.com>
48+L: linux-unionfs@vger.kernel.org
49+L: aufs-users@lists.sourceforge.net (members only)
50+W: http://aufs.sourceforge.net
5527c038 51+T: git://github.com/sfjro/aufs4-linux.git
c1595e42
JR
52+S: Supported
53+F: Documentation/filesystems/aufs/
54+F: Documentation/ABI/testing/debugfs-aufs
55+F: Documentation/ABI/testing/sysfs-aufs
56+F: fs/aufs/
57+F: include/uapi/linux/aufs_type.h
58+
59 AUXILIARY DISPLAY DRIVERS
60 M: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com>
61 W: http://miguelojeda.es/auxdisplay.htm
392086de 62diff --git a/drivers/block/loop.c b/drivers/block/loop.c
f2c43d5f 63index fa1b7a9..6ee9235 100644
392086de
AM
64--- a/drivers/block/loop.c
65+++ b/drivers/block/loop.c
e2f27e51 66@@ -701,6 +701,24 @@ static inline int is_loop_device(struct file *file)
392086de
AM
67 return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
68 }
69
70+/*
71+ * for AUFS
72+ * no get/put for file.
73+ */
74+struct file *loop_backing_file(struct super_block *sb)
75+{
76+ struct file *ret;
77+ struct loop_device *l;
78+
79+ ret = NULL;
80+ if (MAJOR(sb->s_dev) == LOOP_MAJOR) {
81+ l = sb->s_bdev->bd_disk->private_data;
82+ ret = l->lo_backing_file;
83+ }
84+ return ret;
85+}
febd17d6 86+EXPORT_SYMBOL_GPL(loop_backing_file);
392086de
AM
87+
88 /* loop sysfs attributes */
89
90 static ssize_t loop_attr_show(struct device *dev, char *page,
c1595e42 91diff --git a/fs/dcache.c b/fs/dcache.c
e2f27e51 92index 5c7cc95..df0268c 100644
c1595e42
JR
93--- a/fs/dcache.c
94+++ b/fs/dcache.c
e2f27e51 95@@ -1164,7 +1164,7 @@ enum d_walk_ret {
c1595e42
JR
96 *
97 * The @enter() and @finish() callbacks are called with d_lock held.
98 */
99-static void d_walk(struct dentry *parent, void *data,
100+void d_walk(struct dentry *parent, void *data,
101 enum d_walk_ret (*enter)(void *, struct dentry *),
102 void (*finish)(void *))
103 {
febd17d6
JR
104diff --git a/fs/fcntl.c b/fs/fcntl.c
105index 350a2c8..6f42279 100644
106--- a/fs/fcntl.c
107+++ b/fs/fcntl.c
108@@ -29,7 +29,7 @@
109
110 #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
111
112-static int setfl(int fd, struct file * filp, unsigned long arg)
113+int setfl(int fd, struct file * filp, unsigned long arg)
114 {
115 struct inode * inode = file_inode(filp);
116 int error = 0;
117@@ -60,6 +60,8 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
118
119 if (filp->f_op->check_flags)
120 error = filp->f_op->check_flags(arg);
121+ if (!error && filp->f_op->setfl)
122+ error = filp->f_op->setfl(filp, arg);
123 if (error)
124 return error;
125
5afbbe0d 126diff --git a/fs/inode.c b/fs/inode.c
f2c43d5f 127index 88110fd..9a9ba3a 100644
5afbbe0d
AM
128--- a/fs/inode.c
129+++ b/fs/inode.c
ae9dfd79 130@@ -1642,7 +1642,7 @@ EXPORT_SYMBOL(generic_update_time);
5afbbe0d
AM
131 * This does the actual work of updating an inodes time or version. Must have
132 * had called mnt_want_write() before calling this.
133 */
134-static int update_time(struct inode *inode, struct timespec *time, int flags)
135+int update_time(struct inode *inode, struct timespec *time, int flags)
136 {
137 int (*update_time)(struct inode *, struct timespec *, int);
138
ae9dfd79
AM
139diff --git a/fs/namespace.c b/fs/namespace.c
140index e6c234b..db0b1ac 100644
141--- a/fs/namespace.c
142+++ b/fs/namespace.c
143@@ -787,6 +787,12 @@ static inline int check_mnt(struct mount *mnt)
144 return mnt->mnt_ns == current->nsproxy->mnt_ns;
145 }
146
147+/* for aufs, CONFIG_AUFS_BR_FUSE */
148+int is_current_mnt_ns(struct vfsmount *mnt)
149+{
150+ return check_mnt(real_mount(mnt));
151+}
152+
153 /*
154 * vfsmount lock must be held for write
155 */
5527c038 156diff --git a/fs/read_write.c b/fs/read_write.c
f2c43d5f 157index 190e0d36..4052813 100644
5527c038
JR
158--- a/fs/read_write.c
159+++ b/fs/read_write.c
5afbbe0d 160@@ -515,6 +515,28 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count,
5527c038
JR
161 }
162 EXPORT_SYMBOL(__vfs_write);
163
164+vfs_readf_t vfs_readf(struct file *file)
165+{
166+ const struct file_operations *fop = file->f_op;
167+
168+ if (fop->read)
169+ return fop->read;
170+ if (fop->read_iter)
171+ return new_sync_read;
172+ return ERR_PTR(-ENOSYS);
173+}
174+
175+vfs_writef_t vfs_writef(struct file *file)
176+{
177+ const struct file_operations *fop = file->f_op;
178+
179+ if (fop->write)
180+ return fop->write;
181+ if (fop->write_iter)
182+ return new_sync_write;
183+ return ERR_PTR(-ENOSYS);
184+}
185+
186 ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
187 {
188 mm_segment_t old_fs;
7f207e10 189diff --git a/fs/splice.c b/fs/splice.c
f2c43d5f 190index 5a7750b..28160a7 100644
7f207e10
AM
191--- a/fs/splice.c
192+++ b/fs/splice.c
ae9dfd79 193@@ -855,8 +855,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
7f207e10
AM
194 /*
195 * Attempt to initiate a splice from pipe to file.
196 */
197-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
198- loff_t *ppos, size_t len, unsigned int flags)
199+long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
200+ loff_t *ppos, size_t len, unsigned int flags)
201 {
202 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
203 loff_t *, size_t, unsigned int);
f2c43d5f 204@@ -872,9 +872,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
7f207e10
AM
205 /*
206 * Attempt to initiate a splice from a file to a pipe.
207 */
208-static long do_splice_to(struct file *in, loff_t *ppos,
209- struct pipe_inode_info *pipe, size_t len,
210- unsigned int flags)
211+long do_splice_to(struct file *in, loff_t *ppos,
212+ struct pipe_inode_info *pipe, size_t len,
213+ unsigned int flags)
214 {
215 ssize_t (*splice_read)(struct file *, loff_t *,
216 struct pipe_inode_info *, size_t, unsigned int);
ae9dfd79
AM
217diff --git a/fs/sync.c b/fs/sync.c
218index 2a54c1f..7a5fa3f 100644
219--- a/fs/sync.c
220+++ b/fs/sync.c
221@@ -27,7 +27,7 @@
222 * wait == 1 case since in that case write_inode() functions do
223 * sync_dirty_buffer() and thus effectively write one block at a time.
224 */
225-static int __sync_filesystem(struct super_block *sb, int wait)
226+int __sync_filesystem(struct super_block *sb, int wait)
227 {
228 if (wait)
229 sync_inodes_sb(sb);
b912730e 230diff --git a/include/linux/file.h b/include/linux/file.h
5afbbe0d 231index 7444f5f..bdac0be 100644
b912730e
AM
232--- a/include/linux/file.h
233+++ b/include/linux/file.h
ae9dfd79 234@@ -19,6 +19,7 @@ struct dentry;
b912730e
AM
235 struct path;
236 extern struct file *alloc_file(struct path *, fmode_t mode,
237 const struct file_operations *fop);
238+extern struct file *get_empty_filp(void);
239
240 static inline void fput_light(struct file *file, int fput_needed)
241 {
5527c038 242diff --git a/include/linux/fs.h b/include/linux/fs.h
ae9dfd79 243index dc0478c..a02be40d 100644
5527c038
JR
244--- a/include/linux/fs.h
245+++ b/include/linux/fs.h
ae9dfd79 246@@ -1291,6 +1291,7 @@ extern void fasync_free(struct fasync_struct *);
febd17d6
JR
247 /* can be called from interrupts */
248 extern void kill_fasync(struct fasync_struct **, int, int);
249
250+extern int setfl(int fd, struct file * filp, unsigned long arg);
251 extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
252 extern void f_setown(struct file *filp, unsigned long arg, int force);
253 extern void f_delown(struct file *filp);
f2c43d5f 254@@ -1715,6 +1716,7 @@ struct file_operations {
febd17d6
JR
255 ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
256 unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
257 int (*check_flags)(int);
258+ int (*setfl)(struct file *, unsigned long);
259 int (*flock) (struct file *, int, struct file_lock *);
260 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
261 ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
f2c43d5f 262@@ -1768,6 +1770,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
5527c038
JR
263 struct iovec *fast_pointer,
264 struct iovec **ret_pointer);
265
266+typedef ssize_t (*vfs_readf_t)(struct file *, char __user *, size_t, loff_t *);
267+typedef ssize_t (*vfs_writef_t)(struct file *, const char __user *, size_t,
268+ loff_t *);
269+vfs_readf_t vfs_readf(struct file *file);
270+vfs_writef_t vfs_writef(struct file *file);
271+
272 extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *);
273 extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *);
274 extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *);
ae9dfd79 275@@ -2140,6 +2148,7 @@ extern int current_umask(void);
5afbbe0d
AM
276 extern void ihold(struct inode * inode);
277 extern void iput(struct inode *);
278 extern int generic_update_time(struct inode *, struct timespec *, int);
279+extern int update_time(struct inode *, struct timespec *, int);
280
281 /* /sys/fs */
282 extern struct kobject *fs_kobj;
ae9dfd79
AM
283@@ -2419,6 +2428,7 @@ static inline bool sb_is_blkdev_sb(struct super_block *sb)
284 return false;
285 }
286 #endif
287+extern int __sync_filesystem(struct super_block *, int);
288 extern int sync_filesystem(struct super_block *);
289 extern const struct file_operations def_blk_fops;
290 extern const struct file_operations def_chr_fops;
291diff --git a/include/linux/mnt_namespace.h b/include/linux/mnt_namespace.h
292index 12b2ab5..8b810d1 100644
293--- a/include/linux/mnt_namespace.h
294+++ b/include/linux/mnt_namespace.h
295@@ -5,11 +5,14 @@
296 struct mnt_namespace;
297 struct fs_struct;
298 struct user_namespace;
299+struct vfsmount;
300
301 extern struct mnt_namespace *copy_mnt_ns(unsigned long, struct mnt_namespace *,
302 struct user_namespace *, struct fs_struct *);
303 extern void put_mnt_ns(struct mnt_namespace *ns);
304
305+extern int is_current_mnt_ns(struct vfsmount *mnt);
306+
307 extern const struct file_operations proc_mounts_operations;
308 extern const struct file_operations proc_mountinfo_operations;
309 extern const struct file_operations proc_mountstats_operations;
1e00d052 310diff --git a/include/linux/splice.h b/include/linux/splice.h
f2c43d5f 311index 00a2116..1f0a4a2 100644
1e00d052
AM
312--- a/include/linux/splice.h
313+++ b/include/linux/splice.h
ae9dfd79 314@@ -86,4 +86,10 @@ extern void spd_release_page(struct splice_pipe_desc *, unsigned int);
4b3da204
AM
315
316 extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
106341ce 317 extern const struct pipe_buf_operations default_pipe_buf_ops;
1e00d052
AM
318+
319+extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
320+ loff_t *ppos, size_t len, unsigned int flags);
321+extern long do_splice_to(struct file *in, loff_t *ppos,
322+ struct pipe_inode_info *pipe, size_t len,
323+ unsigned int flags);
324 #endif
f2c43d5f 325aufs4.9 mmap patch
fb47a38f 326
c1595e42 327diff --git a/fs/proc/base.c b/fs/proc/base.c
f2c43d5f 328index ca651ac..0e8551a 100644
c1595e42
JR
329--- a/fs/proc/base.c
330+++ b/fs/proc/base.c
f2c43d5f 331@@ -1953,7 +1953,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path)
c1595e42
JR
332 down_read(&mm->mmap_sem);
333 vma = find_exact_vma(mm, vm_start, vm_end);
334 if (vma && vma->vm_file) {
335- *path = vma->vm_file->f_path;
336+ *path = vma_pr_or_file(vma)->f_path;
337 path_get(path);
338 rc = 0;
339 }
fb47a38f 340diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
c2c0f25c 341index f8595e8..cb8eda0 100644
fb47a38f
JR
342--- a/fs/proc/nommu.c
343+++ b/fs/proc/nommu.c
076b876e 344@@ -45,7 +45,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
fb47a38f
JR
345 file = region->vm_file;
346
347 if (file) {
348- struct inode *inode = file_inode(region->vm_file);
349+ struct inode *inode;
076b876e 350+
fb47a38f
JR
351+ file = vmr_pr_or_file(region);
352+ inode = file_inode(file);
353 dev = inode->i_sb->s_dev;
354 ino = inode->i_ino;
355 }
356diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
f2c43d5f 357index 35b92d8..5b981db 100644
fb47a38f
JR
358--- a/fs/proc/task_mmu.c
359+++ b/fs/proc/task_mmu.c
ae9dfd79 360@@ -291,7 +291,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
fb47a38f
JR
361 const char *name = NULL;
362
363 if (file) {
364- struct inode *inode = file_inode(vma->vm_file);
365+ struct inode *inode;
076b876e 366+
fb47a38f
JR
367+ file = vma_pr_or_file(vma);
368+ inode = file_inode(file);
369 dev = inode->i_sb->s_dev;
370 ino = inode->i_ino;
371 pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
f2c43d5f 372@@ -1627,7 +1630,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
076b876e
AM
373 struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
374 struct vm_area_struct *vma = v;
375 struct numa_maps *md = &numa_priv->md;
376- struct file *file = vma->vm_file;
377+ struct file *file = vma_pr_or_file(vma);
076b876e 378 struct mm_struct *mm = vma->vm_mm;
7e9cd9fe
AM
379 struct mm_walk walk = {
380 .hugetlb_entry = gather_hugetlb_stats,
fb47a38f 381diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
f2c43d5f 382index 3717562..6a328f1 100644
fb47a38f
JR
383--- a/fs/proc/task_nommu.c
384+++ b/fs/proc/task_nommu.c
f2c43d5f 385@@ -155,7 +155,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
fb47a38f
JR
386 file = vma->vm_file;
387
388 if (file) {
389- struct inode *inode = file_inode(vma->vm_file);
390+ struct inode *inode;
076b876e 391+
b912730e 392+ file = vma_pr_or_file(vma);
fb47a38f
JR
393+ inode = file_inode(file);
394 dev = inode->i_sb->s_dev;
395 ino = inode->i_ino;
396 pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
397diff --git a/include/linux/mm.h b/include/linux/mm.h
f2c43d5f 398index a92c8d7..1d83a2a 100644
fb47a38f
JR
399--- a/include/linux/mm.h
400+++ b/include/linux/mm.h
f2c43d5f 401@@ -1266,6 +1266,28 @@ static inline int fixup_user_fault(struct task_struct *tsk,
fb47a38f
JR
402 }
403 #endif
404
076b876e
AM
405+extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int);
406+extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[],
f2c43d5f 407+ int);
076b876e
AM
408+extern void vma_do_get_file(struct vm_area_struct *, const char[], int);
409+extern void vma_do_fput(struct vm_area_struct *, const char[], int);
fb47a38f 410+
f2c43d5f
AM
411+#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \
412+ __LINE__)
413+#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \
414+ __LINE__)
415+#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__)
416+#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__)
b912730e
AM
417+
418+#ifndef CONFIG_MMU
076b876e
AM
419+extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int);
420+extern void vmr_do_fput(struct vm_region *, const char[], int);
421+
f2c43d5f
AM
422+#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \
423+ __LINE__)
424+#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__)
b912730e 425+#endif /* !CONFIG_MMU */
fb47a38f 426+
106341ce
AM
427 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len,
428 unsigned int gup_flags);
fb47a38f 429 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
fb47a38f 430diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
f2c43d5f 431index 4a8aced..badd16b 100644
fb47a38f
JR
432--- a/include/linux/mm_types.h
433+++ b/include/linux/mm_types.h
e2f27e51 434@@ -275,6 +275,7 @@ struct vm_region {
fb47a38f
JR
435 unsigned long vm_top; /* region allocated to here */
436 unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */
437 struct file *vm_file; /* the backing file or NULL */
438+ struct file *vm_prfile; /* the virtual backing file or NULL */
439
440 int vm_usage; /* region usage count (access under nommu_region_sem) */
441 bool vm_icache_flushed : 1; /* true if the icache has been flushed for
e2f27e51 442@@ -349,6 +350,7 @@ struct vm_area_struct {
fb47a38f 443 unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
5afbbe0d 444 units */
fb47a38f
JR
445 struct file * vm_file; /* File we map to (can be NULL). */
446+ struct file *vm_prfile; /* shadow of vm_file */
447 void * vm_private_data; /* was vm_pte (shared mem) */
448
449 #ifndef CONFIG_MMU
450diff --git a/kernel/fork.c b/kernel/fork.c
f2c43d5f 451index 997ac1d..4d0131b 100644
fb47a38f
JR
452--- a/kernel/fork.c
453+++ b/kernel/fork.c
f2c43d5f 454@@ -624,7 +624,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
fb47a38f
JR
455 struct inode *inode = file_inode(file);
456 struct address_space *mapping = file->f_mapping;
457
458- get_file(file);
459+ vma_get_file(tmp);
460 if (tmp->vm_flags & VM_DENYWRITE)
461 atomic_dec(&inode->i_writecount);
2000de60 462 i_mmap_lock_write(mapping);
076b876e 463diff --git a/mm/Makefile b/mm/Makefile
f2c43d5f 464index 295bd7a..14fa1c8 100644
076b876e
AM
465--- a/mm/Makefile
466+++ b/mm/Makefile
f2c43d5f 467@@ -37,7 +37,7 @@ obj-y := filemap.o mempool.o oom_kill.o \
076b876e 468 mm_init.o mmu_context.o percpu.o slab_common.o \
c1595e42 469 compaction.o vmacache.o \
076b876e 470 interval_tree.o list_lru.o workingset.o \
7e9cd9fe
AM
471- debug.o $(mmu-y)
472+ prfile.o debug.o $(mmu-y)
076b876e
AM
473
474 obj-y += init-mm.o
475
fb47a38f 476diff --git a/mm/filemap.c b/mm/filemap.c
f2c43d5f 477index 50b52fe..9e607f9 100644
fb47a38f
JR
478--- a/mm/filemap.c
479+++ b/mm/filemap.c
f2c43d5f 480@@ -2304,7 +2304,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
fb47a38f
JR
481 int ret = VM_FAULT_LOCKED;
482
483 sb_start_pagefault(inode->i_sb);
484- file_update_time(vma->vm_file);
485+ vma_file_update_time(vma);
486 lock_page(page);
487 if (page->mapping != inode->i_mapping) {
488 unlock_page(page);
fb47a38f 489diff --git a/mm/memory.c b/mm/memory.c
f2c43d5f 490index e18c57b..7be4a39 100644
fb47a38f
JR
491--- a/mm/memory.c
492+++ b/mm/memory.c
f2c43d5f 493@@ -2117,7 +2117,7 @@ static inline int wp_page_reuse(struct fault_env *fe, pte_t orig_pte,
fb47a38f 494 }
7e9cd9fe 495
b912730e
AM
496 if (!page_mkwrite)
497- file_update_time(vma->vm_file);
498+ vma_file_update_time(vma);
499 }
500
501 return VM_FAULT_WRITE;
fb47a38f 502diff --git a/mm/mmap.c b/mm/mmap.c
f2c43d5f 503index 1af87c1..95b0ff4 100644
fb47a38f
JR
504--- a/mm/mmap.c
505+++ b/mm/mmap.c
f2c43d5f 506@@ -170,7 +170,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
fb47a38f
JR
507 if (vma->vm_ops && vma->vm_ops->close)
508 vma->vm_ops->close(vma);
509 if (vma->vm_file)
510- fput(vma->vm_file);
511+ vma_fput(vma);
512 mpol_put(vma_policy(vma));
513 kmem_cache_free(vm_area_cachep, vma);
514 return next;
f2c43d5f 515@@ -879,7 +879,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
fb47a38f
JR
516 if (remove_next) {
517 if (file) {
518 uprobe_munmap(next, next->vm_start, next->vm_end);
519- fput(file);
520+ vma_fput(vma);
521 }
522 if (next->anon_vma)
523 anon_vma_merge(vma, next);
f2c43d5f 524@@ -1727,8 +1727,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
35939ee7
JR
525 return addr;
526
fb47a38f 527 unmap_and_free_vma:
fb47a38f
JR
528+ vma_fput(vma);
529 vma->vm_file = NULL;
530- fput(file);
531
532 /* Undo any partial mapping done by a device driver. */
533 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
f2c43d5f 534@@ -2533,7 +2533,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
fb47a38f
JR
535 goto out_free_mpol;
536
537 if (new->vm_file)
538- get_file(new->vm_file);
539+ vma_get_file(new);
540
541 if (new->vm_ops && new->vm_ops->open)
542 new->vm_ops->open(new);
f2c43d5f 543@@ -2552,7 +2552,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
fb47a38f
JR
544 if (new->vm_ops && new->vm_ops->close)
545 new->vm_ops->close(new);
546 if (new->vm_file)
547- fput(new->vm_file);
548+ vma_fput(new);
549 unlink_anon_vmas(new);
550 out_free_mpol:
551 mpol_put(vma_policy(new));
ae9dfd79 552@@ -2703,7 +2703,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
7e9cd9fe
AM
553 struct vm_area_struct *vma;
554 unsigned long populate = 0;
555 unsigned long ret = -EINVAL;
556- struct file *file;
5afbbe0d 557+ struct file *file, *prfile;
7e9cd9fe 558
5afbbe0d
AM
559 pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.txt.\n",
560 current->comm, current->pid);
ae9dfd79 561@@ -2778,10 +2778,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
febd17d6 562 }
7e9cd9fe
AM
563 }
564
565- file = get_file(vma->vm_file);
566+ vma_get_file(vma);
5afbbe0d
AM
567+ file = vma->vm_file;
568+ prfile = vma->vm_prfile;
7e9cd9fe
AM
569 ret = do_mmap_pgoff(vma->vm_file, start, size,
570 prot, flags, pgoff, &populate);
5afbbe0d
AM
571+ if (!IS_ERR_VALUE(ret) && file && prfile) {
572+ struct vm_area_struct *new_vma;
573+
574+ new_vma = find_vma(mm, ret);
575+ if (!new_vma->vm_prfile)
576+ new_vma->vm_prfile = prfile;
577+ if (new_vma != vma)
578+ get_file(prfile);
579+ }
580+ /*
581+ * two fput()s instead of vma_fput(vma),
582+ * coz vma may not be available anymore.
583+ */
584 fput(file);
585+ if (prfile)
586+ fput(prfile);
7e9cd9fe
AM
587 out:
588 up_write(&mm->mmap_sem);
589 if (populate)
f2c43d5f 590@@ -3056,7 +3073,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
79b8bda9
AM
591 if (anon_vma_clone(new_vma, vma))
592 goto out_free_mempol;
593 if (new_vma->vm_file)
594- get_file(new_vma->vm_file);
595+ vma_get_file(new_vma);
596 if (new_vma->vm_ops && new_vma->vm_ops->open)
597 new_vma->vm_ops->open(new_vma);
598 vma_link(mm, new_vma, prev, rb_link, rb_parent);
fb47a38f 599diff --git a/mm/nommu.c b/mm/nommu.c
f2c43d5f 600index 8b8faaf..5d26ed94 100644
fb47a38f
JR
601--- a/mm/nommu.c
602+++ b/mm/nommu.c
f2c43d5f 603@@ -636,7 +636,7 @@ static void __put_nommu_region(struct vm_region *region)
fb47a38f
JR
604 up_write(&nommu_region_sem);
605
606 if (region->vm_file)
607- fput(region->vm_file);
608+ vmr_fput(region);
609
610 /* IO memory and memory shared directly out of the pagecache
611 * from ramfs/tmpfs mustn't be released here */
f2c43d5f 612@@ -794,7 +794,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
fb47a38f
JR
613 if (vma->vm_ops && vma->vm_ops->close)
614 vma->vm_ops->close(vma);
615 if (vma->vm_file)
616- fput(vma->vm_file);
617+ vma_fput(vma);
618 put_nommu_region(vma->vm_region);
619 kmem_cache_free(vm_area_cachep, vma);
620 }
f2c43d5f 621@@ -1320,7 +1320,7 @@ unsigned long do_mmap(struct file *file,
fb47a38f
JR
622 goto error_just_free;
623 }
624 }
625- fput(region->vm_file);
626+ vmr_fput(region);
627 kmem_cache_free(vm_region_jar, region);
628 region = pregion;
629 result = start;
f2c43d5f 630@@ -1395,10 +1395,10 @@ unsigned long do_mmap(struct file *file,
fb47a38f
JR
631 up_write(&nommu_region_sem);
632 error:
633 if (region->vm_file)
634- fput(region->vm_file);
635+ vmr_fput(region);
636 kmem_cache_free(vm_region_jar, region);
637 if (vma->vm_file)
638- fput(vma->vm_file);
639+ vma_fput(vma);
640 kmem_cache_free(vm_area_cachep, vma);
fb47a38f 641 return ret;
c2c0f25c 642
076b876e
AM
643diff --git a/mm/prfile.c b/mm/prfile.c
644new file mode 100644
ae9dfd79 645index 0000000..86e01bd
076b876e
AM
646--- /dev/null
647+++ b/mm/prfile.c
ae9dfd79 648@@ -0,0 +1,85 @@
076b876e 649+/*
ae9dfd79
AM
650+ * Mainly for aufs which mmap(2) different file and wants to print different
651+ * path in /proc/PID/maps.
076b876e
AM
652+ * Call these functions via macros defined in linux/mm.h.
653+ *
654+ * See Documentation/filesystems/aufs/design/06mmap.txt
655+ *
ae9dfd79 656+ * Copyright (c) 2014-2018 Junjro R. Okajima
076b876e
AM
657+ * Copyright (c) 2014 Ian Campbell
658+ */
659+
660+#include <linux/mm.h>
661+#include <linux/file.h>
662+#include <linux/fs.h>
663+
664+/* #define PRFILE_TRACE */
665+static inline void prfile_trace(struct file *f, struct file *pr,
666+ const char func[], int line, const char func2[])
667+{
668+#ifdef PRFILE_TRACE
669+ if (pr)
ae9dfd79 670+ pr_info("%s:%d: %s, %pD2\n", func, line, func2, f);
076b876e
AM
671+#endif
672+}
673+
076b876e
AM
674+void vma_do_file_update_time(struct vm_area_struct *vma, const char func[],
675+ int line)
676+{
677+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
678+
679+ prfile_trace(f, pr, func, line, __func__);
680+ file_update_time(f);
681+ if (f && pr)
682+ file_update_time(pr);
683+}
684+
685+struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[],
686+ int line)
687+{
688+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
689+
690+ prfile_trace(f, pr, func, line, __func__);
691+ return (f && pr) ? pr : f;
692+}
693+
694+void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line)
695+{
696+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
697+
698+ prfile_trace(f, pr, func, line, __func__);
699+ get_file(f);
700+ if (f && pr)
701+ get_file(pr);
702+}
703+
704+void vma_do_fput(struct vm_area_struct *vma, const char func[], int line)
705+{
706+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
707+
708+ prfile_trace(f, pr, func, line, __func__);
709+ fput(f);
710+ if (f && pr)
711+ fput(pr);
712+}
b912730e
AM
713+
714+#ifndef CONFIG_MMU
076b876e
AM
715+struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[],
716+ int line)
717+{
718+ struct file *f = region->vm_file, *pr = region->vm_prfile;
719+
720+ prfile_trace(f, pr, func, line, __func__);
721+ return (f && pr) ? pr : f;
722+}
723+
724+void vmr_do_fput(struct vm_region *region, const char func[], int line)
725+{
726+ struct file *f = region->vm_file, *pr = region->vm_prfile;
727+
728+ prfile_trace(f, pr, func, line, __func__);
729+ fput(f);
730+ if (f && pr)
731+ fput(pr);
732+}
b912730e 733+#endif /* !CONFIG_MMU */
f2c43d5f 734aufs4.9 standalone patch
7f207e10 735
c1595e42 736diff --git a/fs/dcache.c b/fs/dcache.c
f2c43d5f 737index df0268c..755fea1 100644
c1595e42
JR
738--- a/fs/dcache.c
739+++ b/fs/dcache.c
f2c43d5f 740@@ -1272,6 +1272,7 @@ void d_walk(struct dentry *parent, void *data,
c1595e42
JR
741 seq = 1;
742 goto again;
743 }
febd17d6 744+EXPORT_SYMBOL_GPL(d_walk);
c1595e42
JR
745
746 /*
747 * Search for at least 1 mount point in the dentry's subdirs.
f2c43d5f
AM
748@@ -2855,6 +2856,7 @@ void d_exchange(struct dentry *dentry1, struct dentry *dentry2)
749
750 write_sequnlock(&rename_lock);
751 }
752+EXPORT_SYMBOL_GPL(d_exchange);
753
754 /**
755 * d_ancestor - search for an ancestor
79b8bda9 756diff --git a/fs/exec.c b/fs/exec.c
f2c43d5f 757index 4e497b9..e27d323 100644
79b8bda9
AM
758--- a/fs/exec.c
759+++ b/fs/exec.c
5afbbe0d 760@@ -104,6 +104,7 @@ bool path_noexec(const struct path *path)
79b8bda9
AM
761 return (path->mnt->mnt_flags & MNT_NOEXEC) ||
762 (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC);
763 }
febd17d6 764+EXPORT_SYMBOL_GPL(path_noexec);
79b8bda9
AM
765
766 #ifdef CONFIG_USELIB
767 /*
febd17d6
JR
768diff --git a/fs/fcntl.c b/fs/fcntl.c
769index 6f42279..04fd33c 100644
770--- a/fs/fcntl.c
771+++ b/fs/fcntl.c
772@@ -82,6 +82,7 @@ int setfl(int fd, struct file * filp, unsigned long arg)
773 out:
774 return error;
775 }
776+EXPORT_SYMBOL_GPL(setfl);
777
778 static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
779 int force)
b912730e 780diff --git a/fs/file_table.c b/fs/file_table.c
febd17d6 781index ad17e05..ae9f267 100644
b912730e
AM
782--- a/fs/file_table.c
783+++ b/fs/file_table.c
f2c43d5f 784@@ -147,6 +147,7 @@ struct file *get_empty_filp(void)
b912730e
AM
785 }
786 return ERR_PTR(-ENFILE);
787 }
febd17d6 788+EXPORT_SYMBOL_GPL(get_empty_filp);
b912730e
AM
789
790 /**
791 * alloc_file - allocate and initialize a 'struct file'
8cdd5066
JR
792@@ -258,6 +259,7 @@ void flush_delayed_fput(void)
793 {
794 delayed_fput(NULL);
795 }
febd17d6 796+EXPORT_SYMBOL_GPL(flush_delayed_fput);
8cdd5066
JR
797
798 static DECLARE_DELAYED_WORK(delayed_fput_work, delayed_fput);
799
800@@ -300,6 +302,7 @@ void __fput_sync(struct file *file)
801 }
802
803 EXPORT_SYMBOL(fput);
febd17d6 804+EXPORT_SYMBOL_GPL(__fput_sync);
8cdd5066
JR
805
806 void put_filp(struct file *file)
807 {
808@@ -308,6 +311,7 @@ void put_filp(struct file *file)
b912730e
AM
809 file_free(file);
810 }
811 }
febd17d6 812+EXPORT_SYMBOL_GPL(put_filp);
b912730e 813
79b8bda9 814 void __init files_init(void)
b912730e 815 {
5afbbe0d 816diff --git a/fs/inode.c b/fs/inode.c
ae9dfd79 817index 9a9ba3a..a3a18d83 100644
5afbbe0d
AM
818--- a/fs/inode.c
819+++ b/fs/inode.c
f2c43d5f 820@@ -1651,6 +1651,7 @@ int update_time(struct inode *inode, struct timespec *time, int flags)
5afbbe0d
AM
821
822 return update_time(inode, time, flags);
823 }
824+EXPORT_SYMBOL_GPL(update_time);
825
826 /**
827 * touch_atime - update the access time
7f207e10 828diff --git a/fs/namespace.c b/fs/namespace.c
ae9dfd79 829index db0b1ac..2d1e8ff 100644
7f207e10
AM
830--- a/fs/namespace.c
831+++ b/fs/namespace.c
f2c43d5f 832@@ -466,6 +466,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
c06a8ce3
AM
833 mnt_dec_writers(real_mount(mnt));
834 preempt_enable();
835 }
836+EXPORT_SYMBOL_GPL(__mnt_drop_write);
837
838 /**
839 * mnt_drop_write - give up write access to a mount
ae9dfd79
AM
840@@ -792,6 +793,7 @@ int is_current_mnt_ns(struct vfsmount *mnt)
841 {
842 return check_mnt(real_mount(mnt));
843 }
844+EXPORT_SYMBOL_GPL(is_current_mnt_ns);
845
846 /*
847 * vfsmount lock must be held for write
848@@ -1829,6 +1831,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
7f207e10
AM
849 }
850 return 0;
851 }
febd17d6 852+EXPORT_SYMBOL_GPL(iterate_mounts);
7f207e10 853
7eafdf33 854 static void cleanup_group_ids(struct mount *mnt, struct mount *end)
7f207e10
AM
855 {
856diff --git a/fs/notify/group.c b/fs/notify/group.c
f2c43d5f 857index fbe3cbe..bdfc61e 100644
7f207e10
AM
858--- a/fs/notify/group.c
859+++ b/fs/notify/group.c
860@@ -22,6 +22,7 @@
861 #include <linux/srcu.h>
862 #include <linux/rculist.h>
863 #include <linux/wait.h>
864+#include <linux/module.h>
865
866 #include <linux/fsnotify_backend.h>
867 #include "fsnotify.h"
e2f27e51 868@@ -100,6 +101,7 @@ void fsnotify_get_group(struct fsnotify_group *group)
1716fcea
AM
869 {
870 atomic_inc(&group->refcnt);
871 }
febd17d6 872+EXPORT_SYMBOL_GPL(fsnotify_get_group);
1716fcea
AM
873
874 /*
875 * Drop a reference to a group. Free it if it's through.
e2f27e51 876@@ -109,6 +111,7 @@ void fsnotify_put_group(struct fsnotify_group *group)
7f207e10 877 if (atomic_dec_and_test(&group->refcnt))
1716fcea 878 fsnotify_final_destroy_group(group);
7f207e10 879 }
febd17d6 880+EXPORT_SYMBOL_GPL(fsnotify_put_group);
7f207e10
AM
881
882 /*
883 * Create a new fsnotify_group and hold a reference for the group returned.
e2f27e51 884@@ -137,6 +140,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
7f207e10
AM
885
886 return group;
887 }
febd17d6 888+EXPORT_SYMBOL_GPL(fsnotify_alloc_group);
1716fcea
AM
889
890 int fsnotify_fasync(int fd, struct file *file, int on)
891 {
7f207e10 892diff --git a/fs/notify/mark.c b/fs/notify/mark.c
5afbbe0d 893index d3fea0b..5fc06ad 100644
7f207e10
AM
894--- a/fs/notify/mark.c
895+++ b/fs/notify/mark.c
febd17d6 896@@ -113,6 +113,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
7f207e10 897 mark->free_mark(mark);
1716fcea 898 }
7f207e10 899 }
febd17d6 900+EXPORT_SYMBOL_GPL(fsnotify_put_mark);
7f207e10 901
2000de60
JR
902 /* Calculate mask of events for a list of marks */
903 u32 fsnotify_recalc_mask(struct hlist_head *head)
5afbbe0d 904@@ -230,6 +231,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark,
1716fcea 905 mutex_unlock(&group->mark_mutex);
79b8bda9 906 fsnotify_free_mark(mark);
7f207e10 907 }
febd17d6 908+EXPORT_SYMBOL_GPL(fsnotify_destroy_mark);
7f207e10 909
79b8bda9
AM
910 void fsnotify_destroy_marks(struct hlist_head *head, spinlock_t *lock)
911 {
f2c43d5f 912@@ -415,6 +417,7 @@ int fsnotify_add_mark_locked(struct fsnotify_mark *mark,
7f207e10
AM
913
914 return ret;
915 }
febd17d6 916+EXPORT_SYMBOL_GPL(fsnotify_add_mark);
7f207e10 917
1716fcea
AM
918 int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
919 struct inode *inode, struct vfsmount *mnt, int allow_dups)
5afbbe0d 920@@ -533,6 +536,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
7f207e10
AM
921 atomic_set(&mark->refcnt, 1);
922 mark->free_mark = free_mark;
923 }
febd17d6 924+EXPORT_SYMBOL_GPL(fsnotify_init_mark);
7f207e10 925
5afbbe0d
AM
926 /*
927 * Destroy all marks in destroy_list, waits for SRCU period to finish before
7f207e10 928diff --git a/fs/open.c b/fs/open.c
f2c43d5f 929index d3ed817..20d2494 100644
7f207e10
AM
930--- a/fs/open.c
931+++ b/fs/open.c
c2c0f25c 932@@ -64,6 +64,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
febd17d6 933 inode_unlock(dentry->d_inode);
7f207e10
AM
934 return ret;
935 }
febd17d6 936+EXPORT_SYMBOL_GPL(do_truncate);
7f207e10 937
5afbbe0d 938 long vfs_truncate(const struct path *path, loff_t length)
7f207e10 939 {
f2c43d5f 940@@ -695,6 +696,7 @@ int open_check_o_direct(struct file *f)
b912730e
AM
941 }
942 return 0;
943 }
febd17d6 944+EXPORT_SYMBOL_GPL(open_check_o_direct);
b912730e
AM
945
946 static int do_dentry_open(struct file *f,
c2c0f25c 947 struct inode *inode,
5527c038 948diff --git a/fs/read_write.c b/fs/read_write.c
f2c43d5f 949index 4052813..7dfd732 100644
5527c038
JR
950--- a/fs/read_write.c
951+++ b/fs/read_write.c
5afbbe0d 952@@ -525,6 +525,7 @@ vfs_readf_t vfs_readf(struct file *file)
5527c038
JR
953 return new_sync_read;
954 return ERR_PTR(-ENOSYS);
955 }
febd17d6 956+EXPORT_SYMBOL_GPL(vfs_readf);
5527c038
JR
957
958 vfs_writef_t vfs_writef(struct file *file)
959 {
5afbbe0d 960@@ -536,6 +537,7 @@ vfs_writef_t vfs_writef(struct file *file)
5527c038
JR
961 return new_sync_write;
962 return ERR_PTR(-ENOSYS);
963 }
febd17d6 964+EXPORT_SYMBOL_GPL(vfs_writef);
5527c038
JR
965
966 ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
967 {
7f207e10 968diff --git a/fs/splice.c b/fs/splice.c
f2c43d5f 969index 28160a7..98c1902 100644
7f207e10
AM
970--- a/fs/splice.c
971+++ b/fs/splice.c
f2c43d5f 972@@ -868,6 +868,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
392086de
AM
973
974 return splice_write(pipe, out, ppos, len, flags);
7f207e10 975 }
febd17d6 976+EXPORT_SYMBOL_GPL(do_splice_from);
7f207e10
AM
977
978 /*
979 * Attempt to initiate a splice from a file to a pipe.
f2c43d5f 980@@ -897,6 +898,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
7f207e10
AM
981
982 return splice_read(in, ppos, pipe, len, flags);
983 }
febd17d6 984+EXPORT_SYMBOL_GPL(do_splice_to);
7f207e10
AM
985
986 /**
987 * splice_direct_to_actor - splices data directly between two non-pipes
ae9dfd79
AM
988diff --git a/fs/sync.c b/fs/sync.c
989index 7a5fa3f..c9b9d46 100644
990--- a/fs/sync.c
991+++ b/fs/sync.c
992@@ -38,6 +38,7 @@ int __sync_filesystem(struct super_block *sb, int wait)
993 sb->s_op->sync_fs(sb, wait);
994 return __sync_blockdev(sb->s_bdev, wait);
995 }
996+EXPORT_SYMBOL_GPL(__sync_filesystem);
997
998 /*
999 * Write out and wait upon all dirty data associated with this
c1595e42 1000diff --git a/fs/xattr.c b/fs/xattr.c
f2c43d5f 1001index 2d13b4e..41c2bcd 100644
c1595e42
JR
1002--- a/fs/xattr.c
1003+++ b/fs/xattr.c
ae9dfd79 1004@@ -296,6 +296,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
c1595e42
JR
1005 *xattr_value = value;
1006 return error;
1007 }
febd17d6 1008+EXPORT_SYMBOL_GPL(vfs_getxattr_alloc);
c1595e42 1009
febd17d6 1010 ssize_t
f2c43d5f 1011 __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name,
8cdd5066 1012diff --git a/kernel/task_work.c b/kernel/task_work.c
e2f27e51 1013index d513051..e056d54 100644
8cdd5066
JR
1014--- a/kernel/task_work.c
1015+++ b/kernel/task_work.c
e2f27e51 1016@@ -119,3 +119,4 @@ void task_work_run(void)
8cdd5066
JR
1017 } while (work);
1018 }
1019 }
febd17d6 1020+EXPORT_SYMBOL_GPL(task_work_run);
7f207e10 1021diff --git a/security/commoncap.c b/security/commoncap.c
f2c43d5f 1022index 8df676f..6b5cc07 100644
7f207e10
AM
1023--- a/security/commoncap.c
1024+++ b/security/commoncap.c
f2c43d5f 1025@@ -1061,12 +1061,14 @@ int cap_mmap_addr(unsigned long addr)
94337f0d 1026 }
7f207e10
AM
1027 return ret;
1028 }
febd17d6 1029+EXPORT_SYMBOL_GPL(cap_mmap_addr);
0c3ec466
AM
1030
1031 int cap_mmap_file(struct file *file, unsigned long reqprot,
1032 unsigned long prot, unsigned long flags)
1033 {
1034 return 0;
1035 }
febd17d6 1036+EXPORT_SYMBOL_GPL(cap_mmap_file);
c2c0f25c
AM
1037
1038 #ifdef CONFIG_SECURITY
1039
7f207e10 1040diff --git a/security/device_cgroup.c b/security/device_cgroup.c
febd17d6 1041index 03c1652..f88c84b 100644
7f207e10
AM
1042--- a/security/device_cgroup.c
1043+++ b/security/device_cgroup.c
f6c5ef8b
AM
1044@@ -7,6 +7,7 @@
1045 #include <linux/device_cgroup.h>
1046 #include <linux/cgroup.h>
1047 #include <linux/ctype.h>
1048+#include <linux/export.h>
1049 #include <linux/list.h>
1050 #include <linux/uaccess.h>
1051 #include <linux/seq_file.h>
076b876e 1052@@ -849,6 +850,7 @@ int __devcgroup_inode_permission(struct inode *inode, int mask)
537831f9
AM
1053 return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
1054 access);
7f207e10 1055 }
febd17d6 1056+EXPORT_SYMBOL_GPL(__devcgroup_inode_permission);
7f207e10
AM
1057
1058 int devcgroup_inode_mknod(int mode, dev_t dev)
1059 {
1060diff --git a/security/security.c b/security/security.c
f2c43d5f 1061index f825304..8dd441d 100644
7f207e10
AM
1062--- a/security/security.c
1063+++ b/security/security.c
f2c43d5f 1064@@ -443,6 +443,7 @@ int security_path_rmdir(const struct path *dir, struct dentry *dentry)
7f207e10 1065 return 0;
c2c0f25c 1066 return call_int_hook(path_rmdir, 0, dir, dentry);
7f207e10 1067 }
febd17d6 1068+EXPORT_SYMBOL_GPL(security_path_rmdir);
7f207e10 1069
5afbbe0d 1070 int security_path_unlink(const struct path *dir, struct dentry *dentry)
7f207e10 1071 {
f2c43d5f 1072@@ -459,6 +460,7 @@ int security_path_symlink(const struct path *dir, struct dentry *dentry,
7f207e10 1073 return 0;
c2c0f25c 1074 return call_int_hook(path_symlink, 0, dir, dentry, old_name);
7f207e10 1075 }
febd17d6 1076+EXPORT_SYMBOL_GPL(security_path_symlink);
7f207e10 1077
5afbbe0d 1078 int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
7f207e10 1079 struct dentry *new_dentry)
f2c43d5f 1080@@ -467,6 +469,7 @@ int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
7f207e10 1081 return 0;
c2c0f25c 1082 return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry);
7f207e10 1083 }
febd17d6 1084+EXPORT_SYMBOL_GPL(security_path_link);
7f207e10 1085
5afbbe0d
AM
1086 int security_path_rename(const struct path *old_dir, struct dentry *old_dentry,
1087 const struct path *new_dir, struct dentry *new_dentry,
f2c43d5f 1088@@ -494,6 +497,7 @@ int security_path_truncate(const struct path *path)
7f207e10 1089 return 0;
c2c0f25c 1090 return call_int_hook(path_truncate, 0, path);
7f207e10 1091 }
febd17d6 1092+EXPORT_SYMBOL_GPL(security_path_truncate);
7f207e10 1093
5afbbe0d 1094 int security_path_chmod(const struct path *path, umode_t mode)
7eafdf33 1095 {
f2c43d5f 1096@@ -501,6 +505,7 @@ int security_path_chmod(const struct path *path, umode_t mode)
7f207e10 1097 return 0;
c2c0f25c 1098 return call_int_hook(path_chmod, 0, path, mode);
7f207e10 1099 }
febd17d6 1100+EXPORT_SYMBOL_GPL(security_path_chmod);
7f207e10 1101
5afbbe0d 1102 int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
7f207e10 1103 {
f2c43d5f 1104@@ -508,6 +513,7 @@ int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
7f207e10 1105 return 0;
c2c0f25c 1106 return call_int_hook(path_chown, 0, path, uid, gid);
7f207e10 1107 }
febd17d6 1108+EXPORT_SYMBOL_GPL(security_path_chown);
7f207e10 1109
5afbbe0d 1110 int security_path_chroot(const struct path *path)
7f207e10 1111 {
f2c43d5f 1112@@ -593,6 +599,7 @@ int security_inode_readlink(struct dentry *dentry)
7f207e10 1113 return 0;
c2c0f25c 1114 return call_int_hook(inode_readlink, 0, dentry);
7f207e10 1115 }
febd17d6 1116+EXPORT_SYMBOL_GPL(security_inode_readlink);
7f207e10 1117
c2c0f25c
AM
1118 int security_inode_follow_link(struct dentry *dentry, struct inode *inode,
1119 bool rcu)
f2c43d5f 1120@@ -608,6 +615,7 @@ int security_inode_permission(struct inode *inode, int mask)
7f207e10 1121 return 0;
c2c0f25c 1122 return call_int_hook(inode_permission, 0, inode, mask);
7f207e10 1123 }
febd17d6 1124+EXPORT_SYMBOL_GPL(security_inode_permission);
7f207e10 1125
1e00d052 1126 int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
7f207e10 1127 {
f2c43d5f 1128@@ -779,6 +787,7 @@ int security_file_permission(struct file *file, int mask)
7f207e10
AM
1129
1130 return fsnotify_perm(file, mask);
1131 }
febd17d6 1132+EXPORT_SYMBOL_GPL(security_file_permission);
7f207e10
AM
1133
1134 int security_file_alloc(struct file *file)
1135 {
f2c43d5f 1136@@ -838,6 +847,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
7f207e10
AM
1137 return ret;
1138 return ima_file_mmap(file, prot);
1139 }
febd17d6 1140+EXPORT_SYMBOL_GPL(security_mmap_file);
7f207e10 1141
0c3ec466
AM
1142 int security_mmap_addr(unsigned long addr)
1143 {
7f207e10
AM
1144diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs
1145--- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 1146+++ linux/Documentation/ABI/testing/debugfs-aufs 2017-07-29 12:14:25.893041746 +0200
86dc4139 1147@@ -0,0 +1,50 @@
7f207e10
AM
1148+What: /debug/aufs/si_<id>/
1149+Date: March 2009
f6b6e03d 1150+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1151+Description:
1152+ Under /debug/aufs, a directory named si_<id> is created
1153+ per aufs mount, where <id> is a unique id generated
1154+ internally.
1facf9fc 1155+
86dc4139
AM
1156+What: /debug/aufs/si_<id>/plink
1157+Date: Apr 2013
f6b6e03d 1158+Contact: J. R. Okajima <hooanon05g@gmail.com>
86dc4139
AM
1159+Description:
1160+ It has three lines and shows the information about the
1161+ pseudo-link. The first line is a single number
1162+ representing a number of buckets. The second line is a
1163+ number of pseudo-links per buckets (separated by a
1164+ blank). The last line is a single number representing a
1165+ total number of psedo-links.
1166+ When the aufs mount option 'noplink' is specified, it
1167+ will show "1\n0\n0\n".
1168+
7f207e10
AM
1169+What: /debug/aufs/si_<id>/xib
1170+Date: March 2009
f6b6e03d 1171+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1172+Description:
1173+ It shows the consumed blocks by xib (External Inode Number
1174+ Bitmap), its block size and file size.
1175+ When the aufs mount option 'noxino' is specified, it
1176+ will be empty. About XINO files, see the aufs manual.
1177+
1178+What: /debug/aufs/si_<id>/xino0, xino1 ... xinoN
1179+Date: March 2009
f6b6e03d 1180+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1181+Description:
1182+ It shows the consumed blocks by xino (External Inode Number
1183+ Translation Table), its link count, block size and file
1184+ size.
1185+ When the aufs mount option 'noxino' is specified, it
1186+ will be empty. About XINO files, see the aufs manual.
1187+
1188+What: /debug/aufs/si_<id>/xigen
1189+Date: March 2009
f6b6e03d 1190+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1191+Description:
1192+ It shows the consumed blocks by xigen (External Inode
1193+ Generation Table), its block size and file size.
1194+ If CONFIG_AUFS_EXPORT is disabled, this entry will not
1195+ be created.
1196+ When the aufs mount option 'noxino' is specified, it
1197+ will be empty. About XINO files, see the aufs manual.
1198diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs
1199--- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 1200+++ linux/Documentation/ABI/testing/sysfs-aufs 2017-07-29 12:14:25.893041746 +0200
392086de 1201@@ -0,0 +1,31 @@
7f207e10
AM
1202+What: /sys/fs/aufs/si_<id>/
1203+Date: March 2009
f6b6e03d 1204+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1205+Description:
1206+ Under /sys/fs/aufs, a directory named si_<id> is created
1207+ per aufs mount, where <id> is a unique id generated
1208+ internally.
1209+
1210+What: /sys/fs/aufs/si_<id>/br0, br1 ... brN
1211+Date: March 2009
f6b6e03d 1212+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1213+Description:
1214+ It shows the abolute path of a member directory (which
1215+ is called branch) in aufs, and its permission.
1216+
392086de
AM
1217+What: /sys/fs/aufs/si_<id>/brid0, brid1 ... bridN
1218+Date: July 2013
f6b6e03d 1219+Contact: J. R. Okajima <hooanon05g@gmail.com>
392086de
AM
1220+Description:
1221+ It shows the id of a member directory (which is called
1222+ branch) in aufs.
1223+
7f207e10
AM
1224+What: /sys/fs/aufs/si_<id>/xi_path
1225+Date: March 2009
f6b6e03d 1226+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1227+Description:
1228+ It shows the abolute path of XINO (External Inode Number
1229+ Bitmap, Translation Table and Generation Table) file
1230+ even if it is the default path.
1231+ When the aufs mount option 'noxino' is specified, it
1232+ will be empty. About XINO files, see the aufs manual.
53392da6
AM
1233diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt
1234--- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
1235+++ linux/Documentation/filesystems/aufs/design/01intro.txt 2018-04-15 08:49:13.394483860 +0200
1236@@ -0,0 +1,171 @@
53392da6 1237+
ae9dfd79 1238+# Copyright (C) 2005-2018 Junjiro R. Okajima
53392da6
AM
1239+#
1240+# This program is free software; you can redistribute it and/or modify
1241+# it under the terms of the GNU General Public License as published by
1242+# the Free Software Foundation; either version 2 of the License, or
1243+# (at your option) any later version.
1244+#
1245+# This program is distributed in the hope that it will be useful,
1246+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1247+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1248+# GNU General Public License for more details.
1249+#
1250+# You should have received a copy of the GNU General Public License
523b37e3 1251+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1252+
1253+Introduction
1254+----------------------------------------
1255+
ae9dfd79 1256+aufs [ei ju: ef es] | /ey-yoo-ef-es/ | [a u f s]
53392da6
AM
1257+1. abbrev. for "advanced multi-layered unification filesystem".
1258+2. abbrev. for "another unionfs".
1259+3. abbrev. for "auf das" in German which means "on the" in English.
1260+ Ex. "Butter aufs Brot"(G) means "butter onto bread"(E).
1261+ But "Filesystem aufs Filesystem" is hard to understand.
ae9dfd79 1262+4. abbrev. for "African Urban Fashion Show".
53392da6
AM
1263+
1264+AUFS is a filesystem with features:
1265+- multi layered stackable unification filesystem, the member directory
1266+ is called as a branch.
1267+- branch permission and attribute, 'readonly', 'real-readonly',
7e9cd9fe 1268+ 'readwrite', 'whiteout-able', 'link-able whiteout', etc. and their
53392da6
AM
1269+ combination.
1270+- internal "file copy-on-write".
1271+- logical deletion, whiteout.
1272+- dynamic branch manipulation, adding, deleting and changing permission.
1273+- allow bypassing aufs, user's direct branch access.
1274+- external inode number translation table and bitmap which maintains the
1275+ persistent aufs inode number.
1276+- seekable directory, including NFS readdir.
1277+- file mapping, mmap and sharing pages.
1278+- pseudo-link, hardlink over branches.
1279+- loopback mounted filesystem as a branch.
1280+- several policies to select one among multiple writable branches.
1281+- revert a single systemcall when an error occurs in aufs.
1282+- and more...
1283+
1284+
1285+Multi Layered Stackable Unification Filesystem
1286+----------------------------------------------------------------------
1287+Most people already knows what it is.
1288+It is a filesystem which unifies several directories and provides a
1289+merged single directory. When users access a file, the access will be
1290+passed/re-directed/converted (sorry, I am not sure which English word is
1291+correct) to the real file on the member filesystem. The member
1292+filesystem is called 'lower filesystem' or 'branch' and has a mode
1293+'readonly' and 'readwrite.' And the deletion for a file on the lower
1294+readonly branch is handled by creating 'whiteout' on the upper writable
1295+branch.
1296+
1297+On LKML, there have been discussions about UnionMount (Jan Blunck,
1298+Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took
1299+different approaches to implement the merged-view.
1300+The former tries putting it into VFS, and the latter implements as a
1301+separate filesystem.
1302+(If I misunderstand about these implementations, please let me know and
1303+I shall correct it. Because it is a long time ago when I read their
1304+source files last time).
1305+
1306+UnionMount's approach will be able to small, but may be hard to share
1307+branches between several UnionMount since the whiteout in it is
1308+implemented in the inode on branch filesystem and always
1309+shared. According to Bharata's post, readdir does not seems to be
1310+finished yet.
1311+There are several missing features known in this implementations such as
1312+- for users, the inode number may change silently. eg. copy-up.
1313+- link(2) may break by copy-up.
1314+- read(2) may get an obsoleted filedata (fstat(2) too).
1315+- fcntl(F_SETLK) may be broken by copy-up.
1316+- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
1317+ open(O_RDWR).
1318+
7e9cd9fe
AM
1319+In linux-3.18, "overlay" filesystem (formerly known as "overlayfs") was
1320+merged into mainline. This is another implementation of UnionMount as a
1321+separated filesystem. All the limitations and known problems which
1322+UnionMount are equally inherited to "overlay" filesystem.
1323+
1324+Unionfs has a longer history. When I started implementing a stackable
1325+filesystem (Aug 2005), it already existed. It has virtual super_block,
1326+inode, dentry and file objects and they have an array pointing lower
1327+same kind objects. After contributing many patches for Unionfs, I
1328+re-started my project AUFS (Jun 2006).
53392da6
AM
1329+
1330+In AUFS, the structure of filesystem resembles to Unionfs, but I
1331+implemented my own ideas, approaches and enhancements and it became
1332+totally different one.
1333+
1334+Comparing DM snapshot and fs based implementation
1335+- the number of bytes to be copied between devices is much smaller.
1336+- the type of filesystem must be one and only.
1337+- the fs must be writable, no readonly fs, even for the lower original
1338+ device. so the compression fs will not be usable. but if we use
1339+ loopback mount, we may address this issue.
1340+ for instance,
1341+ mount /cdrom/squashfs.img /sq
1342+ losetup /sq/ext2.img
1343+ losetup /somewhere/cow
1344+ dmsetup "snapshot /dev/loop0 /dev/loop1 ..."
1345+- it will be difficult (or needs more operations) to extract the
1346+ difference between the original device and COW.
1347+- DM snapshot-merge may help a lot when users try merging. in the
1348+ fs-layer union, users will use rsync(1).
1349+
7e9cd9fe
AM
1350+You may want to read my old paper "Filesystems in LiveCD"
1351+(http://aufs.sourceforge.net/aufs2/report/sq/sq.pdf).
53392da6 1352+
7e9cd9fe
AM
1353+
1354+Several characters/aspects/persona of aufs
53392da6
AM
1355+----------------------------------------------------------------------
1356+
7e9cd9fe 1357+Aufs has several characters, aspects or persona.
53392da6
AM
1358+1. a filesystem, callee of VFS helper
1359+2. sub-VFS, caller of VFS helper for branches
1360+3. a virtual filesystem which maintains persistent inode number
1361+4. reader/writer of files on branches such like an application
1362+
1363+1. Callee of VFS Helper
1364+As an ordinary linux filesystem, aufs is a callee of VFS. For instance,
1365+unlink(2) from an application reaches sys_unlink() kernel function and
1366+then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it
1367+calls filesystem specific unlink operation. Actually aufs implements the
1368+unlink operation but it behaves like a redirector.
1369+
1370+2. Caller of VFS Helper for Branches
1371+aufs_unlink() passes the unlink request to the branch filesystem as if
1372+it were called from VFS. So the called unlink operation of the branch
1373+filesystem acts as usual. As a caller of VFS helper, aufs should handle
1374+every necessary pre/post operation for the branch filesystem.
1375+- acquire the lock for the parent dir on a branch
1376+- lookup in a branch
1377+- revalidate dentry on a branch
1378+- mnt_want_write() for a branch
1379+- vfs_unlink() for a branch
1380+- mnt_drop_write() for a branch
1381+- release the lock on a branch
1382+
1383+3. Persistent Inode Number
1384+One of the most important issue for a filesystem is to maintain inode
1385+numbers. This is particularly important to support exporting a
1386+filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
1387+backend block device for its own. But some storage is necessary to
7e9cd9fe
AM
1388+keep and maintain the inode numbers. It may be a large space and may not
1389+suit to keep in memory. Aufs rents some space from its first writable
1390+branch filesystem (by default) and creates file(s) on it. These files
1391+are created by aufs internally and removed soon (currently) keeping
1392+opened.
53392da6
AM
1393+Note: Because these files are removed, they are totally gone after
1394+ unmounting aufs. It means the inode numbers are not persistent
1395+ across unmount or reboot. I have a plan to make them really
1396+ persistent which will be important for aufs on NFS server.
1397+
1398+4. Read/Write Files Internally (copy-on-write)
1399+Because a branch can be readonly, when you write a file on it, aufs will
1400+"copy-up" it to the upper writable branch internally. And then write the
1401+originally requested thing to the file. Generally kernel doesn't
1402+open/read/write file actively. In aufs, even a single write may cause a
1403+internal "file copy". This behaviour is very similar to cp(1) command.
1404+
1405+Some people may think it is better to pass such work to user space
1406+helper, instead of doing in kernel space. Actually I am still thinking
1407+about it. But currently I have implemented it in kernel space.
1408diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt linux/Documentation/filesystems/aufs/design/02struct.txt
1409--- /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 1410+++ linux/Documentation/filesystems/aufs/design/02struct.txt 2018-04-15 08:49:13.394483860 +0200
7e9cd9fe 1411@@ -0,0 +1,258 @@
53392da6 1412+
ae9dfd79 1413+# Copyright (C) 2005-2018 Junjiro R. Okajima
53392da6
AM
1414+#
1415+# This program is free software; you can redistribute it and/or modify
1416+# it under the terms of the GNU General Public License as published by
1417+# the Free Software Foundation; either version 2 of the License, or
1418+# (at your option) any later version.
1419+#
1420+# This program is distributed in the hope that it will be useful,
1421+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1422+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1423+# GNU General Public License for more details.
1424+#
1425+# You should have received a copy of the GNU General Public License
523b37e3 1426+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1427+
1428+Basic Aufs Internal Structure
1429+
1430+Superblock/Inode/Dentry/File Objects
1431+----------------------------------------------------------------------
1432+As like an ordinary filesystem, aufs has its own
1433+superblock/inode/dentry/file objects. All these objects have a
1434+dynamically allocated array and store the same kind of pointers to the
1435+lower filesystem, branch.
1436+For example, when you build a union with one readwrite branch and one
1437+readonly, mounted /au, /rw and /ro respectively.
1438+- /au = /rw + /ro
1439+- /ro/fileA exists but /rw/fileA
1440+
1441+Aufs lookup operation finds /ro/fileA and gets dentry for that. These
1442+pointers are stored in a aufs dentry. The array in aufs dentry will be,
7e9cd9fe 1443+- [0] = NULL (because /rw/fileA doesn't exist)
53392da6
AM
1444+- [1] = /ro/fileA
1445+
1446+This style of an array is essentially same to the aufs
1447+superblock/inode/dentry/file objects.
1448+
1449+Because aufs supports manipulating branches, ie. add/delete/change
7e9cd9fe
AM
1450+branches dynamically, these objects has its own generation. When
1451+branches are changed, the generation in aufs superblock is
1452+incremented. And a generation in other object are compared when it is
1453+accessed. When a generation in other objects are obsoleted, aufs
1454+refreshes the internal array.
53392da6
AM
1455+
1456+
1457+Superblock
1458+----------------------------------------------------------------------
1459+Additionally aufs superblock has some data for policies to select one
1460+among multiple writable branches, XIB files, pseudo-links and kobject.
1461+See below in detail.
7e9cd9fe
AM
1462+About the policies which supports copy-down a directory, see
1463+wbr_policy.txt too.
53392da6
AM
1464+
1465+
1466+Branch and XINO(External Inode Number Translation Table)
1467+----------------------------------------------------------------------
1468+Every branch has its own xino (external inode number translation table)
1469+file. The xino file is created and unlinked by aufs internally. When two
1470+members of a union exist on the same filesystem, they share the single
1471+xino file.
1472+The struct of a xino file is simple, just a sequence of aufs inode
1473+numbers which is indexed by the lower inode number.
1474+In the above sample, assume the inode number of /ro/fileA is i111 and
1475+aufs assigns the inode number i999 for fileA. Then aufs writes 999 as
1476+4(8) bytes at 111 * 4(8) bytes offset in the xino file.
1477+
1478+When the inode numbers are not contiguous, the xino file will be sparse
1479+which has a hole in it and doesn't consume as much disk space as it
1480+might appear. If your branch filesystem consumes disk space for such
1481+holes, then you should specify 'xino=' option at mounting aufs.
1482+
7e9cd9fe
AM
1483+Aufs has a mount option to free the disk blocks for such holes in XINO
1484+files on tmpfs or ramdisk. But it is not so effective actually. If you
1485+meet a problem of disk shortage due to XINO files, then you should try
1486+"tmpfs-ino.patch" (and "vfs-ino.patch" too) in aufs4-standalone.git.
1487+The patch localizes the assignment inumbers per tmpfs-mount and avoid
1488+the holes in XINO files.
1489+
53392da6 1490+Also a writable branch has three kinds of "whiteout bases". All these
7e9cd9fe 1491+are existed when the branch is joined to aufs, and their names are
53392da6
AM
1492+whiteout-ed doubly, so that users will never see their names in aufs
1493+hierarchy.
7e9cd9fe 1494+1. a regular file which will be hardlinked to all whiteouts.
53392da6 1495+2. a directory to store a pseudo-link.
7e9cd9fe 1496+3. a directory to store an "orphan"-ed file temporary.
53392da6
AM
1497+
1498+1. Whiteout Base
1499+ When you remove a file on a readonly branch, aufs handles it as a
1500+ logical deletion and creates a whiteout on the upper writable branch
1501+ as a hardlink of this file in order not to consume inode on the
1502+ writable branch.
1503+2. Pseudo-link Dir
1504+ See below, Pseudo-link.
1505+3. Step-Parent Dir
1506+ When "fileC" exists on the lower readonly branch only and it is
1507+ opened and removed with its parent dir, and then user writes
1508+ something into it, then aufs copies-up fileC to this
1509+ directory. Because there is no other dir to store fileC. After
1510+ creating a file under this dir, the file is unlinked.
1511+
1512+Because aufs supports manipulating branches, ie. add/delete/change
7e9cd9fe
AM
1513+dynamically, a branch has its own id. When the branch order changes,
1514+aufs finds the new index by searching the branch id.
53392da6
AM
1515+
1516+
1517+Pseudo-link
1518+----------------------------------------------------------------------
1519+Assume "fileA" exists on the lower readonly branch only and it is
1520+hardlinked to "fileB" on the branch. When you write something to fileA,
1521+aufs copies-up it to the upper writable branch. Additionally aufs
1522+creates a hardlink under the Pseudo-link Directory of the writable
1523+branch. The inode of a pseudo-link is kept in aufs super_block as a
1524+simple list. If fileB is read after unlinking fileA, aufs returns
1525+filedata from the pseudo-link instead of the lower readonly
1526+branch. Because the pseudo-link is based upon the inode, to keep the
7e9cd9fe 1527+inode number by xino (see above) is essentially necessary.
53392da6
AM
1528+
1529+All the hardlinks under the Pseudo-link Directory of the writable branch
1530+should be restored in a proper location later. Aufs provides a utility
1531+to do this. The userspace helpers executed at remounting and unmounting
1532+aufs by default.
1533+During this utility is running, it puts aufs into the pseudo-link
1534+maintenance mode. In this mode, only the process which began the
1535+maintenance mode (and its child processes) is allowed to operate in
1536+aufs. Some other processes which are not related to the pseudo-link will
1537+be allowed to run too, but the rest have to return an error or wait
1538+until the maintenance mode ends. If a process already acquires an inode
1539+mutex (in VFS), it has to return an error.
1540+
1541+
1542+XIB(external inode number bitmap)
1543+----------------------------------------------------------------------
1544+Addition to the xino file per a branch, aufs has an external inode number
7e9cd9fe
AM
1545+bitmap in a superblock object. It is also an internal file such like a
1546+xino file.
53392da6
AM
1547+It is a simple bitmap to mark whether the aufs inode number is in-use or
1548+not.
1549+To reduce the file I/O, aufs prepares a single memory page to cache xib.
1550+
7e9cd9fe 1551+As well as XINO files, aufs has a feature to truncate/refresh XIB to
53392da6
AM
1552+reduce the number of consumed disk blocks for these files.
1553+
1554+
1555+Virtual or Vertical Dir, and Readdir in Userspace
1556+----------------------------------------------------------------------
1557+In order to support multiple layers (branches), aufs readdir operation
1558+constructs a virtual dir block on memory. For readdir, aufs calls
1559+vfs_readdir() internally for each dir on branches, merges their entries
1560+with eliminating the whiteout-ed ones, and sets it to file (dir)
1561+object. So the file object has its entry list until it is closed. The
1562+entry list will be updated when the file position is zero and becomes
7e9cd9fe 1563+obsoleted. This decision is made in aufs automatically.
53392da6
AM
1564+
1565+The dynamically allocated memory block for the name of entries has a
1566+unit of 512 bytes (by default) and stores the names contiguously (no
1567+padding). Another block for each entry is handled by kmem_cache too.
1568+During building dir blocks, aufs creates hash list and judging whether
1569+the entry is whiteouted by its upper branch or already listed.
1570+The merged result is cached in the corresponding inode object and
1571+maintained by a customizable life-time option.
1572+
1573+Some people may call it can be a security hole or invite DoS attack
1574+since the opened and once readdir-ed dir (file object) holds its entry
1575+list and becomes a pressure for system memory. But I'd say it is similar
1576+to files under /proc or /sys. The virtual files in them also holds a
1577+memory page (generally) while they are opened. When an idea to reduce
1578+memory for them is introduced, it will be applied to aufs too.
1579+For those who really hate this situation, I've developed readdir(3)
1580+library which operates this merging in userspace. You just need to set
1581+LD_PRELOAD environment variable, and aufs will not consume no memory in
1582+kernel space for readdir(3).
1583+
1584+
1585+Workqueue
1586+----------------------------------------------------------------------
1587+Aufs sometimes requires privilege access to a branch. For instance,
1588+in copy-up/down operation. When a user process is going to make changes
1589+to a file which exists in the lower readonly branch only, and the mode
1590+of one of ancestor directories may not be writable by a user
1591+process. Here aufs copy-up the file with its ancestors and they may
1592+require privilege to set its owner/group/mode/etc.
1593+This is a typical case of a application character of aufs (see
1594+Introduction).
1595+
1596+Aufs uses workqueue synchronously for this case. It creates its own
1597+workqueue. The workqueue is a kernel thread and has privilege. Aufs
1598+passes the request to call mkdir or write (for example), and wait for
1599+its completion. This approach solves a problem of a signal handler
1600+simply.
1601+If aufs didn't adopt the workqueue and changed the privilege of the
7e9cd9fe
AM
1602+process, then the process may receive the unexpected SIGXFSZ or other
1603+signals.
53392da6
AM
1604+
1605+Also aufs uses the system global workqueue ("events" kernel thread) too
1606+for asynchronous tasks, such like handling inotify/fsnotify, re-creating a
1607+whiteout base and etc. This is unrelated to a privilege.
1608+Most of aufs operation tries acquiring a rw_semaphore for aufs
1609+superblock at the beginning, at the same time waits for the completion
1610+of all queued asynchronous tasks.
1611+
1612+
1613+Whiteout
1614+----------------------------------------------------------------------
1615+The whiteout in aufs is very similar to Unionfs's. That is represented
1616+by its filename. UnionMount takes an approach of a file mode, but I am
1617+afraid several utilities (find(1) or something) will have to support it.
1618+
1619+Basically the whiteout represents "logical deletion" which stops aufs to
1620+lookup further, but also it represents "dir is opaque" which also stop
7e9cd9fe 1621+further lookup.
53392da6
AM
1622+
1623+In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively.
1624+In order to make several functions in a single systemcall to be
1625+revertible, aufs adopts an approach to rename a directory to a temporary
1626+unique whiteouted name.
1627+For example, in rename(2) dir where the target dir already existed, aufs
1628+renames the target dir to a temporary unique whiteouted name before the
7e9cd9fe 1629+actual rename on a branch, and then handles other actions (make it opaque,
53392da6
AM
1630+update the attributes, etc). If an error happens in these actions, aufs
1631+simply renames the whiteouted name back and returns an error. If all are
1632+succeeded, aufs registers a function to remove the whiteouted unique
1633+temporary name completely and asynchronously to the system global
1634+workqueue.
1635+
1636+
1637+Copy-up
1638+----------------------------------------------------------------------
1639+It is a well-known feature or concept.
1640+When user modifies a file on a readonly branch, aufs operate "copy-up"
1641+internally and makes change to the new file on the upper writable branch.
1642+When the trigger systemcall does not update the timestamps of the parent
1643+dir, aufs reverts it after copy-up.
c2b27bf2
AM
1644+
1645+
1646+Move-down (aufs3.9 and later)
1647+----------------------------------------------------------------------
1648+"Copy-up" is one of the essential feature in aufs. It copies a file from
1649+the lower readonly branch to the upper writable branch when a user
1650+changes something about the file.
1651+"Move-down" is an opposite action of copy-up. Basically this action is
1652+ran manually instead of automatically and internally.
076b876e
AM
1653+For desgin and implementation, aufs has to consider these issues.
1654+- whiteout for the file may exist on the lower branch.
1655+- ancestor directories may not exist on the lower branch.
1656+- diropq for the ancestor directories may exist on the upper branch.
1657+- free space on the lower branch will reduce.
1658+- another access to the file may happen during moving-down, including
7e9cd9fe 1659+ UDBA (see "Revalidate Dentry and UDBA").
076b876e
AM
1660+- the file should not be hard-linked nor pseudo-linked. they should be
1661+ handled by auplink utility later.
c2b27bf2
AM
1662+
1663+Sometimes users want to move-down a file from the upper writable branch
1664+to the lower readonly or writable branch. For instance,
1665+- the free space of the upper writable branch is going to run out.
1666+- create a new intermediate branch between the upper and lower branch.
1667+- etc.
1668+
1669+For this purpose, use "aumvdown" command in aufs-util.git.
b912730e
AM
1670diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.txt linux/Documentation/filesystems/aufs/design/03atomic_open.txt
1671--- /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.txt 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 1672+++ linux/Documentation/filesystems/aufs/design/03atomic_open.txt 2018-04-15 08:49:13.394483860 +0200
b912730e
AM
1673@@ -0,0 +1,85 @@
1674+
ae9dfd79 1675+# Copyright (C) 2015-2018 Junjiro R. Okajima
b912730e
AM
1676+#
1677+# This program is free software; you can redistribute it and/or modify
1678+# it under the terms of the GNU General Public License as published by
1679+# the Free Software Foundation; either version 2 of the License, or
1680+# (at your option) any later version.
1681+#
1682+# This program is distributed in the hope that it will be useful,
1683+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1684+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1685+# GNU General Public License for more details.
1686+#
1687+# You should have received a copy of the GNU General Public License
1688+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1689+
1690+Support for a branch who has its ->atomic_open()
1691+----------------------------------------------------------------------
1692+The filesystems who implement its ->atomic_open() are not majority. For
1693+example NFSv4 does, and aufs should call NFSv4 ->atomic_open,
1694+particularly for open(O_CREAT|O_EXCL, 0400) case. Other than
1695+->atomic_open(), NFSv4 returns an error for this open(2). While I am not
1696+sure whether all filesystems who have ->atomic_open() behave like this,
1697+but NFSv4 surely returns the error.
1698+
1699+In order to support ->atomic_open() for aufs, there are a few
1700+approaches.
1701+
1702+A. Introduce aufs_atomic_open()
1703+ - calls one of VFS:do_last(), lookup_open() or atomic_open() for
1704+ branch fs.
1705+B. Introduce aufs_atomic_open() calling create, open and chmod. this is
1706+ an aufs user Pip Cet's approach
1707+ - calls aufs_create(), VFS finish_open() and notify_change().
1708+ - pass fake-mode to finish_open(), and then correct the mode by
1709+ notify_change().
1710+C. Extend aufs_open() to call branch fs's ->atomic_open()
1711+ - no aufs_atomic_open().
1712+ - aufs_lookup() registers the TID to an aufs internal object.
1713+ - aufs_create() does nothing when the matching TID is registered, but
1714+ registers the mode.
1715+ - aufs_open() calls branch fs's ->atomic_open() when the matching
1716+ TID is registered.
1717+D. Extend aufs_open() to re-try branch fs's ->open() with superuser's
1718+ credential
1719+ - no aufs_atomic_open().
1720+ - aufs_create() registers the TID to an internal object. this info
1721+ represents "this process created this file just now."
1722+ - when aufs gets EACCES from branch fs's ->open(), then confirm the
1723+ registered TID and re-try open() with superuser's credential.
1724+
1725+Pros and cons for each approach.
1726+
1727+A.
1728+ - straightforward but highly depends upon VFS internal.
1729+ - the atomic behavaiour is kept.
1730+ - some of parameters such as nameidata are hard to reproduce for
1731+ branch fs.
1732+ - large overhead.
1733+B.
1734+ - easy to implement.
1735+ - the atomic behavaiour is lost.
1736+C.
1737+ - the atomic behavaiour is kept.
1738+ - dirty and tricky.
1739+ - VFS checks whether the file is created correctly after calling
1740+ ->create(), which means this approach doesn't work.
1741+D.
1742+ - easy to implement.
1743+ - the atomic behavaiour is lost.
1744+ - to open a file with superuser's credential and give it to a user
1745+ process is a bad idea, since the file object keeps the credential
1746+ in it. It may affect LSM or something. This approach doesn't work
1747+ either.
1748+
1749+The approach A is ideal, but it hard to implement. So here is a
1750+variation of A, which is to be implemented.
1751+
1752+A-1. Introduce aufs_atomic_open()
1753+ - calls branch fs ->atomic_open() if exists. otherwise calls
1754+ vfs_create() and finish_open().
1755+ - the demerit is that the several checks after branch fs
1756+ ->atomic_open() are lost. in the ordinary case, the checks are
1757+ done by VFS:do_last(), lookup_open() and atomic_open(). some can
1758+ be implemented in aufs, but not all I am afraid.
53392da6
AM
1759diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt
1760--- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 1761+++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2018-04-15 08:49:13.394483860 +0200
7e9cd9fe 1762@@ -0,0 +1,113 @@
53392da6 1763+
ae9dfd79 1764+# Copyright (C) 2005-2018 Junjiro R. Okajima
53392da6
AM
1765+#
1766+# This program is free software; you can redistribute it and/or modify
1767+# it under the terms of the GNU General Public License as published by
1768+# the Free Software Foundation; either version 2 of the License, or
1769+# (at your option) any later version.
1770+#
1771+# This program is distributed in the hope that it will be useful,
1772+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1773+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1774+# GNU General Public License for more details.
1775+#
1776+# You should have received a copy of the GNU General Public License
523b37e3 1777+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1778+
1779+Lookup in a Branch
1780+----------------------------------------------------------------------
1781+Since aufs has a character of sub-VFS (see Introduction), it operates
7e9cd9fe
AM
1782+lookup for branches as VFS does. It may be a heavy work. But almost all
1783+lookup operation in aufs is the simplest case, ie. lookup only an entry
1784+directly connected to its parent. Digging down the directory hierarchy
1785+is unnecessary. VFS has a function lookup_one_len() for that use, and
1786+aufs calls it.
1787+
1788+When a branch is a remote filesystem, aufs basically relies upon its
53392da6
AM
1789+->d_revalidate(), also aufs forces the hardest revalidate tests for
1790+them.
1791+For d_revalidate, aufs implements three levels of revalidate tests. See
1792+"Revalidate Dentry and UDBA" in detail.
1793+
1794+
076b876e
AM
1795+Test Only the Highest One for the Directory Permission (dirperm1 option)
1796+----------------------------------------------------------------------
1797+Let's try case study.
1798+- aufs has two branches, upper readwrite and lower readonly.
1799+ /au = /rw + /ro
1800+- "dirA" exists under /ro, but /rw. and its mode is 0700.
1801+- user invoked "chmod a+rx /au/dirA"
1802+- the internal copy-up is activated and "/rw/dirA" is created and its
7e9cd9fe 1803+ permission bits are set to world readable.
076b876e
AM
1804+- then "/au/dirA" becomes world readable?
1805+
1806+In this case, /ro/dirA is still 0700 since it exists in readonly branch,
1807+or it may be a natively readonly filesystem. If aufs respects the lower
1808+branch, it should not respond readdir request from other users. But user
1809+allowed it by chmod. Should really aufs rejects showing the entries
1810+under /ro/dirA?
1811+
7e9cd9fe
AM
1812+To be honest, I don't have a good solution for this case. So aufs
1813+implements 'dirperm1' and 'nodirperm1' mount options, and leave it to
1814+users.
076b876e
AM
1815+When dirperm1 is specified, aufs checks only the highest one for the
1816+directory permission, and shows the entries. Otherwise, as usual, checks
1817+every dir existing on all branches and rejects the request.
1818+
1819+As a side effect, dirperm1 option improves the performance of aufs
1820+because the number of permission check is reduced when the number of
1821+branch is many.
1822+
1823+
53392da6
AM
1824+Revalidate Dentry and UDBA (User's Direct Branch Access)
1825+----------------------------------------------------------------------
1826+Generally VFS helpers re-validate a dentry as a part of lookup.
1827+0. digging down the directory hierarchy.
1828+1. lock the parent dir by its i_mutex.
1829+2. lookup the final (child) entry.
1830+3. revalidate it.
1831+4. call the actual operation (create, unlink, etc.)
1832+5. unlock the parent dir
1833+
1834+If the filesystem implements its ->d_revalidate() (step 3), then it is
1835+called. Actually aufs implements it and checks the dentry on a branch is
1836+still valid.
1837+But it is not enough. Because aufs has to release the lock for the
1838+parent dir on a branch at the end of ->lookup() (step 2) and
1839+->d_revalidate() (step 3) while the i_mutex of the aufs dir is still
1840+held by VFS.
1841+If the file on a branch is changed directly, eg. bypassing aufs, after
1842+aufs released the lock, then the subsequent operation may cause
1843+something unpleasant result.
1844+
1845+This situation is a result of VFS architecture, ->lookup() and
1846+->d_revalidate() is separated. But I never say it is wrong. It is a good
1847+design from VFS's point of view. It is just not suitable for sub-VFS
1848+character in aufs.
1849+
1850+Aufs supports such case by three level of revalidation which is
1851+selectable by user.
1852+1. Simple Revalidate
1853+ Addition to the native flow in VFS's, confirm the child-parent
1854+ relationship on the branch just after locking the parent dir on the
1855+ branch in the "actual operation" (step 4). When this validation
1856+ fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still
1857+ checks the validation of the dentry on branches.
1858+2. Monitor Changes Internally by Inotify/Fsnotify
1859+ Addition to above, in the "actual operation" (step 4) aufs re-lookup
1860+ the dentry on the branch, and returns EBUSY if it finds different
1861+ dentry.
1862+ Additionally, aufs sets the inotify/fsnotify watch for every dir on branches
1863+ during it is in cache. When the event is notified, aufs registers a
1864+ function to kernel 'events' thread by schedule_work(). And the
1865+ function sets some special status to the cached aufs dentry and inode
1866+ private data. If they are not cached, then aufs has nothing to
1867+ do. When the same file is accessed through aufs (step 0-3) later,
1868+ aufs will detect the status and refresh all necessary data.
1869+ In this mode, aufs has to ignore the event which is fired by aufs
1870+ itself.
1871+3. No Extra Validation
1872+ This is the simplest test and doesn't add any additional revalidation
7e9cd9fe 1873+ test, and skip the revalidation in step 4. It is useful and improves
53392da6
AM
1874+ aufs performance when system surely hide the aufs branches from user,
1875+ by over-mounting something (or another method).
1876diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt linux/Documentation/filesystems/aufs/design/04branch.txt
1877--- /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 1878+++ linux/Documentation/filesystems/aufs/design/04branch.txt 2018-04-15 08:49:13.394483860 +0200
7e9cd9fe 1879@@ -0,0 +1,74 @@
53392da6 1880+
ae9dfd79 1881+# Copyright (C) 2005-2018 Junjiro R. Okajima
53392da6
AM
1882+#
1883+# This program is free software; you can redistribute it and/or modify
1884+# it under the terms of the GNU General Public License as published by
1885+# the Free Software Foundation; either version 2 of the License, or
1886+# (at your option) any later version.
1887+#
1888+# This program is distributed in the hope that it will be useful,
1889+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1890+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1891+# GNU General Public License for more details.
1892+#
1893+# You should have received a copy of the GNU General Public License
523b37e3 1894+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1895+
1896+Branch Manipulation
1897+
1898+Since aufs supports dynamic branch manipulation, ie. add/remove a branch
1899+and changing its permission/attribute, there are a lot of works to do.
1900+
1901+
1902+Add a Branch
1903+----------------------------------------------------------------------
1904+o Confirm the adding dir exists outside of aufs, including loopback
7e9cd9fe 1905+ mount, and its various attributes.
53392da6
AM
1906+o Initialize the xino file and whiteout bases if necessary.
1907+ See struct.txt.
1908+
1909+o Check the owner/group/mode of the directory
1910+ When the owner/group/mode of the adding directory differs from the
1911+ existing branch, aufs issues a warning because it may impose a
1912+ security risk.
1913+ For example, when a upper writable branch has a world writable empty
1914+ top directory, a malicious user can create any files on the writable
1915+ branch directly, like copy-up and modify manually. If something like
1916+ /etc/{passwd,shadow} exists on the lower readonly branch but the upper
1917+ writable branch, and the writable branch is world-writable, then a
1918+ malicious guy may create /etc/passwd on the writable branch directly
1919+ and the infected file will be valid in aufs.
7e9cd9fe 1920+ I am afraid it can be a security issue, but aufs can do nothing except
53392da6
AM
1921+ producing a warning.
1922+
1923+
1924+Delete a Branch
1925+----------------------------------------------------------------------
1926+o Confirm the deleting branch is not busy
1927+ To be general, there is one merit to adopt "remount" interface to
1928+ manipulate branches. It is to discard caches. At deleting a branch,
1929+ aufs checks the still cached (and connected) dentries and inodes. If
1930+ there are any, then they are all in-use. An inode without its
1931+ corresponding dentry can be alive alone (for example, inotify/fsnotify case).
1932+
1933+ For the cached one, aufs checks whether the same named entry exists on
1934+ other branches.
1935+ If the cached one is a directory, because aufs provides a merged view
1936+ to users, as long as one dir is left on any branch aufs can show the
1937+ dir to users. In this case, the branch can be removed from aufs.
1938+ Otherwise aufs rejects deleting the branch.
1939+
1940+ If any file on the deleting branch is opened by aufs, then aufs
1941+ rejects deleting.
1942+
1943+
1944+Modify the Permission of a Branch
1945+----------------------------------------------------------------------
1946+o Re-initialize or remove the xino file and whiteout bases if necessary.
1947+ See struct.txt.
1948+
1949+o rw --> ro: Confirm the modifying branch is not busy
1950+ Aufs rejects the request if any of these conditions are true.
1951+ - a file on the branch is mmap-ed.
1952+ - a regular file on the branch is opened for write and there is no
1953+ same named entry on the upper branch.
1954diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt linux/Documentation/filesystems/aufs/design/05wbr_policy.txt
1955--- /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 1956+++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2018-04-15 08:49:13.394483860 +0200
523b37e3 1957@@ -0,0 +1,64 @@
53392da6 1958+
ae9dfd79 1959+# Copyright (C) 2005-2018 Junjiro R. Okajima
53392da6
AM
1960+#
1961+# This program is free software; you can redistribute it and/or modify
1962+# it under the terms of the GNU General Public License as published by
1963+# the Free Software Foundation; either version 2 of the License, or
1964+# (at your option) any later version.
1965+#
1966+# This program is distributed in the hope that it will be useful,
1967+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1968+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1969+# GNU General Public License for more details.
1970+#
1971+# You should have received a copy of the GNU General Public License
523b37e3 1972+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1973+
1974+Policies to Select One among Multiple Writable Branches
1975+----------------------------------------------------------------------
1976+When the number of writable branch is more than one, aufs has to decide
1977+the target branch for file creation or copy-up. By default, the highest
1978+writable branch which has the parent (or ancestor) dir of the target
1979+file is chosen (top-down-parent policy).
1980+By user's request, aufs implements some other policies to select the
7e9cd9fe
AM
1981+writable branch, for file creation several policies, round-robin,
1982+most-free-space, and other policies. For copy-up, top-down-parent,
1983+bottom-up-parent, bottom-up and others.
53392da6
AM
1984+
1985+As expected, the round-robin policy selects the branch in circular. When
1986+you have two writable branches and creates 10 new files, 5 files will be
1987+created for each branch. mkdir(2) systemcall is an exception. When you
1988+create 10 new directories, all will be created on the same branch.
1989+And the most-free-space policy selects the one which has most free
1990+space among the writable branches. The amount of free space will be
1991+checked by aufs internally, and users can specify its time interval.
1992+
1993+The policies for copy-up is more simple,
1994+top-down-parent is equivalent to the same named on in create policy,
1995+bottom-up-parent selects the writable branch where the parent dir
1996+exists and the nearest upper one from the copyup-source,
1997+bottom-up selects the nearest upper writable branch from the
1998+copyup-source, regardless the existence of the parent dir.
1999+
2000+There are some rules or exceptions to apply these policies.
2001+- If there is a readonly branch above the policy-selected branch and
2002+ the parent dir is marked as opaque (a variation of whiteout), or the
2003+ target (creating) file is whiteout-ed on the upper readonly branch,
2004+ then the result of the policy is ignored and the target file will be
2005+ created on the nearest upper writable branch than the readonly branch.
2006+- If there is a writable branch above the policy-selected branch and
2007+ the parent dir is marked as opaque or the target file is whiteouted
2008+ on the branch, then the result of the policy is ignored and the target
2009+ file will be created on the highest one among the upper writable
2010+ branches who has diropq or whiteout. In case of whiteout, aufs removes
2011+ it as usual.
2012+- link(2) and rename(2) systemcalls are exceptions in every policy.
2013+ They try selecting the branch where the source exists as possible
2014+ since copyup a large file will take long time. If it can't be,
2015+ ie. the branch where the source exists is readonly, then they will
2016+ follow the copyup policy.
2017+- There is an exception for rename(2) when the target exists.
2018+ If the rename target exists, aufs compares the index of the branches
2019+ where the source and the target exists and selects the higher
2020+ one. If the selected branch is readonly, then aufs follows the
2021+ copyup policy.
ae9dfd79
AM
2022diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.dot linux/Documentation/filesystems/aufs/design/06dirren.dot
2023--- /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.dot 1970-01-01 01:00:00.000000000 +0100
2024+++ linux/Documentation/filesystems/aufs/design/06dirren.dot 2018-04-15 08:49:13.394483860 +0200
2025@@ -0,0 +1,31 @@
2026+
2027+// to view this graph, run dot(1) command in GRAPHVIZ.
2028+
2029+digraph G {
2030+node [shape=box];
2031+whinfo [label="detailed info file\n(lower_brid_root-hinum, h_inum, namelen, old name)"];
2032+
2033+node [shape=oval];
2034+
2035+aufs_rename -> whinfo [label="store/remove"];
2036+
2037+node [shape=oval];
2038+inode_list [label="h_inum list in branch\ncache"];
2039+
2040+node [shape=box];
2041+whinode [label="h_inum list file"];
2042+
2043+node [shape=oval];
2044+brmgmt [label="br_add/del/mod/umount"];
2045+
2046+brmgmt -> inode_list [label="create/remove"];
2047+brmgmt -> whinode [label="load/store"];
2048+
2049+inode_list -> whinode [style=dashed,dir=both];
2050+
2051+aufs_rename -> inode_list [label="add/del"];
2052+
2053+aufs_lookup -> inode_list [label="search"];
2054+
2055+aufs_lookup -> whinfo [label="load/remove"];
2056+}
2057diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.txt linux/Documentation/filesystems/aufs/design/06dirren.txt
2058--- /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.txt 1970-01-01 01:00:00.000000000 +0100
2059+++ linux/Documentation/filesystems/aufs/design/06dirren.txt 2018-04-15 08:49:13.394483860 +0200
2060@@ -0,0 +1,102 @@
2061+
2062+# Copyright (C) 2017-2018 Junjiro R. Okajima
2063+#
2064+# This program is free software; you can redistribute it and/or modify
2065+# it under the terms of the GNU General Public License as published by
2066+# the Free Software Foundation; either version 2 of the License, or
2067+# (at your option) any later version.
2068+#
2069+# This program is distributed in the hope that it will be useful,
2070+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2071+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2072+# GNU General Public License for more details.
2073+#
2074+# You should have received a copy of the GNU General Public License
2075+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2076+
2077+Special handling for renaming a directory (DIRREN)
2078+----------------------------------------------------------------------
2079+First, let's assume we have a simple usecase.
2080+
2081+- /u = /rw + /ro
2082+- /rw/dirA exists
2083+- /ro/dirA and /ro/dirA/file exist too
2084+- there is no dirB on both branches
2085+- a user issues rename("dirA", "dirB")
2086+
2087+Now, what should aufs behave against this rename(2)?
2088+There are a few possible cases.
2089+
2090+A. returns EROFS.
2091+ since dirA exists on a readonly branch which cannot be renamed.
2092+B. returns EXDEV.
2093+ it is possible to copy-up dirA (only the dir itself), but the child
2094+ entries ("file" in this case) should not be. it must be a bad
2095+ approach to copy-up recursively.
2096+C. returns a success.
2097+ even the branch /ro is readonly, aufs tries renaming it. Obviously it
2098+ is a violation of aufs' policy.
2099+D. construct an extra information which indicates that /ro/dirA should
2100+ be handled as the name of dirB.
2101+ overlayfs has a similar feature called REDIRECT.
2102+
2103+Until now, aufs implements the case B only which returns EXDEV, and
2104+expects the userspace application behaves like mv(1) which tries
2105+issueing rename(2) recursively.
2106+
2107+A new aufs feature called DIRREN is introduced which implements the case
2108+D. There are several "extra information" added.
2109+
2110+1. detailed info per renamed directory
2111+ path: /rw/dirB/$AUFS_WH_DR_INFO_PFX.<lower branch-id>
2112+2. the inode-number list of directories on a branch
2113+ path: /rw/dirB/$AUFS_WH_DR_BRHINO
2114+
2115+The filename of "detailed info per directory" represents the lower
2116+branch, and its format is
2117+- a type of the branch id
2118+ one of these.
2119+ + uuid (not implemented yet)
2120+ + fsid
2121+ + dev
2122+- the inode-number of the branch root dir
2123+
2124+And it contains these info in a single regular file.
2125+- magic number
2126+- branch's inode-number of the logically renamed dir
2127+- the name of the before-renamed dir
2128+
2129+The "detailed info per directory" file is created in aufs rename(2), and
2130+loaded in any lookup.
2131+The info is considered in lookup for the matching case only. Here
2132+"matching" means that the root of branch (in the info filename) is same
2133+to the current looking-up branch. After looking-up the before-renamed
2134+name, the inode-number is compared. And the matched dentry is used.
2135+
2136+The "inode-number list of directories" is a regular file which contains
2137+simply the inode-numbers on the branch. The file is created or updated
2138+in removing the branch, and loaded in adding the branch. Its lifetime is
2139+equal to the branch.
2140+The list is refered in lookup, and when the current target inode is
2141+found in the list, the aufs tries loading the "detailed info per
2142+directory" and get the changed and valid name of the dir.
2143+
2144+Theoretically these "extra informaiton" may be able to be put into XATTR
2145+in the dir inode. But aufs doesn't choose this way because
2146+1. XATTR may not be supported by the branch (or its configuration)
2147+2. XATTR may have its size limit.
2148+3. XATTR may be less easy to convert than a regular file, when the
2149+ format of the info is changed in the future.
2150+At the same time, I agree that the regular file approach is much slower
2151+than XATTR approach. So, in the future, aufs may take the XATTR or other
2152+better approach.
2153+
2154+This DIRREN feature is enabled by aufs configuration, and is activated
2155+by a new mount option.
2156+
2157+For the more complicated case, there is a work with UDBA option, which
2158+is to dected the direct access to the branches (by-passing aufs) and to
2159+maintain the cashes in aufs. Since a single cached aufs dentry may
2160+contains two names, before- and after-rename, the name comparision in
2161+UDBA handler may not work correctly. In this case, the behaviour will be
2162+equivalen to udba=reval case.
076b876e
AM
2163diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt linux/Documentation/filesystems/aufs/design/06fhsm.txt
2164--- /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 2165+++ linux/Documentation/filesystems/aufs/design/06fhsm.txt 2018-04-15 08:49:13.394483860 +0200
076b876e
AM
2166@@ -0,0 +1,120 @@
2167+
ae9dfd79 2168+# Copyright (C) 2011-2018 Junjiro R. Okajima
076b876e
AM
2169+#
2170+# This program is free software; you can redistribute it and/or modify
2171+# it under the terms of the GNU General Public License as published by
2172+# the Free Software Foundation; either version 2 of the License, or
2173+# (at your option) any later version.
2174+#
2175+# This program is distributed in the hope that it will be useful,
2176+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2177+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2178+# GNU General Public License for more details.
2179+#
2180+# You should have received a copy of the GNU General Public License
2181+# along with this program; if not, write to the Free Software
2182+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2183+
2184+
2185+File-based Hierarchical Storage Management (FHSM)
2186+----------------------------------------------------------------------
2187+Hierarchical Storage Management (or HSM) is a well-known feature in the
2188+storage world. Aufs provides this feature as file-based with multiple
7e9cd9fe 2189+writable branches, based upon the principle of "Colder, the Lower".
076b876e 2190+Here the word "colder" means that the less used files, and "lower" means
7e9cd9fe 2191+that the position in the order of the stacked branches vertically.
076b876e
AM
2192+These multiple writable branches are prioritized, ie. the topmost one
2193+should be the fastest drive and be used heavily.
2194+
2195+o Characters in aufs FHSM story
2196+- aufs itself and a new branch attribute.
2197+- a new ioctl interface to move-down and to establish a connection with
2198+ the daemon ("move-down" is a converse of "copy-up").
2199+- userspace tool and daemon.
2200+
2201+The userspace daemon establishes a connection with aufs and waits for
2202+the notification. The notified information is very similar to struct
2203+statfs containing the number of consumed blocks and inodes.
2204+When the consumed blocks/inodes of a branch exceeds the user-specified
2205+upper watermark, the daemon activates its move-down process until the
2206+consumed blocks/inodes reaches the user-specified lower watermark.
2207+
2208+The actual move-down is done by aufs based upon the request from
2209+user-space since we need to maintain the inode number and the internal
2210+pointer arrays in aufs.
2211+
2212+Currently aufs FHSM handles the regular files only. Additionally they
2213+must not be hard-linked nor pseudo-linked.
2214+
2215+
2216+o Cowork of aufs and the user-space daemon
2217+ During the userspace daemon established the connection, aufs sends a
2218+ small notification to it whenever aufs writes something into the
2219+ writable branch. But it may cost high since aufs issues statfs(2)
2220+ internally. So user can specify a new option to cache the
2221+ info. Actually the notification is controlled by these factors.
2222+ + the specified cache time.
2223+ + classified as "force" by aufs internally.
2224+ Until the specified time expires, aufs doesn't send the info
2225+ except the forced cases. When aufs decide forcing, the info is always
2226+ notified to userspace.
2227+ For example, the number of free inodes is generally large enough and
2228+ the shortage of it happens rarely. So aufs doesn't force the
2229+ notification when creating a new file, directory and others. This is
2230+ the typical case which aufs doesn't force.
2231+ When aufs writes the actual filedata and the files consumes any of new
2232+ blocks, the aufs forces notifying.
2233+
2234+
2235+o Interfaces in aufs
2236+- New branch attribute.
2237+ + fhsm
2238+ Specifies that the branch is managed by FHSM feature. In other word,
2239+ participant in the FHSM.
2240+ When nofhsm is set to the branch, it will not be the source/target
2241+ branch of the move-down operation. This attribute is set
2242+ independently from coo and moo attributes, and if you want full
2243+ FHSM, you should specify them as well.
2244+- New mount option.
2245+ + fhsm_sec
2246+ Specifies a second to suppress many less important info to be
2247+ notified.
2248+- New ioctl.
2249+ + AUFS_CTL_FHSM_FD
2250+ create a new file descriptor which userspace can read the notification
2251+ (a subset of struct statfs) from aufs.
2252+- Module parameter 'brs'
2253+ It has to be set to 1. Otherwise the new mount option 'fhsm' will not
2254+ be set.
2255+- mount helpers /sbin/mount.aufs and /sbin/umount.aufs
2256+ When there are two or more branches with fhsm attributes,
2257+ /sbin/mount.aufs invokes the user-space daemon and /sbin/umount.aufs
2258+ terminates it. As a result of remounting and branch-manipulation, the
2259+ number of branches with fhsm attribute can be one. In this case,
2260+ /sbin/mount.aufs will terminate the user-space daemon.
2261+
2262+
2263+Finally the operation is done as these steps in kernel-space.
2264+- make sure that,
2265+ + no one else is using the file.
2266+ + the file is not hard-linked.
2267+ + the file is not pseudo-linked.
2268+ + the file is a regular file.
2269+ + the parent dir is not opaqued.
2270+- find the target writable branch.
2271+- make sure the file is not whiteout-ed by the upper (than the target)
2272+ branch.
2273+- make the parent dir on the target branch.
2274+- mutex lock the inode on the branch.
2275+- unlink the whiteout on the target branch (if exists).
2276+- lookup and create the whiteout-ed temporary name on the target branch.
2277+- copy the file as the whiteout-ed temporary name on the target branch.
2278+- rename the whiteout-ed temporary name to the original name.
2279+- unlink the file on the source branch.
2280+- maintain the internal pointer array and the external inode number
2281+ table (XINO).
2282+- maintain the timestamps and other attributes of the parent dir and the
2283+ file.
2284+
2285+And of course, in every step, an error may happen. So the operation
2286+should restore the original file state after an error happens.
53392da6
AM
2287diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt
2288--- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 2289+++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2018-04-15 08:49:13.394483860 +0200
b912730e 2290@@ -0,0 +1,72 @@
53392da6 2291+
ae9dfd79 2292+# Copyright (C) 2005-2018 Junjiro R. Okajima
53392da6
AM
2293+#
2294+# This program is free software; you can redistribute it and/or modify
2295+# it under the terms of the GNU General Public License as published by
2296+# the Free Software Foundation; either version 2 of the License, or
2297+# (at your option) any later version.
2298+#
2299+# This program is distributed in the hope that it will be useful,
2300+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2301+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2302+# GNU General Public License for more details.
2303+#
2304+# You should have received a copy of the GNU General Public License
523b37e3 2305+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2306+
2307+mmap(2) -- File Memory Mapping
2308+----------------------------------------------------------------------
2309+In aufs, the file-mapped pages are handled by a branch fs directly, no
2310+interaction with aufs. It means aufs_mmap() calls the branch fs's
2311+->mmap().
2312+This approach is simple and good, but there is one problem.
7e9cd9fe 2313+Under /proc, several entries show the mmapped files by its path (with
53392da6
AM
2314+device and inode number), and the printed path will be the path on the
2315+branch fs's instead of virtual aufs's.
2316+This is not a problem in most cases, but some utilities lsof(1) (and its
2317+user) may expect the path on aufs.
2318+
2319+To address this issue, aufs adds a new member called vm_prfile in struct
2320+vm_area_struct (and struct vm_region). The original vm_file points to
2321+the file on the branch fs in order to handle everything correctly as
2322+usual. The new vm_prfile points to a virtual file in aufs, and the
2323+show-functions in procfs refers to vm_prfile if it is set.
2324+Also we need to maintain several other places where touching vm_file
2325+such like
2326+- fork()/clone() copies vma and the reference count of vm_file is
2327+ incremented.
2328+- merging vma maintains the ref count too.
2329+
7e9cd9fe 2330+This is not a good approach. It just fakes the printed path. But it
53392da6
AM
2331+leaves all behaviour around f_mapping unchanged. This is surely an
2332+advantage.
2333+Actually aufs had adopted another complicated approach which calls
2334+generic_file_mmap() and handles struct vm_operations_struct. In this
2335+approach, aufs met a hard problem and I could not solve it without
2336+switching the approach.
b912730e
AM
2337+
2338+There may be one more another approach which is
2339+- bind-mount the branch-root onto the aufs-root internally
2340+- grab the new vfsmount (ie. struct mount)
2341+- lazy-umount the branch-root internally
2342+- in open(2) the aufs-file, open the branch-file with the hidden
2343+ vfsmount (instead of the original branch's vfsmount)
2344+- ideally this "bind-mount and lazy-umount" should be done atomically,
2345+ but it may be possible from userspace by the mount helper.
2346+
2347+Adding the internal hidden vfsmount and using it in opening a file, the
2348+file path under /proc will be printed correctly. This approach looks
2349+smarter, but is not possible I am afraid.
2350+- aufs-root may be bind-mount later. when it happens, another hidden
2351+ vfsmount will be required.
2352+- it is hard to get the chance to bind-mount and lazy-umount
2353+ + in kernel-space, FS can have vfsmount in open(2) via
2354+ file->f_path, and aufs can know its vfsmount. But several locks are
2355+ already acquired, and if aufs tries to bind-mount and lazy-umount
2356+ here, then it may cause a deadlock.
2357+ + in user-space, bind-mount doesn't invoke the mount helper.
2358+- since /proc shows dev and ino, aufs has to give vma these info. it
2359+ means a new member vm_prinode will be necessary. this is essentially
2360+ equivalent to vm_prfile described above.
2361+
2362+I have to give up this "looks-smater" approach.
c1595e42
JR
2363diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt linux/Documentation/filesystems/aufs/design/06xattr.txt
2364--- /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 2365+++ linux/Documentation/filesystems/aufs/design/06xattr.txt 2018-04-15 08:49:13.394483860 +0200
c1595e42
JR
2366@@ -0,0 +1,96 @@
2367+
ae9dfd79 2368+# Copyright (C) 2014-2018 Junjiro R. Okajima
c1595e42
JR
2369+#
2370+# This program is free software; you can redistribute it and/or modify
2371+# it under the terms of the GNU General Public License as published by
2372+# the Free Software Foundation; either version 2 of the License, or
2373+# (at your option) any later version.
2374+#
2375+# This program is distributed in the hope that it will be useful,
2376+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2377+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2378+# GNU General Public License for more details.
2379+#
2380+# You should have received a copy of the GNU General Public License
2381+# along with this program; if not, write to the Free Software
2382+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2383+
2384+
2385+Listing XATTR/EA and getting the value
2386+----------------------------------------------------------------------
2387+For the inode standard attributes (owner, group, timestamps, etc.), aufs
2388+shows the values from the topmost existing file. This behaviour is good
7e9cd9fe 2389+for the non-dir entries since the bahaviour exactly matches the shown
c1595e42
JR
2390+information. But for the directories, aufs considers all the same named
2391+entries on the lower branches. Which means, if one of the lower entry
2392+rejects readdir call, then aufs returns an error even if the topmost
2393+entry allows it. This behaviour is necessary to respect the branch fs's
2394+security, but can make users confused since the user-visible standard
2395+attributes don't match the behaviour.
2396+To address this issue, aufs has a mount option called dirperm1 which
2397+checks the permission for the topmost entry only, and ignores the lower
2398+entry's permission.
2399+
2400+A similar issue can happen around XATTR.
2401+getxattr(2) and listxattr(2) families behave as if dirperm1 option is
7e9cd9fe
AM
2402+always set. Otherwise these very unpleasant situation would happen.
2403+- listxattr(2) may return the duplicated entries.
c1595e42
JR
2404+- users may not be able to remove or reset the XATTR forever,
2405+
2406+
2407+XATTR/EA support in the internal (copy,move)-(up,down)
2408+----------------------------------------------------------------------
7e9cd9fe 2409+Generally the extended attributes of inode are categorized as these.
c1595e42
JR
2410+- "security" for LSM and capability.
2411+- "system" for posix ACL, 'acl' mount option is required for the branch
2412+ fs generally.
2413+- "trusted" for userspace, CAP_SYS_ADMIN is required.
2414+- "user" for userspace, 'user_xattr' mount option is required for the
2415+ branch fs generally.
2416+
2417+Moreover there are some other categories. Aufs handles these rather
2418+unpopular categories as the ordinary ones, ie. there is no special
2419+condition nor exception.
2420+
2421+In copy-up, the support for XATTR on the dst branch may differ from the
2422+src branch. In this case, the copy-up operation will get an error and
7e9cd9fe
AM
2423+the original user operation which triggered the copy-up will fail. It
2424+can happen that even all copy-up will fail.
c1595e42
JR
2425+When both of src and dst branches support XATTR and if an error occurs
2426+during copying XATTR, then the copy-up should fail obviously. That is a
2427+good reason and aufs should return an error to userspace. But when only
7e9cd9fe 2428+the src branch support that XATTR, aufs should not return an error.
c1595e42
JR
2429+For example, the src branch supports ACL but the dst branch doesn't
2430+because the dst branch may natively un-support it or temporary
2431+un-support it due to "noacl" mount option. Of course, the dst branch fs
2432+may NOT return an error even if the XATTR is not supported. It is
2433+totally up to the branch fs.
2434+
2435+Anyway when the aufs internal copy-up gets an error from the dst branch
2436+fs, then aufs tries removing the just copied entry and returns the error
2437+to the userspace. The worst case of this situation will be all copy-up
2438+will fail.
2439+
2440+For the copy-up operation, there two basic approaches.
2441+- copy the specified XATTR only (by category above), and return the
7e9cd9fe 2442+ error unconditionally if it happens.
c1595e42
JR
2443+- copy all XATTR, and ignore the error on the specified category only.
2444+
2445+In order to support XATTR and to implement the correct behaviour, aufs
7e9cd9fe
AM
2446+chooses the latter approach and introduces some new branch attributes,
2447+"icexsec", "icexsys", "icextr", "icexusr", and "icexoth".
c1595e42 2448+They correspond to the XATTR namespaces (see above). Additionally, to be
7e9cd9fe
AM
2449+convenient, "icex" is also provided which means all "icex*" attributes
2450+are set (here the word "icex" stands for "ignore copy-error on XATTR").
c1595e42
JR
2451+
2452+The meaning of these attributes is to ignore the error from setting
2453+XATTR on that branch.
2454+Note that aufs tries copying all XATTR unconditionally, and ignores the
2455+error from the dst branch according to the specified attributes.
2456+
2457+Some XATTR may have its default value. The default value may come from
2458+the parent dir or the environment. If the default value is set at the
2459+file creating-time, it will be overwritten by copy-up.
2460+Some contradiction may happen I am afraid.
2461+Do we need another attribute to stop copying XATTR? I am unsure. For
2462+now, aufs implements the branch attributes to ignore the error.
53392da6
AM
2463diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt
2464--- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 2465+++ linux/Documentation/filesystems/aufs/design/07export.txt 2018-04-15 08:49:13.394483860 +0200
523b37e3 2466@@ -0,0 +1,58 @@
53392da6 2467+
ae9dfd79 2468+# Copyright (C) 2005-2018 Junjiro R. Okajima
53392da6
AM
2469+#
2470+# This program is free software; you can redistribute it and/or modify
2471+# it under the terms of the GNU General Public License as published by
2472+# the Free Software Foundation; either version 2 of the License, or
2473+# (at your option) any later version.
2474+#
2475+# This program is distributed in the hope that it will be useful,
2476+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2477+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2478+# GNU General Public License for more details.
2479+#
2480+# You should have received a copy of the GNU General Public License
523b37e3 2481+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2482+
2483+Export Aufs via NFS
2484+----------------------------------------------------------------------
2485+Here is an approach.
2486+- like xino/xib, add a new file 'xigen' which stores aufs inode
2487+ generation.
2488+- iget_locked(): initialize aufs inode generation for a new inode, and
2489+ store it in xigen file.
2490+- destroy_inode(): increment aufs inode generation and store it in xigen
2491+ file. it is necessary even if it is not unlinked, because any data of
2492+ inode may be changed by UDBA.
2493+- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise
2494+ build file handle by
2495+ + branch id (4 bytes)
2496+ + superblock generation (4 bytes)
2497+ + inode number (4 or 8 bytes)
2498+ + parent dir inode number (4 or 8 bytes)
2499+ + inode generation (4 bytes))
2500+ + return value of exportfs_encode_fh() for the parent on a branch (4
2501+ bytes)
2502+ + file handle for a branch (by exportfs_encode_fh())
2503+- fh_to_dentry():
2504+ + find the index of a branch from its id in handle, and check it is
2505+ still exist in aufs.
2506+ + 1st level: get the inode number from handle and search it in cache.
7e9cd9fe
AM
2507+ + 2nd level: if not found in cache, get the parent inode number from
2508+ the handle and search it in cache. and then open the found parent
2509+ dir, find the matching inode number by vfs_readdir() and get its
2510+ name, and call lookup_one_len() for the target dentry.
53392da6
AM
2511+ + 3rd level: if the parent dir is not cached, call
2512+ exportfs_decode_fh() for a branch and get the parent on a branch,
2513+ build a pathname of it, convert it a pathname in aufs, call
2514+ path_lookup(). now aufs gets a parent dir dentry, then handle it as
2515+ the 2nd level.
2516+ + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount
2517+ for every branch, but not itself. to get this, (currently) aufs
2518+ searches in current->nsproxy->mnt_ns list. it may not be a good
2519+ idea, but I didn't get other approach.
2520+ + test the generation of the gotten inode.
2521+- every inode operation: they may get EBUSY due to UDBA. in this case,
2522+ convert it into ESTALE for NFSD.
2523+- readdir(): call lockdep_on/off() because filldir in NFSD calls
2524+ lookup_one_len(), vfs_getattr(), encode_fh() and others.
2525diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linux/Documentation/filesystems/aufs/design/08shwh.txt
2526--- /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 2527+++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2018-04-15 08:49:13.394483860 +0200
523b37e3 2528@@ -0,0 +1,52 @@
53392da6 2529+
ae9dfd79 2530+# Copyright (C) 2005-2018 Junjiro R. Okajima
53392da6
AM
2531+#
2532+# This program is free software; you can redistribute it and/or modify
2533+# it under the terms of the GNU General Public License as published by
2534+# the Free Software Foundation; either version 2 of the License, or
2535+# (at your option) any later version.
2536+#
2537+# This program is distributed in the hope that it will be useful,
2538+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2539+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2540+# GNU General Public License for more details.
2541+#
2542+# You should have received a copy of the GNU General Public License
523b37e3 2543+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2544+
2545+Show Whiteout Mode (shwh)
2546+----------------------------------------------------------------------
2547+Generally aufs hides the name of whiteouts. But in some cases, to show
2548+them is very useful for users. For instance, creating a new middle layer
2549+(branch) by merging existing layers.
2550+
2551+(borrowing aufs1 HOW-TO from a user, Michael Towers)
2552+When you have three branches,
2553+- Bottom: 'system', squashfs (underlying base system), read-only
2554+- Middle: 'mods', squashfs, read-only
2555+- Top: 'overlay', ram (tmpfs), read-write
2556+
2557+The top layer is loaded at boot time and saved at shutdown, to preserve
2558+the changes made to the system during the session.
2559+When larger changes have been made, or smaller changes have accumulated,
2560+the size of the saved top layer data grows. At this point, it would be
2561+nice to be able to merge the two overlay branches ('mods' and 'overlay')
2562+and rewrite the 'mods' squashfs, clearing the top layer and thus
2563+restoring save and load speed.
2564+
2565+This merging is simplified by the use of another aufs mount, of just the
2566+two overlay branches using the 'shwh' option.
2567+# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \
2568+ aufs /livesys/merge_union
2569+
2570+A merged view of these two branches is then available at
2571+/livesys/merge_union, and the new feature is that the whiteouts are
2572+visible!
2573+Note that in 'shwh' mode the aufs mount must be 'ro', which will disable
2574+writing to all branches. Also the default mode for all branches is 'ro'.
2575+It is now possible to save the combined contents of the two overlay
2576+branches to a new squashfs, e.g.:
2577+# mksquashfs /livesys/merge_union /path/to/newmods.squash
2578+
2579+This new squashfs archive can be stored on the boot device and the
2580+initramfs will use it to replace the old one at the next boot.
2581diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt linux/Documentation/filesystems/aufs/design/10dynop.txt
2582--- /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 2583+++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2018-04-15 08:49:13.394483860 +0200
7e9cd9fe 2584@@ -0,0 +1,47 @@
53392da6 2585+
ae9dfd79 2586+# Copyright (C) 2010-2018 Junjiro R. Okajima
53392da6
AM
2587+#
2588+# This program is free software; you can redistribute it and/or modify
2589+# it under the terms of the GNU General Public License as published by
2590+# the Free Software Foundation; either version 2 of the License, or
2591+# (at your option) any later version.
2592+#
2593+# This program is distributed in the hope that it will be useful,
2594+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2595+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2596+# GNU General Public License for more details.
2597+#
2598+# You should have received a copy of the GNU General Public License
523b37e3 2599+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2600+
2601+Dynamically customizable FS operations
2602+----------------------------------------------------------------------
2603+Generally FS operations (struct inode_operations, struct
2604+address_space_operations, struct file_operations, etc.) are defined as
2605+"static const", but it never means that FS have only one set of
2606+operation. Some FS have multiple sets of them. For instance, ext2 has
2607+three sets, one for XIP, for NOBH, and for normal.
2608+Since aufs overrides and redirects these operations, sometimes aufs has
7e9cd9fe 2609+to change its behaviour according to the branch FS type. More importantly
53392da6
AM
2610+VFS acts differently if a function (member in the struct) is set or
2611+not. It means aufs should have several sets of operations and select one
2612+among them according to the branch FS definition.
2613+
7e9cd9fe 2614+In order to solve this problem and not to affect the behaviour of VFS,
53392da6 2615+aufs defines these operations dynamically. For instance, aufs defines
7e9cd9fe
AM
2616+dummy direct_IO function for struct address_space_operations, but it may
2617+not be set to the address_space_operations actually. When the branch FS
2618+doesn't have it, aufs doesn't set it to its address_space_operations
2619+while the function definition itself is still alive. So the behaviour
2620+itself will not change, and it will return an error when direct_IO is
2621+not set.
53392da6
AM
2622+
2623+The lifetime of these dynamically generated operation object is
2624+maintained by aufs branch object. When the branch is removed from aufs,
2625+the reference counter of the object is decremented. When it reaches
2626+zero, the dynamically generated operation object will be freed.
2627+
7e9cd9fe
AM
2628+This approach is designed to support AIO (io_submit), Direct I/O and
2629+XIP (DAX) mainly.
2630+Currently this approach is applied to address_space_operations for
2631+regular files only.
53392da6
AM
2632diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README
2633--- /usr/share/empty/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 2634+++ linux/Documentation/filesystems/aufs/README 2017-07-29 12:14:25.893041746 +0200
f2c43d5f 2635@@ -0,0 +1,393 @@
53392da6 2636+
5527c038 2637+Aufs4 -- advanced multi layered unification filesystem version 4.x
53392da6
AM
2638+http://aufs.sf.net
2639+Junjiro R. Okajima
2640+
2641+
2642+0. Introduction
2643+----------------------------------------
2644+In the early days, aufs was entirely re-designed and re-implemented
7e9cd9fe 2645+Unionfs Version 1.x series. Adding many original ideas, approaches,
53392da6
AM
2646+improvements and implementations, it becomes totally different from
2647+Unionfs while keeping the basic features.
2648+Recently, Unionfs Version 2.x series begin taking some of the same
2649+approaches to aufs1's.
2650+Unionfs is being developed by Professor Erez Zadok at Stony Brook
2651+University and his team.
2652+
5527c038 2653+Aufs4 supports linux-4.0 and later, and for linux-3.x series try aufs3.
53392da6
AM
2654+If you want older kernel version support, try aufs2-2.6.git or
2655+aufs2-standalone.git repository, aufs1 from CVS on SourceForge.
2656+
2657+Note: it becomes clear that "Aufs was rejected. Let's give it up."
38d290e6
JR
2658+ According to Christoph Hellwig, linux rejects all union-type
2659+ filesystems but UnionMount.
53392da6
AM
2660+<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
2661+
38d290e6
JR
2662+PS. Al Viro seems have a plan to merge aufs as well as overlayfs and
2663+ UnionMount, and he pointed out an issue around a directory mutex
2664+ lock and aufs addressed it. But it is still unsure whether aufs will
2665+ be merged (or any other union solution).
076b876e 2666+<http://marc.info/?l=linux-kernel&m=136312705029295&w=1>
38d290e6 2667+
53392da6
AM
2668+
2669+1. Features
2670+----------------------------------------
2671+- unite several directories into a single virtual filesystem. The member
2672+ directory is called as a branch.
2673+- you can specify the permission flags to the branch, which are 'readonly',
2674+ 'readwrite' and 'whiteout-able.'
2675+- by upper writable branch, internal copyup and whiteout, files/dirs on
2676+ readonly branch are modifiable logically.
2677+- dynamic branch manipulation, add, del.
2678+- etc...
2679+
7e9cd9fe
AM
2680+Also there are many enhancements in aufs, such as:
2681+- test only the highest one for the directory permission (dirperm1)
2682+- copyup on open (coo=)
2683+- 'move' policy for copy-up between two writable branches, after
2684+ checking free space.
2685+- xattr, acl
53392da6
AM
2686+- readdir(3) in userspace.
2687+- keep inode number by external inode number table
2688+- keep the timestamps of file/dir in internal copyup operation
2689+- seekable directory, supporting NFS readdir.
2690+- whiteout is hardlinked in order to reduce the consumption of inodes
2691+ on branch
2692+- do not copyup, nor create a whiteout when it is unnecessary
2693+- revert a single systemcall when an error occurs in aufs
2694+- remount interface instead of ioctl
2695+- maintain /etc/mtab by an external command, /sbin/mount.aufs.
2696+- loopback mounted filesystem as a branch
2697+- kernel thread for removing the dir who has a plenty of whiteouts
2698+- support copyup sparse file (a file which has a 'hole' in it)
2699+- default permission flags for branches
2700+- selectable permission flags for ro branch, whether whiteout can
2701+ exist or not
2702+- export via NFS.
2703+- support <sysfs>/fs/aufs and <debugfs>/aufs.
2704+- support multiple writable branches, some policies to select one
2705+ among multiple writable branches.
2706+- a new semantics for link(2) and rename(2) to support multiple
2707+ writable branches.
2708+- no glibc changes are required.
2709+- pseudo hardlink (hardlink over branches)
2710+- allow a direct access manually to a file on branch, e.g. bypassing aufs.
2711+ including NFS or remote filesystem branch.
2712+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
2713+- and more...
2714+
5527c038 2715+Currently these features are dropped temporary from aufs4.
53392da6 2716+See design/08plan.txt in detail.
53392da6
AM
2717+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
2718+ (robr)
2719+- statistics of aufs thread (/sys/fs/aufs/stat)
53392da6
AM
2720+
2721+Features or just an idea in the future (see also design/*.txt),
2722+- reorder the branch index without del/re-add.
2723+- permanent xino files for NFSD
2724+- an option for refreshing the opened files after add/del branches
53392da6
AM
2725+- light version, without branch manipulation. (unnecessary?)
2726+- copyup in userspace
2727+- inotify in userspace
2728+- readv/writev
53392da6
AM
2729+
2730+
2731+2. Download
2732+----------------------------------------
5527c038
JR
2733+There are three GIT trees for aufs4, aufs4-linux.git,
2734+aufs4-standalone.git, and aufs-util.git. Note that there is no "4" in
1e00d052 2735+"aufs-util.git."
5527c038
JR
2736+While the aufs-util is always necessary, you need either of aufs4-linux
2737+or aufs4-standalone.
1e00d052 2738+
5527c038 2739+The aufs4-linux tree includes the whole linux mainline GIT tree,
1e00d052
AM
2740+git://git.kernel.org/.../torvalds/linux.git.
2741+And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
5527c038 2742+build aufs4 as an external kernel module.
2000de60 2743+Several extra patches are not included in this tree. Only
be52b249 2744+aufs4-standalone tree contains them. They are described in the later
2000de60 2745+section "Configuration and Compilation."
1e00d052 2746+
5527c038 2747+On the other hand, the aufs4-standalone tree has only aufs source files
53392da6 2748+and necessary patches, and you can select CONFIG_AUFS_FS=m.
2000de60 2749+But you need to apply all aufs patches manually.
53392da6 2750+
5527c038
JR
2751+You will find GIT branches whose name is in form of "aufs4.x" where "x"
2752+represents the linux kernel version, "linux-4.x". For instance,
2753+"aufs4.0" is for linux-4.0. For latest "linux-4.x-rcN", use
2754+"aufs4.x-rcN" branch.
1e00d052 2755+
5527c038 2756+o aufs4-linux tree
1e00d052 2757+$ git clone --reference /your/linux/git/tree \
5527c038 2758+ git://github.com/sfjro/aufs4-linux.git aufs4-linux.git
1e00d052 2759+- if you don't have linux GIT tree, then remove "--reference ..."
5527c038
JR
2760+$ cd aufs4-linux.git
2761+$ git checkout origin/aufs4.0
53392da6 2762+
2000de60
JR
2763+Or You may want to directly git-pull aufs into your linux GIT tree, and
2764+leave the patch-work to GIT.
2765+$ cd /your/linux/git/tree
5527c038
JR
2766+$ git remote add aufs4 git://github.com/sfjro/aufs4-linux.git
2767+$ git fetch aufs4
2768+$ git checkout -b my4.0 v4.0
2769+$ (add your local change...)
2770+$ git pull aufs4 aufs4.0
2771+- now you have v4.0 + your_changes + aufs4.0 in you my4.0 branch.
2000de60 2772+- you may need to solve some conflicts between your_changes and
5527c038
JR
2773+ aufs4.0. in this case, git-rerere is recommended so that you can
2774+ solve the similar conflicts automatically when you upgrade to 4.1 or
2000de60
JR
2775+ later in the future.
2776+
5527c038
JR
2777+o aufs4-standalone tree
2778+$ git clone git://github.com/sfjro/aufs4-standalone.git aufs4-standalone.git
2779+$ cd aufs4-standalone.git
2780+$ git checkout origin/aufs4.0
53392da6
AM
2781+
2782+o aufs-util tree
5527c038
JR
2783+$ git clone git://git.code.sf.net/p/aufs/aufs-util aufs-util.git
2784+- note that the public aufs-util.git is on SourceForge instead of
2785+ GitHUB.
53392da6 2786+$ cd aufs-util.git
5527c038 2787+$ git checkout origin/aufs4.0
53392da6 2788+
5527c038
JR
2789+Note: The 4.x-rcN branch is to be used with `rc' kernel versions ONLY.
2790+The minor version number, 'x' in '4.x', of aufs may not always
9dbd164d
AM
2791+follow the minor version number of the kernel.
2792+Because changes in the kernel that cause the use of a new
2793+minor version number do not always require changes to aufs-util.
2794+
2795+Since aufs-util has its own minor version number, you may not be
2796+able to find a GIT branch in aufs-util for your kernel's
2797+exact minor version number.
2798+In this case, you should git-checkout the branch for the
53392da6 2799+nearest lower number.
9dbd164d
AM
2800+
2801+For (an unreleased) example:
5527c038
JR
2802+If you are using "linux-4.10" and the "aufs4.10" branch
2803+does not exist in aufs-util repository, then "aufs4.9", "aufs4.8"
9dbd164d
AM
2804+or something numerically smaller is the branch for your kernel.
2805+
53392da6
AM
2806+Also you can view all branches by
2807+ $ git branch -a
2808+
2809+
2810+3. Configuration and Compilation
2811+----------------------------------------
2812+Make sure you have git-checkout'ed the correct branch.
2813+
5527c038 2814+For aufs4-linux tree,
c06a8ce3 2815+- enable CONFIG_AUFS_FS.
1e00d052
AM
2816+- set other aufs configurations if necessary.
2817+
5527c038 2818+For aufs4-standalone tree,
53392da6
AM
2819+There are several ways to build.
2820+
2821+1.
5527c038
JR
2822+- apply ./aufs4-kbuild.patch to your kernel source files.
2823+- apply ./aufs4-base.patch too.
2824+- apply ./aufs4-mmap.patch too.
2825+- apply ./aufs4-standalone.patch too, if you have a plan to set
2826+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs4-standalone.patch.
537831f9
AM
2827+- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
2828+ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
c06a8ce3 2829+- enable CONFIG_AUFS_FS, you can select either
53392da6
AM
2830+ =m or =y.
2831+- and build your kernel as usual.
2832+- install the built kernel.
c06a8ce3
AM
2833+ Note: Since linux-3.9, every filesystem module requires an alias
2834+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
2835+ modules.aliases file if you set CONFIG_AUFS_FS=m.
7eafdf33
AM
2836+- install the header files too by "make headers_install" to the
2837+ directory where you specify. By default, it is $PWD/usr.
b4510431 2838+ "make help" shows a brief note for headers_install.
53392da6
AM
2839+- and reboot your system.
2840+
2841+2.
2842+- module only (CONFIG_AUFS_FS=m).
5527c038
JR
2843+- apply ./aufs4-base.patch to your kernel source files.
2844+- apply ./aufs4-mmap.patch too.
2845+- apply ./aufs4-standalone.patch too.
53392da6
AM
2846+- build your kernel, don't forget "make headers_install", and reboot.
2847+- edit ./config.mk and set other aufs configurations if necessary.
b4510431 2848+ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
53392da6
AM
2849+ every aufs configurations.
2850+- build the module by simple "make".
c06a8ce3
AM
2851+ Note: Since linux-3.9, every filesystem module requires an alias
2852+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
2853+ modules.aliases file.
53392da6
AM
2854+- you can specify ${KDIR} make variable which points to your kernel
2855+ source tree.
2856+- install the files
2857+ + run "make install" to install the aufs module, or copy the built
b4510431
AM
2858+ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply).
2859+ + run "make install_headers" (instead of headers_install) to install
2860+ the modified aufs header file (you can specify DESTDIR which is
2861+ available in aufs standalone version's Makefile only), or copy
2862+ $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever
2863+ you like manually. By default, the target directory is $PWD/usr.
5527c038 2864+- no need to apply aufs4-kbuild.patch, nor copying source files to your
53392da6
AM
2865+ kernel source tree.
2866+
b4510431 2867+Note: The header file aufs_type.h is necessary to build aufs-util
53392da6
AM
2868+ as well as "make headers_install" in the kernel source tree.
2869+ headers_install is subject to be forgotten, but it is essentially
2870+ necessary, not only for building aufs-util.
2871+ You may not meet problems without headers_install in some older
2872+ version though.
2873+
2874+And then,
2875+- read README in aufs-util, build and install it
9dbd164d
AM
2876+- note that your distribution may contain an obsoleted version of
2877+ aufs_type.h in /usr/include/linux or something. When you build aufs
2878+ utilities, make sure that your compiler refers the correct aufs header
2879+ file which is built by "make headers_install."
53392da6
AM
2880+- if you want to use readdir(3) in userspace or pathconf(3) wrapper,
2881+ then run "make install_ulib" too. And refer to the aufs manual in
2882+ detail.
2883+
5527c038 2884+There several other patches in aufs4-standalone.git. They are all
38d290e6 2885+optional. When you meet some problems, they will help you.
5527c038 2886+- aufs4-loopback.patch
38d290e6
JR
2887+ Supports a nested loopback mount in a branch-fs. This patch is
2888+ unnecessary until aufs produces a message like "you may want to try
2889+ another patch for loopback file".
2890+- vfs-ino.patch
2891+ Modifies a system global kernel internal function get_next_ino() in
2892+ order to stop assigning 0 for an inode-number. Not directly related to
2893+ aufs, but recommended generally.
2894+- tmpfs-idr.patch
2895+ Keeps the tmpfs inode number as the lowest value. Effective to reduce
2896+ the size of aufs XINO files for tmpfs branch. Also it prevents the
2897+ duplication of inode number, which is important for backup tools and
2898+ other utilities. When you find aufs XINO files for tmpfs branch
2899+ growing too much, try this patch.
be52b249
AM
2900+- lockdep-debug.patch
2901+ Because aufs is not only an ordinary filesystem (callee of VFS), but
2902+ also a caller of VFS functions for branch filesystems, subclassing of
2903+ the internal locks for LOCKDEP is necessary. LOCKDEP is a debugging
2904+ feature of linux kernel. If you enable CONFIG_LOCKDEP, then you will
2905+ need to apply this debug patch to expand several constant values.
2906+ If don't know what LOCKDEP, then you don't have apply this patch.
38d290e6 2907+
53392da6
AM
2908+
2909+4. Usage
2910+----------------------------------------
2911+At first, make sure aufs-util are installed, and please read the aufs
2912+manual, aufs.5 in aufs-util.git tree.
2913+$ man -l aufs.5
2914+
2915+And then,
2916+$ mkdir /tmp/rw /tmp/aufs
2917+# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs
2918+
2919+Here is another example. The result is equivalent.
2920+# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
2921+ Or
2922+# mount -t aufs -o br:/tmp/rw none /tmp/aufs
2923+# mount -o remount,append:${HOME} /tmp/aufs
2924+
2925+Then, you can see whole tree of your home dir through /tmp/aufs. If
2926+you modify a file under /tmp/aufs, the one on your home directory is
2927+not affected, instead the same named file will be newly created under
2928+/tmp/rw. And all of your modification to a file will be applied to
2929+the one under /tmp/rw. This is called the file based Copy on Write
2930+(COW) method.
2931+Aufs mount options are described in aufs.5.
2932+If you run chroot or something and make your aufs as a root directory,
2933+then you need to customize the shutdown script. See the aufs manual in
2934+detail.
2935+
2936+Additionally, there are some sample usages of aufs which are a
2937+diskless system with network booting, and LiveCD over NFS.
2938+See sample dir in CVS tree on SourceForge.
2939+
2940+
2941+5. Contact
2942+----------------------------------------
2943+When you have any problems or strange behaviour in aufs, please let me
2944+know with:
2945+- /proc/mounts (instead of the output of mount(8))
2946+- /sys/module/aufs/*
2947+- /sys/fs/aufs/* (if you have them)
2948+- /debug/aufs/* (if you have them)
2949+- linux kernel version
2950+ if your kernel is not plain, for example modified by distributor,
2951+ the url where i can download its source is necessary too.
2952+- aufs version which was printed at loading the module or booting the
2953+ system, instead of the date you downloaded.
2954+- configuration (define/undefine CONFIG_AUFS_xxx)
2955+- kernel configuration or /proc/config.gz (if you have it)
2956+- behaviour which you think to be incorrect
2957+- actual operation, reproducible one is better
2958+- mailto: aufs-users at lists.sourceforge.net
2959+
2960+Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches,
2961+and Feature Requests) on SourceForge. Please join and write to
2962+aufs-users ML.
2963+
2964+
2965+6. Acknowledgements
2966+----------------------------------------
2967+Thanks to everyone who have tried and are using aufs, whoever
2968+have reported a bug or any feedback.
2969+
2970+Especially donators:
2971+Tomas Matejicek(slax.org) made a donation (much more than once).
2972+ Since Apr 2010, Tomas M (the author of Slax and Linux Live
2973+ scripts) is making "doubling" donations.
2974+ Unfortunately I cannot list all of the donators, but I really
b4510431 2975+ appreciate.
53392da6
AM
2976+ It ends Aug 2010, but the ordinary donation URL is still available.
2977+ <http://sourceforge.net/donate/index.php?group_id=167503>
2978+Dai Itasaka made a donation (2007/8).
2979+Chuck Smith made a donation (2008/4, 10 and 12).
2980+Henk Schoneveld made a donation (2008/9).
2981+Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10).
2982+Francois Dupoux made a donation (2008/11).
2983+Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public
2984+ aufs2 GIT tree (2009/2).
2985+William Grant made a donation (2009/3).
2986+Patrick Lane made a donation (2009/4).
2987+The Mail Archive (mail-archive.com) made donations (2009/5).
2988+Nippy Networks (Ed Wildgoose) made a donation (2009/7).
2989+New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11).
2990+Pavel Pronskiy made a donation (2011/2).
2991+Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy
2992+ Networks (Ed Wildgoose) made a donation for hardware (2011/3).
537831f9
AM
2993+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
2994+11).
1e00d052 2995+Sam Liddicott made a donation (2011/9).
86dc4139
AM
2996+Era Scarecrow made a donation (2013/4).
2997+Bor Ratajc made a donation (2013/4).
2998+Alessandro Gorreta made a donation (2013/4).
2999+POIRETTE Marc made a donation (2013/4).
3000+Alessandro Gorreta made a donation (2013/4).
3001+lauri kasvandik made a donation (2013/5).
392086de 3002+"pemasu from Finland" made a donation (2013/7).
523b37e3
AM
3003+The Parted Magic Project made a donation (2013/9 and 11).
3004+Pavel Barta made a donation (2013/10).
38d290e6 3005+Nikolay Pertsev made a donation (2014/5).
c2c0f25c 3006+James B made a donation (2014/7 and 2015/7).
076b876e 3007+Stefano Di Biase made a donation (2014/8).
2000de60 3008+Daniel Epellei made a donation (2015/1).
8cdd5066 3009+OmegaPhil made a donation (2016/1).
5afbbe0d 3010+Tomasz Szewczyk made a donation (2016/4).
f2c43d5f 3011+James Burry made a donation (2016/12).
53392da6
AM
3012+
3013+Thank you very much.
3014+Donations are always, including future donations, very important and
3015+helpful for me to keep on developing aufs.
3016+
3017+
3018+7.
3019+----------------------------------------
3020+If you are an experienced user, no explanation is needed. Aufs is
3021+just a linux filesystem.
3022+
3023+
3024+Enjoy!
3025+
3026+# Local variables: ;
3027+# mode: text;
3028+# End: ;
7f207e10
AM
3029diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
3030--- /usr/share/empty/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
3031+++ linux/fs/aufs/aufs.h 2018-04-15 08:49:13.394483860 +0200
3032@@ -0,0 +1,60 @@
7f207e10 3033+/*
ae9dfd79 3034+ * Copyright (C) 2005-2018 Junjiro R. Okajima
7f207e10
AM
3035+ *
3036+ * This program, aufs is free software; you can redistribute it and/or modify
3037+ * it under the terms of the GNU General Public License as published by
3038+ * the Free Software Foundation; either version 2 of the License, or
3039+ * (at your option) any later version.
3040+ *
3041+ * This program is distributed in the hope that it will be useful,
3042+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3043+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3044+ * GNU General Public License for more details.
3045+ *
3046+ * You should have received a copy of the GNU General Public License
523b37e3 3047+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
3048+ */
3049+
3050+/*
3051+ * all header files
3052+ */
3053+
3054+#ifndef __AUFS_H__
3055+#define __AUFS_H__
3056+
3057+#ifdef __KERNEL__
3058+
3059+#define AuStub(type, name, body, ...) \
3060+ static inline type name(__VA_ARGS__) { body; }
3061+
3062+#define AuStubVoid(name, ...) \
3063+ AuStub(void, name, , __VA_ARGS__)
3064+#define AuStubInt0(name, ...) \
3065+ AuStub(int, name, return 0, __VA_ARGS__)
3066+
3067+#include "debug.h"
3068+
3069+#include "branch.h"
3070+#include "cpup.h"
3071+#include "dcsub.h"
3072+#include "dbgaufs.h"
3073+#include "dentry.h"
3074+#include "dir.h"
ae9dfd79 3075+#include "dirren.h"
7f207e10
AM
3076+#include "dynop.h"
3077+#include "file.h"
3078+#include "fstype.h"
ae9dfd79 3079+#include "hbl.h"
7f207e10
AM
3080+#include "inode.h"
3081+#include "loop.h"
3082+#include "module.h"
7f207e10
AM
3083+#include "opts.h"
3084+#include "rwsem.h"
7f207e10
AM
3085+#include "super.h"
3086+#include "sysaufs.h"
3087+#include "vfsub.h"
3088+#include "whout.h"
3089+#include "wkq.h"
3090+
3091+#endif /* __KERNEL__ */
3092+#endif /* __AUFS_H__ */
3093diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
3094--- /usr/share/empty/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
3095+++ linux/fs/aufs/branch.c 2018-04-15 08:49:13.394483860 +0200
3096@@ -0,0 +1,1432 @@
7f207e10 3097+/*
ae9dfd79 3098+ * Copyright (C) 2005-2018 Junjiro R. Okajima
7f207e10
AM
3099+ *
3100+ * This program, aufs is free software; you can redistribute it and/or modify
3101+ * it under the terms of the GNU General Public License as published by
3102+ * the Free Software Foundation; either version 2 of the License, or
3103+ * (at your option) any later version.
3104+ *
3105+ * This program is distributed in the hope that it will be useful,
3106+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3107+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3108+ * GNU General Public License for more details.
3109+ *
3110+ * You should have received a copy of the GNU General Public License
523b37e3 3111+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
3112+ */
3113+
3114+/*
3115+ * branch management
3116+ */
3117+
027c5e7a 3118+#include <linux/compat.h>
7f207e10
AM
3119+#include <linux/statfs.h>
3120+#include "aufs.h"
3121+
3122+/*
3123+ * free a single branch
1facf9fc 3124+ */
3125+static void au_br_do_free(struct au_branch *br)
3126+{
3127+ int i;
3128+ struct au_wbr *wbr;
4a4d8108 3129+ struct au_dykey **key;
1facf9fc 3130+
027c5e7a 3131+ au_hnotify_fin_br(br);
ae9dfd79
AM
3132+ /* always, regardless the mount option */
3133+ au_dr_hino_free(&br->br_dirren);
027c5e7a 3134+
1facf9fc 3135+ if (br->br_xino.xi_file)
3136+ fput(br->br_xino.xi_file);
ae9dfd79
AM
3137+ for (i = br->br_xino.xi_nondir.total - 1; i >= 0; i--)
3138+ AuDebugOn(br->br_xino.xi_nondir.array[i]);
3139+ kfree(br->br_xino.xi_nondir.array);
1facf9fc 3140+
5afbbe0d
AM
3141+ AuDebugOn(au_br_count(br));
3142+ au_br_count_fin(br);
1facf9fc 3143+
3144+ wbr = br->br_wbr;
3145+ if (wbr) {
3146+ for (i = 0; i < AuBrWh_Last; i++)
3147+ dput(wbr->wbr_wh[i]);
3148+ AuDebugOn(atomic_read(&wbr->wbr_wh_running));
dece6358 3149+ AuRwDestroy(&wbr->wbr_wh_rwsem);
1facf9fc 3150+ }
3151+
076b876e
AM
3152+ if (br->br_fhsm) {
3153+ au_br_fhsm_fin(br->br_fhsm);
ae9dfd79 3154+ kfree(br->br_fhsm);
076b876e
AM
3155+ }
3156+
4a4d8108
AM
3157+ key = br->br_dykey;
3158+ for (i = 0; i < AuBrDynOp; i++, key++)
3159+ if (*key)
3160+ au_dy_put(*key);
3161+ else
3162+ break;
3163+
537831f9
AM
3164+ /* recursive lock, s_umount of branch's */
3165+ lockdep_off();
86dc4139 3166+ path_put(&br->br_path);
537831f9 3167+ lockdep_on();
ae9dfd79
AM
3168+ kfree(wbr);
3169+ kfree(br);
1facf9fc 3170+}
3171+
3172+/*
3173+ * frees all branches
3174+ */
3175+void au_br_free(struct au_sbinfo *sbinfo)
3176+{
3177+ aufs_bindex_t bmax;
3178+ struct au_branch **br;
3179+
dece6358
AM
3180+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3181+
5afbbe0d 3182+ bmax = sbinfo->si_bbot + 1;
1facf9fc 3183+ br = sbinfo->si_branch;
3184+ while (bmax--)
3185+ au_br_do_free(*br++);
3186+}
3187+
3188+/*
3189+ * find the index of a branch which is specified by @br_id.
3190+ */
3191+int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
3192+{
5afbbe0d 3193+ aufs_bindex_t bindex, bbot;
1facf9fc 3194+
5afbbe0d
AM
3195+ bbot = au_sbbot(sb);
3196+ for (bindex = 0; bindex <= bbot; bindex++)
1facf9fc 3197+ if (au_sbr_id(sb, bindex) == br_id)
3198+ return bindex;
3199+ return -1;
3200+}
3201+
3202+/* ---------------------------------------------------------------------- */
3203+
3204+/*
3205+ * add a branch
3206+ */
3207+
b752ccd1
AM
3208+static int test_overlap(struct super_block *sb, struct dentry *h_adding,
3209+ struct dentry *h_root)
1facf9fc 3210+{
b752ccd1
AM
3211+ if (unlikely(h_adding == h_root
3212+ || au_test_loopback_overlap(sb, h_adding)))
1facf9fc 3213+ return 1;
b752ccd1
AM
3214+ if (h_adding->d_sb != h_root->d_sb)
3215+ return 0;
3216+ return au_test_subdir(h_adding, h_root)
3217+ || au_test_subdir(h_root, h_adding);
1facf9fc 3218+}
3219+
3220+/*
3221+ * returns a newly allocated branch. @new_nbranch is a number of branches
3222+ * after adding a branch.
3223+ */
3224+static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
3225+ int perm)
3226+{
3227+ struct au_branch *add_branch;
3228+ struct dentry *root;
5527c038 3229+ struct inode *inode;
4a4d8108 3230+ int err;
1facf9fc 3231+
4a4d8108 3232+ err = -ENOMEM;
be52b249 3233+ add_branch = kzalloc(sizeof(*add_branch), GFP_NOFS);
1facf9fc 3234+ if (unlikely(!add_branch))
3235+ goto out;
ae9dfd79
AM
3236+ add_branch->br_xino.xi_nondir.total = 8; /* initial size */
3237+ add_branch->br_xino.xi_nondir.array
3238+ = kcalloc(add_branch->br_xino.xi_nondir.total, sizeof(ino_t),
3239+ GFP_NOFS);
3240+ if (unlikely(!add_branch->br_xino.xi_nondir.array))
3241+ goto out_br;
1facf9fc 3242+
027c5e7a
AM
3243+ err = au_hnotify_init_br(add_branch, perm);
3244+ if (unlikely(err))
ae9dfd79 3245+ goto out_xinondir;
027c5e7a 3246+
1facf9fc 3247+ if (au_br_writable(perm)) {
3248+ /* may be freed separately at changing the branch permission */
be52b249 3249+ add_branch->br_wbr = kzalloc(sizeof(*add_branch->br_wbr),
1facf9fc 3250+ GFP_NOFS);
3251+ if (unlikely(!add_branch->br_wbr))
027c5e7a 3252+ goto out_hnotify;
1facf9fc 3253+ }
3254+
076b876e
AM
3255+ if (au_br_fhsm(perm)) {
3256+ err = au_fhsm_br_alloc(add_branch);
3257+ if (unlikely(err))
3258+ goto out_wbr;
3259+ }
3260+
ae9dfd79 3261+ root = sb->s_root;
e2f27e51 3262+ err = au_sbr_realloc(au_sbi(sb), new_nbranch, /*may_shrink*/0);
4a4d8108 3263+ if (!err)
e2f27e51 3264+ err = au_di_realloc(au_di(root), new_nbranch, /*may_shrink*/0);
5527c038
JR
3265+ if (!err) {
3266+ inode = d_inode(root);
ae9dfd79
AM
3267+ err = au_hinode_realloc(au_ii(inode), new_nbranch,
3268+ /*may_shrink*/0);
5527c038 3269+ }
4a4d8108
AM
3270+ if (!err)
3271+ return add_branch; /* success */
1facf9fc 3272+
076b876e 3273+out_wbr:
ae9dfd79 3274+ kfree(add_branch->br_wbr);
027c5e7a
AM
3275+out_hnotify:
3276+ au_hnotify_fin_br(add_branch);
ae9dfd79
AM
3277+out_xinondir:
3278+ kfree(add_branch->br_xino.xi_nondir.array);
4f0767ce 3279+out_br:
ae9dfd79 3280+ kfree(add_branch);
4f0767ce 3281+out:
4a4d8108 3282+ return ERR_PTR(err);
1facf9fc 3283+}
3284+
3285+/*
3286+ * test if the branch permission is legal or not.
3287+ */
3288+static int test_br(struct inode *inode, int brperm, char *path)
3289+{
3290+ int err;
3291+
4a4d8108
AM
3292+ err = (au_br_writable(brperm) && IS_RDONLY(inode));
3293+ if (!err)
3294+ goto out;
1facf9fc 3295+
4a4d8108
AM
3296+ err = -EINVAL;
3297+ pr_err("write permission for readonly mount or inode, %s\n", path);
3298+
4f0767ce 3299+out:
1facf9fc 3300+ return err;
3301+}
3302+
3303+/*
3304+ * returns:
3305+ * 0: success, the caller will add it
3306+ * plus: success, it is already unified, the caller should ignore it
3307+ * minus: error
3308+ */
3309+static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
3310+{
3311+ int err;
5afbbe0d 3312+ aufs_bindex_t bbot, bindex;
5527c038 3313+ struct dentry *root, *h_dentry;
1facf9fc 3314+ struct inode *inode, *h_inode;
3315+
3316+ root = sb->s_root;
5afbbe0d
AM
3317+ bbot = au_sbbot(sb);
3318+ if (unlikely(bbot >= 0
1facf9fc 3319+ && au_find_dbindex(root, add->path.dentry) >= 0)) {
3320+ err = 1;
3321+ if (!remount) {
3322+ err = -EINVAL;
4a4d8108 3323+ pr_err("%s duplicated\n", add->pathname);
1facf9fc 3324+ }
3325+ goto out;
3326+ }
3327+
3328+ err = -ENOSPC; /* -E2BIG; */
3329+ if (unlikely(AUFS_BRANCH_MAX <= add->bindex
5afbbe0d 3330+ || AUFS_BRANCH_MAX - 1 <= bbot)) {
4a4d8108 3331+ pr_err("number of branches exceeded %s\n", add->pathname);
1facf9fc 3332+ goto out;
3333+ }
3334+
3335+ err = -EDOM;
5afbbe0d 3336+ if (unlikely(add->bindex < 0 || bbot + 1 < add->bindex)) {
4a4d8108 3337+ pr_err("bad index %d\n", add->bindex);
1facf9fc 3338+ goto out;
3339+ }
3340+
5527c038 3341+ inode = d_inode(add->path.dentry);
1facf9fc 3342+ err = -ENOENT;
3343+ if (unlikely(!inode->i_nlink)) {
4a4d8108 3344+ pr_err("no existence %s\n", add->pathname);
1facf9fc 3345+ goto out;
3346+ }
3347+
3348+ err = -EINVAL;
3349+ if (unlikely(inode->i_sb == sb)) {
4a4d8108 3350+ pr_err("%s must be outside\n", add->pathname);
1facf9fc 3351+ goto out;
3352+ }
3353+
3354+ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
4a4d8108
AM
3355+ pr_err("unsupported filesystem, %s (%s)\n",
3356+ add->pathname, au_sbtype(inode->i_sb));
1facf9fc 3357+ goto out;
3358+ }
3359+
c1595e42
JR
3360+ if (unlikely(inode->i_sb->s_stack_depth)) {
3361+ pr_err("already stacked, %s (%s)\n",
3362+ add->pathname, au_sbtype(inode->i_sb));
3363+ goto out;
3364+ }
3365+
5527c038 3366+ err = test_br(d_inode(add->path.dentry), add->perm, add->pathname);
1facf9fc 3367+ if (unlikely(err))
3368+ goto out;
3369+
5afbbe0d 3370+ if (bbot < 0)
1facf9fc 3371+ return 0; /* success */
3372+
3373+ err = -EINVAL;
5afbbe0d 3374+ for (bindex = 0; bindex <= bbot; bindex++)
1facf9fc 3375+ if (unlikely(test_overlap(sb, add->path.dentry,
3376+ au_h_dptr(root, bindex)))) {
4a4d8108 3377+ pr_err("%s is overlapped\n", add->pathname);
1facf9fc 3378+ goto out;
3379+ }
3380+
3381+ err = 0;
3382+ if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
5527c038
JR
3383+ h_dentry = au_h_dptr(root, 0);
3384+ h_inode = d_inode(h_dentry);
1facf9fc 3385+ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
0c3ec466
AM
3386+ || !uid_eq(h_inode->i_uid, inode->i_uid)
3387+ || !gid_eq(h_inode->i_gid, inode->i_gid))
3388+ pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
3389+ add->pathname,
3390+ i_uid_read(inode), i_gid_read(inode),
3391+ (inode->i_mode & S_IALLUGO),
3392+ i_uid_read(h_inode), i_gid_read(h_inode),
3393+ (h_inode->i_mode & S_IALLUGO));
1facf9fc 3394+ }
3395+
4f0767ce 3396+out:
1facf9fc 3397+ return err;
3398+}
3399+
3400+/*
3401+ * initialize or clean the whiteouts for an adding branch
3402+ */
3403+static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
86dc4139 3404+ int new_perm)
1facf9fc 3405+{
3406+ int err, old_perm;
3407+ aufs_bindex_t bindex;
febd17d6 3408+ struct inode *h_inode;
1facf9fc 3409+ struct au_wbr *wbr;
3410+ struct au_hinode *hdir;
5527c038 3411+ struct dentry *h_dentry;
1facf9fc 3412+
86dc4139
AM
3413+ err = vfsub_mnt_want_write(au_br_mnt(br));
3414+ if (unlikely(err))
3415+ goto out;
3416+
1facf9fc 3417+ wbr = br->br_wbr;
3418+ old_perm = br->br_perm;
3419+ br->br_perm = new_perm;
3420+ hdir = NULL;
febd17d6 3421+ h_inode = NULL;
1facf9fc 3422+ bindex = au_br_index(sb, br->br_id);
3423+ if (0 <= bindex) {
5527c038 3424+ hdir = au_hi(d_inode(sb->s_root), bindex);
5afbbe0d 3425+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 3426+ } else {
5527c038 3427+ h_dentry = au_br_dentry(br);
febd17d6
JR
3428+ h_inode = d_inode(h_dentry);
3429+ inode_lock_nested(h_inode, AuLsc_I_PARENT);
1facf9fc 3430+ }
3431+ if (!wbr)
86dc4139 3432+ err = au_wh_init(br, sb);
1facf9fc 3433+ else {
3434+ wbr_wh_write_lock(wbr);
86dc4139 3435+ err = au_wh_init(br, sb);
1facf9fc 3436+ wbr_wh_write_unlock(wbr);
3437+ }
3438+ if (hdir)
5afbbe0d 3439+ au_hn_inode_unlock(hdir);
1facf9fc 3440+ else
febd17d6 3441+ inode_unlock(h_inode);
86dc4139 3442+ vfsub_mnt_drop_write(au_br_mnt(br));
1facf9fc 3443+ br->br_perm = old_perm;
3444+
3445+ if (!err && wbr && !au_br_writable(new_perm)) {
ae9dfd79 3446+ kfree(wbr);
1facf9fc 3447+ br->br_wbr = NULL;
3448+ }
3449+
86dc4139 3450+out:
1facf9fc 3451+ return err;
3452+}
3453+
3454+static int au_wbr_init(struct au_branch *br, struct super_block *sb,
86dc4139 3455+ int perm)
1facf9fc 3456+{
3457+ int err;
4a4d8108 3458+ struct kstatfs kst;
1facf9fc 3459+ struct au_wbr *wbr;
3460+
3461+ wbr = br->br_wbr;
dece6358 3462+ au_rw_init(&wbr->wbr_wh_rwsem);
1facf9fc 3463+ atomic_set(&wbr->wbr_wh_running, 0);
1facf9fc 3464+
4a4d8108
AM
3465+ /*
3466+ * a limit for rmdir/rename a dir
523b37e3 3467+ * cf. AUFS_MAX_NAMELEN in include/uapi/linux/aufs_type.h
4a4d8108 3468+ */
86dc4139 3469+ err = vfs_statfs(&br->br_path, &kst);
4a4d8108
AM
3470+ if (unlikely(err))
3471+ goto out;
3472+ err = -EINVAL;
3473+ if (kst.f_namelen >= NAME_MAX)
86dc4139 3474+ err = au_br_init_wh(sb, br, perm);
4a4d8108 3475+ else
523b37e3
AM
3476+ pr_err("%pd(%s), unsupported namelen %ld\n",
3477+ au_br_dentry(br),
86dc4139 3478+ au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen);
1facf9fc 3479+
4f0767ce 3480+out:
1facf9fc 3481+ return err;
3482+}
3483+
c1595e42 3484+/* initialize a new branch */
1facf9fc 3485+static int au_br_init(struct au_branch *br, struct super_block *sb,
3486+ struct au_opt_add *add)
3487+{
3488+ int err;
5527c038 3489+ struct inode *h_inode;
1facf9fc 3490+
3491+ err = 0;
ae9dfd79
AM
3492+ spin_lock_init(&br->br_xino.xi_nondir.spin);
3493+ init_waitqueue_head(&br->br_xino.xi_nondir.wqh);
1facf9fc 3494+ br->br_perm = add->perm;
86dc4139 3495+ br->br_path = add->path; /* set first, path_get() later */
4a4d8108 3496+ spin_lock_init(&br->br_dykey_lock);
5afbbe0d 3497+ au_br_count_init(br);
1facf9fc 3498+ atomic_set(&br->br_xino_running, 0);
3499+ br->br_id = au_new_br_id(sb);
7f207e10 3500+ AuDebugOn(br->br_id < 0);
1facf9fc 3501+
ae9dfd79
AM
3502+ /* always, regardless the given option */
3503+ err = au_dr_br_init(sb, br, &add->path);
3504+ if (unlikely(err))
3505+ goto out_err;
3506+
1facf9fc 3507+ if (au_br_writable(add->perm)) {
86dc4139 3508+ err = au_wbr_init(br, sb, add->perm);
1facf9fc 3509+ if (unlikely(err))
b752ccd1 3510+ goto out_err;
1facf9fc 3511+ }
3512+
3513+ if (au_opt_test(au_mntflags(sb), XINO)) {
5527c038
JR
3514+ h_inode = d_inode(add->path.dentry);
3515+ err = au_xino_br(sb, br, h_inode->i_ino,
1facf9fc 3516+ au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
3517+ if (unlikely(err)) {
3518+ AuDebugOn(br->br_xino.xi_file);
b752ccd1 3519+ goto out_err;
1facf9fc 3520+ }
3521+ }
3522+
3523+ sysaufs_br_init(br);
86dc4139 3524+ path_get(&br->br_path);
b752ccd1 3525+ goto out; /* success */
1facf9fc 3526+
4f0767ce 3527+out_err:
86dc4139 3528+ memset(&br->br_path, 0, sizeof(br->br_path));
4f0767ce 3529+out:
1facf9fc 3530+ return err;
3531+}
3532+
3533+static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
5afbbe0d 3534+ struct au_branch *br, aufs_bindex_t bbot,
1facf9fc 3535+ aufs_bindex_t amount)
3536+{
3537+ struct au_branch **brp;
3538+
dece6358
AM
3539+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3540+
1facf9fc 3541+ brp = sbinfo->si_branch + bindex;
3542+ memmove(brp + 1, brp, sizeof(*brp) * amount);
3543+ *brp = br;
5afbbe0d
AM
3544+ sbinfo->si_bbot++;
3545+ if (unlikely(bbot < 0))
3546+ sbinfo->si_bbot = 0;
1facf9fc 3547+}
3548+
3549+static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
5afbbe0d 3550+ aufs_bindex_t bbot, aufs_bindex_t amount)
1facf9fc 3551+{
3552+ struct au_hdentry *hdp;
3553+
1308ab2a 3554+ AuRwMustWriteLock(&dinfo->di_rwsem);
3555+
5afbbe0d 3556+ hdp = au_hdentry(dinfo, bindex);
1facf9fc 3557+ memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
3558+ au_h_dentry_init(hdp);
5afbbe0d
AM
3559+ dinfo->di_bbot++;
3560+ if (unlikely(bbot < 0))
3561+ dinfo->di_btop = 0;
1facf9fc 3562+}
3563+
3564+static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
5afbbe0d 3565+ aufs_bindex_t bbot, aufs_bindex_t amount)
1facf9fc 3566+{
3567+ struct au_hinode *hip;
3568+
1308ab2a 3569+ AuRwMustWriteLock(&iinfo->ii_rwsem);
3570+
5afbbe0d 3571+ hip = au_hinode(iinfo, bindex);
1facf9fc 3572+ memmove(hip + 1, hip, sizeof(*hip) * amount);
5afbbe0d
AM
3573+ au_hinode_init(hip);
3574+ iinfo->ii_bbot++;
3575+ if (unlikely(bbot < 0))
3576+ iinfo->ii_btop = 0;
1facf9fc 3577+}
3578+
86dc4139
AM
3579+static void au_br_do_add(struct super_block *sb, struct au_branch *br,
3580+ aufs_bindex_t bindex)
1facf9fc 3581+{
86dc4139 3582+ struct dentry *root, *h_dentry;
5527c038 3583+ struct inode *root_inode, *h_inode;
5afbbe0d 3584+ aufs_bindex_t bbot, amount;
1facf9fc 3585+
3586+ root = sb->s_root;
5527c038 3587+ root_inode = d_inode(root);
5afbbe0d
AM
3588+ bbot = au_sbbot(sb);
3589+ amount = bbot + 1 - bindex;
86dc4139 3590+ h_dentry = au_br_dentry(br);
53392da6 3591+ au_sbilist_lock();
5afbbe0d
AM
3592+ au_br_do_add_brp(au_sbi(sb), bindex, br, bbot, amount);
3593+ au_br_do_add_hdp(au_di(root), bindex, bbot, amount);
3594+ au_br_do_add_hip(au_ii(root_inode), bindex, bbot, amount);
1facf9fc 3595+ au_set_h_dptr(root, bindex, dget(h_dentry));
5527c038
JR
3596+ h_inode = d_inode(h_dentry);
3597+ au_set_h_iptr(root_inode, bindex, au_igrab(h_inode), /*flags*/0);
53392da6 3598+ au_sbilist_unlock();
1facf9fc 3599+}
3600+
3601+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
3602+{
3603+ int err;
5afbbe0d 3604+ aufs_bindex_t bbot, add_bindex;
1facf9fc 3605+ struct dentry *root, *h_dentry;
3606+ struct inode *root_inode;
3607+ struct au_branch *add_branch;
3608+
3609+ root = sb->s_root;
5527c038 3610+ root_inode = d_inode(root);
1facf9fc 3611+ IMustLock(root_inode);
5afbbe0d 3612+ IiMustWriteLock(root_inode);
1facf9fc 3613+ err = test_add(sb, add, remount);
3614+ if (unlikely(err < 0))
3615+ goto out;
3616+ if (err) {
3617+ err = 0;
3618+ goto out; /* success */
3619+ }
3620+
5afbbe0d
AM
3621+ bbot = au_sbbot(sb);
3622+ add_branch = au_br_alloc(sb, bbot + 2, add->perm);
1facf9fc 3623+ err = PTR_ERR(add_branch);
3624+ if (IS_ERR(add_branch))
3625+ goto out;
3626+
3627+ err = au_br_init(add_branch, sb, add);
3628+ if (unlikely(err)) {
3629+ au_br_do_free(add_branch);
3630+ goto out;
3631+ }
3632+
3633+ add_bindex = add->bindex;
1facf9fc 3634+ if (!remount)
86dc4139 3635+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 3636+ else {
3637+ sysaufs_brs_del(sb, add_bindex);
86dc4139 3638+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 3639+ sysaufs_brs_add(sb, add_bindex);
3640+ }
3641+
86dc4139 3642+ h_dentry = add->path.dentry;
1308ab2a 3643+ if (!add_bindex) {
1facf9fc 3644+ au_cpup_attr_all(root_inode, /*force*/1);
1308ab2a 3645+ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
3646+ } else
5527c038 3647+ au_add_nlink(root_inode, d_inode(h_dentry));
1facf9fc 3648+
3649+ /*
4a4d8108 3650+ * this test/set prevents aufs from handling unnecesary notify events
027c5e7a 3651+ * of xino files, in case of re-adding a writable branch which was
1facf9fc 3652+ * once detached from aufs.
3653+ */
3654+ if (au_xino_brid(sb) < 0
3655+ && au_br_writable(add_branch->br_perm)
3656+ && !au_test_fs_bad_xino(h_dentry->d_sb)
3657+ && add_branch->br_xino.xi_file
2000de60 3658+ && add_branch->br_xino.xi_file->f_path.dentry->d_parent == h_dentry)
1facf9fc 3659+ au_xino_brid_set(sb, add_branch->br_id);
3660+
4f0767ce 3661+out:
1facf9fc 3662+ return err;
3663+}
3664+
3665+/* ---------------------------------------------------------------------- */
3666+
79b8bda9 3667+static unsigned long long au_farray_cb(struct super_block *sb, void *a,
076b876e
AM
3668+ unsigned long long max __maybe_unused,
3669+ void *arg)
3670+{
3671+ unsigned long long n;
3672+ struct file **p, *f;
ae9dfd79
AM
3673+ struct hlist_bl_head *files;
3674+ struct hlist_bl_node *pos;
076b876e 3675+ struct au_finfo *finfo;
076b876e
AM
3676+
3677+ n = 0;
3678+ p = a;
3679+ files = &au_sbi(sb)->si_files;
ae9dfd79
AM
3680+ hlist_bl_lock(files);
3681+ hlist_bl_for_each_entry(finfo, pos, files, fi_hlist) {
076b876e
AM
3682+ f = finfo->fi_file;
3683+ if (file_count(f)
3684+ && !special_file(file_inode(f)->i_mode)) {
3685+ get_file(f);
3686+ *p++ = f;
3687+ n++;
3688+ AuDebugOn(n > max);
3689+ }
3690+ }
ae9dfd79 3691+ hlist_bl_unlock(files);
076b876e
AM
3692+
3693+ return n;
3694+}
3695+
3696+static struct file **au_farray_alloc(struct super_block *sb,
3697+ unsigned long long *max)
3698+{
5afbbe0d 3699+ *max = au_nfiles(sb);
79b8bda9 3700+ return au_array_alloc(max, au_farray_cb, sb, /*arg*/NULL);
076b876e
AM
3701+}
3702+
3703+static void au_farray_free(struct file **a, unsigned long long max)
3704+{
3705+ unsigned long long ull;
3706+
3707+ for (ull = 0; ull < max; ull++)
3708+ if (a[ull])
3709+ fput(a[ull]);
be52b249 3710+ kvfree(a);
076b876e
AM
3711+}
3712+
3713+/* ---------------------------------------------------------------------- */
3714+
1facf9fc 3715+/*
3716+ * delete a branch
3717+ */
3718+
3719+/* to show the line number, do not make it inlined function */
4a4d8108 3720+#define AuVerbose(do_info, fmt, ...) do { \
1facf9fc 3721+ if (do_info) \
4a4d8108 3722+ pr_info(fmt, ##__VA_ARGS__); \
1facf9fc 3723+} while (0)
3724+
5afbbe0d
AM
3725+static int au_test_ibusy(struct inode *inode, aufs_bindex_t btop,
3726+ aufs_bindex_t bbot)
027c5e7a 3727+{
5afbbe0d 3728+ return (inode && !S_ISDIR(inode->i_mode)) || btop == bbot;
027c5e7a
AM
3729+}
3730+
5afbbe0d
AM
3731+static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t btop,
3732+ aufs_bindex_t bbot)
027c5e7a 3733+{
5afbbe0d 3734+ return au_test_ibusy(d_inode(dentry), btop, bbot);
027c5e7a
AM
3735+}
3736+
1facf9fc 3737+/*
3738+ * test if the branch is deletable or not.
3739+ */
3740+static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
b752ccd1 3741+ unsigned int sigen, const unsigned int verbose)
1facf9fc 3742+{
3743+ int err, i, j, ndentry;
5afbbe0d 3744+ aufs_bindex_t btop, bbot;
1facf9fc 3745+ struct au_dcsub_pages dpages;
3746+ struct au_dpage *dpage;
3747+ struct dentry *d;
1facf9fc 3748+
3749+ err = au_dpages_init(&dpages, GFP_NOFS);
3750+ if (unlikely(err))
3751+ goto out;
3752+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
3753+ if (unlikely(err))
3754+ goto out_dpages;
3755+
1facf9fc 3756+ for (i = 0; !err && i < dpages.ndpage; i++) {
3757+ dpage = dpages.dpages + i;
3758+ ndentry = dpage->ndentry;
3759+ for (j = 0; !err && j < ndentry; j++) {
3760+ d = dpage->dentries[j];
c1595e42 3761+ AuDebugOn(au_dcount(d) <= 0);
027c5e7a 3762+ if (!au_digen_test(d, sigen)) {
1facf9fc 3763+ di_read_lock_child(d, AuLock_IR);
027c5e7a
AM
3764+ if (unlikely(au_dbrange_test(d))) {
3765+ di_read_unlock(d, AuLock_IR);
3766+ continue;
3767+ }
3768+ } else {
1facf9fc 3769+ di_write_lock_child(d);
027c5e7a
AM
3770+ if (unlikely(au_dbrange_test(d))) {
3771+ di_write_unlock(d);
3772+ continue;
3773+ }
1facf9fc 3774+ err = au_reval_dpath(d, sigen);
3775+ if (!err)
3776+ di_downgrade_lock(d, AuLock_IR);
3777+ else {
3778+ di_write_unlock(d);
3779+ break;
3780+ }
3781+ }
3782+
027c5e7a 3783+ /* AuDbgDentry(d); */
5afbbe0d
AM
3784+ btop = au_dbtop(d);
3785+ bbot = au_dbbot(d);
3786+ if (btop <= bindex
3787+ && bindex <= bbot
1facf9fc 3788+ && au_h_dptr(d, bindex)
5afbbe0d 3789+ && au_test_dbusy(d, btop, bbot)) {
1facf9fc 3790+ err = -EBUSY;
523b37e3 3791+ AuVerbose(verbose, "busy %pd\n", d);
027c5e7a 3792+ AuDbgDentry(d);
1facf9fc 3793+ }
3794+ di_read_unlock(d, AuLock_IR);
3795+ }
3796+ }
3797+
4f0767ce 3798+out_dpages:
1facf9fc 3799+ au_dpages_free(&dpages);
4f0767ce 3800+out:
1facf9fc 3801+ return err;
3802+}
3803+
3804+static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
b752ccd1 3805+ unsigned int sigen, const unsigned int verbose)
1facf9fc 3806+{
3807+ int err;
7f207e10
AM
3808+ unsigned long long max, ull;
3809+ struct inode *i, **array;
5afbbe0d 3810+ aufs_bindex_t btop, bbot;
1facf9fc 3811+
7f207e10
AM
3812+ array = au_iarray_alloc(sb, &max);
3813+ err = PTR_ERR(array);
3814+ if (IS_ERR(array))
3815+ goto out;
3816+
1facf9fc 3817+ err = 0;
7f207e10
AM
3818+ AuDbg("b%d\n", bindex);
3819+ for (ull = 0; !err && ull < max; ull++) {
3820+ i = array[ull];
076b876e
AM
3821+ if (unlikely(!i))
3822+ break;
7f207e10 3823+ if (i->i_ino == AUFS_ROOT_INO)
1facf9fc 3824+ continue;
3825+
7f207e10 3826+ /* AuDbgInode(i); */
537831f9 3827+ if (au_iigen(i, NULL) == sigen)
1facf9fc 3828+ ii_read_lock_child(i);
3829+ else {
3830+ ii_write_lock_child(i);
027c5e7a
AM
3831+ err = au_refresh_hinode_self(i);
3832+ au_iigen_dec(i);
1facf9fc 3833+ if (!err)
3834+ ii_downgrade_lock(i);
3835+ else {
3836+ ii_write_unlock(i);
3837+ break;
3838+ }
3839+ }
3840+
5afbbe0d
AM
3841+ btop = au_ibtop(i);
3842+ bbot = au_ibbot(i);
3843+ if (btop <= bindex
3844+ && bindex <= bbot
1facf9fc 3845+ && au_h_iptr(i, bindex)
5afbbe0d 3846+ && au_test_ibusy(i, btop, bbot)) {
1facf9fc 3847+ err = -EBUSY;
3848+ AuVerbose(verbose, "busy i%lu\n", i->i_ino);
7f207e10 3849+ AuDbgInode(i);
1facf9fc 3850+ }
3851+ ii_read_unlock(i);
3852+ }
7f207e10 3853+ au_iarray_free(array, max);
1facf9fc 3854+
7f207e10 3855+out:
1facf9fc 3856+ return err;
3857+}
3858+
b752ccd1
AM
3859+static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
3860+ const unsigned int verbose)
1facf9fc 3861+{
3862+ int err;
3863+ unsigned int sigen;
3864+
3865+ sigen = au_sigen(root->d_sb);
3866+ DiMustNoWaiters(root);
5527c038 3867+ IiMustNoWaiters(d_inode(root));
1facf9fc 3868+ di_write_unlock(root);
b752ccd1 3869+ err = test_dentry_busy(root, bindex, sigen, verbose);
1facf9fc 3870+ if (!err)
b752ccd1 3871+ err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
1facf9fc 3872+ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
3873+
3874+ return err;
3875+}
3876+
076b876e
AM
3877+static int test_dir_busy(struct file *file, aufs_bindex_t br_id,
3878+ struct file **to_free, int *idx)
3879+{
3880+ int err;
c1595e42 3881+ unsigned char matched, root;
5afbbe0d 3882+ aufs_bindex_t bindex, bbot;
076b876e
AM
3883+ struct au_fidir *fidir;
3884+ struct au_hfile *hfile;
3885+
3886+ err = 0;
2000de60 3887+ root = IS_ROOT(file->f_path.dentry);
c1595e42
JR
3888+ if (root) {
3889+ get_file(file);
3890+ to_free[*idx] = file;
3891+ (*idx)++;
3892+ goto out;
3893+ }
3894+
076b876e 3895+ matched = 0;
076b876e
AM
3896+ fidir = au_fi(file)->fi_hdir;
3897+ AuDebugOn(!fidir);
5afbbe0d
AM
3898+ bbot = au_fbbot_dir(file);
3899+ for (bindex = au_fbtop(file); bindex <= bbot; bindex++) {
076b876e
AM
3900+ hfile = fidir->fd_hfile + bindex;
3901+ if (!hfile->hf_file)
3902+ continue;
3903+
c1595e42 3904+ if (hfile->hf_br->br_id == br_id) {
076b876e 3905+ matched = 1;
076b876e 3906+ break;
c1595e42 3907+ }
076b876e 3908+ }
c1595e42 3909+ if (matched)
076b876e
AM
3910+ err = -EBUSY;
3911+
3912+out:
3913+ return err;
3914+}
3915+
3916+static int test_file_busy(struct super_block *sb, aufs_bindex_t br_id,
3917+ struct file **to_free, int opened)
3918+{
3919+ int err, idx;
3920+ unsigned long long ull, max;
5afbbe0d 3921+ aufs_bindex_t btop;
076b876e 3922+ struct file *file, **array;
076b876e
AM
3923+ struct dentry *root;
3924+ struct au_hfile *hfile;
3925+
3926+ array = au_farray_alloc(sb, &max);
3927+ err = PTR_ERR(array);
3928+ if (IS_ERR(array))
3929+ goto out;
3930+
3931+ err = 0;
3932+ idx = 0;
3933+ root = sb->s_root;
3934+ di_write_unlock(root);
3935+ for (ull = 0; ull < max; ull++) {
3936+ file = array[ull];
3937+ if (unlikely(!file))
3938+ break;
3939+
3940+ /* AuDbg("%pD\n", file); */
3941+ fi_read_lock(file);
5afbbe0d 3942+ btop = au_fbtop(file);
2000de60 3943+ if (!d_is_dir(file->f_path.dentry)) {
076b876e
AM
3944+ hfile = &au_fi(file)->fi_htop;
3945+ if (hfile->hf_br->br_id == br_id)
3946+ err = -EBUSY;
3947+ } else
3948+ err = test_dir_busy(file, br_id, to_free, &idx);
3949+ fi_read_unlock(file);
3950+ if (unlikely(err))
3951+ break;
3952+ }
3953+ di_write_lock_child(root);
3954+ au_farray_free(array, max);
3955+ AuDebugOn(idx > opened);
3956+
3957+out:
3958+ return err;
3959+}
3960+
3961+static void br_del_file(struct file **to_free, unsigned long long opened,
3962+ aufs_bindex_t br_id)
3963+{
3964+ unsigned long long ull;
5afbbe0d 3965+ aufs_bindex_t bindex, btop, bbot, bfound;
076b876e
AM
3966+ struct file *file;
3967+ struct au_fidir *fidir;
3968+ struct au_hfile *hfile;
3969+
3970+ for (ull = 0; ull < opened; ull++) {
3971+ file = to_free[ull];
3972+ if (unlikely(!file))
3973+ break;
3974+
3975+ /* AuDbg("%pD\n", file); */
2000de60 3976+ AuDebugOn(!d_is_dir(file->f_path.dentry));
076b876e
AM
3977+ bfound = -1;
3978+ fidir = au_fi(file)->fi_hdir;
3979+ AuDebugOn(!fidir);
3980+ fi_write_lock(file);
5afbbe0d
AM
3981+ btop = au_fbtop(file);
3982+ bbot = au_fbbot_dir(file);
3983+ for (bindex = btop; bindex <= bbot; bindex++) {
076b876e
AM
3984+ hfile = fidir->fd_hfile + bindex;
3985+ if (!hfile->hf_file)
3986+ continue;
3987+
3988+ if (hfile->hf_br->br_id == br_id) {
3989+ bfound = bindex;
3990+ break;
3991+ }
3992+ }
3993+ AuDebugOn(bfound < 0);
3994+ au_set_h_fptr(file, bfound, NULL);
5afbbe0d
AM
3995+ if (bfound == btop) {
3996+ for (btop++; btop <= bbot; btop++)
3997+ if (au_hf_dir(file, btop)) {
3998+ au_set_fbtop(file, btop);
076b876e
AM
3999+ break;
4000+ }
4001+ }
4002+ fi_write_unlock(file);
4003+ }
4004+}
4005+
1facf9fc 4006+static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
4007+ const aufs_bindex_t bindex,
5afbbe0d 4008+ const aufs_bindex_t bbot)
1facf9fc 4009+{
4010+ struct au_branch **brp, **p;
4011+
dece6358
AM
4012+ AuRwMustWriteLock(&sbinfo->si_rwsem);
4013+
1facf9fc 4014+ brp = sbinfo->si_branch + bindex;
5afbbe0d
AM
4015+ if (bindex < bbot)
4016+ memmove(brp, brp + 1, sizeof(*brp) * (bbot - bindex));
4017+ sbinfo->si_branch[0 + bbot] = NULL;
4018+ sbinfo->si_bbot--;
1facf9fc 4019+
e2f27e51
AM
4020+ p = au_krealloc(sbinfo->si_branch, sizeof(*p) * bbot, AuGFP_SBILIST,
4021+ /*may_shrink*/1);
1facf9fc 4022+ if (p)
4023+ sbinfo->si_branch = p;
4a4d8108 4024+ /* harmless error */
1facf9fc 4025+}
4026+
4027+static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
5afbbe0d 4028+ const aufs_bindex_t bbot)
1facf9fc 4029+{
4030+ struct au_hdentry *hdp, *p;
4031+
1308ab2a 4032+ AuRwMustWriteLock(&dinfo->di_rwsem);
4033+
5afbbe0d
AM
4034+ hdp = au_hdentry(dinfo, bindex);
4035+ if (bindex < bbot)
4036+ memmove(hdp, hdp + 1, sizeof(*hdp) * (bbot - bindex));
4037+ /* au_h_dentry_init(au_hdentry(dinfo, bbot); */
4038+ dinfo->di_bbot--;
1facf9fc 4039+
e2f27e51
AM
4040+ p = au_krealloc(dinfo->di_hdentry, sizeof(*p) * bbot, AuGFP_SBILIST,
4041+ /*may_shrink*/1);
1facf9fc 4042+ if (p)
4043+ dinfo->di_hdentry = p;
4a4d8108 4044+ /* harmless error */
1facf9fc 4045+}
4046+
4047+static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
5afbbe0d 4048+ const aufs_bindex_t bbot)
1facf9fc 4049+{
4050+ struct au_hinode *hip, *p;
4051+
1308ab2a 4052+ AuRwMustWriteLock(&iinfo->ii_rwsem);
4053+
5afbbe0d
AM
4054+ hip = au_hinode(iinfo, bindex);
4055+ if (bindex < bbot)
4056+ memmove(hip, hip + 1, sizeof(*hip) * (bbot - bindex));
4057+ /* au_hinode_init(au_hinode(iinfo, bbot)); */
4058+ iinfo->ii_bbot--;
1facf9fc 4059+
e2f27e51
AM
4060+ p = au_krealloc(iinfo->ii_hinode, sizeof(*p) * bbot, AuGFP_SBILIST,
4061+ /*may_shrink*/1);
1facf9fc 4062+ if (p)
4063+ iinfo->ii_hinode = p;
4a4d8108 4064+ /* harmless error */
1facf9fc 4065+}
4066+
4067+static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
4068+ struct au_branch *br)
4069+{
5afbbe0d 4070+ aufs_bindex_t bbot;
1facf9fc 4071+ struct au_sbinfo *sbinfo;
53392da6
AM
4072+ struct dentry *root, *h_root;
4073+ struct inode *inode, *h_inode;
4074+ struct au_hinode *hinode;
1facf9fc 4075+
dece6358
AM
4076+ SiMustWriteLock(sb);
4077+
1facf9fc 4078+ root = sb->s_root;
5527c038 4079+ inode = d_inode(root);
1facf9fc 4080+ sbinfo = au_sbi(sb);
5afbbe0d 4081+ bbot = sbinfo->si_bbot;
1facf9fc 4082+
53392da6
AM
4083+ h_root = au_h_dptr(root, bindex);
4084+ hinode = au_hi(inode, bindex);
4085+ h_inode = au_igrab(hinode->hi_inode);
4086+ au_hiput(hinode);
1facf9fc 4087+
53392da6 4088+ au_sbilist_lock();
5afbbe0d
AM
4089+ au_br_do_del_brp(sbinfo, bindex, bbot);
4090+ au_br_do_del_hdp(au_di(root), bindex, bbot);
4091+ au_br_do_del_hip(au_ii(inode), bindex, bbot);
53392da6
AM
4092+ au_sbilist_unlock();
4093+
ae9dfd79
AM
4094+ /* ignore an error */
4095+ au_dr_br_fin(sb, br); /* always, regardless the mount option */
4096+
53392da6
AM
4097+ dput(h_root);
4098+ iput(h_inode);
4099+ au_br_do_free(br);
1facf9fc 4100+}
4101+
79b8bda9
AM
4102+static unsigned long long empty_cb(struct super_block *sb, void *array,
4103+ unsigned long long max, void *arg)
076b876e
AM
4104+{
4105+ return max;
4106+}
4107+
1facf9fc 4108+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
4109+{
4110+ int err, rerr, i;
076b876e 4111+ unsigned long long opened;
1facf9fc 4112+ unsigned int mnt_flags;
5afbbe0d 4113+ aufs_bindex_t bindex, bbot, br_id;
1facf9fc 4114+ unsigned char do_wh, verbose;
4115+ struct au_branch *br;
4116+ struct au_wbr *wbr;
076b876e
AM
4117+ struct dentry *root;
4118+ struct file **to_free;
1facf9fc 4119+
4120+ err = 0;
076b876e
AM
4121+ opened = 0;
4122+ to_free = NULL;
4123+ root = sb->s_root;
4124+ bindex = au_find_dbindex(root, del->h_path.dentry);
1facf9fc 4125+ if (bindex < 0) {
4126+ if (remount)
4127+ goto out; /* success */
4128+ err = -ENOENT;
4a4d8108 4129+ pr_err("%s no such branch\n", del->pathname);
1facf9fc 4130+ goto out;
4131+ }
4132+ AuDbg("bindex b%d\n", bindex);
4133+
4134+ err = -EBUSY;
4135+ mnt_flags = au_mntflags(sb);
4136+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
5afbbe0d
AM
4137+ bbot = au_sbbot(sb);
4138+ if (unlikely(!bbot)) {
1facf9fc 4139+ AuVerbose(verbose, "no more branches left\n");
4140+ goto out;
4141+ }
4142+ br = au_sbr(sb, bindex);
86dc4139 4143+ AuDebugOn(!path_equal(&br->br_path, &del->h_path));
076b876e
AM
4144+
4145+ br_id = br->br_id;
5afbbe0d 4146+ opened = au_br_count(br);
076b876e 4147+ if (unlikely(opened)) {
79b8bda9 4148+ to_free = au_array_alloc(&opened, empty_cb, sb, NULL);
076b876e
AM
4149+ err = PTR_ERR(to_free);
4150+ if (IS_ERR(to_free))
4151+ goto out;
4152+
4153+ err = test_file_busy(sb, br_id, to_free, opened);
4154+ if (unlikely(err)) {
4155+ AuVerbose(verbose, "%llu file(s) opened\n", opened);
4156+ goto out;
4157+ }
1facf9fc 4158+ }
4159+
4160+ wbr = br->br_wbr;
4161+ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
4162+ if (do_wh) {
1308ab2a 4163+ /* instead of WbrWhMustWriteLock(wbr) */
4164+ SiMustWriteLock(sb);
1facf9fc 4165+ for (i = 0; i < AuBrWh_Last; i++) {
4166+ dput(wbr->wbr_wh[i]);
4167+ wbr->wbr_wh[i] = NULL;
4168+ }
4169+ }
4170+
076b876e 4171+ err = test_children_busy(root, bindex, verbose);
1facf9fc 4172+ if (unlikely(err)) {
4173+ if (do_wh)
4174+ goto out_wh;
4175+ goto out;
4176+ }
4177+
4178+ err = 0;
076b876e
AM
4179+ if (to_free) {
4180+ /*
4181+ * now we confirmed the branch is deletable.
4182+ * let's free the remaining opened dirs on the branch.
4183+ */
4184+ di_write_unlock(root);
4185+ br_del_file(to_free, opened, br_id);
4186+ di_write_lock_child(root);
4187+ }
4188+
1facf9fc 4189+ if (!remount)
4190+ au_br_do_del(sb, bindex, br);
4191+ else {
4192+ sysaufs_brs_del(sb, bindex);
4193+ au_br_do_del(sb, bindex, br);
4194+ sysaufs_brs_add(sb, bindex);
4195+ }
4196+
1308ab2a 4197+ if (!bindex) {
5527c038 4198+ au_cpup_attr_all(d_inode(root), /*force*/1);
1308ab2a 4199+ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
4200+ } else
5527c038 4201+ au_sub_nlink(d_inode(root), d_inode(del->h_path.dentry));
1facf9fc 4202+ if (au_opt_test(mnt_flags, PLINK))
4203+ au_plink_half_refresh(sb, br_id);
4204+
b752ccd1 4205+ if (au_xino_brid(sb) == br_id)
1facf9fc 4206+ au_xino_brid_set(sb, -1);
4207+ goto out; /* success */
4208+
4f0767ce 4209+out_wh:
1facf9fc 4210+ /* revert */
86dc4139 4211+ rerr = au_br_init_wh(sb, br, br->br_perm);
1facf9fc 4212+ if (rerr)
0c3ec466
AM
4213+ pr_warn("failed re-creating base whiteout, %s. (%d)\n",
4214+ del->pathname, rerr);
4f0767ce 4215+out:
076b876e
AM
4216+ if (to_free)
4217+ au_farray_free(to_free, opened);
1facf9fc 4218+ return err;
4219+}
4220+
4221+/* ---------------------------------------------------------------------- */
4222+
027c5e7a
AM
4223+static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg)
4224+{
4225+ int err;
5afbbe0d 4226+ aufs_bindex_t btop, bbot;
027c5e7a
AM
4227+ struct aufs_ibusy ibusy;
4228+ struct inode *inode, *h_inode;
4229+
4230+ err = -EPERM;
4231+ if (unlikely(!capable(CAP_SYS_ADMIN)))
4232+ goto out;
4233+
4234+ err = copy_from_user(&ibusy, arg, sizeof(ibusy));
4235+ if (!err)
4236+ err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino));
4237+ if (unlikely(err)) {
4238+ err = -EFAULT;
4239+ AuTraceErr(err);
4240+ goto out;
4241+ }
4242+
4243+ err = -EINVAL;
4244+ si_read_lock(sb, AuLock_FLUSH);
5afbbe0d 4245+ if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbbot(sb)))
027c5e7a
AM
4246+ goto out_unlock;
4247+
4248+ err = 0;
4249+ ibusy.h_ino = 0; /* invalid */
4250+ inode = ilookup(sb, ibusy.ino);
4251+ if (!inode
4252+ || inode->i_ino == AUFS_ROOT_INO
5afbbe0d 4253+ || au_is_bad_inode(inode))
027c5e7a
AM
4254+ goto out_unlock;
4255+
4256+ ii_read_lock_child(inode);
5afbbe0d
AM
4257+ btop = au_ibtop(inode);
4258+ bbot = au_ibbot(inode);
4259+ if (btop <= ibusy.bindex && ibusy.bindex <= bbot) {
027c5e7a 4260+ h_inode = au_h_iptr(inode, ibusy.bindex);
5afbbe0d 4261+ if (h_inode && au_test_ibusy(inode, btop, bbot))
027c5e7a
AM
4262+ ibusy.h_ino = h_inode->i_ino;
4263+ }
4264+ ii_read_unlock(inode);
4265+ iput(inode);
4266+
4267+out_unlock:
4268+ si_read_unlock(sb);
4269+ if (!err) {
4270+ err = __put_user(ibusy.h_ino, &arg->h_ino);
4271+ if (unlikely(err)) {
4272+ err = -EFAULT;
4273+ AuTraceErr(err);
4274+ }
4275+ }
4276+out:
4277+ return err;
4278+}
4279+
4280+long au_ibusy_ioctl(struct file *file, unsigned long arg)
4281+{
2000de60 4282+ return au_ibusy(file->f_path.dentry->d_sb, (void __user *)arg);
027c5e7a
AM
4283+}
4284+
4285+#ifdef CONFIG_COMPAT
4286+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg)
4287+{
2000de60 4288+ return au_ibusy(file->f_path.dentry->d_sb, compat_ptr(arg));
027c5e7a
AM
4289+}
4290+#endif
4291+
4292+/* ---------------------------------------------------------------------- */
4293+
1facf9fc 4294+/*
4295+ * change a branch permission
4296+ */
4297+
dece6358
AM
4298+static void au_warn_ima(void)
4299+{
4300+#ifdef CONFIG_IMA
1308ab2a 4301+ /* since it doesn't support mark_files_ro() */
027c5e7a 4302+ AuWarn1("RW -> RO makes IMA to produce wrong message\n");
dece6358
AM
4303+#endif
4304+}
4305+
1facf9fc 4306+static int do_need_sigen_inc(int a, int b)
4307+{
4308+ return au_br_whable(a) && !au_br_whable(b);
4309+}
4310+
4311+static int need_sigen_inc(int old, int new)
4312+{
4313+ return do_need_sigen_inc(old, new)
4314+ || do_need_sigen_inc(new, old);
4315+}
4316+
4317+static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
4318+{
7f207e10 4319+ int err, do_warn;
027c5e7a 4320+ unsigned int mnt_flags;
7f207e10 4321+ unsigned long long ull, max;
e49829fe 4322+ aufs_bindex_t br_id;
38d290e6 4323+ unsigned char verbose, writer;
7f207e10 4324+ struct file *file, *hf, **array;
e49829fe 4325+ struct au_hfile *hfile;
1facf9fc 4326+
027c5e7a
AM
4327+ mnt_flags = au_mntflags(sb);
4328+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
4329+
7f207e10
AM
4330+ array = au_farray_alloc(sb, &max);
4331+ err = PTR_ERR(array);
4332+ if (IS_ERR(array))
1facf9fc 4333+ goto out;
4334+
7f207e10 4335+ do_warn = 0;
e49829fe 4336+ br_id = au_sbr_id(sb, bindex);
7f207e10
AM
4337+ for (ull = 0; ull < max; ull++) {
4338+ file = array[ull];
076b876e
AM
4339+ if (unlikely(!file))
4340+ break;
1facf9fc 4341+
523b37e3 4342+ /* AuDbg("%pD\n", file); */
1facf9fc 4343+ fi_read_lock(file);
4344+ if (unlikely(au_test_mmapped(file))) {
4345+ err = -EBUSY;
523b37e3 4346+ AuVerbose(verbose, "mmapped %pD\n", file);
7f207e10 4347+ AuDbgFile(file);
1facf9fc 4348+ FiMustNoWaiters(file);
4349+ fi_read_unlock(file);
7f207e10 4350+ goto out_array;
1facf9fc 4351+ }
4352+
e49829fe
JR
4353+ hfile = &au_fi(file)->fi_htop;
4354+ hf = hfile->hf_file;
7e9cd9fe 4355+ if (!d_is_reg(file->f_path.dentry)
1facf9fc 4356+ || !(file->f_mode & FMODE_WRITE)
e49829fe 4357+ || hfile->hf_br->br_id != br_id
7f207e10
AM
4358+ || !(hf->f_mode & FMODE_WRITE))
4359+ array[ull] = NULL;
4360+ else {
4361+ do_warn = 1;
4362+ get_file(file);
1facf9fc 4363+ }
4364+
1facf9fc 4365+ FiMustNoWaiters(file);
4366+ fi_read_unlock(file);
7f207e10
AM
4367+ fput(file);
4368+ }
1facf9fc 4369+
4370+ err = 0;
7f207e10 4371+ if (do_warn)
dece6358 4372+ au_warn_ima();
7f207e10
AM
4373+
4374+ for (ull = 0; ull < max; ull++) {
4375+ file = array[ull];
4376+ if (!file)
4377+ continue;
4378+
1facf9fc 4379+ /* todo: already flushed? */
523b37e3
AM
4380+ /*
4381+ * fs/super.c:mark_files_ro() is gone, but aufs keeps its
4382+ * approach which resets f_mode and calls mnt_drop_write() and
4383+ * file_release_write() for each file, because the branch
4384+ * attribute in aufs world is totally different from the native
4385+ * fs rw/ro mode.
4386+ */
7f207e10
AM
4387+ /* fi_read_lock(file); */
4388+ hfile = &au_fi(file)->fi_htop;
4389+ hf = hfile->hf_file;
4390+ /* fi_read_unlock(file); */
027c5e7a 4391+ spin_lock(&hf->f_lock);
38d290e6
JR
4392+ writer = !!(hf->f_mode & FMODE_WRITER);
4393+ hf->f_mode &= ~(FMODE_WRITE | FMODE_WRITER);
027c5e7a 4394+ spin_unlock(&hf->f_lock);
38d290e6
JR
4395+ if (writer) {
4396+ put_write_access(file_inode(hf));
c06a8ce3 4397+ __mnt_drop_write(hf->f_path.mnt);
1facf9fc 4398+ }
4399+ }
4400+
7f207e10
AM
4401+out_array:
4402+ au_farray_free(array, max);
4f0767ce 4403+out:
7f207e10 4404+ AuTraceErr(err);
1facf9fc 4405+ return err;
4406+}
4407+
4408+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 4409+ int *do_refresh)
1facf9fc 4410+{
4411+ int err, rerr;
4412+ aufs_bindex_t bindex;
4413+ struct dentry *root;
4414+ struct au_branch *br;
076b876e 4415+ struct au_br_fhsm *bf;
1facf9fc 4416+
4417+ root = sb->s_root;
1facf9fc 4418+ bindex = au_find_dbindex(root, mod->h_root);
4419+ if (bindex < 0) {
4420+ if (remount)
4421+ return 0; /* success */
4422+ err = -ENOENT;
4a4d8108 4423+ pr_err("%s no such branch\n", mod->path);
1facf9fc 4424+ goto out;
4425+ }
4426+ AuDbg("bindex b%d\n", bindex);
4427+
5527c038 4428+ err = test_br(d_inode(mod->h_root), mod->perm, mod->path);
1facf9fc 4429+ if (unlikely(err))
4430+ goto out;
4431+
4432+ br = au_sbr(sb, bindex);
86dc4139 4433+ AuDebugOn(mod->h_root != au_br_dentry(br));
1facf9fc 4434+ if (br->br_perm == mod->perm)
4435+ return 0; /* success */
4436+
076b876e
AM
4437+ /* pre-allocate for non-fhsm --> fhsm */
4438+ bf = NULL;
4439+ if (!au_br_fhsm(br->br_perm) && au_br_fhsm(mod->perm)) {
4440+ err = au_fhsm_br_alloc(br);
4441+ if (unlikely(err))
4442+ goto out;
4443+ bf = br->br_fhsm;
4444+ br->br_fhsm = NULL;
4445+ }
4446+
1facf9fc 4447+ if (au_br_writable(br->br_perm)) {
4448+ /* remove whiteout base */
86dc4139 4449+ err = au_br_init_wh(sb, br, mod->perm);
1facf9fc 4450+ if (unlikely(err))
076b876e 4451+ goto out_bf;
1facf9fc 4452+
4453+ if (!au_br_writable(mod->perm)) {
4454+ /* rw --> ro, file might be mmapped */
4455+ DiMustNoWaiters(root);
5527c038 4456+ IiMustNoWaiters(d_inode(root));
1facf9fc 4457+ di_write_unlock(root);
4458+ err = au_br_mod_files_ro(sb, bindex);
4459+ /* aufs_write_lock() calls ..._child() */
4460+ di_write_lock_child(root);
4461+
4462+ if (unlikely(err)) {
4463+ rerr = -ENOMEM;
be52b249 4464+ br->br_wbr = kzalloc(sizeof(*br->br_wbr),
1facf9fc 4465+ GFP_NOFS);
86dc4139
AM
4466+ if (br->br_wbr)
4467+ rerr = au_wbr_init(br, sb, br->br_perm);
1facf9fc 4468+ if (unlikely(rerr)) {
4469+ AuIOErr("nested error %d (%d)\n",
4470+ rerr, err);
4471+ br->br_perm = mod->perm;
4472+ }
4473+ }
4474+ }
4475+ } else if (au_br_writable(mod->perm)) {
4476+ /* ro --> rw */
4477+ err = -ENOMEM;
be52b249 4478+ br->br_wbr = kzalloc(sizeof(*br->br_wbr), GFP_NOFS);
1facf9fc 4479+ if (br->br_wbr) {
86dc4139 4480+ err = au_wbr_init(br, sb, mod->perm);
1facf9fc 4481+ if (unlikely(err)) {
ae9dfd79 4482+ kfree(br->br_wbr);
1facf9fc 4483+ br->br_wbr = NULL;
4484+ }
4485+ }
4486+ }
076b876e
AM
4487+ if (unlikely(err))
4488+ goto out_bf;
4489+
4490+ if (au_br_fhsm(br->br_perm)) {
4491+ if (!au_br_fhsm(mod->perm)) {
4492+ /* fhsm --> non-fhsm */
4493+ au_br_fhsm_fin(br->br_fhsm);
ae9dfd79 4494+ kfree(br->br_fhsm);
076b876e
AM
4495+ br->br_fhsm = NULL;
4496+ }
4497+ } else if (au_br_fhsm(mod->perm))
4498+ /* non-fhsm --> fhsm */
4499+ br->br_fhsm = bf;
4500+
076b876e
AM
4501+ *do_refresh |= need_sigen_inc(br->br_perm, mod->perm);
4502+ br->br_perm = mod->perm;
4503+ goto out; /* success */
1facf9fc 4504+
076b876e 4505+out_bf:
ae9dfd79 4506+ kfree(bf);
076b876e
AM
4507+out:
4508+ AuTraceErr(err);
4509+ return err;
4510+}
4511+
4512+/* ---------------------------------------------------------------------- */
4513+
4514+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs)
4515+{
4516+ int err;
4517+ struct kstatfs kstfs;
4518+
4519+ err = vfs_statfs(&br->br_path, &kstfs);
1facf9fc 4520+ if (!err) {
076b876e
AM
4521+ stfs->f_blocks = kstfs.f_blocks;
4522+ stfs->f_bavail = kstfs.f_bavail;
4523+ stfs->f_files = kstfs.f_files;
4524+ stfs->f_ffree = kstfs.f_ffree;
1facf9fc 4525+ }
4526+
1facf9fc 4527+ return err;
4528+}
7f207e10
AM
4529diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
4530--- /usr/share/empty/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
4531+++ linux/fs/aufs/branch.h 2018-04-15 08:49:13.394483860 +0200
4532@@ -0,0 +1,324 @@
1facf9fc 4533+/*
ae9dfd79 4534+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 4535+ *
4536+ * This program, aufs is free software; you can redistribute it and/or modify
4537+ * it under the terms of the GNU General Public License as published by
4538+ * the Free Software Foundation; either version 2 of the License, or
4539+ * (at your option) any later version.
dece6358
AM
4540+ *
4541+ * This program is distributed in the hope that it will be useful,
4542+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4543+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4544+ * GNU General Public License for more details.
4545+ *
4546+ * You should have received a copy of the GNU General Public License
523b37e3 4547+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 4548+ */
4549+
4550+/*
4551+ * branch filesystems and xino for them
4552+ */
4553+
4554+#ifndef __AUFS_BRANCH_H__
4555+#define __AUFS_BRANCH_H__
4556+
4557+#ifdef __KERNEL__
4558+
1facf9fc 4559+#include <linux/mount.h>
ae9dfd79 4560+#include "dirren.h"
4a4d8108 4561+#include "dynop.h"
1facf9fc 4562+#include "rwsem.h"
4563+#include "super.h"
4564+
4565+/* ---------------------------------------------------------------------- */
4566+
4567+/* a xino file */
4568+struct au_xino_file {
4569+ struct file *xi_file;
ae9dfd79
AM
4570+ struct {
4571+ spinlock_t spin;
4572+ ino_t *array;
4573+ int total;
4574+ /* reserved for future use */
4575+ /* unsigned long *bitmap; */
4576+ wait_queue_head_t wqh;
4577+ } xi_nondir;
1facf9fc 4578+
4579+ /* todo: make xino files an array to support huge inode number */
4580+
4581+#ifdef CONFIG_DEBUG_FS
4582+ struct dentry *xi_dbgaufs;
4583+#endif
4584+};
4585+
076b876e
AM
4586+/* File-based Hierarchical Storage Management */
4587+struct au_br_fhsm {
4588+#ifdef CONFIG_AUFS_FHSM
4589+ struct mutex bf_lock;
4590+ unsigned long bf_jiffy;
4591+ struct aufs_stfs bf_stfs;
4592+ int bf_readable;
4593+#endif
4594+};
4595+
1facf9fc 4596+/* members for writable branch only */
4597+enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
4598+struct au_wbr {
dece6358 4599+ struct au_rwsem wbr_wh_rwsem;
1facf9fc 4600+ struct dentry *wbr_wh[AuBrWh_Last];
4a4d8108 4601+ atomic_t wbr_wh_running;
1facf9fc 4602+#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
4603+#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
4604+#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
4605+
4606+ /* mfs mode */
4607+ unsigned long long wbr_bytes;
4608+};
4609+
4a4d8108
AM
4610+/* ext2 has 3 types of operations at least, ext3 has 4 */
4611+#define AuBrDynOp (AuDyLast * 4)
4612+
1716fcea
AM
4613+#ifdef CONFIG_AUFS_HFSNOTIFY
4614+/* support for asynchronous destruction */
4615+struct au_br_hfsnotify {
4616+ struct fsnotify_group *hfsn_group;
4617+};
4618+#endif
4619+
392086de
AM
4620+/* sysfs entries */
4621+struct au_brsysfs {
4622+ char name[16];
4623+ struct attribute attr;
4624+};
4625+
4626+enum {
4627+ AuBrSysfs_BR,
4628+ AuBrSysfs_BRID,
4629+ AuBrSysfs_Last
4630+};
4631+
1facf9fc 4632+/* protected by superblock rwsem */
4633+struct au_branch {
4634+ struct au_xino_file br_xino;
4635+
4636+ aufs_bindex_t br_id;
4637+
4638+ int br_perm;
86dc4139 4639+ struct path br_path;
4a4d8108
AM
4640+ spinlock_t br_dykey_lock;
4641+ struct au_dykey *br_dykey[AuBrDynOp];
5afbbe0d 4642+ struct percpu_counter br_count;
1facf9fc 4643+
4644+ struct au_wbr *br_wbr;
076b876e 4645+ struct au_br_fhsm *br_fhsm;
1facf9fc 4646+
4647+ /* xino truncation */
1facf9fc 4648+ atomic_t br_xino_running;
4649+
027c5e7a 4650+#ifdef CONFIG_AUFS_HFSNOTIFY
1716fcea 4651+ struct au_br_hfsnotify *br_hfsn;
027c5e7a
AM
4652+#endif
4653+
1facf9fc 4654+#ifdef CONFIG_SYSFS
392086de
AM
4655+ /* entries under sysfs per mount-point */
4656+ struct au_brsysfs br_sysfs[AuBrSysfs_Last];
1facf9fc 4657+#endif
ae9dfd79
AM
4658+
4659+ struct au_dr_br br_dirren;
1facf9fc 4660+};
4661+
4662+/* ---------------------------------------------------------------------- */
4663+
86dc4139
AM
4664+static inline struct vfsmount *au_br_mnt(struct au_branch *br)
4665+{
4666+ return br->br_path.mnt;
4667+}
4668+
4669+static inline struct dentry *au_br_dentry(struct au_branch *br)
4670+{
4671+ return br->br_path.dentry;
4672+}
4673+
4674+static inline struct super_block *au_br_sb(struct au_branch *br)
4675+{
4676+ return au_br_mnt(br)->mnt_sb;
4677+}
4678+
5afbbe0d
AM
4679+static inline void au_br_get(struct au_branch *br)
4680+{
4681+ percpu_counter_inc(&br->br_count);
4682+}
4683+
4684+static inline void au_br_put(struct au_branch *br)
4685+{
4686+ percpu_counter_dec(&br->br_count);
4687+}
4688+
4689+static inline s64 au_br_count(struct au_branch *br)
4690+{
4691+ return percpu_counter_sum(&br->br_count);
4692+}
4693+
4694+static inline void au_br_count_init(struct au_branch *br)
4695+{
4696+ percpu_counter_init(&br->br_count, 0, GFP_NOFS);
4697+}
4698+
4699+static inline void au_br_count_fin(struct au_branch *br)
4700+{
4701+ percpu_counter_destroy(&br->br_count);
4702+}
4703+
1facf9fc 4704+static inline int au_br_rdonly(struct au_branch *br)
4705+{
86dc4139 4706+ return ((au_br_sb(br)->s_flags & MS_RDONLY)
1facf9fc 4707+ || !au_br_writable(br->br_perm))
4708+ ? -EROFS : 0;
4709+}
4710+
4a4d8108 4711+static inline int au_br_hnotifyable(int brperm __maybe_unused)
1facf9fc 4712+{
4a4d8108 4713+#ifdef CONFIG_AUFS_HNOTIFY
1e00d052 4714+ return !(brperm & AuBrPerm_RR);
1facf9fc 4715+#else
4716+ return 0;
4717+#endif
4718+}
4719+
b912730e
AM
4720+static inline int au_br_test_oflag(int oflag, struct au_branch *br)
4721+{
4722+ int err, exec_flag;
4723+
4724+ err = 0;
4725+ exec_flag = oflag & __FMODE_EXEC;
79b8bda9 4726+ if (unlikely(exec_flag && path_noexec(&br->br_path)))
b912730e
AM
4727+ err = -EACCES;
4728+
4729+ return err;
4730+}
4731+
1facf9fc 4732+/* ---------------------------------------------------------------------- */
4733+
4734+/* branch.c */
4735+struct au_sbinfo;
4736+void au_br_free(struct au_sbinfo *sinfo);
4737+int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
4738+struct au_opt_add;
4739+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
4740+struct au_opt_del;
4741+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
027c5e7a
AM
4742+long au_ibusy_ioctl(struct file *file, unsigned long arg);
4743+#ifdef CONFIG_COMPAT
4744+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
4745+#endif
1facf9fc 4746+struct au_opt_mod;
4747+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 4748+ int *do_refresh);
076b876e
AM
4749+struct aufs_stfs;
4750+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs);
1facf9fc 4751+
4752+/* xino.c */
4753+static const loff_t au_loff_max = LLONG_MAX;
4754+
4755+int au_xib_trunc(struct super_block *sb);
5527c038 4756+ssize_t xino_fread(vfs_readf_t func, struct file *file, void *buf, size_t size,
1facf9fc 4757+ loff_t *pos);
5527c038
JR
4758+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf,
4759+ size_t size, loff_t *pos);
1facf9fc 4760+struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
4761+struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
4762+ino_t au_xino_new_ino(struct super_block *sb);
b752ccd1 4763+void au_xino_delete_inode(struct inode *inode, const int unlinked);
1facf9fc 4764+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4765+ ino_t ino);
4766+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4767+ ino_t *ino);
4768+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
4769+ struct file *base_file, int do_test);
4770+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
4771+
4772+struct au_opt_xino;
4773+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
4774+void au_xino_clr(struct super_block *sb);
4775+struct file *au_xino_def(struct super_block *sb);
4776+int au_xino_path(struct seq_file *seq, struct file *file);
4777+
ae9dfd79
AM
4778+void au_xinondir_leave(struct super_block *sb, aufs_bindex_t bindex,
4779+ ino_t h_ino, int idx);
4780+int au_xinondir_enter(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4781+ int *idx);
4782+
1facf9fc 4783+/* ---------------------------------------------------------------------- */
4784+
4785+/* Superblock to branch */
4786+static inline
4787+aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
4788+{
4789+ return au_sbr(sb, bindex)->br_id;
4790+}
4791+
4792+static inline
4793+struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
4794+{
86dc4139 4795+ return au_br_mnt(au_sbr(sb, bindex));
1facf9fc 4796+}
4797+
4798+static inline
4799+struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
4800+{
86dc4139 4801+ return au_br_sb(au_sbr(sb, bindex));
1facf9fc 4802+}
4803+
5afbbe0d
AM
4804+static inline void au_sbr_get(struct super_block *sb, aufs_bindex_t bindex)
4805+{
4806+ au_br_get(au_sbr(sb, bindex));
4807+}
4808+
1facf9fc 4809+static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
4810+{
5afbbe0d 4811+ au_br_put(au_sbr(sb, bindex));
1facf9fc 4812+}
4813+
4814+static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
4815+{
4816+ return au_sbr(sb, bindex)->br_perm;
4817+}
4818+
4819+static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
4820+{
4821+ return au_br_whable(au_sbr_perm(sb, bindex));
4822+}
4823+
4824+/* ---------------------------------------------------------------------- */
4825+
4826+/*
4827+ * wbr_wh_read_lock, wbr_wh_write_lock
4828+ * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
4829+ */
4830+AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
4831+
dece6358
AM
4832+#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
4833+#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
4834+#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
4835+
076b876e
AM
4836+/* ---------------------------------------------------------------------- */
4837+
4838+#ifdef CONFIG_AUFS_FHSM
4839+static inline void au_br_fhsm_init(struct au_br_fhsm *brfhsm)
4840+{
4841+ mutex_init(&brfhsm->bf_lock);
4842+ brfhsm->bf_jiffy = 0;
4843+ brfhsm->bf_readable = 0;
4844+}
4845+
4846+static inline void au_br_fhsm_fin(struct au_br_fhsm *brfhsm)
4847+{
4848+ mutex_destroy(&brfhsm->bf_lock);
4849+}
4850+#else
4851+AuStubVoid(au_br_fhsm_init, struct au_br_fhsm *brfhsm)
4852+AuStubVoid(au_br_fhsm_fin, struct au_br_fhsm *brfhsm)
4853+#endif
4854+
1facf9fc 4855+#endif /* __KERNEL__ */
4856+#endif /* __AUFS_BRANCH_H__ */
7f207e10
AM
4857diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
4858--- /usr/share/empty/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
4859+++ linux/fs/aufs/conf.mk 2018-04-15 08:49:13.394483860 +0200
4860@@ -0,0 +1,39 @@
4a4d8108
AM
4861+
4862+AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
4863+
4864+define AuConf
4865+ifdef ${1}
4866+AuConfStr += ${1}=${${1}}
4867+endif
4868+endef
4869+
b752ccd1 4870+AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
e49829fe 4871+ SBILIST \
7f207e10 4872+ HNOTIFY HFSNOTIFY \
4a4d8108 4873+ EXPORT INO_T_64 \
c1595e42 4874+ XATTR \
076b876e 4875+ FHSM \
4a4d8108 4876+ RDU \
ae9dfd79 4877+ DIRREN \
4a4d8108
AM
4878+ SHWH \
4879+ BR_RAMFS \
4880+ BR_FUSE POLL \
4881+ BR_HFSPLUS \
4882+ BDEV_LOOP \
b752ccd1
AM
4883+ DEBUG MAGIC_SYSRQ
4884+$(foreach i, ${AuConfAll}, \
4a4d8108
AM
4885+ $(eval $(call AuConf,CONFIG_AUFS_${i})))
4886+
4887+AuConfName = ${obj}/conf.str
4888+${AuConfName}.tmp: FORCE
4889+ @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
4890+${AuConfName}: ${AuConfName}.tmp
4891+ @diff -q $< $@ > /dev/null 2>&1 || { \
4892+ echo ' GEN ' $@; \
4893+ cp -p $< $@; \
4894+ }
4895+FORCE:
4896+clean-files += ${AuConfName} ${AuConfName}.tmp
4897+${obj}/sysfs.o: ${AuConfName}
b752ccd1
AM
4898+
4899+-include ${srctree}/${src}/conf_priv.mk
7f207e10
AM
4900diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
4901--- /usr/share/empty/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
4902+++ linux/fs/aufs/cpup.c 2018-04-15 08:49:13.397817296 +0200
4903@@ -0,0 +1,1414 @@
1facf9fc 4904+/*
ae9dfd79 4905+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 4906+ *
4907+ * This program, aufs is free software; you can redistribute it and/or modify
4908+ * it under the terms of the GNU General Public License as published by
4909+ * the Free Software Foundation; either version 2 of the License, or
4910+ * (at your option) any later version.
dece6358
AM
4911+ *
4912+ * This program is distributed in the hope that it will be useful,
4913+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4914+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4915+ * GNU General Public License for more details.
4916+ *
4917+ * You should have received a copy of the GNU General Public License
523b37e3 4918+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 4919+ */
4920+
4921+/*
4922+ * copy-up functions, see wbr_policy.c for copy-down
4923+ */
4924+
4925+#include <linux/fs_stack.h>
dece6358 4926+#include <linux/mm.h>
8cdd5066 4927+#include <linux/task_work.h>
1facf9fc 4928+#include "aufs.h"
4929+
86dc4139 4930+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags)
1facf9fc 4931+{
4932+ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
367653fa 4933+ | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT;
1facf9fc 4934+
86dc4139
AM
4935+ BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags));
4936+
4937+ dst->i_flags |= iflags & ~mask;
1facf9fc 4938+ if (au_test_fs_notime(dst->i_sb))
4939+ dst->i_flags |= S_NOATIME | S_NOCMTIME;
4940+}
4941+
4942+void au_cpup_attr_timesizes(struct inode *inode)
4943+{
4944+ struct inode *h_inode;
4945+
5afbbe0d 4946+ h_inode = au_h_iptr(inode, au_ibtop(inode));
1facf9fc 4947+ fsstack_copy_attr_times(inode, h_inode);
4a4d8108 4948+ fsstack_copy_inode_size(inode, h_inode);
1facf9fc 4949+}
4950+
4951+void au_cpup_attr_nlink(struct inode *inode, int force)
4952+{
4953+ struct inode *h_inode;
4954+ struct super_block *sb;
5afbbe0d 4955+ aufs_bindex_t bindex, bbot;
1facf9fc 4956+
4957+ sb = inode->i_sb;
5afbbe0d 4958+ bindex = au_ibtop(inode);
1facf9fc 4959+ h_inode = au_h_iptr(inode, bindex);
4960+ if (!force
4961+ && !S_ISDIR(h_inode->i_mode)
4962+ && au_opt_test(au_mntflags(sb), PLINK)
4963+ && au_plink_test(inode))
4964+ return;
4965+
7eafdf33
AM
4966+ /*
4967+ * 0 can happen in revalidating.
38d290e6
JR
4968+ * h_inode->i_mutex may not be held here, but it is harmless since once
4969+ * i_nlink reaches 0, it will never become positive except O_TMPFILE
4970+ * case.
4971+ * todo: O_TMPFILE+linkat(AT_SYMLINK_FOLLOW) bypassing aufs may cause
4972+ * the incorrect link count.
7eafdf33 4973+ */
92d182d2 4974+ set_nlink(inode, h_inode->i_nlink);
1facf9fc 4975+
4976+ /*
4977+ * fewer nlink makes find(1) noisy, but larger nlink doesn't.
4978+ * it may includes whplink directory.
4979+ */
4980+ if (S_ISDIR(h_inode->i_mode)) {
5afbbe0d
AM
4981+ bbot = au_ibbot(inode);
4982+ for (bindex++; bindex <= bbot; bindex++) {
1facf9fc 4983+ h_inode = au_h_iptr(inode, bindex);
4984+ if (h_inode)
4985+ au_add_nlink(inode, h_inode);
4986+ }
4987+ }
4988+}
4989+
4990+void au_cpup_attr_changeable(struct inode *inode)
4991+{
4992+ struct inode *h_inode;
4993+
5afbbe0d 4994+ h_inode = au_h_iptr(inode, au_ibtop(inode));
1facf9fc 4995+ inode->i_mode = h_inode->i_mode;
4996+ inode->i_uid = h_inode->i_uid;
4997+ inode->i_gid = h_inode->i_gid;
4998+ au_cpup_attr_timesizes(inode);
86dc4139 4999+ au_cpup_attr_flags(inode, h_inode->i_flags);
1facf9fc 5000+}
5001+
5002+void au_cpup_igen(struct inode *inode, struct inode *h_inode)
5003+{
5004+ struct au_iinfo *iinfo = au_ii(inode);
5005+
1308ab2a 5006+ IiMustWriteLock(inode);
5007+
1facf9fc 5008+ iinfo->ii_higen = h_inode->i_generation;
5009+ iinfo->ii_hsb1 = h_inode->i_sb;
5010+}
5011+
5012+void au_cpup_attr_all(struct inode *inode, int force)
5013+{
5014+ struct inode *h_inode;
5015+
5afbbe0d 5016+ h_inode = au_h_iptr(inode, au_ibtop(inode));
1facf9fc 5017+ au_cpup_attr_changeable(inode);
5018+ if (inode->i_nlink > 0)
5019+ au_cpup_attr_nlink(inode, force);
5020+ inode->i_rdev = h_inode->i_rdev;
5021+ inode->i_blkbits = h_inode->i_blkbits;
5022+ au_cpup_igen(inode, h_inode);
5023+}
5024+
5025+/* ---------------------------------------------------------------------- */
5026+
5027+/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
5028+
5029+/* keep the timestamps of the parent dir when cpup */
5030+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
5031+ struct path *h_path)
5032+{
5033+ struct inode *h_inode;
5034+
5035+ dt->dt_dentry = dentry;
5036+ dt->dt_h_path = *h_path;
5527c038 5037+ h_inode = d_inode(h_path->dentry);
1facf9fc 5038+ dt->dt_atime = h_inode->i_atime;
5039+ dt->dt_mtime = h_inode->i_mtime;
5040+ /* smp_mb(); */
5041+}
5042+
5043+void au_dtime_revert(struct au_dtime *dt)
5044+{
5045+ struct iattr attr;
5046+ int err;
5047+
5048+ attr.ia_atime = dt->dt_atime;
5049+ attr.ia_mtime = dt->dt_mtime;
5050+ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
5051+ | ATTR_ATIME | ATTR_ATIME_SET;
5052+
523b37e3
AM
5053+ /* no delegation since this is a directory */
5054+ err = vfsub_notify_change(&dt->dt_h_path, &attr, /*delegated*/NULL);
1facf9fc 5055+ if (unlikely(err))
0c3ec466 5056+ pr_warn("restoring timestamps failed(%d). ignored\n", err);
1facf9fc 5057+}
5058+
5059+/* ---------------------------------------------------------------------- */
5060+
86dc4139
AM
5061+/* internal use only */
5062+struct au_cpup_reg_attr {
5063+ int valid;
5064+ struct kstat st;
5065+ unsigned int iflags; /* inode->i_flags */
5066+};
5067+
1facf9fc 5068+static noinline_for_stack
86dc4139
AM
5069+int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src,
5070+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 5071+{
c1595e42 5072+ int err, sbits, icex;
7e9cd9fe
AM
5073+ unsigned int mnt_flags;
5074+ unsigned char verbose;
1facf9fc 5075+ struct iattr ia;
5076+ struct path h_path;
1308ab2a 5077+ struct inode *h_isrc, *h_idst;
86dc4139 5078+ struct kstat *h_st;
c1595e42 5079+ struct au_branch *br;
1facf9fc 5080+
5081+ h_path.dentry = au_h_dptr(dst, bindex);
5527c038 5082+ h_idst = d_inode(h_path.dentry);
c1595e42
JR
5083+ br = au_sbr(dst->d_sb, bindex);
5084+ h_path.mnt = au_br_mnt(br);
5527c038 5085+ h_isrc = d_inode(h_src);
1308ab2a 5086+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
1facf9fc 5087+ | ATTR_ATIME | ATTR_MTIME
5088+ | ATTR_ATIME_SET | ATTR_MTIME_SET;
86dc4139
AM
5089+ if (h_src_attr && h_src_attr->valid) {
5090+ h_st = &h_src_attr->st;
5091+ ia.ia_uid = h_st->uid;
5092+ ia.ia_gid = h_st->gid;
5093+ ia.ia_atime = h_st->atime;
5094+ ia.ia_mtime = h_st->mtime;
5095+ if (h_idst->i_mode != h_st->mode
5096+ && !S_ISLNK(h_idst->i_mode)) {
5097+ ia.ia_valid |= ATTR_MODE;
5098+ ia.ia_mode = h_st->mode;
5099+ }
5100+ sbits = !!(h_st->mode & (S_ISUID | S_ISGID));
5101+ au_cpup_attr_flags(h_idst, h_src_attr->iflags);
5102+ } else {
5103+ ia.ia_uid = h_isrc->i_uid;
5104+ ia.ia_gid = h_isrc->i_gid;
5105+ ia.ia_atime = h_isrc->i_atime;
5106+ ia.ia_mtime = h_isrc->i_mtime;
5107+ if (h_idst->i_mode != h_isrc->i_mode
5108+ && !S_ISLNK(h_idst->i_mode)) {
5109+ ia.ia_valid |= ATTR_MODE;
5110+ ia.ia_mode = h_isrc->i_mode;
5111+ }
5112+ sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
5113+ au_cpup_attr_flags(h_idst, h_isrc->i_flags);
1308ab2a 5114+ }
523b37e3
AM
5115+ /* no delegation since it is just created */
5116+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 5117+
5118+ /* is this nfs only? */
5119+ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
5120+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
5121+ ia.ia_mode = h_isrc->i_mode;
523b37e3 5122+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 5123+ }
5124+
c1595e42 5125+ icex = br->br_perm & AuBrAttr_ICEX;
7e9cd9fe
AM
5126+ if (!err) {
5127+ mnt_flags = au_mntflags(dst->d_sb);
5128+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
5129+ err = au_cpup_xattr(h_path.dentry, h_src, icex, verbose);
5130+ }
c1595e42 5131+
1facf9fc 5132+ return err;
5133+}
5134+
5135+/* ---------------------------------------------------------------------- */
5136+
5137+static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
5138+ char *buf, unsigned long blksize)
5139+{
5140+ int err;
5141+ size_t sz, rbytes, wbytes;
5142+ unsigned char all_zero;
5143+ char *p, *zp;
febd17d6 5144+ struct inode *h_inode;
1facf9fc 5145+ /* reduce stack usage */
5146+ struct iattr *ia;
5147+
5148+ zp = page_address(ZERO_PAGE(0));
5149+ if (unlikely(!zp))
5150+ return -ENOMEM; /* possible? */
5151+
5152+ err = 0;
5153+ all_zero = 0;
5154+ while (len) {
5155+ AuDbg("len %lld\n", len);
5156+ sz = blksize;
5157+ if (len < blksize)
5158+ sz = len;
5159+
5160+ rbytes = 0;
5161+ /* todo: signal_pending? */
5162+ while (!rbytes || err == -EAGAIN || err == -EINTR) {
5163+ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
5164+ err = rbytes;
5165+ }
5166+ if (unlikely(err < 0))
5167+ break;
5168+
5169+ all_zero = 0;
5170+ if (len >= rbytes && rbytes == blksize)
5171+ all_zero = !memcmp(buf, zp, rbytes);
5172+ if (!all_zero) {
5173+ wbytes = rbytes;
5174+ p = buf;
5175+ while (wbytes) {
5176+ size_t b;
5177+
5178+ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
5179+ err = b;
5180+ /* todo: signal_pending? */
5181+ if (unlikely(err == -EAGAIN || err == -EINTR))
5182+ continue;
5183+ if (unlikely(err < 0))
5184+ break;
5185+ wbytes -= b;
5186+ p += b;
5187+ }
392086de
AM
5188+ if (unlikely(err < 0))
5189+ break;
1facf9fc 5190+ } else {
5191+ loff_t res;
5192+
5193+ AuLabel(hole);
5194+ res = vfsub_llseek(dst, rbytes, SEEK_CUR);
5195+ err = res;
5196+ if (unlikely(res < 0))
5197+ break;
5198+ }
5199+ len -= rbytes;
5200+ err = 0;
5201+ }
5202+
5203+ /* the last block may be a hole */
5204+ if (!err && all_zero) {
5205+ AuLabel(last hole);
5206+
5207+ err = 1;
2000de60 5208+ if (au_test_nfs(dst->f_path.dentry->d_sb)) {
1facf9fc 5209+ /* nfs requires this step to make last hole */
5210+ /* is this only nfs? */
5211+ do {
5212+ /* todo: signal_pending? */
5213+ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
5214+ } while (err == -EAGAIN || err == -EINTR);
5215+ if (err == 1)
5216+ dst->f_pos--;
5217+ }
5218+
5219+ if (err == 1) {
5220+ ia = (void *)buf;
5221+ ia->ia_size = dst->f_pos;
5222+ ia->ia_valid = ATTR_SIZE | ATTR_FILE;
5223+ ia->ia_file = dst;
febd17d6
JR
5224+ h_inode = file_inode(dst);
5225+ inode_lock_nested(h_inode, AuLsc_I_CHILD2);
523b37e3
AM
5226+ /* no delegation since it is just created */
5227+ err = vfsub_notify_change(&dst->f_path, ia,
5228+ /*delegated*/NULL);
febd17d6 5229+ inode_unlock(h_inode);
1facf9fc 5230+ }
5231+ }
5232+
5233+ return err;
5234+}
5235+
5236+int au_copy_file(struct file *dst, struct file *src, loff_t len)
5237+{
5238+ int err;
5239+ unsigned long blksize;
5240+ unsigned char do_kfree;
5241+ char *buf;
5242+
5243+ err = -ENOMEM;
2000de60 5244+ blksize = dst->f_path.dentry->d_sb->s_blocksize;
1facf9fc 5245+ if (!blksize || PAGE_SIZE < blksize)
5246+ blksize = PAGE_SIZE;
5247+ AuDbg("blksize %lu\n", blksize);
5248+ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
5249+ if (do_kfree)
5250+ buf = kmalloc(blksize, GFP_NOFS);
5251+ else
5252+ buf = (void *)__get_free_page(GFP_NOFS);
5253+ if (unlikely(!buf))
5254+ goto out;
5255+
5256+ if (len > (1 << 22))
5257+ AuDbg("copying a large file %lld\n", (long long)len);
5258+
5259+ src->f_pos = 0;
5260+ dst->f_pos = 0;
5261+ err = au_do_copy_file(dst, src, len, buf, blksize);
5262+ if (do_kfree)
ae9dfd79 5263+ kfree(buf);
1facf9fc 5264+ else
ae9dfd79 5265+ free_page((unsigned long)buf);
1facf9fc 5266+
4f0767ce 5267+out:
1facf9fc 5268+ return err;
5269+}
5270+
5271+/*
5272+ * to support a sparse file which is opened with O_APPEND,
5273+ * we need to close the file.
5274+ */
c2b27bf2 5275+static int au_cp_regular(struct au_cp_generic *cpg)
1facf9fc 5276+{
5277+ int err, i;
5278+ enum { SRC, DST };
5279+ struct {
5280+ aufs_bindex_t bindex;
5281+ unsigned int flags;
5282+ struct dentry *dentry;
392086de 5283+ int force_wr;
1facf9fc 5284+ struct file *file;
523b37e3 5285+ void *label;
1facf9fc 5286+ } *f, file[] = {
5287+ {
c2b27bf2 5288+ .bindex = cpg->bsrc,
1facf9fc 5289+ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
523b37e3 5290+ .label = &&out
1facf9fc 5291+ },
5292+ {
c2b27bf2 5293+ .bindex = cpg->bdst,
1facf9fc 5294+ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
392086de 5295+ .force_wr = !!au_ftest_cpup(cpg->flags, RWDST),
523b37e3 5296+ .label = &&out_src
1facf9fc 5297+ }
5298+ };
ae9dfd79 5299+ struct super_block *sb, *h_src_sb;
e2f27e51 5300+ struct inode *h_src_inode;
8cdd5066 5301+ struct task_struct *tsk = current;
1facf9fc 5302+
5303+ /* bsrc branch can be ro/rw. */
c2b27bf2 5304+ sb = cpg->dentry->d_sb;
1facf9fc 5305+ f = file;
5306+ for (i = 0; i < 2; i++, f++) {
c2b27bf2
AM
5307+ f->dentry = au_h_dptr(cpg->dentry, f->bindex);
5308+ f->file = au_h_open(cpg->dentry, f->bindex, f->flags,
392086de 5309+ /*file*/NULL, f->force_wr);
1facf9fc 5310+ err = PTR_ERR(f->file);
5311+ if (IS_ERR(f->file))
5312+ goto *f->label;
1facf9fc 5313+ }
5314+
5315+ /* try stopping to update while we copyup */
e2f27e51 5316+ h_src_inode = d_inode(file[SRC].dentry);
ae9dfd79
AM
5317+ h_src_sb = h_src_inode->i_sb;
5318+ if (!au_test_nfs(h_src_sb))
e2f27e51 5319+ IMustLock(h_src_inode);
ae9dfd79
AM
5320+
5321+ if (h_src_sb != file_inode(file[DST].file)->i_sb
5322+ || !file[DST].file->f_op->clone_file_range)
5323+ err = au_copy_file(file[DST].file, file[SRC].file, cpg->len);
5324+ else {
5325+ if (!au_test_nfs(h_src_sb)) {
5326+ inode_unlock_shared(h_src_inode);
5327+ err = vfsub_clone_file_range(file[SRC].file,
5328+ file[DST].file, cpg->len);
5329+ vfsub_inode_lock_shared_nested(h_src_inode,
5330+ AuLsc_I_CHILD);
5331+ } else
5332+ err = vfsub_clone_file_range(file[SRC].file,
5333+ file[DST].file, cpg->len);
5334+ if (unlikely(err == -EOPNOTSUPP && au_test_nfs(h_src_sb)))
5335+ /* the backend fs on NFS may not support cloning */
5336+ err = au_copy_file(file[DST].file, file[SRC].file,
5337+ cpg->len);
5338+ AuTraceErr(err);
5339+ }
1facf9fc 5340+
8cdd5066
JR
5341+ /* i wonder if we had O_NO_DELAY_FPUT flag */
5342+ if (tsk->flags & PF_KTHREAD)
5343+ __fput_sync(file[DST].file);
5344+ else {
ae9dfd79 5345+ /* it happend actually */
8cdd5066
JR
5346+ fput(file[DST].file);
5347+ /*
5348+ * too bad.
5349+ * we have to call both since we don't know which place the file
5350+ * was added to.
5351+ */
5352+ task_work_run();
5353+ flush_delayed_fput();
5354+ }
1facf9fc 5355+ au_sbr_put(sb, file[DST].bindex);
523b37e3 5356+
4f0767ce 5357+out_src:
1facf9fc 5358+ fput(file[SRC].file);
5359+ au_sbr_put(sb, file[SRC].bindex);
4f0767ce 5360+out:
1facf9fc 5361+ return err;
5362+}
5363+
c2b27bf2 5364+static int au_do_cpup_regular(struct au_cp_generic *cpg,
86dc4139 5365+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 5366+{
5367+ int err, rerr;
5368+ loff_t l;
86dc4139 5369+ struct path h_path;
38d290e6 5370+ struct inode *h_src_inode, *h_dst_inode;
1facf9fc 5371+
5372+ err = 0;
5527c038 5373+ h_src_inode = au_h_iptr(d_inode(cpg->dentry), cpg->bsrc);
86dc4139 5374+ l = i_size_read(h_src_inode);
c2b27bf2
AM
5375+ if (cpg->len == -1 || l < cpg->len)
5376+ cpg->len = l;
5377+ if (cpg->len) {
86dc4139 5378+ /* try stopping to update while we are referencing */
ae9dfd79 5379+ vfsub_inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD);
c2b27bf2 5380+ au_pin_hdir_unlock(cpg->pin);
1facf9fc 5381+
c2b27bf2
AM
5382+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
5383+ h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc);
86dc4139 5384+ h_src_attr->iflags = h_src_inode->i_flags;
5527c038
JR
5385+ if (!au_test_nfs(h_src_inode->i_sb))
5386+ err = vfs_getattr(&h_path, &h_src_attr->st);
5387+ else {
ae9dfd79 5388+ inode_unlock_shared(h_src_inode);
5527c038 5389+ err = vfs_getattr(&h_path, &h_src_attr->st);
ae9dfd79
AM
5390+ vfsub_inode_lock_shared_nested(h_src_inode,
5391+ AuLsc_I_CHILD);
5527c038 5392+ }
86dc4139 5393+ if (unlikely(err)) {
ae9dfd79 5394+ inode_unlock_shared(h_src_inode);
86dc4139
AM
5395+ goto out;
5396+ }
5397+ h_src_attr->valid = 1;
e2f27e51
AM
5398+ if (!au_test_nfs(h_src_inode->i_sb)) {
5399+ err = au_cp_regular(cpg);
ae9dfd79 5400+ inode_unlock_shared(h_src_inode);
e2f27e51 5401+ } else {
ae9dfd79 5402+ inode_unlock_shared(h_src_inode);
e2f27e51
AM
5403+ err = au_cp_regular(cpg);
5404+ }
c2b27bf2 5405+ rerr = au_pin_hdir_relock(cpg->pin);
86dc4139
AM
5406+ if (!err && rerr)
5407+ err = rerr;
1facf9fc 5408+ }
38d290e6
JR
5409+ if (!err && (h_src_inode->i_state & I_LINKABLE)) {
5410+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bdst);
5527c038 5411+ h_dst_inode = d_inode(h_path.dentry);
38d290e6
JR
5412+ spin_lock(&h_dst_inode->i_lock);
5413+ h_dst_inode->i_state |= I_LINKABLE;
5414+ spin_unlock(&h_dst_inode->i_lock);
5415+ }
1facf9fc 5416+
4f0767ce 5417+out:
1facf9fc 5418+ return err;
5419+}
5420+
5421+static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
5422+ struct inode *h_dir)
5423+{
5424+ int err, symlen;
5425+ mm_segment_t old_fs;
b752ccd1
AM
5426+ union {
5427+ char *k;
5428+ char __user *u;
5429+ } sym;
5527c038
JR
5430+ struct inode *h_inode = d_inode(h_src);
5431+ const struct inode_operations *h_iop = h_inode->i_op;
1facf9fc 5432+
5433+ err = -ENOSYS;
5527c038 5434+ if (unlikely(!h_iop->readlink))
1facf9fc 5435+ goto out;
5436+
5437+ err = -ENOMEM;
537831f9 5438+ sym.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 5439+ if (unlikely(!sym.k))
1facf9fc 5440+ goto out;
5441+
9dbd164d 5442+ /* unnecessary to support mmap_sem since symlink is not mmap-able */
1facf9fc 5443+ old_fs = get_fs();
5444+ set_fs(KERNEL_DS);
5527c038 5445+ symlen = h_iop->readlink(h_src, sym.u, PATH_MAX);
1facf9fc 5446+ err = symlen;
5447+ set_fs(old_fs);
5448+
5449+ if (symlen > 0) {
b752ccd1
AM
5450+ sym.k[symlen] = 0;
5451+ err = vfsub_symlink(h_dir, h_path, sym.k);
1facf9fc 5452+ }
ae9dfd79 5453+ free_page((unsigned long)sym.k);
1facf9fc 5454+
4f0767ce 5455+out:
1facf9fc 5456+ return err;
5457+}
5458+
8cdd5066
JR
5459+/*
5460+ * regardless 'acl' option, reset all ACL.
5461+ * All ACL will be copied up later from the original entry on the lower branch.
5462+ */
5463+static int au_reset_acl(struct inode *h_dir, struct path *h_path, umode_t mode)
5464+{
5465+ int err;
5466+ struct dentry *h_dentry;
5467+ struct inode *h_inode;
5468+
5469+ h_dentry = h_path->dentry;
5470+ h_inode = d_inode(h_dentry);
5471+ /* forget_all_cached_acls(h_inode)); */
5472+ err = vfsub_removexattr(h_dentry, XATTR_NAME_POSIX_ACL_ACCESS);
5473+ AuTraceErr(err);
5474+ if (err == -EOPNOTSUPP)
5475+ err = 0;
5476+ if (!err)
5477+ err = vfsub_acl_chmod(h_inode, mode);
5478+
5479+ AuTraceErr(err);
5480+ return err;
5481+}
5482+
5483+static int au_do_cpup_dir(struct au_cp_generic *cpg, struct dentry *dst_parent,
5484+ struct inode *h_dir, struct path *h_path)
5485+{
5486+ int err;
5487+ struct inode *dir, *inode;
5488+
5489+ err = vfsub_removexattr(h_path->dentry, XATTR_NAME_POSIX_ACL_DEFAULT);
5490+ AuTraceErr(err);
5491+ if (err == -EOPNOTSUPP)
5492+ err = 0;
5493+ if (unlikely(err))
5494+ goto out;
5495+
5496+ /*
5497+ * strange behaviour from the users view,
5498+ * particularry setattr case
5499+ */
5500+ dir = d_inode(dst_parent);
5afbbe0d 5501+ if (au_ibtop(dir) == cpg->bdst)
8cdd5066
JR
5502+ au_cpup_attr_nlink(dir, /*force*/1);
5503+ inode = d_inode(cpg->dentry);
5504+ au_cpup_attr_nlink(inode, /*force*/1);
5505+
5506+out:
5507+ return err;
5508+}
5509+
1facf9fc 5510+static noinline_for_stack
c2b27bf2 5511+int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent,
86dc4139 5512+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 5513+{
5514+ int err;
5515+ umode_t mode;
5516+ unsigned int mnt_flags;
076b876e 5517+ unsigned char isdir, isreg, force;
c2b27bf2 5518+ const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 5519+ struct au_dtime dt;
5520+ struct path h_path;
5521+ struct dentry *h_src, *h_dst, *h_parent;
8cdd5066 5522+ struct inode *h_inode, *h_dir;
1facf9fc 5523+ struct super_block *sb;
5524+
5525+ /* bsrc branch can be ro/rw. */
c2b27bf2 5526+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
5527c038
JR
5527+ h_inode = d_inode(h_src);
5528+ AuDebugOn(h_inode != au_h_iptr(d_inode(cpg->dentry), cpg->bsrc));
1facf9fc 5529+
5530+ /* try stopping to be referenced while we are creating */
c2b27bf2
AM
5531+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
5532+ if (au_ftest_cpup(cpg->flags, RENAME))
86dc4139
AM
5533+ AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX,
5534+ AUFS_WH_PFX_LEN));
1facf9fc 5535+ h_parent = h_dst->d_parent; /* dir inode is locked */
5527c038 5536+ h_dir = d_inode(h_parent);
1facf9fc 5537+ IMustLock(h_dir);
5538+ AuDebugOn(h_parent != h_dst->d_parent);
5539+
c2b27bf2
AM
5540+ sb = cpg->dentry->d_sb;
5541+ h_path.mnt = au_sbr_mnt(sb, cpg->bdst);
1facf9fc 5542+ if (do_dt) {
5543+ h_path.dentry = h_parent;
5544+ au_dtime_store(&dt, dst_parent, &h_path);
5545+ }
5546+ h_path.dentry = h_dst;
5547+
076b876e 5548+ isreg = 0;
1facf9fc 5549+ isdir = 0;
5550+ mode = h_inode->i_mode;
5551+ switch (mode & S_IFMT) {
5552+ case S_IFREG:
076b876e 5553+ isreg = 1;
8cdd5066 5554+ err = vfsub_create(h_dir, &h_path, S_IRUSR | S_IWUSR,
b4510431 5555+ /*want_excl*/true);
1facf9fc 5556+ if (!err)
c2b27bf2 5557+ err = au_do_cpup_regular(cpg, h_src_attr);
1facf9fc 5558+ break;
5559+ case S_IFDIR:
5560+ isdir = 1;
5561+ err = vfsub_mkdir(h_dir, &h_path, mode);
8cdd5066
JR
5562+ if (!err)
5563+ err = au_do_cpup_dir(cpg, dst_parent, h_dir, &h_path);
1facf9fc 5564+ break;
5565+ case S_IFLNK:
5566+ err = au_do_cpup_symlink(&h_path, h_src, h_dir);
5567+ break;
5568+ case S_IFCHR:
5569+ case S_IFBLK:
5570+ AuDebugOn(!capable(CAP_MKNOD));
5571+ /*FALLTHROUGH*/
5572+ case S_IFIFO:
5573+ case S_IFSOCK:
5574+ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
5575+ break;
5576+ default:
5577+ AuIOErr("Unknown inode type 0%o\n", mode);
5578+ err = -EIO;
5579+ }
8cdd5066
JR
5580+ if (!err)
5581+ err = au_reset_acl(h_dir, &h_path, mode);
1facf9fc 5582+
5583+ mnt_flags = au_mntflags(sb);
5584+ if (!au_opt_test(mnt_flags, UDBA_NONE)
5585+ && !isdir
5586+ && au_opt_test(mnt_flags, XINO)
38d290e6
JR
5587+ && (h_inode->i_nlink == 1
5588+ || (h_inode->i_state & I_LINKABLE))
1facf9fc 5589+ /* todo: unnecessary? */
5527c038 5590+ /* && d_inode(cpg->dentry)->i_nlink == 1 */
c2b27bf2
AM
5591+ && cpg->bdst < cpg->bsrc
5592+ && !au_ftest_cpup(cpg->flags, KEEPLINO))
5593+ au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0);
1facf9fc 5594+ /* ignore this error */
5595+
076b876e
AM
5596+ if (!err) {
5597+ force = 0;
5598+ if (isreg) {
5599+ force = !!cpg->len;
5600+ if (cpg->len == -1)
5601+ force = !!i_size_read(h_inode);
5602+ }
5603+ au_fhsm_wrote(sb, cpg->bdst, force);
5604+ }
5605+
1facf9fc 5606+ if (do_dt)
5607+ au_dtime_revert(&dt);
5608+ return err;
5609+}
5610+
392086de 5611+static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path)
86dc4139
AM
5612+{
5613+ int err;
392086de 5614+ struct dentry *dentry, *h_dentry, *h_parent, *parent;
86dc4139 5615+ struct inode *h_dir;
392086de 5616+ aufs_bindex_t bdst;
86dc4139 5617+
392086de
AM
5618+ dentry = cpg->dentry;
5619+ bdst = cpg->bdst;
5620+ h_dentry = au_h_dptr(dentry, bdst);
5621+ if (!au_ftest_cpup(cpg->flags, OVERWRITE)) {
5622+ dget(h_dentry);
5623+ au_set_h_dptr(dentry, bdst, NULL);
5624+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
5625+ if (!err)
5626+ h_path->dentry = dget(au_h_dptr(dentry, bdst));
86dc4139 5627+ au_set_h_dptr(dentry, bdst, h_dentry);
392086de
AM
5628+ } else {
5629+ err = 0;
5630+ parent = dget_parent(dentry);
5631+ h_parent = au_h_dptr(parent, bdst);
5632+ dput(parent);
5633+ h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
5634+ if (IS_ERR(h_path->dentry))
5635+ err = PTR_ERR(h_path->dentry);
86dc4139 5636+ }
392086de
AM
5637+ if (unlikely(err))
5638+ goto out;
86dc4139 5639+
86dc4139 5640+ h_parent = h_dentry->d_parent; /* dir inode is locked */
5527c038 5641+ h_dir = d_inode(h_parent);
86dc4139 5642+ IMustLock(h_dir);
523b37e3
AM
5643+ AuDbg("%pd %pd\n", h_dentry, h_path->dentry);
5644+ /* no delegation since it is just created */
f2c43d5f
AM
5645+ err = vfsub_rename(h_dir, h_dentry, h_dir, h_path, /*delegated*/NULL,
5646+ /*flags*/0);
86dc4139
AM
5647+ dput(h_path->dentry);
5648+
5649+out:
5650+ return err;
5651+}
5652+
1facf9fc 5653+/*
5654+ * copyup the @dentry from @bsrc to @bdst.
5655+ * the caller must set the both of lower dentries.
5656+ * @len is for truncating when it is -1 copyup the entire file.
5657+ * in link/rename cases, @dst_parent may be different from the real one.
c2b27bf2 5658+ * basic->bsrc can be larger than basic->bdst.
f2c43d5f
AM
5659+ * aufs doesn't touch the credential so
5660+ * security_inode_copy_up{,_xattr}() are unnecrssary.
1facf9fc 5661+ */
c2b27bf2 5662+static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 5663+{
5664+ int err, rerr;
5afbbe0d 5665+ aufs_bindex_t old_ibtop;
1facf9fc 5666+ unsigned char isdir, plink;
1facf9fc 5667+ struct dentry *h_src, *h_dst, *h_parent;
5527c038 5668+ struct inode *dst_inode, *h_dir, *inode, *delegated, *src_inode;
1facf9fc 5669+ struct super_block *sb;
86dc4139 5670+ struct au_branch *br;
c2b27bf2
AM
5671+ /* to reuduce stack size */
5672+ struct {
5673+ struct au_dtime dt;
5674+ struct path h_path;
5675+ struct au_cpup_reg_attr h_src_attr;
5676+ } *a;
1facf9fc 5677+
c2b27bf2
AM
5678+ err = -ENOMEM;
5679+ a = kmalloc(sizeof(*a), GFP_NOFS);
5680+ if (unlikely(!a))
5681+ goto out;
5682+ a->h_src_attr.valid = 0;
1facf9fc 5683+
c2b27bf2
AM
5684+ sb = cpg->dentry->d_sb;
5685+ br = au_sbr(sb, cpg->bdst);
5686+ a->h_path.mnt = au_br_mnt(br);
5687+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
1facf9fc 5688+ h_parent = h_dst->d_parent; /* dir inode is locked */
5527c038 5689+ h_dir = d_inode(h_parent);
1facf9fc 5690+ IMustLock(h_dir);
5691+
c2b27bf2 5692+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
5527c038 5693+ inode = d_inode(cpg->dentry);
1facf9fc 5694+
5695+ if (!dst_parent)
c2b27bf2 5696+ dst_parent = dget_parent(cpg->dentry);
1facf9fc 5697+ else
5698+ dget(dst_parent);
5699+
5700+ plink = !!au_opt_test(au_mntflags(sb), PLINK);
c2b27bf2 5701+ dst_inode = au_h_iptr(inode, cpg->bdst);
1facf9fc 5702+ if (dst_inode) {
5703+ if (unlikely(!plink)) {
5704+ err = -EIO;
027c5e7a
AM
5705+ AuIOErr("hi%lu(i%lu) exists on b%d "
5706+ "but plink is disabled\n",
c2b27bf2
AM
5707+ dst_inode->i_ino, inode->i_ino, cpg->bdst);
5708+ goto out_parent;
1facf9fc 5709+ }
5710+
5711+ if (dst_inode->i_nlink) {
c2b27bf2 5712+ const int do_dt = au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 5713+
c2b27bf2 5714+ h_src = au_plink_lkup(inode, cpg->bdst);
1facf9fc 5715+ err = PTR_ERR(h_src);
5716+ if (IS_ERR(h_src))
c2b27bf2 5717+ goto out_parent;
5527c038 5718+ if (unlikely(d_is_negative(h_src))) {
1facf9fc 5719+ err = -EIO;
79b8bda9 5720+ AuIOErr("i%lu exists on b%d "
027c5e7a 5721+ "but not pseudo-linked\n",
79b8bda9 5722+ inode->i_ino, cpg->bdst);
1facf9fc 5723+ dput(h_src);
c2b27bf2 5724+ goto out_parent;
1facf9fc 5725+ }
5726+
5727+ if (do_dt) {
c2b27bf2
AM
5728+ a->h_path.dentry = h_parent;
5729+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
1facf9fc 5730+ }
86dc4139 5731+
c2b27bf2 5732+ a->h_path.dentry = h_dst;
523b37e3
AM
5733+ delegated = NULL;
5734+ err = vfsub_link(h_src, h_dir, &a->h_path, &delegated);
c2b27bf2 5735+ if (!err && au_ftest_cpup(cpg->flags, RENAME))
392086de 5736+ err = au_do_ren_after_cpup(cpg, &a->h_path);
1facf9fc 5737+ if (do_dt)
c2b27bf2 5738+ au_dtime_revert(&a->dt);
523b37e3
AM
5739+ if (unlikely(err == -EWOULDBLOCK)) {
5740+ pr_warn("cannot retry for NFSv4 delegation"
5741+ " for an internal link\n");
5742+ iput(delegated);
5743+ }
1facf9fc 5744+ dput(h_src);
c2b27bf2 5745+ goto out_parent;
1facf9fc 5746+ } else
5747+ /* todo: cpup_wh_file? */
5748+ /* udba work */
4a4d8108 5749+ au_update_ibrange(inode, /*do_put_zero*/1);
1facf9fc 5750+ }
5751+
86dc4139 5752+ isdir = S_ISDIR(inode->i_mode);
5afbbe0d 5753+ old_ibtop = au_ibtop(inode);
c2b27bf2 5754+ err = cpup_entry(cpg, dst_parent, &a->h_src_attr);
1facf9fc 5755+ if (unlikely(err))
86dc4139 5756+ goto out_rev;
5527c038 5757+ dst_inode = d_inode(h_dst);
febd17d6 5758+ inode_lock_nested(dst_inode, AuLsc_I_CHILD2);
86dc4139 5759+ /* todo: necessary? */
c2b27bf2 5760+ /* au_pin_hdir_unlock(cpg->pin); */
1facf9fc 5761+
c2b27bf2 5762+ err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &a->h_src_attr);
86dc4139
AM
5763+ if (unlikely(err)) {
5764+ /* todo: necessary? */
c2b27bf2 5765+ /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */
febd17d6 5766+ inode_unlock(dst_inode);
86dc4139
AM
5767+ goto out_rev;
5768+ }
5769+
5afbbe0d 5770+ if (cpg->bdst < old_ibtop) {
86dc4139 5771+ if (S_ISREG(inode->i_mode)) {
c2b27bf2 5772+ err = au_dy_iaop(inode, cpg->bdst, dst_inode);
86dc4139 5773+ if (unlikely(err)) {
c2b27bf2
AM
5774+ /* ignore an error */
5775+ /* au_pin_hdir_relock(cpg->pin); */
febd17d6 5776+ inode_unlock(dst_inode);
86dc4139 5777+ goto out_rev;
4a4d8108 5778+ }
4a4d8108 5779+ }
5afbbe0d 5780+ au_set_ibtop(inode, cpg->bdst);
c2b27bf2 5781+ } else
5afbbe0d 5782+ au_set_ibbot(inode, cpg->bdst);
c2b27bf2 5783+ au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode),
86dc4139
AM
5784+ au_hi_flags(inode, isdir));
5785+
5786+ /* todo: necessary? */
c2b27bf2 5787+ /* err = au_pin_hdir_relock(cpg->pin); */
febd17d6 5788+ inode_unlock(dst_inode);
86dc4139
AM
5789+ if (unlikely(err))
5790+ goto out_rev;
5791+
5527c038 5792+ src_inode = d_inode(h_src);
86dc4139 5793+ if (!isdir
5527c038
JR
5794+ && (src_inode->i_nlink > 1
5795+ || src_inode->i_state & I_LINKABLE)
86dc4139 5796+ && plink)
c2b27bf2 5797+ au_plink_append(inode, cpg->bdst, h_dst);
86dc4139 5798+
c2b27bf2
AM
5799+ if (au_ftest_cpup(cpg->flags, RENAME)) {
5800+ a->h_path.dentry = h_dst;
392086de 5801+ err = au_do_ren_after_cpup(cpg, &a->h_path);
86dc4139
AM
5802+ }
5803+ if (!err)
c2b27bf2 5804+ goto out_parent; /* success */
1facf9fc 5805+
5806+ /* revert */
4a4d8108 5807+out_rev:
c2b27bf2
AM
5808+ a->h_path.dentry = h_parent;
5809+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
5810+ a->h_path.dentry = h_dst;
86dc4139 5811+ rerr = 0;
5527c038 5812+ if (d_is_positive(h_dst)) {
523b37e3
AM
5813+ if (!isdir) {
5814+ /* no delegation since it is just created */
5815+ rerr = vfsub_unlink(h_dir, &a->h_path,
5816+ /*delegated*/NULL, /*force*/0);
5817+ } else
c2b27bf2 5818+ rerr = vfsub_rmdir(h_dir, &a->h_path);
86dc4139 5819+ }
c2b27bf2 5820+ au_dtime_revert(&a->dt);
1facf9fc 5821+ if (rerr) {
5822+ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
5823+ err = -EIO;
5824+ }
c2b27bf2 5825+out_parent:
1facf9fc 5826+ dput(dst_parent);
ae9dfd79 5827+ kfree(a);
c2b27bf2 5828+out:
1facf9fc 5829+ return err;
5830+}
5831+
7e9cd9fe 5832+#if 0 /* reserved */
1facf9fc 5833+struct au_cpup_single_args {
5834+ int *errp;
c2b27bf2 5835+ struct au_cp_generic *cpg;
1facf9fc 5836+ struct dentry *dst_parent;
5837+};
5838+
5839+static void au_call_cpup_single(void *args)
5840+{
5841+ struct au_cpup_single_args *a = args;
86dc4139 5842+
c2b27bf2
AM
5843+ au_pin_hdir_acquire_nest(a->cpg->pin);
5844+ *a->errp = au_cpup_single(a->cpg, a->dst_parent);
5845+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5846+}
c2b27bf2 5847+#endif
1facf9fc 5848+
53392da6
AM
5849+/*
5850+ * prevent SIGXFSZ in copy-up.
5851+ * testing CAP_MKNOD is for generic fs,
5852+ * but CAP_FSETID is for xfs only, currently.
5853+ */
86dc4139 5854+static int au_cpup_sio_test(struct au_pin *pin, umode_t mode)
53392da6
AM
5855+{
5856+ int do_sio;
86dc4139
AM
5857+ struct super_block *sb;
5858+ struct inode *h_dir;
53392da6
AM
5859+
5860+ do_sio = 0;
86dc4139 5861+ sb = au_pinned_parent(pin)->d_sb;
53392da6
AM
5862+ if (!au_wkq_test()
5863+ && (!au_sbi(sb)->si_plink_maint_pid
5864+ || au_plink_maint(sb, AuLock_NOPLM))) {
5865+ switch (mode & S_IFMT) {
5866+ case S_IFREG:
5867+ /* no condition about RLIMIT_FSIZE and the file size */
5868+ do_sio = 1;
5869+ break;
5870+ case S_IFCHR:
5871+ case S_IFBLK:
5872+ do_sio = !capable(CAP_MKNOD);
5873+ break;
5874+ }
5875+ if (!do_sio)
5876+ do_sio = ((mode & (S_ISUID | S_ISGID))
5877+ && !capable(CAP_FSETID));
86dc4139
AM
5878+ /* this workaround may be removed in the future */
5879+ if (!do_sio) {
5880+ h_dir = au_pinned_h_dir(pin);
5881+ do_sio = h_dir->i_mode & S_ISVTX;
5882+ }
53392da6
AM
5883+ }
5884+
5885+ return do_sio;
5886+}
5887+
7e9cd9fe 5888+#if 0 /* reserved */
c2b27bf2 5889+int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 5890+{
5891+ int err, wkq_err;
1facf9fc 5892+ struct dentry *h_dentry;
5893+
c2b27bf2 5894+ h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
5527c038 5895+ if (!au_cpup_sio_test(pin, d_inode(h_dentry)->i_mode))
c2b27bf2 5896+ err = au_cpup_single(cpg, dst_parent);
1facf9fc 5897+ else {
5898+ struct au_cpup_single_args args = {
5899+ .errp = &err,
c2b27bf2
AM
5900+ .cpg = cpg,
5901+ .dst_parent = dst_parent
1facf9fc 5902+ };
5903+ wkq_err = au_wkq_wait(au_call_cpup_single, &args);
5904+ if (unlikely(wkq_err))
5905+ err = wkq_err;
5906+ }
5907+
5908+ return err;
5909+}
c2b27bf2 5910+#endif
1facf9fc 5911+
5912+/*
5913+ * copyup the @dentry from the first active lower branch to @bdst,
5914+ * using au_cpup_single().
5915+ */
c2b27bf2 5916+static int au_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 5917+{
5918+ int err;
c2b27bf2
AM
5919+ unsigned int flags_orig;
5920+ struct dentry *dentry;
5921+
5922+ AuDebugOn(cpg->bsrc < 0);
1facf9fc 5923+
c2b27bf2 5924+ dentry = cpg->dentry;
86dc4139 5925+ DiMustWriteLock(dentry);
1facf9fc 5926+
c2b27bf2 5927+ err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1);
1facf9fc 5928+ if (!err) {
c2b27bf2
AM
5929+ flags_orig = cpg->flags;
5930+ au_fset_cpup(cpg->flags, RENAME);
5931+ err = au_cpup_single(cpg, NULL);
5932+ cpg->flags = flags_orig;
1facf9fc 5933+ if (!err)
5934+ return 0; /* success */
5935+
5936+ /* revert */
c2b27bf2 5937+ au_set_h_dptr(dentry, cpg->bdst, NULL);
5afbbe0d 5938+ au_set_dbtop(dentry, cpg->bsrc);
1facf9fc 5939+ }
5940+
5941+ return err;
5942+}
5943+
5944+struct au_cpup_simple_args {
5945+ int *errp;
c2b27bf2 5946+ struct au_cp_generic *cpg;
1facf9fc 5947+};
5948+
5949+static void au_call_cpup_simple(void *args)
5950+{
5951+ struct au_cpup_simple_args *a = args;
86dc4139 5952+
c2b27bf2
AM
5953+ au_pin_hdir_acquire_nest(a->cpg->pin);
5954+ *a->errp = au_cpup_simple(a->cpg);
5955+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5956+}
5957+
c2b27bf2 5958+static int au_do_sio_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 5959+{
5960+ int err, wkq_err;
c2b27bf2
AM
5961+ struct dentry *dentry, *parent;
5962+ struct file *h_file;
1facf9fc 5963+ struct inode *h_dir;
5964+
c2b27bf2
AM
5965+ dentry = cpg->dentry;
5966+ h_file = NULL;
5967+ if (au_ftest_cpup(cpg->flags, HOPEN)) {
5968+ AuDebugOn(cpg->bsrc < 0);
392086de 5969+ h_file = au_h_open_pre(dentry, cpg->bsrc, /*force_wr*/0);
c2b27bf2
AM
5970+ err = PTR_ERR(h_file);
5971+ if (IS_ERR(h_file))
5972+ goto out;
5973+ }
5974+
1facf9fc 5975+ parent = dget_parent(dentry);
5527c038 5976+ h_dir = au_h_iptr(d_inode(parent), cpg->bdst);
53392da6 5977+ if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
5527c038 5978+ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode))
c2b27bf2 5979+ err = au_cpup_simple(cpg);
1facf9fc 5980+ else {
5981+ struct au_cpup_simple_args args = {
5982+ .errp = &err,
c2b27bf2 5983+ .cpg = cpg
1facf9fc 5984+ };
5985+ wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
5986+ if (unlikely(wkq_err))
5987+ err = wkq_err;
5988+ }
5989+
5990+ dput(parent);
c2b27bf2
AM
5991+ if (h_file)
5992+ au_h_open_post(dentry, cpg->bsrc, h_file);
5993+
5994+out:
1facf9fc 5995+ return err;
5996+}
5997+
c2b27bf2 5998+int au_sio_cpup_simple(struct au_cp_generic *cpg)
367653fa 5999+{
5afbbe0d 6000+ aufs_bindex_t bsrc, bbot;
c2b27bf2 6001+ struct dentry *dentry, *h_dentry;
367653fa 6002+
c2b27bf2
AM
6003+ if (cpg->bsrc < 0) {
6004+ dentry = cpg->dentry;
5afbbe0d
AM
6005+ bbot = au_dbbot(dentry);
6006+ for (bsrc = cpg->bdst + 1; bsrc <= bbot; bsrc++) {
c2b27bf2
AM
6007+ h_dentry = au_h_dptr(dentry, bsrc);
6008+ if (h_dentry) {
5527c038 6009+ AuDebugOn(d_is_negative(h_dentry));
c2b27bf2
AM
6010+ break;
6011+ }
6012+ }
5afbbe0d 6013+ AuDebugOn(bsrc > bbot);
c2b27bf2 6014+ cpg->bsrc = bsrc;
367653fa 6015+ }
c2b27bf2
AM
6016+ AuDebugOn(cpg->bsrc <= cpg->bdst);
6017+ return au_do_sio_cpup_simple(cpg);
6018+}
367653fa 6019+
c2b27bf2
AM
6020+int au_sio_cpdown_simple(struct au_cp_generic *cpg)
6021+{
6022+ AuDebugOn(cpg->bdst <= cpg->bsrc);
6023+ return au_do_sio_cpup_simple(cpg);
367653fa
AM
6024+}
6025+
1facf9fc 6026+/* ---------------------------------------------------------------------- */
6027+
6028+/*
6029+ * copyup the deleted file for writing.
6030+ */
c2b27bf2
AM
6031+static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry,
6032+ struct file *file)
1facf9fc 6033+{
6034+ int err;
c2b27bf2
AM
6035+ unsigned int flags_orig;
6036+ aufs_bindex_t bsrc_orig;
c2b27bf2 6037+ struct au_dinfo *dinfo;
5afbbe0d
AM
6038+ struct {
6039+ struct au_hdentry *hd;
6040+ struct dentry *h_dentry;
6041+ } hdst, hsrc;
1facf9fc 6042+
c2b27bf2 6043+ dinfo = au_di(cpg->dentry);
1308ab2a 6044+ AuRwMustWriteLock(&dinfo->di_rwsem);
6045+
c2b27bf2 6046+ bsrc_orig = cpg->bsrc;
5afbbe0d
AM
6047+ cpg->bsrc = dinfo->di_btop;
6048+ hdst.hd = au_hdentry(dinfo, cpg->bdst);
6049+ hdst.h_dentry = hdst.hd->hd_dentry;
6050+ hdst.hd->hd_dentry = wh_dentry;
6051+ dinfo->di_btop = cpg->bdst;
6052+
6053+ hsrc.h_dentry = NULL;
027c5e7a 6054+ if (file) {
5afbbe0d
AM
6055+ hsrc.hd = au_hdentry(dinfo, cpg->bsrc);
6056+ hsrc.h_dentry = hsrc.hd->hd_dentry;
6057+ hsrc.hd->hd_dentry = au_hf_top(file)->f_path.dentry;
027c5e7a 6058+ }
c2b27bf2
AM
6059+ flags_orig = cpg->flags;
6060+ cpg->flags = !AuCpup_DTIME;
6061+ err = au_cpup_single(cpg, /*h_parent*/NULL);
6062+ cpg->flags = flags_orig;
027c5e7a
AM
6063+ if (file) {
6064+ if (!err)
6065+ err = au_reopen_nondir(file);
5afbbe0d 6066+ hsrc.hd->hd_dentry = hsrc.h_dentry;
1facf9fc 6067+ }
5afbbe0d
AM
6068+ hdst.hd->hd_dentry = hdst.h_dentry;
6069+ dinfo->di_btop = cpg->bsrc;
c2b27bf2 6070+ cpg->bsrc = bsrc_orig;
1facf9fc 6071+
6072+ return err;
6073+}
6074+
c2b27bf2 6075+static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 6076+{
6077+ int err;
c2b27bf2 6078+ aufs_bindex_t bdst;
1facf9fc 6079+ struct au_dtime dt;
c2b27bf2 6080+ struct dentry *dentry, *parent, *h_parent, *wh_dentry;
1facf9fc 6081+ struct au_branch *br;
6082+ struct path h_path;
6083+
c2b27bf2
AM
6084+ dentry = cpg->dentry;
6085+ bdst = cpg->bdst;
1facf9fc 6086+ br = au_sbr(dentry->d_sb, bdst);
6087+ parent = dget_parent(dentry);
6088+ h_parent = au_h_dptr(parent, bdst);
6089+ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
6090+ err = PTR_ERR(wh_dentry);
6091+ if (IS_ERR(wh_dentry))
6092+ goto out;
6093+
6094+ h_path.dentry = h_parent;
86dc4139 6095+ h_path.mnt = au_br_mnt(br);
1facf9fc 6096+ au_dtime_store(&dt, parent, &h_path);
c2b27bf2 6097+ err = au_do_cpup_wh(cpg, wh_dentry, file);
1facf9fc 6098+ if (unlikely(err))
6099+ goto out_wh;
6100+
6101+ dget(wh_dentry);
6102+ h_path.dentry = wh_dentry;
2000de60 6103+ if (!d_is_dir(wh_dentry)) {
523b37e3 6104+ /* no delegation since it is just created */
5527c038 6105+ err = vfsub_unlink(d_inode(h_parent), &h_path,
523b37e3
AM
6106+ /*delegated*/NULL, /*force*/0);
6107+ } else
5527c038 6108+ err = vfsub_rmdir(d_inode(h_parent), &h_path);
1facf9fc 6109+ if (unlikely(err)) {
523b37e3
AM
6110+ AuIOErr("failed remove copied-up tmp file %pd(%d)\n",
6111+ wh_dentry, err);
1facf9fc 6112+ err = -EIO;
6113+ }
6114+ au_dtime_revert(&dt);
5527c038 6115+ au_set_hi_wh(d_inode(dentry), bdst, wh_dentry);
1facf9fc 6116+
4f0767ce 6117+out_wh:
1facf9fc 6118+ dput(wh_dentry);
4f0767ce 6119+out:
1facf9fc 6120+ dput(parent);
6121+ return err;
6122+}
6123+
6124+struct au_cpup_wh_args {
6125+ int *errp;
c2b27bf2 6126+ struct au_cp_generic *cpg;
1facf9fc 6127+ struct file *file;
6128+};
6129+
6130+static void au_call_cpup_wh(void *args)
6131+{
6132+ struct au_cpup_wh_args *a = args;
86dc4139 6133+
c2b27bf2
AM
6134+ au_pin_hdir_acquire_nest(a->cpg->pin);
6135+ *a->errp = au_cpup_wh(a->cpg, a->file);
6136+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 6137+}
6138+
c2b27bf2 6139+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 6140+{
6141+ int err, wkq_err;
c2b27bf2 6142+ aufs_bindex_t bdst;
c1595e42 6143+ struct dentry *dentry, *parent, *h_orph, *h_parent;
86dc4139 6144+ struct inode *dir, *h_dir, *h_tmpdir;
1facf9fc 6145+ struct au_wbr *wbr;
c2b27bf2 6146+ struct au_pin wh_pin, *pin_orig;
1facf9fc 6147+
c2b27bf2
AM
6148+ dentry = cpg->dentry;
6149+ bdst = cpg->bdst;
1facf9fc 6150+ parent = dget_parent(dentry);
5527c038 6151+ dir = d_inode(parent);
1facf9fc 6152+ h_orph = NULL;
6153+ h_parent = NULL;
6154+ h_dir = au_igrab(au_h_iptr(dir, bdst));
6155+ h_tmpdir = h_dir;
c2b27bf2 6156+ pin_orig = NULL;
1facf9fc 6157+ if (!h_dir->i_nlink) {
6158+ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
6159+ h_orph = wbr->wbr_orph;
6160+
6161+ h_parent = dget(au_h_dptr(parent, bdst));
1facf9fc 6162+ au_set_h_dptr(parent, bdst, dget(h_orph));
5527c038 6163+ h_tmpdir = d_inode(h_orph);
1facf9fc 6164+ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
6165+
febd17d6 6166+ inode_lock_nested(h_tmpdir, AuLsc_I_PARENT3);
4a4d8108 6167+ /* todo: au_h_open_pre()? */
86dc4139 6168+
c2b27bf2 6169+ pin_orig = cpg->pin;
86dc4139 6170+ au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT,
c2b27bf2
AM
6171+ AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED);
6172+ cpg->pin = &wh_pin;
1facf9fc 6173+ }
6174+
53392da6 6175+ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
5527c038 6176+ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode))
c2b27bf2 6177+ err = au_cpup_wh(cpg, file);
1facf9fc 6178+ else {
6179+ struct au_cpup_wh_args args = {
6180+ .errp = &err,
c2b27bf2
AM
6181+ .cpg = cpg,
6182+ .file = file
1facf9fc 6183+ };
6184+ wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
6185+ if (unlikely(wkq_err))
6186+ err = wkq_err;
6187+ }
6188+
6189+ if (h_orph) {
febd17d6 6190+ inode_unlock(h_tmpdir);
4a4d8108 6191+ /* todo: au_h_open_post()? */
1facf9fc 6192+ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
1facf9fc 6193+ au_set_h_dptr(parent, bdst, h_parent);
c2b27bf2
AM
6194+ AuDebugOn(!pin_orig);
6195+ cpg->pin = pin_orig;
1facf9fc 6196+ }
6197+ iput(h_dir);
6198+ dput(parent);
6199+
6200+ return err;
6201+}
6202+
6203+/* ---------------------------------------------------------------------- */
6204+
6205+/*
6206+ * generic routine for both of copy-up and copy-down.
6207+ */
6208+/* cf. revalidate function in file.c */
6209+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
6210+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 6211+ struct au_pin *pin,
1facf9fc 6212+ struct dentry *h_parent, void *arg),
6213+ void *arg)
6214+{
6215+ int err;
6216+ struct au_pin pin;
5527c038 6217+ struct dentry *d, *parent, *h_parent, *real_parent, *h_dentry;
1facf9fc 6218+
6219+ err = 0;
6220+ parent = dget_parent(dentry);
6221+ if (IS_ROOT(parent))
6222+ goto out;
6223+
6224+ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
6225+ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
6226+
6227+ /* do not use au_dpage */
6228+ real_parent = parent;
6229+ while (1) {
6230+ dput(parent);
6231+ parent = dget_parent(dentry);
6232+ h_parent = au_h_dptr(parent, bdst);
6233+ if (h_parent)
6234+ goto out; /* success */
6235+
6236+ /* find top dir which is necessary to cpup */
6237+ do {
6238+ d = parent;
6239+ dput(parent);
6240+ parent = dget_parent(d);
6241+ di_read_lock_parent3(parent, !AuLock_IR);
6242+ h_parent = au_h_dptr(parent, bdst);
6243+ di_read_unlock(parent, !AuLock_IR);
6244+ } while (!h_parent);
6245+
6246+ if (d != real_parent)
6247+ di_write_lock_child3(d);
6248+
6249+ /* somebody else might create while we were sleeping */
5527c038
JR
6250+ h_dentry = au_h_dptr(d, bdst);
6251+ if (!h_dentry || d_is_negative(h_dentry)) {
6252+ if (h_dentry)
5afbbe0d 6253+ au_update_dbtop(d);
1facf9fc 6254+
6255+ au_pin_set_dentry(&pin, d);
6256+ err = au_do_pin(&pin);
6257+ if (!err) {
86dc4139 6258+ err = cp(d, bdst, &pin, h_parent, arg);
1facf9fc 6259+ au_unpin(&pin);
6260+ }
6261+ }
6262+
6263+ if (d != real_parent)
6264+ di_write_unlock(d);
6265+ if (unlikely(err))
6266+ break;
6267+ }
6268+
4f0767ce 6269+out:
1facf9fc 6270+ dput(parent);
6271+ return err;
6272+}
6273+
6274+static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 6275+ struct au_pin *pin,
2000de60 6276+ struct dentry *h_parent __maybe_unused,
1facf9fc 6277+ void *arg __maybe_unused)
6278+{
c2b27bf2
AM
6279+ struct au_cp_generic cpg = {
6280+ .dentry = dentry,
6281+ .bdst = bdst,
6282+ .bsrc = -1,
6283+ .len = 0,
6284+ .pin = pin,
6285+ .flags = AuCpup_DTIME
6286+ };
6287+ return au_sio_cpup_simple(&cpg);
1facf9fc 6288+}
6289+
6290+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
6291+{
6292+ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
6293+}
6294+
6295+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
6296+{
6297+ int err;
6298+ struct dentry *parent;
6299+ struct inode *dir;
6300+
6301+ parent = dget_parent(dentry);
5527c038 6302+ dir = d_inode(parent);
1facf9fc 6303+ err = 0;
6304+ if (au_h_iptr(dir, bdst))
6305+ goto out;
6306+
6307+ di_read_unlock(parent, AuLock_IR);
6308+ di_write_lock_parent(parent);
6309+ /* someone else might change our inode while we were sleeping */
6310+ if (!au_h_iptr(dir, bdst))
6311+ err = au_cpup_dirs(dentry, bdst);
6312+ di_downgrade_lock(parent, AuLock_IR);
6313+
4f0767ce 6314+out:
1facf9fc 6315+ dput(parent);
6316+ return err;
6317+}
7f207e10
AM
6318diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
6319--- /usr/share/empty/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
6320+++ linux/fs/aufs/cpup.h 2018-04-15 08:49:13.397817296 +0200
6321@@ -0,0 +1,99 @@
1facf9fc 6322+/*
ae9dfd79 6323+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 6324+ *
6325+ * This program, aufs is free software; you can redistribute it and/or modify
6326+ * it under the terms of the GNU General Public License as published by
6327+ * the Free Software Foundation; either version 2 of the License, or
6328+ * (at your option) any later version.
dece6358
AM
6329+ *
6330+ * This program is distributed in the hope that it will be useful,
6331+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6332+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6333+ * GNU General Public License for more details.
6334+ *
6335+ * You should have received a copy of the GNU General Public License
523b37e3 6336+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6337+ */
6338+
6339+/*
6340+ * copy-up/down functions
6341+ */
6342+
6343+#ifndef __AUFS_CPUP_H__
6344+#define __AUFS_CPUP_H__
6345+
6346+#ifdef __KERNEL__
6347+
dece6358 6348+#include <linux/path.h>
1facf9fc 6349+
dece6358
AM
6350+struct inode;
6351+struct file;
86dc4139 6352+struct au_pin;
dece6358 6353+
86dc4139 6354+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags);
1facf9fc 6355+void au_cpup_attr_timesizes(struct inode *inode);
6356+void au_cpup_attr_nlink(struct inode *inode, int force);
6357+void au_cpup_attr_changeable(struct inode *inode);
6358+void au_cpup_igen(struct inode *inode, struct inode *h_inode);
6359+void au_cpup_attr_all(struct inode *inode, int force);
6360+
6361+/* ---------------------------------------------------------------------- */
6362+
c2b27bf2
AM
6363+struct au_cp_generic {
6364+ struct dentry *dentry;
6365+ aufs_bindex_t bdst, bsrc;
6366+ loff_t len;
6367+ struct au_pin *pin;
6368+ unsigned int flags;
6369+};
6370+
1facf9fc 6371+/* cpup flags */
392086de
AM
6372+#define AuCpup_DTIME 1 /* do dtime_store/revert */
6373+#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino,
6374+ for link(2) */
6375+#define AuCpup_RENAME (1 << 2) /* rename after cpup */
6376+#define AuCpup_HOPEN (1 << 3) /* call h_open_pre/post() in
6377+ cpup */
6378+#define AuCpup_OVERWRITE (1 << 4) /* allow overwriting the
6379+ existing entry */
6380+#define AuCpup_RWDST (1 << 5) /* force write target even if
6381+ the branch is marked as RO */
c2b27bf2 6382+
ae9dfd79
AM
6383+#ifndef CONFIG_AUFS_BR_HFSPLUS
6384+#undef AuCpup_HOPEN
6385+#define AuCpup_HOPEN 0
6386+#endif
6387+
1facf9fc 6388+#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name)
7f207e10
AM
6389+#define au_fset_cpup(flags, name) \
6390+ do { (flags) |= AuCpup_##name; } while (0)
6391+#define au_fclr_cpup(flags, name) \
6392+ do { (flags) &= ~AuCpup_##name; } while (0)
1facf9fc 6393+
6394+int au_copy_file(struct file *dst, struct file *src, loff_t len);
c2b27bf2
AM
6395+int au_sio_cpup_simple(struct au_cp_generic *cpg);
6396+int au_sio_cpdown_simple(struct au_cp_generic *cpg);
6397+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file);
1facf9fc 6398+
6399+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
6400+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 6401+ struct au_pin *pin,
1facf9fc 6402+ struct dentry *h_parent, void *arg),
6403+ void *arg);
6404+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
6405+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
6406+
6407+/* ---------------------------------------------------------------------- */
6408+
6409+/* keep timestamps when copyup */
6410+struct au_dtime {
6411+ struct dentry *dt_dentry;
6412+ struct path dt_h_path;
6413+ struct timespec dt_atime, dt_mtime;
6414+};
6415+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
6416+ struct path *h_path);
6417+void au_dtime_revert(struct au_dtime *dt);
6418+
6419+#endif /* __KERNEL__ */
6420+#endif /* __AUFS_CPUP_H__ */
7f207e10
AM
6421diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
6422--- /usr/share/empty/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
6423+++ linux/fs/aufs/dbgaufs.c 2018-04-15 08:49:13.397817296 +0200
6424@@ -0,0 +1,437 @@
1facf9fc 6425+/*
ae9dfd79 6426+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 6427+ *
6428+ * This program, aufs is free software; you can redistribute it and/or modify
6429+ * it under the terms of the GNU General Public License as published by
6430+ * the Free Software Foundation; either version 2 of the License, or
6431+ * (at your option) any later version.
dece6358
AM
6432+ *
6433+ * This program is distributed in the hope that it will be useful,
6434+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6435+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6436+ * GNU General Public License for more details.
6437+ *
6438+ * You should have received a copy of the GNU General Public License
523b37e3 6439+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6440+ */
6441+
6442+/*
6443+ * debugfs interface
6444+ */
6445+
6446+#include <linux/debugfs.h>
6447+#include "aufs.h"
6448+
6449+#ifndef CONFIG_SYSFS
6450+#error DEBUG_FS depends upon SYSFS
6451+#endif
6452+
6453+static struct dentry *dbgaufs;
6454+static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
6455+
6456+/* 20 is max digits length of ulong 64 */
6457+struct dbgaufs_arg {
6458+ int n;
6459+ char a[20 * 4];
6460+};
6461+
6462+/*
6463+ * common function for all XINO files
6464+ */
6465+static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
6466+ struct file *file)
6467+{
ae9dfd79 6468+ kfree(file->private_data);
1facf9fc 6469+ return 0;
6470+}
6471+
6472+static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
6473+{
6474+ int err;
6475+ struct kstat st;
6476+ struct dbgaufs_arg *p;
6477+
6478+ err = -ENOMEM;
6479+ p = kmalloc(sizeof(*p), GFP_NOFS);
6480+ if (unlikely(!p))
6481+ goto out;
6482+
6483+ err = 0;
6484+ p->n = 0;
6485+ file->private_data = p;
6486+ if (!xf)
6487+ goto out;
6488+
c06a8ce3 6489+ err = vfs_getattr(&xf->f_path, &st);
1facf9fc 6490+ if (!err) {
6491+ if (do_fcnt)
6492+ p->n = snprintf
6493+ (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n",
6494+ (long)file_count(xf), st.blocks, st.blksize,
6495+ (long long)st.size);
6496+ else
6497+ p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n",
6498+ st.blocks, st.blksize,
6499+ (long long)st.size);
6500+ AuDebugOn(p->n >= sizeof(p->a));
6501+ } else {
6502+ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
6503+ err = 0;
6504+ }
6505+
4f0767ce 6506+out:
1facf9fc 6507+ return err;
6508+
6509+}
6510+
6511+static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
6512+ size_t count, loff_t *ppos)
6513+{
6514+ struct dbgaufs_arg *p;
6515+
6516+ p = file->private_data;
6517+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
6518+}
6519+
6520+/* ---------------------------------------------------------------------- */
6521+
86dc4139
AM
6522+struct dbgaufs_plink_arg {
6523+ int n;
6524+ char a[];
6525+};
6526+
6527+static int dbgaufs_plink_release(struct inode *inode __maybe_unused,
6528+ struct file *file)
6529+{
ae9dfd79 6530+ free_page((unsigned long)file->private_data);
86dc4139
AM
6531+ return 0;
6532+}
6533+
6534+static int dbgaufs_plink_open(struct inode *inode, struct file *file)
6535+{
6536+ int err, i, limit;
6537+ unsigned long n, sum;
6538+ struct dbgaufs_plink_arg *p;
6539+ struct au_sbinfo *sbinfo;
6540+ struct super_block *sb;
ae9dfd79 6541+ struct hlist_bl_head *hbl;
86dc4139
AM
6542+
6543+ err = -ENOMEM;
6544+ p = (void *)get_zeroed_page(GFP_NOFS);
6545+ if (unlikely(!p))
6546+ goto out;
6547+
6548+ err = -EFBIG;
6549+ sbinfo = inode->i_private;
6550+ sb = sbinfo->si_sb;
6551+ si_noflush_read_lock(sb);
6552+ if (au_opt_test(au_mntflags(sb), PLINK)) {
6553+ limit = PAGE_SIZE - sizeof(p->n);
6554+
6555+ /* the number of buckets */
6556+ n = snprintf(p->a + p->n, limit, "%d\n", AuPlink_NHASH);
6557+ p->n += n;
6558+ limit -= n;
6559+
6560+ sum = 0;
ae9dfd79
AM
6561+ for (i = 0, hbl = sbinfo->si_plink; i < AuPlink_NHASH;
6562+ i++, hbl++) {
6563+ n = au_hbl_count(hbl);
86dc4139
AM
6564+ sum += n;
6565+
6566+ n = snprintf(p->a + p->n, limit, "%lu ", n);
6567+ p->n += n;
6568+ limit -= n;
6569+ if (unlikely(limit <= 0))
6570+ goto out_free;
6571+ }
6572+ p->a[p->n - 1] = '\n';
6573+
6574+ /* the sum of plinks */
6575+ n = snprintf(p->a + p->n, limit, "%lu\n", sum);
6576+ p->n += n;
6577+ limit -= n;
6578+ if (unlikely(limit <= 0))
6579+ goto out_free;
6580+ } else {
6581+#define str "1\n0\n0\n"
6582+ p->n = sizeof(str) - 1;
6583+ strcpy(p->a, str);
6584+#undef str
6585+ }
6586+ si_read_unlock(sb);
6587+
6588+ err = 0;
6589+ file->private_data = p;
6590+ goto out; /* success */
6591+
6592+out_free:
ae9dfd79 6593+ free_page((unsigned long)p);
86dc4139
AM
6594+out:
6595+ return err;
6596+}
6597+
6598+static ssize_t dbgaufs_plink_read(struct file *file, char __user *buf,
6599+ size_t count, loff_t *ppos)
6600+{
6601+ struct dbgaufs_plink_arg *p;
6602+
6603+ p = file->private_data;
6604+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
6605+}
6606+
6607+static const struct file_operations dbgaufs_plink_fop = {
6608+ .owner = THIS_MODULE,
6609+ .open = dbgaufs_plink_open,
6610+ .release = dbgaufs_plink_release,
6611+ .read = dbgaufs_plink_read
6612+};
6613+
6614+/* ---------------------------------------------------------------------- */
6615+
1facf9fc 6616+static int dbgaufs_xib_open(struct inode *inode, struct file *file)
6617+{
6618+ int err;
6619+ struct au_sbinfo *sbinfo;
6620+ struct super_block *sb;
6621+
6622+ sbinfo = inode->i_private;
6623+ sb = sbinfo->si_sb;
6624+ si_noflush_read_lock(sb);
6625+ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0);
6626+ si_read_unlock(sb);
6627+ return err;
6628+}
6629+
6630+static const struct file_operations dbgaufs_xib_fop = {
4a4d8108 6631+ .owner = THIS_MODULE,
1facf9fc 6632+ .open = dbgaufs_xib_open,
6633+ .release = dbgaufs_xi_release,
6634+ .read = dbgaufs_xi_read
6635+};
6636+
6637+/* ---------------------------------------------------------------------- */
6638+
6639+#define DbgaufsXi_PREFIX "xi"
6640+
6641+static int dbgaufs_xino_open(struct inode *inode, struct file *file)
6642+{
6643+ int err;
6644+ long l;
6645+ struct au_sbinfo *sbinfo;
6646+ struct super_block *sb;
6647+ struct file *xf;
6648+ struct qstr *name;
6649+
6650+ err = -ENOENT;
6651+ xf = NULL;
2000de60 6652+ name = &file->f_path.dentry->d_name;
1facf9fc 6653+ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
6654+ || memcmp(name->name, DbgaufsXi_PREFIX,
6655+ sizeof(DbgaufsXi_PREFIX) - 1)))
6656+ goto out;
9dbd164d 6657+ err = kstrtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
1facf9fc 6658+ if (unlikely(err))
6659+ goto out;
6660+
6661+ sbinfo = inode->i_private;
6662+ sb = sbinfo->si_sb;
6663+ si_noflush_read_lock(sb);
5afbbe0d 6664+ if (l <= au_sbbot(sb)) {
1facf9fc 6665+ xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file;
6666+ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1);
6667+ } else
6668+ err = -ENOENT;
6669+ si_read_unlock(sb);
6670+
4f0767ce 6671+out:
1facf9fc 6672+ return err;
6673+}
6674+
6675+static const struct file_operations dbgaufs_xino_fop = {
4a4d8108 6676+ .owner = THIS_MODULE,
1facf9fc 6677+ .open = dbgaufs_xino_open,
6678+ .release = dbgaufs_xi_release,
6679+ .read = dbgaufs_xi_read
6680+};
6681+
6682+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
6683+{
5afbbe0d 6684+ aufs_bindex_t bbot;
1facf9fc 6685+ struct au_branch *br;
6686+ struct au_xino_file *xi;
6687+
6688+ if (!au_sbi(sb)->si_dbgaufs)
6689+ return;
6690+
5afbbe0d
AM
6691+ bbot = au_sbbot(sb);
6692+ for (; bindex <= bbot; bindex++) {
1facf9fc 6693+ br = au_sbr(sb, bindex);
6694+ xi = &br->br_xino;
e2f27e51
AM
6695+ /* debugfs acquires the parent i_mutex */
6696+ lockdep_off();
c06a8ce3 6697+ debugfs_remove(xi->xi_dbgaufs);
e2f27e51 6698+ lockdep_on();
c06a8ce3 6699+ xi->xi_dbgaufs = NULL;
1facf9fc 6700+ }
6701+}
6702+
6703+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
6704+{
6705+ struct au_sbinfo *sbinfo;
6706+ struct dentry *parent;
6707+ struct au_branch *br;
6708+ struct au_xino_file *xi;
5afbbe0d 6709+ aufs_bindex_t bbot;
1facf9fc 6710+ char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */
6711+
6712+ sbinfo = au_sbi(sb);
6713+ parent = sbinfo->si_dbgaufs;
6714+ if (!parent)
6715+ return;
6716+
5afbbe0d
AM
6717+ bbot = au_sbbot(sb);
6718+ for (; bindex <= bbot; bindex++) {
1facf9fc 6719+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
6720+ br = au_sbr(sb, bindex);
6721+ xi = &br->br_xino;
6722+ AuDebugOn(xi->xi_dbgaufs);
f0c0a007
AM
6723+ /* debugfs acquires the parent i_mutex */
6724+ lockdep_off();
1facf9fc 6725+ xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
6726+ sbinfo, &dbgaufs_xino_fop);
f0c0a007 6727+ lockdep_on();
1facf9fc 6728+ /* ignore an error */
6729+ if (unlikely(!xi->xi_dbgaufs))
6730+ AuWarn1("failed %s under debugfs\n", name);
6731+ }
6732+}
6733+
6734+/* ---------------------------------------------------------------------- */
6735+
6736+#ifdef CONFIG_AUFS_EXPORT
6737+static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
6738+{
6739+ int err;
6740+ struct au_sbinfo *sbinfo;
6741+ struct super_block *sb;
6742+
6743+ sbinfo = inode->i_private;
6744+ sb = sbinfo->si_sb;
6745+ si_noflush_read_lock(sb);
6746+ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0);
6747+ si_read_unlock(sb);
6748+ return err;
6749+}
6750+
6751+static const struct file_operations dbgaufs_xigen_fop = {
4a4d8108 6752+ .owner = THIS_MODULE,
1facf9fc 6753+ .open = dbgaufs_xigen_open,
6754+ .release = dbgaufs_xi_release,
6755+ .read = dbgaufs_xi_read
6756+};
6757+
6758+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
6759+{
6760+ int err;
6761+
dece6358 6762+ /*
c1595e42 6763+ * This function is a dynamic '__init' function actually,
dece6358
AM
6764+ * so the tiny check for si_rwsem is unnecessary.
6765+ */
6766+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6767+
1facf9fc 6768+ err = -EIO;
6769+ sbinfo->si_dbgaufs_xigen = debugfs_create_file
6770+ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6771+ &dbgaufs_xigen_fop);
6772+ if (sbinfo->si_dbgaufs_xigen)
6773+ err = 0;
6774+
6775+ return err;
6776+}
6777+#else
6778+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
6779+{
6780+ return 0;
6781+}
6782+#endif /* CONFIG_AUFS_EXPORT */
6783+
6784+/* ---------------------------------------------------------------------- */
6785+
6786+void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
6787+{
dece6358 6788+ /*
7e9cd9fe 6789+ * This function is a dynamic '__fin' function actually,
dece6358
AM
6790+ * so the tiny check for si_rwsem is unnecessary.
6791+ */
6792+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6793+
1facf9fc 6794+ debugfs_remove_recursive(sbinfo->si_dbgaufs);
6795+ sbinfo->si_dbgaufs = NULL;
6796+ kobject_put(&sbinfo->si_kobj);
6797+}
6798+
6799+int dbgaufs_si_init(struct au_sbinfo *sbinfo)
6800+{
6801+ int err;
6802+ char name[SysaufsSiNameLen];
6803+
dece6358 6804+ /*
c1595e42 6805+ * This function is a dynamic '__init' function actually,
dece6358
AM
6806+ * so the tiny check for si_rwsem is unnecessary.
6807+ */
6808+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6809+
1facf9fc 6810+ err = -ENOENT;
6811+ if (!dbgaufs) {
6812+ AuErr1("/debug/aufs is uninitialized\n");
6813+ goto out;
6814+ }
6815+
6816+ err = -EIO;
6817+ sysaufs_name(sbinfo, name);
6818+ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
6819+ if (unlikely(!sbinfo->si_dbgaufs))
6820+ goto out;
6821+ kobject_get(&sbinfo->si_kobj);
6822+
6823+ sbinfo->si_dbgaufs_xib = debugfs_create_file
6824+ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6825+ &dbgaufs_xib_fop);
6826+ if (unlikely(!sbinfo->si_dbgaufs_xib))
6827+ goto out_dir;
6828+
86dc4139
AM
6829+ sbinfo->si_dbgaufs_plink = debugfs_create_file
6830+ ("plink", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6831+ &dbgaufs_plink_fop);
6832+ if (unlikely(!sbinfo->si_dbgaufs_plink))
6833+ goto out_dir;
6834+
1facf9fc 6835+ err = dbgaufs_xigen_init(sbinfo);
6836+ if (!err)
6837+ goto out; /* success */
6838+
4f0767ce 6839+out_dir:
1facf9fc 6840+ dbgaufs_si_fin(sbinfo);
4f0767ce 6841+out:
1facf9fc 6842+ return err;
6843+}
6844+
6845+/* ---------------------------------------------------------------------- */
6846+
6847+void dbgaufs_fin(void)
6848+{
6849+ debugfs_remove(dbgaufs);
6850+}
6851+
6852+int __init dbgaufs_init(void)
6853+{
6854+ int err;
6855+
6856+ err = -EIO;
6857+ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
6858+ if (dbgaufs)
6859+ err = 0;
6860+ return err;
6861+}
7f207e10
AM
6862diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
6863--- /usr/share/empty/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 6864+++ linux/fs/aufs/dbgaufs.h 2018-04-15 08:49:13.397817296 +0200
523b37e3 6865@@ -0,0 +1,48 @@
1facf9fc 6866+/*
ae9dfd79 6867+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 6868+ *
6869+ * This program, aufs is free software; you can redistribute it and/or modify
6870+ * it under the terms of the GNU General Public License as published by
6871+ * the Free Software Foundation; either version 2 of the License, or
6872+ * (at your option) any later version.
dece6358
AM
6873+ *
6874+ * This program is distributed in the hope that it will be useful,
6875+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6876+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6877+ * GNU General Public License for more details.
6878+ *
6879+ * You should have received a copy of the GNU General Public License
523b37e3 6880+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6881+ */
6882+
6883+/*
6884+ * debugfs interface
6885+ */
6886+
6887+#ifndef __DBGAUFS_H__
6888+#define __DBGAUFS_H__
6889+
6890+#ifdef __KERNEL__
6891+
dece6358 6892+struct super_block;
1facf9fc 6893+struct au_sbinfo;
dece6358 6894+
1facf9fc 6895+#ifdef CONFIG_DEBUG_FS
6896+/* dbgaufs.c */
6897+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
6898+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
6899+void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
6900+int dbgaufs_si_init(struct au_sbinfo *sbinfo);
6901+void dbgaufs_fin(void);
6902+int __init dbgaufs_init(void);
1facf9fc 6903+#else
4a4d8108
AM
6904+AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
6905+AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
6906+AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
6907+AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
6908+AuStubVoid(dbgaufs_fin, void)
6909+AuStubInt0(__init dbgaufs_init, void)
1facf9fc 6910+#endif /* CONFIG_DEBUG_FS */
6911+
6912+#endif /* __KERNEL__ */
6913+#endif /* __DBGAUFS_H__ */
7f207e10
AM
6914diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
6915--- /usr/share/empty/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 6916+++ linux/fs/aufs/dcsub.c 2018-04-15 08:49:13.397817296 +0200
e2f27e51 6917@@ -0,0 +1,225 @@
1facf9fc 6918+/*
ae9dfd79 6919+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 6920+ *
6921+ * This program, aufs is free software; you can redistribute it and/or modify
6922+ * it under the terms of the GNU General Public License as published by
6923+ * the Free Software Foundation; either version 2 of the License, or
6924+ * (at your option) any later version.
dece6358
AM
6925+ *
6926+ * This program is distributed in the hope that it will be useful,
6927+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6928+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6929+ * GNU General Public License for more details.
6930+ *
6931+ * You should have received a copy of the GNU General Public License
523b37e3 6932+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6933+ */
6934+
6935+/*
6936+ * sub-routines for dentry cache
6937+ */
6938+
6939+#include "aufs.h"
6940+
6941+static void au_dpage_free(struct au_dpage *dpage)
6942+{
6943+ int i;
6944+ struct dentry **p;
6945+
6946+ p = dpage->dentries;
6947+ for (i = 0; i < dpage->ndentry; i++)
6948+ dput(*p++);
ae9dfd79 6949+ free_page((unsigned long)dpage->dentries);
1facf9fc 6950+}
6951+
6952+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
6953+{
6954+ int err;
6955+ void *p;
6956+
6957+ err = -ENOMEM;
6958+ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
6959+ if (unlikely(!dpages->dpages))
6960+ goto out;
6961+
6962+ p = (void *)__get_free_page(gfp);
6963+ if (unlikely(!p))
6964+ goto out_dpages;
6965+
6966+ dpages->dpages[0].ndentry = 0;
6967+ dpages->dpages[0].dentries = p;
6968+ dpages->ndpage = 1;
6969+ return 0; /* success */
6970+
4f0767ce 6971+out_dpages:
ae9dfd79 6972+ kfree(dpages->dpages);
4f0767ce 6973+out:
1facf9fc 6974+ return err;
6975+}
6976+
6977+void au_dpages_free(struct au_dcsub_pages *dpages)
6978+{
6979+ int i;
6980+ struct au_dpage *p;
6981+
6982+ p = dpages->dpages;
6983+ for (i = 0; i < dpages->ndpage; i++)
6984+ au_dpage_free(p++);
ae9dfd79 6985+ kfree(dpages->dpages);
1facf9fc 6986+}
6987+
6988+static int au_dpages_append(struct au_dcsub_pages *dpages,
6989+ struct dentry *dentry, gfp_t gfp)
6990+{
6991+ int err, sz;
6992+ struct au_dpage *dpage;
6993+ void *p;
6994+
6995+ dpage = dpages->dpages + dpages->ndpage - 1;
6996+ sz = PAGE_SIZE / sizeof(dentry);
6997+ if (unlikely(dpage->ndentry >= sz)) {
6998+ AuLabel(new dpage);
6999+ err = -ENOMEM;
7000+ sz = dpages->ndpage * sizeof(*dpages->dpages);
7001+ p = au_kzrealloc(dpages->dpages, sz,
e2f27e51
AM
7002+ sz + sizeof(*dpages->dpages), gfp,
7003+ /*may_shrink*/0);
1facf9fc 7004+ if (unlikely(!p))
7005+ goto out;
7006+
7007+ dpages->dpages = p;
7008+ dpage = dpages->dpages + dpages->ndpage;
7009+ p = (void *)__get_free_page(gfp);
7010+ if (unlikely(!p))
7011+ goto out;
7012+
7013+ dpage->ndentry = 0;
7014+ dpage->dentries = p;
7015+ dpages->ndpage++;
7016+ }
7017+
c1595e42 7018+ AuDebugOn(au_dcount(dentry) <= 0);
027c5e7a 7019+ dpage->dentries[dpage->ndentry++] = dget_dlock(dentry);
1facf9fc 7020+ return 0; /* success */
7021+
4f0767ce 7022+out:
1facf9fc 7023+ return err;
7024+}
7025+
c1595e42
JR
7026+/* todo: BAD approach */
7027+/* copied from linux/fs/dcache.c */
7028+enum d_walk_ret {
7029+ D_WALK_CONTINUE,
7030+ D_WALK_QUIT,
7031+ D_WALK_NORETRY,
7032+ D_WALK_SKIP,
7033+};
7034+
7035+extern void d_walk(struct dentry *parent, void *data,
7036+ enum d_walk_ret (*enter)(void *, struct dentry *),
7037+ void (*finish)(void *));
7038+
7039+struct ac_dpages_arg {
1facf9fc 7040+ int err;
c1595e42
JR
7041+ struct au_dcsub_pages *dpages;
7042+ struct super_block *sb;
7043+ au_dpages_test test;
7044+ void *arg;
7045+};
1facf9fc 7046+
c1595e42
JR
7047+static enum d_walk_ret au_call_dpages_append(void *_arg, struct dentry *dentry)
7048+{
7049+ enum d_walk_ret ret;
7050+ struct ac_dpages_arg *arg = _arg;
1facf9fc 7051+
c1595e42
JR
7052+ ret = D_WALK_CONTINUE;
7053+ if (dentry->d_sb == arg->sb
7054+ && !IS_ROOT(dentry)
7055+ && au_dcount(dentry) > 0
7056+ && au_di(dentry)
7057+ && (!arg->test || arg->test(dentry, arg->arg))) {
7058+ arg->err = au_dpages_append(arg->dpages, dentry, GFP_ATOMIC);
7059+ if (unlikely(arg->err))
7060+ ret = D_WALK_QUIT;
1facf9fc 7061+ }
7062+
c1595e42
JR
7063+ return ret;
7064+}
027c5e7a 7065+
c1595e42
JR
7066+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
7067+ au_dpages_test test, void *arg)
7068+{
7069+ struct ac_dpages_arg args = {
7070+ .err = 0,
7071+ .dpages = dpages,
7072+ .sb = root->d_sb,
7073+ .test = test,
7074+ .arg = arg
7075+ };
027c5e7a 7076+
c1595e42
JR
7077+ d_walk(root, &args, au_call_dpages_append, NULL);
7078+
7079+ return args.err;
1facf9fc 7080+}
7081+
7082+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
7083+ int do_include, au_dpages_test test, void *arg)
7084+{
7085+ int err;
7086+
7087+ err = 0;
027c5e7a
AM
7088+ write_seqlock(&rename_lock);
7089+ spin_lock(&dentry->d_lock);
7090+ if (do_include
c1595e42 7091+ && au_dcount(dentry) > 0
027c5e7a 7092+ && (!test || test(dentry, arg)))
1facf9fc 7093+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
7094+ spin_unlock(&dentry->d_lock);
7095+ if (unlikely(err))
7096+ goto out;
7097+
7098+ /*
523b37e3 7099+ * RCU for vfsmount is unnecessary since this is a traverse in a single
027c5e7a
AM
7100+ * mount
7101+ */
1facf9fc 7102+ while (!IS_ROOT(dentry)) {
027c5e7a
AM
7103+ dentry = dentry->d_parent; /* rename_lock is locked */
7104+ spin_lock(&dentry->d_lock);
c1595e42 7105+ if (au_dcount(dentry) > 0
027c5e7a 7106+ && (!test || test(dentry, arg)))
1facf9fc 7107+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
7108+ spin_unlock(&dentry->d_lock);
7109+ if (unlikely(err))
7110+ break;
1facf9fc 7111+ }
7112+
4f0767ce 7113+out:
027c5e7a 7114+ write_sequnlock(&rename_lock);
1facf9fc 7115+ return err;
7116+}
7117+
027c5e7a
AM
7118+static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg)
7119+{
7120+ return au_di(dentry) && dentry->d_sb == arg;
7121+}
7122+
7123+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
7124+ struct dentry *dentry, int do_include)
7125+{
7126+ return au_dcsub_pages_rev(dpages, dentry, do_include,
7127+ au_dcsub_dpages_aufs, dentry->d_sb);
7128+}
7129+
4a4d8108 7130+int au_test_subdir(struct dentry *d1, struct dentry *d2)
1facf9fc 7131+{
4a4d8108
AM
7132+ struct path path[2] = {
7133+ {
7134+ .dentry = d1
7135+ },
7136+ {
7137+ .dentry = d2
7138+ }
7139+ };
1facf9fc 7140+
4a4d8108 7141+ return path_is_under(path + 0, path + 1);
1facf9fc 7142+}
7f207e10
AM
7143diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
7144--- /usr/share/empty/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 7145+++ linux/fs/aufs/dcsub.h 2018-04-15 08:49:13.397817296 +0200
5527c038 7146@@ -0,0 +1,136 @@
1facf9fc 7147+/*
ae9dfd79 7148+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 7149+ *
7150+ * This program, aufs is free software; you can redistribute it and/or modify
7151+ * it under the terms of the GNU General Public License as published by
7152+ * the Free Software Foundation; either version 2 of the License, or
7153+ * (at your option) any later version.
dece6358
AM
7154+ *
7155+ * This program is distributed in the hope that it will be useful,
7156+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7157+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7158+ * GNU General Public License for more details.
7159+ *
7160+ * You should have received a copy of the GNU General Public License
523b37e3 7161+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7162+ */
7163+
7164+/*
7165+ * sub-routines for dentry cache
7166+ */
7167+
7168+#ifndef __AUFS_DCSUB_H__
7169+#define __AUFS_DCSUB_H__
7170+
7171+#ifdef __KERNEL__
7172+
7f207e10 7173+#include <linux/dcache.h>
027c5e7a 7174+#include <linux/fs.h>
dece6358 7175+
1facf9fc 7176+struct au_dpage {
7177+ int ndentry;
7178+ struct dentry **dentries;
7179+};
7180+
7181+struct au_dcsub_pages {
7182+ int ndpage;
7183+ struct au_dpage *dpages;
7184+};
7185+
7186+/* ---------------------------------------------------------------------- */
7187+
7f207e10 7188+/* dcsub.c */
1facf9fc 7189+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
7190+void au_dpages_free(struct au_dcsub_pages *dpages);
7191+typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
7192+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
7193+ au_dpages_test test, void *arg);
7194+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
7195+ int do_include, au_dpages_test test, void *arg);
027c5e7a
AM
7196+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
7197+ struct dentry *dentry, int do_include);
4a4d8108 7198+int au_test_subdir(struct dentry *d1, struct dentry *d2);
1facf9fc 7199+
7f207e10
AM
7200+/* ---------------------------------------------------------------------- */
7201+
523b37e3
AM
7202+/*
7203+ * todo: in linux-3.13, several similar (but faster) helpers are added to
7204+ * include/linux/dcache.h. Try them (in the future).
7205+ */
7206+
027c5e7a
AM
7207+static inline int au_d_hashed_positive(struct dentry *d)
7208+{
7209+ int err;
5527c038 7210+ struct inode *inode = d_inode(d);
076b876e 7211+
027c5e7a 7212+ err = 0;
5527c038
JR
7213+ if (unlikely(d_unhashed(d)
7214+ || d_is_negative(d)
7215+ || !inode->i_nlink))
027c5e7a
AM
7216+ err = -ENOENT;
7217+ return err;
7218+}
7219+
38d290e6
JR
7220+static inline int au_d_linkable(struct dentry *d)
7221+{
7222+ int err;
5527c038 7223+ struct inode *inode = d_inode(d);
076b876e 7224+
38d290e6
JR
7225+ err = au_d_hashed_positive(d);
7226+ if (err
5527c038 7227+ && d_is_positive(d)
38d290e6
JR
7228+ && (inode->i_state & I_LINKABLE))
7229+ err = 0;
7230+ return err;
7231+}
7232+
027c5e7a
AM
7233+static inline int au_d_alive(struct dentry *d)
7234+{
7235+ int err;
7236+ struct inode *inode;
076b876e 7237+
027c5e7a
AM
7238+ err = 0;
7239+ if (!IS_ROOT(d))
7240+ err = au_d_hashed_positive(d);
7241+ else {
5527c038
JR
7242+ inode = d_inode(d);
7243+ if (unlikely(d_unlinked(d)
7244+ || d_is_negative(d)
7245+ || !inode->i_nlink))
027c5e7a
AM
7246+ err = -ENOENT;
7247+ }
7248+ return err;
7249+}
7250+
7251+static inline int au_alive_dir(struct dentry *d)
7f207e10 7252+{
027c5e7a 7253+ int err;
076b876e 7254+
027c5e7a 7255+ err = au_d_alive(d);
5527c038 7256+ if (unlikely(err || IS_DEADDIR(d_inode(d))))
027c5e7a
AM
7257+ err = -ENOENT;
7258+ return err;
7f207e10
AM
7259+}
7260+
38d290e6
JR
7261+static inline int au_qstreq(struct qstr *a, struct qstr *b)
7262+{
7263+ return a->len == b->len
7264+ && !memcmp(a->name, b->name, a->len);
7265+}
7266+
7e9cd9fe
AM
7267+/*
7268+ * by the commit
7269+ * 360f547 2015-01-25 dcache: let the dentry count go down to zero without
7270+ * taking d_lock
7271+ * the type of d_lockref.count became int, but the inlined function d_count()
7272+ * still returns unsigned int.
7273+ * I don't know why. Maybe it is for every d_count() users?
7274+ * Anyway au_dcount() lives on.
7275+ */
c1595e42
JR
7276+static inline int au_dcount(struct dentry *d)
7277+{
7278+ return (int)d_count(d);
7279+}
7280+
1facf9fc 7281+#endif /* __KERNEL__ */
7282+#endif /* __AUFS_DCSUB_H__ */
7f207e10
AM
7283diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
7284--- /usr/share/empty/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 7285+++ linux/fs/aufs/debug.c 2018-04-15 08:49:13.397817296 +0200
f0c0a007 7286@@ -0,0 +1,440 @@
1facf9fc 7287+/*
ae9dfd79 7288+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 7289+ *
7290+ * This program, aufs is free software; you can redistribute it and/or modify
7291+ * it under the terms of the GNU General Public License as published by
7292+ * the Free Software Foundation; either version 2 of the License, or
7293+ * (at your option) any later version.
dece6358
AM
7294+ *
7295+ * This program is distributed in the hope that it will be useful,
7296+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7297+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7298+ * GNU General Public License for more details.
7299+ *
7300+ * You should have received a copy of the GNU General Public License
523b37e3 7301+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7302+ */
7303+
7304+/*
7305+ * debug print functions
7306+ */
7307+
7308+#include "aufs.h"
7309+
392086de
AM
7310+/* Returns 0, or -errno. arg is in kp->arg. */
7311+static int param_atomic_t_set(const char *val, const struct kernel_param *kp)
7312+{
7313+ int err, n;
7314+
7315+ err = kstrtoint(val, 0, &n);
7316+ if (!err) {
7317+ if (n > 0)
7318+ au_debug_on();
7319+ else
7320+ au_debug_off();
7321+ }
7322+ return err;
7323+}
7324+
7325+/* Returns length written or -errno. Buffer is 4k (ie. be short!) */
7326+static int param_atomic_t_get(char *buffer, const struct kernel_param *kp)
7327+{
7328+ atomic_t *a;
7329+
7330+ a = kp->arg;
7331+ return sprintf(buffer, "%d", atomic_read(a));
7332+}
7333+
7334+static struct kernel_param_ops param_ops_atomic_t = {
7335+ .set = param_atomic_t_set,
7336+ .get = param_atomic_t_get
7337+ /* void (*free)(void *arg) */
7338+};
7339+
7340+atomic_t aufs_debug = ATOMIC_INIT(0);
1facf9fc 7341+MODULE_PARM_DESC(debug, "debug print");
392086de 7342+module_param_named(debug, aufs_debug, atomic_t, S_IRUGO | S_IWUSR | S_IWGRP);
1facf9fc 7343+
c1595e42 7344+DEFINE_MUTEX(au_dbg_mtx); /* just to serialize the dbg msgs */
1facf9fc 7345+char *au_plevel = KERN_DEBUG;
e49829fe
JR
7346+#define dpri(fmt, ...) do { \
7347+ if ((au_plevel \
7348+ && strcmp(au_plevel, KERN_DEBUG)) \
7349+ || au_debug_test()) \
7350+ printk("%s" fmt, au_plevel, ##__VA_ARGS__); \
1facf9fc 7351+} while (0)
7352+
7353+/* ---------------------------------------------------------------------- */
7354+
7355+void au_dpri_whlist(struct au_nhash *whlist)
7356+{
7357+ unsigned long ul, n;
7358+ struct hlist_head *head;
c06a8ce3 7359+ struct au_vdir_wh *pos;
1facf9fc 7360+
7361+ n = whlist->nh_num;
7362+ head = whlist->nh_head;
7363+ for (ul = 0; ul < n; ul++) {
c06a8ce3 7364+ hlist_for_each_entry(pos, head, wh_hash)
1facf9fc 7365+ dpri("b%d, %.*s, %d\n",
c06a8ce3
AM
7366+ pos->wh_bindex,
7367+ pos->wh_str.len, pos->wh_str.name,
7368+ pos->wh_str.len);
1facf9fc 7369+ head++;
7370+ }
7371+}
7372+
7373+void au_dpri_vdir(struct au_vdir *vdir)
7374+{
7375+ unsigned long ul;
7376+ union au_vdir_deblk_p p;
7377+ unsigned char *o;
7378+
7379+ if (!vdir || IS_ERR(vdir)) {
7380+ dpri("err %ld\n", PTR_ERR(vdir));
7381+ return;
7382+ }
7383+
7384+ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n",
7385+ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
7386+ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
7387+ for (ul = 0; ul < vdir->vd_nblk; ul++) {
7388+ p.deblk = vdir->vd_deblk[ul];
7389+ o = p.deblk;
7390+ dpri("[%lu]: %p\n", ul, o);
7391+ }
7392+}
7393+
53392da6 7394+static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn,
1facf9fc 7395+ struct dentry *wh)
7396+{
7397+ char *n = NULL;
7398+ int l = 0;
7399+
7400+ if (!inode || IS_ERR(inode)) {
7401+ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
7402+ return -1;
7403+ }
7404+
c2b27bf2 7405+ /* the type of i_blocks depends upon CONFIG_LBDAF */
1facf9fc 7406+ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
7407+ && sizeof(inode->i_blocks) != sizeof(u64));
7408+ if (wh) {
7409+ n = (void *)wh->d_name.name;
7410+ l = wh->d_name.len;
7411+ }
7412+
53392da6
AM
7413+ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
7414+ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
7415+ bindex, inode,
1facf9fc 7416+ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
7417+ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
7418+ i_size_read(inode), (unsigned long long)inode->i_blocks,
53392da6 7419+ hn, (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
1facf9fc 7420+ inode->i_mapping ? inode->i_mapping->nrpages : 0,
b752ccd1
AM
7421+ inode->i_state, inode->i_flags, inode->i_version,
7422+ inode->i_generation,
1facf9fc 7423+ l ? ", wh " : "", l, n);
7424+ return 0;
7425+}
7426+
7427+void au_dpri_inode(struct inode *inode)
7428+{
7429+ struct au_iinfo *iinfo;
5afbbe0d 7430+ struct au_hinode *hi;
1facf9fc 7431+ aufs_bindex_t bindex;
53392da6 7432+ int err, hn;
1facf9fc 7433+
53392da6 7434+ err = do_pri_inode(-1, inode, -1, NULL);
5afbbe0d 7435+ if (err || !au_test_aufs(inode->i_sb) || au_is_bad_inode(inode))
1facf9fc 7436+ return;
7437+
7438+ iinfo = au_ii(inode);
5afbbe0d
AM
7439+ dpri("i-1: btop %d, bbot %d, gen %d\n",
7440+ iinfo->ii_btop, iinfo->ii_bbot, au_iigen(inode, NULL));
7441+ if (iinfo->ii_btop < 0)
1facf9fc 7442+ return;
53392da6 7443+ hn = 0;
5afbbe0d
AM
7444+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot; bindex++) {
7445+ hi = au_hinode(iinfo, bindex);
7446+ hn = !!au_hn(hi);
7447+ do_pri_inode(bindex, hi->hi_inode, hn, hi->hi_whdentry);
53392da6 7448+ }
1facf9fc 7449+}
7450+
2cbb1c4b
JR
7451+void au_dpri_dalias(struct inode *inode)
7452+{
7453+ struct dentry *d;
7454+
7455+ spin_lock(&inode->i_lock);
c1595e42 7456+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias)
2cbb1c4b
JR
7457+ au_dpri_dentry(d);
7458+ spin_unlock(&inode->i_lock);
7459+}
7460+
1facf9fc 7461+static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
7462+{
7463+ struct dentry *wh = NULL;
53392da6 7464+ int hn;
5afbbe0d 7465+ struct inode *inode;
076b876e 7466+ struct au_iinfo *iinfo;
5afbbe0d 7467+ struct au_hinode *hi;
1facf9fc 7468+
7469+ if (!dentry || IS_ERR(dentry)) {
7470+ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
7471+ return -1;
7472+ }
7473+ /* do not call dget_parent() here */
027c5e7a 7474+ /* note: access d_xxx without d_lock */
523b37e3
AM
7475+ dpri("d%d: %p, %pd2?, %s, cnt %d, flags 0x%x, %shashed\n",
7476+ bindex, dentry, dentry,
1facf9fc 7477+ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
c1595e42 7478+ au_dcount(dentry), dentry->d_flags,
523b37e3 7479+ d_unhashed(dentry) ? "un" : "");
53392da6 7480+ hn = -1;
5afbbe0d
AM
7481+ inode = NULL;
7482+ if (d_is_positive(dentry))
7483+ inode = d_inode(dentry);
7484+ if (inode
7485+ && au_test_aufs(dentry->d_sb)
7486+ && bindex >= 0
7487+ && !au_is_bad_inode(inode)) {
7488+ iinfo = au_ii(inode);
7489+ hi = au_hinode(iinfo, bindex);
7490+ hn = !!au_hn(hi);
7491+ wh = hi->hi_whdentry;
7492+ }
7493+ do_pri_inode(bindex, inode, hn, wh);
1facf9fc 7494+ return 0;
7495+}
7496+
7497+void au_dpri_dentry(struct dentry *dentry)
7498+{
7499+ struct au_dinfo *dinfo;
7500+ aufs_bindex_t bindex;
7501+ int err;
7502+
7503+ err = do_pri_dentry(-1, dentry);
7504+ if (err || !au_test_aufs(dentry->d_sb))
7505+ return;
7506+
7507+ dinfo = au_di(dentry);
7508+ if (!dinfo)
7509+ return;
5afbbe0d
AM
7510+ dpri("d-1: btop %d, bbot %d, bwh %d, bdiropq %d, gen %d, tmp %d\n",
7511+ dinfo->di_btop, dinfo->di_bbot,
38d290e6
JR
7512+ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry),
7513+ dinfo->di_tmpfile);
5afbbe0d 7514+ if (dinfo->di_btop < 0)
1facf9fc 7515+ return;
5afbbe0d
AM
7516+ for (bindex = dinfo->di_btop; bindex <= dinfo->di_bbot; bindex++)
7517+ do_pri_dentry(bindex, au_hdentry(dinfo, bindex)->hd_dentry);
1facf9fc 7518+}
7519+
7520+static int do_pri_file(aufs_bindex_t bindex, struct file *file)
7521+{
7522+ char a[32];
7523+
7524+ if (!file || IS_ERR(file)) {
7525+ dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
7526+ return -1;
7527+ }
7528+ a[0] = 0;
7529+ if (bindex < 0
b912730e 7530+ && !IS_ERR_OR_NULL(file->f_path.dentry)
2000de60 7531+ && au_test_aufs(file->f_path.dentry->d_sb)
1facf9fc 7532+ && au_fi(file))
e49829fe 7533+ snprintf(a, sizeof(a), ", gen %d, mmapped %d",
2cbb1c4b 7534+ au_figen(file), atomic_read(&au_fi(file)->fi_mmapped));
b752ccd1 7535+ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
1facf9fc 7536+ bindex, file->f_mode, file->f_flags, (long)file_count(file),
b752ccd1 7537+ file->f_version, file->f_pos, a);
b912730e 7538+ if (!IS_ERR_OR_NULL(file->f_path.dentry))
2000de60 7539+ do_pri_dentry(bindex, file->f_path.dentry);
1facf9fc 7540+ return 0;
7541+}
7542+
7543+void au_dpri_file(struct file *file)
7544+{
7545+ struct au_finfo *finfo;
4a4d8108
AM
7546+ struct au_fidir *fidir;
7547+ struct au_hfile *hfile;
1facf9fc 7548+ aufs_bindex_t bindex;
7549+ int err;
7550+
7551+ err = do_pri_file(-1, file);
2000de60 7552+ if (err
b912730e 7553+ || IS_ERR_OR_NULL(file->f_path.dentry)
2000de60 7554+ || !au_test_aufs(file->f_path.dentry->d_sb))
1facf9fc 7555+ return;
7556+
7557+ finfo = au_fi(file);
7558+ if (!finfo)
7559+ return;
4a4d8108 7560+ if (finfo->fi_btop < 0)
1facf9fc 7561+ return;
4a4d8108
AM
7562+ fidir = finfo->fi_hdir;
7563+ if (!fidir)
7564+ do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
7565+ else
e49829fe
JR
7566+ for (bindex = finfo->fi_btop;
7567+ bindex >= 0 && bindex <= fidir->fd_bbot;
4a4d8108
AM
7568+ bindex++) {
7569+ hfile = fidir->fd_hfile + bindex;
7570+ do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
7571+ }
1facf9fc 7572+}
7573+
7574+static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
7575+{
7576+ struct vfsmount *mnt;
7577+ struct super_block *sb;
7578+
7579+ if (!br || IS_ERR(br))
7580+ goto out;
86dc4139 7581+ mnt = au_br_mnt(br);
1facf9fc 7582+ if (!mnt || IS_ERR(mnt))
7583+ goto out;
7584+ sb = mnt->mnt_sb;
7585+ if (!sb || IS_ERR(sb))
7586+ goto out;
7587+
5afbbe0d 7588+ dpri("s%d: {perm 0x%x, id %d, cnt %lld, wbr %p}, "
b752ccd1 7589+ "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
1facf9fc 7590+ "xino %d\n",
5afbbe0d 7591+ bindex, br->br_perm, br->br_id, au_br_count(br),
1e00d052 7592+ br->br_wbr, au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
b752ccd1 7593+ sb->s_flags, sb->s_count,
1facf9fc 7594+ atomic_read(&sb->s_active), !!br->br_xino.xi_file);
7595+ return 0;
7596+
4f0767ce 7597+out:
1facf9fc 7598+ dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
7599+ return -1;
7600+}
7601+
7602+void au_dpri_sb(struct super_block *sb)
7603+{
7604+ struct au_sbinfo *sbinfo;
7605+ aufs_bindex_t bindex;
7606+ int err;
7607+ /* to reuduce stack size */
7608+ struct {
7609+ struct vfsmount mnt;
7610+ struct au_branch fake;
7611+ } *a;
7612+
7613+ /* this function can be called from magic sysrq */
7614+ a = kzalloc(sizeof(*a), GFP_ATOMIC);
7615+ if (unlikely(!a)) {
7616+ dpri("no memory\n");
7617+ return;
7618+ }
7619+
7620+ a->mnt.mnt_sb = sb;
86dc4139 7621+ a->fake.br_path.mnt = &a->mnt;
5afbbe0d 7622+ au_br_count_init(&a->fake);
1facf9fc 7623+ err = do_pri_br(-1, &a->fake);
5afbbe0d 7624+ au_br_count_fin(&a->fake);
ae9dfd79 7625+ kfree(a);
1facf9fc 7626+ dpri("dev 0x%x\n", sb->s_dev);
7627+ if (err || !au_test_aufs(sb))
7628+ return;
7629+
7630+ sbinfo = au_sbi(sb);
7631+ if (!sbinfo)
7632+ return;
f0c0a007
AM
7633+ dpri("nw %d, gen %u, kobj %d\n",
7634+ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
1facf9fc 7635+ atomic_read(&sbinfo->si_kobj.kref.refcount));
5afbbe0d 7636+ for (bindex = 0; bindex <= sbinfo->si_bbot; bindex++)
1facf9fc 7637+ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
7638+}
7639+
7640+/* ---------------------------------------------------------------------- */
7641+
027c5e7a
AM
7642+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
7643+{
5527c038 7644+ struct inode *h_inode, *inode = d_inode(dentry);
027c5e7a 7645+ struct dentry *h_dentry;
5afbbe0d 7646+ aufs_bindex_t bindex, bbot, bi;
027c5e7a
AM
7647+
7648+ if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */)
7649+ return;
7650+
5afbbe0d
AM
7651+ bbot = au_dbbot(dentry);
7652+ bi = au_ibbot(inode);
7653+ if (bi < bbot)
7654+ bbot = bi;
7655+ bindex = au_dbtop(dentry);
7656+ bi = au_ibtop(inode);
027c5e7a
AM
7657+ if (bi > bindex)
7658+ bindex = bi;
7659+
5afbbe0d 7660+ for (; bindex <= bbot; bindex++) {
027c5e7a
AM
7661+ h_dentry = au_h_dptr(dentry, bindex);
7662+ if (!h_dentry)
7663+ continue;
7664+ h_inode = au_h_iptr(inode, bindex);
5527c038 7665+ if (unlikely(h_inode != d_inode(h_dentry))) {
392086de 7666+ au_debug_on();
027c5e7a
AM
7667+ AuDbg("b%d, %s:%d\n", bindex, func, line);
7668+ AuDbgDentry(dentry);
7669+ AuDbgInode(inode);
392086de 7670+ au_debug_off();
027c5e7a
AM
7671+ BUG();
7672+ }
7673+ }
7674+}
7675+
1facf9fc 7676+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
7677+{
7678+ int err, i, j;
7679+ struct au_dcsub_pages dpages;
7680+ struct au_dpage *dpage;
7681+ struct dentry **dentries;
7682+
7683+ err = au_dpages_init(&dpages, GFP_NOFS);
7684+ AuDebugOn(err);
027c5e7a 7685+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
1facf9fc 7686+ AuDebugOn(err);
7687+ for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
7688+ dpage = dpages.dpages + i;
7689+ dentries = dpage->dentries;
7690+ for (j = dpage->ndentry - 1; !err && j >= 0; j--)
027c5e7a 7691+ AuDebugOn(au_digen_test(dentries[j], sigen));
1facf9fc 7692+ }
7693+ au_dpages_free(&dpages);
7694+}
7695+
1facf9fc 7696+void au_dbg_verify_kthread(void)
7697+{
53392da6 7698+ if (au_wkq_test()) {
1facf9fc 7699+ au_dbg_blocked();
1e00d052
AM
7700+ /*
7701+ * It may be recursive, but udba=notify between two aufs mounts,
7702+ * where a single ro branch is shared, is not a problem.
7703+ */
7704+ /* WARN_ON(1); */
1facf9fc 7705+ }
7706+}
7707+
7708+/* ---------------------------------------------------------------------- */
7709+
1facf9fc 7710+int __init au_debug_init(void)
7711+{
7712+ aufs_bindex_t bindex;
7713+ struct au_vdir_destr destr;
7714+
7715+ bindex = -1;
7716+ AuDebugOn(bindex >= 0);
7717+
7718+ destr.len = -1;
7719+ AuDebugOn(destr.len < NAME_MAX);
7720+
7721+#ifdef CONFIG_4KSTACKS
0c3ec466 7722+ pr_warn("CONFIG_4KSTACKS is defined.\n");
1facf9fc 7723+#endif
7724+
1facf9fc 7725+ return 0;
7726+}
7f207e10
AM
7727diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
7728--- /usr/share/empty/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 7729+++ linux/fs/aufs/debug.h 2018-04-15 08:49:13.397817296 +0200
5527c038 7730@@ -0,0 +1,225 @@
1facf9fc 7731+/*
ae9dfd79 7732+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 7733+ *
7734+ * This program, aufs is free software; you can redistribute it and/or modify
7735+ * it under the terms of the GNU General Public License as published by
7736+ * the Free Software Foundation; either version 2 of the License, or
7737+ * (at your option) any later version.
dece6358
AM
7738+ *
7739+ * This program is distributed in the hope that it will be useful,
7740+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7741+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7742+ * GNU General Public License for more details.
7743+ *
7744+ * You should have received a copy of the GNU General Public License
523b37e3 7745+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7746+ */
7747+
7748+/*
7749+ * debug print functions
7750+ */
7751+
7752+#ifndef __AUFS_DEBUG_H__
7753+#define __AUFS_DEBUG_H__
7754+
7755+#ifdef __KERNEL__
7756+
392086de 7757+#include <linux/atomic.h>
4a4d8108
AM
7758+#include <linux/module.h>
7759+#include <linux/kallsyms.h>
1facf9fc 7760+#include <linux/sysrq.h>
4a4d8108 7761+
1facf9fc 7762+#ifdef CONFIG_AUFS_DEBUG
7763+#define AuDebugOn(a) BUG_ON(a)
7764+
7765+/* module parameter */
392086de
AM
7766+extern atomic_t aufs_debug;
7767+static inline void au_debug_on(void)
1facf9fc 7768+{
392086de
AM
7769+ atomic_inc(&aufs_debug);
7770+}
7771+static inline void au_debug_off(void)
7772+{
7773+ atomic_dec_if_positive(&aufs_debug);
1facf9fc 7774+}
7775+
7776+static inline int au_debug_test(void)
7777+{
392086de 7778+ return atomic_read(&aufs_debug) > 0;
1facf9fc 7779+}
7780+#else
7781+#define AuDebugOn(a) do {} while (0)
392086de
AM
7782+AuStubVoid(au_debug_on, void)
7783+AuStubVoid(au_debug_off, void)
4a4d8108 7784+AuStubInt0(au_debug_test, void)
1facf9fc 7785+#endif /* CONFIG_AUFS_DEBUG */
7786+
392086de
AM
7787+#define param_check_atomic_t(name, p) __param_check(name, p, atomic_t)
7788+
1facf9fc 7789+/* ---------------------------------------------------------------------- */
7790+
7791+/* debug print */
7792+
4a4d8108 7793+#define AuDbg(fmt, ...) do { \
1facf9fc 7794+ if (au_debug_test()) \
4a4d8108 7795+ pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
1facf9fc 7796+} while (0)
4a4d8108
AM
7797+#define AuLabel(l) AuDbg(#l "\n")
7798+#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__)
7799+#define AuWarn1(fmt, ...) do { \
1facf9fc 7800+ static unsigned char _c; \
7801+ if (!_c++) \
0c3ec466 7802+ pr_warn(fmt, ##__VA_ARGS__); \
1facf9fc 7803+} while (0)
7804+
4a4d8108 7805+#define AuErr1(fmt, ...) do { \
1facf9fc 7806+ static unsigned char _c; \
7807+ if (!_c++) \
4a4d8108 7808+ pr_err(fmt, ##__VA_ARGS__); \
1facf9fc 7809+} while (0)
7810+
4a4d8108 7811+#define AuIOErr1(fmt, ...) do { \
1facf9fc 7812+ static unsigned char _c; \
7813+ if (!_c++) \
4a4d8108 7814+ AuIOErr(fmt, ##__VA_ARGS__); \
1facf9fc 7815+} while (0)
7816+
7817+#define AuUnsupportMsg "This operation is not supported." \
7818+ " Please report this application to aufs-users ML."
4a4d8108
AM
7819+#define AuUnsupport(fmt, ...) do { \
7820+ pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
1facf9fc 7821+ dump_stack(); \
7822+} while (0)
7823+
7824+#define AuTraceErr(e) do { \
7825+ if (unlikely((e) < 0)) \
7826+ AuDbg("err %d\n", (int)(e)); \
7827+} while (0)
7828+
7829+#define AuTraceErrPtr(p) do { \
7830+ if (IS_ERR(p)) \
7831+ AuDbg("err %ld\n", PTR_ERR(p)); \
7832+} while (0)
7833+
7834+/* dirty macros for debug print, use with "%.*s" and caution */
7835+#define AuLNPair(qstr) (qstr)->len, (qstr)->name
1facf9fc 7836+
7837+/* ---------------------------------------------------------------------- */
7838+
dece6358 7839+struct dentry;
1facf9fc 7840+#ifdef CONFIG_AUFS_DEBUG
c1595e42 7841+extern struct mutex au_dbg_mtx;
1facf9fc 7842+extern char *au_plevel;
7843+struct au_nhash;
7844+void au_dpri_whlist(struct au_nhash *whlist);
7845+struct au_vdir;
7846+void au_dpri_vdir(struct au_vdir *vdir);
dece6358 7847+struct inode;
1facf9fc 7848+void au_dpri_inode(struct inode *inode);
2cbb1c4b 7849+void au_dpri_dalias(struct inode *inode);
1facf9fc 7850+void au_dpri_dentry(struct dentry *dentry);
dece6358 7851+struct file;
1facf9fc 7852+void au_dpri_file(struct file *filp);
dece6358 7853+struct super_block;
1facf9fc 7854+void au_dpri_sb(struct super_block *sb);
7855+
027c5e7a
AM
7856+#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__)
7857+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line);
1facf9fc 7858+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
1facf9fc 7859+void au_dbg_verify_kthread(void);
7860+
7861+int __init au_debug_init(void);
7e9cd9fe 7862+
1facf9fc 7863+#define AuDbgWhlist(w) do { \
c1595e42 7864+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7865+ AuDbg(#w "\n"); \
7866+ au_dpri_whlist(w); \
c1595e42 7867+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7868+} while (0)
7869+
7870+#define AuDbgVdir(v) do { \
c1595e42 7871+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7872+ AuDbg(#v "\n"); \
7873+ au_dpri_vdir(v); \
c1595e42 7874+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7875+} while (0)
7876+
7877+#define AuDbgInode(i) do { \
c1595e42 7878+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7879+ AuDbg(#i "\n"); \
7880+ au_dpri_inode(i); \
c1595e42 7881+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7882+} while (0)
7883+
2cbb1c4b 7884+#define AuDbgDAlias(i) do { \
c1595e42 7885+ mutex_lock(&au_dbg_mtx); \
2cbb1c4b
JR
7886+ AuDbg(#i "\n"); \
7887+ au_dpri_dalias(i); \
c1595e42 7888+ mutex_unlock(&au_dbg_mtx); \
2cbb1c4b
JR
7889+} while (0)
7890+
1facf9fc 7891+#define AuDbgDentry(d) do { \
c1595e42 7892+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7893+ AuDbg(#d "\n"); \
7894+ au_dpri_dentry(d); \
c1595e42 7895+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7896+} while (0)
7897+
7898+#define AuDbgFile(f) do { \
c1595e42 7899+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7900+ AuDbg(#f "\n"); \
7901+ au_dpri_file(f); \
c1595e42 7902+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7903+} while (0)
7904+
7905+#define AuDbgSb(sb) do { \
c1595e42 7906+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7907+ AuDbg(#sb "\n"); \
7908+ au_dpri_sb(sb); \
c1595e42 7909+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7910+} while (0)
7911+
4a4d8108
AM
7912+#define AuDbgSym(addr) do { \
7913+ char sym[KSYM_SYMBOL_LEN]; \
7914+ sprint_symbol(sym, (unsigned long)addr); \
7915+ AuDbg("%s\n", sym); \
7916+} while (0)
1facf9fc 7917+#else
027c5e7a 7918+AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
4a4d8108
AM
7919+AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
7920+AuStubVoid(au_dbg_verify_kthread, void)
7921+AuStubInt0(__init au_debug_init, void)
1facf9fc 7922+
1facf9fc 7923+#define AuDbgWhlist(w) do {} while (0)
7924+#define AuDbgVdir(v) do {} while (0)
7925+#define AuDbgInode(i) do {} while (0)
2cbb1c4b 7926+#define AuDbgDAlias(i) do {} while (0)
1facf9fc 7927+#define AuDbgDentry(d) do {} while (0)
7928+#define AuDbgFile(f) do {} while (0)
7929+#define AuDbgSb(sb) do {} while (0)
4a4d8108 7930+#define AuDbgSym(addr) do {} while (0)
1facf9fc 7931+#endif /* CONFIG_AUFS_DEBUG */
7932+
7933+/* ---------------------------------------------------------------------- */
7934+
7935+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
7936+int __init au_sysrq_init(void);
7937+void au_sysrq_fin(void);
7938+
7939+#ifdef CONFIG_HW_CONSOLE
7940+#define au_dbg_blocked() do { \
7941+ WARN_ON(1); \
0c5527e5 7942+ handle_sysrq('w'); \
1facf9fc 7943+} while (0)
7944+#else
4a4d8108 7945+AuStubVoid(au_dbg_blocked, void)
1facf9fc 7946+#endif
7947+
7948+#else
4a4d8108
AM
7949+AuStubInt0(__init au_sysrq_init, void)
7950+AuStubVoid(au_sysrq_fin, void)
7951+AuStubVoid(au_dbg_blocked, void)
1facf9fc 7952+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
7953+
7954+#endif /* __KERNEL__ */
7955+#endif /* __AUFS_DEBUG_H__ */
7f207e10
AM
7956diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
7957--- /usr/share/empty/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
7958+++ linux/fs/aufs/dentry.c 2018-04-15 08:49:13.397817296 +0200
7959@@ -0,0 +1,1152 @@
1facf9fc 7960+/*
ae9dfd79 7961+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 7962+ *
7963+ * This program, aufs is free software; you can redistribute it and/or modify
7964+ * it under the terms of the GNU General Public License as published by
7965+ * the Free Software Foundation; either version 2 of the License, or
7966+ * (at your option) any later version.
dece6358
AM
7967+ *
7968+ * This program is distributed in the hope that it will be useful,
7969+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7970+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7971+ * GNU General Public License for more details.
7972+ *
7973+ * You should have received a copy of the GNU General Public License
523b37e3 7974+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7975+ */
7976+
7977+/*
7978+ * lookup and dentry operations
7979+ */
7980+
dece6358 7981+#include <linux/namei.h>
1facf9fc 7982+#include "aufs.h"
7983+
1facf9fc 7984+/*
7985+ * returns positive/negative dentry, NULL or an error.
7986+ * NULL means whiteout-ed or not-found.
7987+ */
7988+static struct dentry*
7989+au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
ae9dfd79 7990+ aufs_bindex_t bindex, struct au_do_lookup_args *args)
1facf9fc 7991+{
7992+ struct dentry *h_dentry;
2000de60 7993+ struct inode *h_inode;
1facf9fc 7994+ struct au_branch *br;
7995+ int wh_found, opq;
7996+ unsigned char wh_able;
7997+ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
076b876e
AM
7998+ const unsigned char ignore_perm = !!au_ftest_lkup(args->flags,
7999+ IGNORE_PERM);
1facf9fc 8000+
1facf9fc 8001+ wh_found = 0;
8002+ br = au_sbr(dentry->d_sb, bindex);
8003+ wh_able = !!au_br_whable(br->br_perm);
8004+ if (wh_able)
ae9dfd79 8005+ wh_found = au_wh_test(h_parent, &args->whname, ignore_perm);
1facf9fc 8006+ h_dentry = ERR_PTR(wh_found);
8007+ if (!wh_found)
8008+ goto real_lookup;
8009+ if (unlikely(wh_found < 0))
8010+ goto out;
8011+
8012+ /* We found a whiteout */
5afbbe0d 8013+ /* au_set_dbbot(dentry, bindex); */
1facf9fc 8014+ au_set_dbwh(dentry, bindex);
8015+ if (!allow_neg)
8016+ return NULL; /* success */
8017+
4f0767ce 8018+real_lookup:
076b876e 8019+ if (!ignore_perm)
ae9dfd79 8020+ h_dentry = vfsub_lkup_one(args->name, h_parent);
076b876e 8021+ else
ae9dfd79 8022+ h_dentry = au_sio_lkup_one(args->name, h_parent);
2000de60
JR
8023+ if (IS_ERR(h_dentry)) {
8024+ if (PTR_ERR(h_dentry) == -ENAMETOOLONG
8025+ && !allow_neg)
8026+ h_dentry = NULL;
1facf9fc 8027+ goto out;
2000de60 8028+ }
1facf9fc 8029+
5527c038
JR
8030+ h_inode = d_inode(h_dentry);
8031+ if (d_is_negative(h_dentry)) {
1facf9fc 8032+ if (!allow_neg)
8033+ goto out_neg;
8034+ } else if (wh_found
8035+ || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
8036+ goto out_neg;
ae9dfd79
AM
8037+ else if (au_ftest_lkup(args->flags, DIRREN)
8038+ /* && h_inode */
8039+ && !au_dr_lkup_h_ino(args, bindex, h_inode->i_ino)) {
8040+ AuDbg("b%d %pd ignored hi%llu\n", bindex, h_dentry,
8041+ (unsigned long long)h_inode->i_ino);
8042+ goto out_neg;
8043+ }
1facf9fc 8044+
5afbbe0d
AM
8045+ if (au_dbbot(dentry) <= bindex)
8046+ au_set_dbbot(dentry, bindex);
8047+ if (au_dbtop(dentry) < 0 || bindex < au_dbtop(dentry))
8048+ au_set_dbtop(dentry, bindex);
1facf9fc 8049+ au_set_h_dptr(dentry, bindex, h_dentry);
8050+
2000de60
JR
8051+ if (!d_is_dir(h_dentry)
8052+ || !wh_able
5527c038 8053+ || (d_really_is_positive(dentry) && !d_is_dir(dentry)))
1facf9fc 8054+ goto out; /* success */
8055+
ae9dfd79 8056+ vfsub_inode_lock_shared_nested(h_inode, AuLsc_I_CHILD);
076b876e 8057+ opq = au_diropq_test(h_dentry);
ae9dfd79 8058+ inode_unlock_shared(h_inode);
1facf9fc 8059+ if (opq > 0)
8060+ au_set_dbdiropq(dentry, bindex);
8061+ else if (unlikely(opq < 0)) {
8062+ au_set_h_dptr(dentry, bindex, NULL);
8063+ h_dentry = ERR_PTR(opq);
8064+ }
8065+ goto out;
8066+
4f0767ce 8067+out_neg:
1facf9fc 8068+ dput(h_dentry);
8069+ h_dentry = NULL;
4f0767ce 8070+out:
1facf9fc 8071+ return h_dentry;
8072+}
8073+
dece6358
AM
8074+static int au_test_shwh(struct super_block *sb, const struct qstr *name)
8075+{
8076+ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
8077+ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
8078+ return -EPERM;
8079+ return 0;
8080+}
8081+
1facf9fc 8082+/*
8083+ * returns the number of lower positive dentries,
8084+ * otherwise an error.
8085+ * can be called at unlinking with @type is zero.
8086+ */
5afbbe0d
AM
8087+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop,
8088+ unsigned int flags)
1facf9fc 8089+{
8090+ int npositive, err;
8091+ aufs_bindex_t bindex, btail, bdiropq;
ae9dfd79 8092+ unsigned char isdir, dirperm1, dirren;
1facf9fc 8093+ struct au_do_lookup_args args = {
ae9dfd79
AM
8094+ .flags = flags,
8095+ .name = &dentry->d_name
1facf9fc 8096+ };
1facf9fc 8097+ struct dentry *parent;
076b876e 8098+ struct super_block *sb;
1facf9fc 8099+
076b876e 8100+ sb = dentry->d_sb;
ae9dfd79 8101+ err = au_test_shwh(sb, args.name);
dece6358 8102+ if (unlikely(err))
1facf9fc 8103+ goto out;
8104+
ae9dfd79 8105+ err = au_wh_name_alloc(&args.whname, args.name);
1facf9fc 8106+ if (unlikely(err))
8107+ goto out;
8108+
2000de60 8109+ isdir = !!d_is_dir(dentry);
076b876e 8110+ dirperm1 = !!au_opt_test(au_mntflags(sb), DIRPERM1);
ae9dfd79
AM
8111+ dirren = !!au_opt_test(au_mntflags(sb), DIRREN);
8112+ if (dirren)
8113+ au_fset_lkup(args.flags, DIRREN);
1facf9fc 8114+
8115+ npositive = 0;
4a4d8108 8116+ parent = dget_parent(dentry);
1facf9fc 8117+ btail = au_dbtaildir(parent);
5afbbe0d 8118+ for (bindex = btop; bindex <= btail; bindex++) {
1facf9fc 8119+ struct dentry *h_parent, *h_dentry;
8120+ struct inode *h_inode, *h_dir;
ae9dfd79 8121+ struct au_branch *br;
1facf9fc 8122+
8123+ h_dentry = au_h_dptr(dentry, bindex);
8124+ if (h_dentry) {
5527c038 8125+ if (d_is_positive(h_dentry))
1facf9fc 8126+ npositive++;
5afbbe0d 8127+ break;
1facf9fc 8128+ }
8129+ h_parent = au_h_dptr(parent, bindex);
2000de60 8130+ if (!h_parent || !d_is_dir(h_parent))
1facf9fc 8131+ continue;
8132+
ae9dfd79
AM
8133+ if (dirren) {
8134+ /* if the inum matches, then use the prepared name */
8135+ err = au_dr_lkup_name(&args, bindex);
8136+ if (unlikely(err))
8137+ goto out_parent;
8138+ }
8139+
5527c038 8140+ h_dir = d_inode(h_parent);
ae9dfd79
AM
8141+ vfsub_inode_lock_shared_nested(h_dir, AuLsc_I_PARENT);
8142+ h_dentry = au_do_lookup(h_parent, dentry, bindex, &args);
8143+ inode_unlock_shared(h_dir);
1facf9fc 8144+ err = PTR_ERR(h_dentry);
8145+ if (IS_ERR(h_dentry))
4a4d8108 8146+ goto out_parent;
2000de60
JR
8147+ if (h_dentry)
8148+ au_fclr_lkup(args.flags, ALLOW_NEG);
076b876e
AM
8149+ if (dirperm1)
8150+ au_fset_lkup(args.flags, IGNORE_PERM);
1facf9fc 8151+
79b8bda9 8152+ if (au_dbwh(dentry) == bindex)
1facf9fc 8153+ break;
8154+ if (!h_dentry)
8155+ continue;
5527c038 8156+ if (d_is_negative(h_dentry))
1facf9fc 8157+ continue;
5527c038 8158+ h_inode = d_inode(h_dentry);
1facf9fc 8159+ npositive++;
8160+ if (!args.type)
8161+ args.type = h_inode->i_mode & S_IFMT;
8162+ if (args.type != S_IFDIR)
8163+ break;
8164+ else if (isdir) {
8165+ /* the type of lower may be different */
8166+ bdiropq = au_dbdiropq(dentry);
8167+ if (bdiropq >= 0 && bdiropq <= bindex)
8168+ break;
8169+ }
ae9dfd79
AM
8170+ br = au_sbr(sb, bindex);
8171+ if (dirren
8172+ && au_dr_hino_test_add(&br->br_dirren, h_inode->i_ino,
8173+ /*add_ent*/NULL)) {
8174+ /* prepare next name to lookup */
8175+ err = au_dr_lkup(&args, dentry, bindex);
8176+ if (unlikely(err))
8177+ goto out_parent;
8178+ }
1facf9fc 8179+ }
8180+
8181+ if (npositive) {
8182+ AuLabel(positive);
5afbbe0d 8183+ au_update_dbtop(dentry);
1facf9fc 8184+ }
8185+ err = npositive;
076b876e 8186+ if (unlikely(!au_opt_test(au_mntflags(sb), UDBA_NONE)
5afbbe0d 8187+ && au_dbtop(dentry) < 0)) {
1facf9fc 8188+ err = -EIO;
523b37e3
AM
8189+ AuIOErr("both of real entry and whiteout found, %pd, err %d\n",
8190+ dentry, err);
027c5e7a 8191+ }
1facf9fc 8192+
4f0767ce 8193+out_parent:
4a4d8108 8194+ dput(parent);
ae9dfd79
AM
8195+ kfree(args.whname.name);
8196+ if (dirren)
8197+ au_dr_lkup_fin(&args);
4f0767ce 8198+out:
1facf9fc 8199+ return err;
8200+}
8201+
076b876e 8202+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent)
1facf9fc 8203+{
8204+ struct dentry *dentry;
8205+ int wkq_err;
8206+
5527c038 8207+ if (!au_test_h_perm_sio(d_inode(parent), MAY_EXEC))
b4510431 8208+ dentry = vfsub_lkup_one(name, parent);
1facf9fc 8209+ else {
b4510431
AM
8210+ struct vfsub_lkup_one_args args = {
8211+ .errp = &dentry,
8212+ .name = name,
8213+ .parent = parent
1facf9fc 8214+ };
8215+
b4510431 8216+ wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args);
1facf9fc 8217+ if (unlikely(wkq_err))
8218+ dentry = ERR_PTR(wkq_err);
8219+ }
8220+
8221+ return dentry;
8222+}
8223+
8224+/*
8225+ * lookup @dentry on @bindex which should be negative.
8226+ */
86dc4139 8227+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh)
1facf9fc 8228+{
8229+ int err;
8230+ struct dentry *parent, *h_parent, *h_dentry;
86dc4139 8231+ struct au_branch *br;
1facf9fc 8232+
1facf9fc 8233+ parent = dget_parent(dentry);
8234+ h_parent = au_h_dptr(parent, bindex);
86dc4139
AM
8235+ br = au_sbr(dentry->d_sb, bindex);
8236+ if (wh)
8237+ h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
8238+ else
076b876e 8239+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent);
1facf9fc 8240+ err = PTR_ERR(h_dentry);
8241+ if (IS_ERR(h_dentry))
8242+ goto out;
5527c038 8243+ if (unlikely(d_is_positive(h_dentry))) {
1facf9fc 8244+ err = -EIO;
523b37e3 8245+ AuIOErr("%pd should be negative on b%d.\n", h_dentry, bindex);
1facf9fc 8246+ dput(h_dentry);
8247+ goto out;
8248+ }
8249+
4a4d8108 8250+ err = 0;
5afbbe0d
AM
8251+ if (bindex < au_dbtop(dentry))
8252+ au_set_dbtop(dentry, bindex);
8253+ if (au_dbbot(dentry) < bindex)
8254+ au_set_dbbot(dentry, bindex);
1facf9fc 8255+ au_set_h_dptr(dentry, bindex, h_dentry);
1facf9fc 8256+
4f0767ce 8257+out:
1facf9fc 8258+ dput(parent);
8259+ return err;
8260+}
8261+
8262+/* ---------------------------------------------------------------------- */
8263+
8264+/* subset of struct inode */
8265+struct au_iattr {
8266+ unsigned long i_ino;
8267+ /* unsigned int i_nlink; */
0c3ec466
AM
8268+ kuid_t i_uid;
8269+ kgid_t i_gid;
1facf9fc 8270+ u64 i_version;
8271+/*
8272+ loff_t i_size;
8273+ blkcnt_t i_blocks;
8274+*/
8275+ umode_t i_mode;
8276+};
8277+
8278+static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
8279+{
8280+ ia->i_ino = h_inode->i_ino;
8281+ /* ia->i_nlink = h_inode->i_nlink; */
8282+ ia->i_uid = h_inode->i_uid;
8283+ ia->i_gid = h_inode->i_gid;
8284+ ia->i_version = h_inode->i_version;
8285+/*
8286+ ia->i_size = h_inode->i_size;
8287+ ia->i_blocks = h_inode->i_blocks;
8288+*/
8289+ ia->i_mode = (h_inode->i_mode & S_IFMT);
8290+}
8291+
8292+static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
8293+{
8294+ return ia->i_ino != h_inode->i_ino
8295+ /* || ia->i_nlink != h_inode->i_nlink */
0c3ec466 8296+ || !uid_eq(ia->i_uid, h_inode->i_uid)
2dfbb274 8297+ || !gid_eq(ia->i_gid, h_inode->i_gid)
1facf9fc 8298+ || ia->i_version != h_inode->i_version
8299+/*
8300+ || ia->i_size != h_inode->i_size
8301+ || ia->i_blocks != h_inode->i_blocks
8302+*/
8303+ || ia->i_mode != (h_inode->i_mode & S_IFMT);
8304+}
8305+
8306+static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
8307+ struct au_branch *br)
8308+{
8309+ int err;
8310+ struct au_iattr ia;
8311+ struct inode *h_inode;
8312+ struct dentry *h_d;
8313+ struct super_block *h_sb;
8314+
8315+ err = 0;
8316+ memset(&ia, -1, sizeof(ia));
8317+ h_sb = h_dentry->d_sb;
5527c038
JR
8318+ h_inode = NULL;
8319+ if (d_is_positive(h_dentry)) {
8320+ h_inode = d_inode(h_dentry);
1facf9fc 8321+ au_iattr_save(&ia, h_inode);
5527c038 8322+ } else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
1facf9fc 8323+ /* nfs d_revalidate may return 0 for negative dentry */
8324+ /* fuse d_revalidate always return 0 for negative dentry */
8325+ goto out;
8326+
8327+ /* main purpose is namei.c:cached_lookup() and d_revalidate */
b4510431 8328+ h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent);
1facf9fc 8329+ err = PTR_ERR(h_d);
8330+ if (IS_ERR(h_d))
8331+ goto out;
8332+
8333+ err = 0;
8334+ if (unlikely(h_d != h_dentry
5527c038 8335+ || d_inode(h_d) != h_inode
1facf9fc 8336+ || (h_inode && au_iattr_test(&ia, h_inode))))
8337+ err = au_busy_or_stale();
8338+ dput(h_d);
8339+
4f0767ce 8340+out:
1facf9fc 8341+ AuTraceErr(err);
8342+ return err;
8343+}
8344+
8345+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
8346+ struct dentry *h_parent, struct au_branch *br)
8347+{
8348+ int err;
8349+
8350+ err = 0;
027c5e7a
AM
8351+ if (udba == AuOpt_UDBA_REVAL
8352+ && !au_test_fs_remote(h_dentry->d_sb)) {
1facf9fc 8353+ IMustLock(h_dir);
5527c038 8354+ err = (d_inode(h_dentry->d_parent) != h_dir);
027c5e7a 8355+ } else if (udba != AuOpt_UDBA_NONE)
1facf9fc 8356+ err = au_h_verify_dentry(h_dentry, h_parent, br);
8357+
8358+ return err;
8359+}
8360+
8361+/* ---------------------------------------------------------------------- */
8362+
027c5e7a 8363+static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
1facf9fc 8364+{
027c5e7a 8365+ int err;
5afbbe0d 8366+ aufs_bindex_t new_bindex, bindex, bbot, bwh, bdiropq;
027c5e7a
AM
8367+ struct au_hdentry tmp, *p, *q;
8368+ struct au_dinfo *dinfo;
8369+ struct super_block *sb;
1facf9fc 8370+
027c5e7a 8371+ DiMustWriteLock(dentry);
1308ab2a 8372+
027c5e7a
AM
8373+ sb = dentry->d_sb;
8374+ dinfo = au_di(dentry);
5afbbe0d 8375+ bbot = dinfo->di_bbot;
1facf9fc 8376+ bwh = dinfo->di_bwh;
8377+ bdiropq = dinfo->di_bdiropq;
5afbbe0d
AM
8378+ bindex = dinfo->di_btop;
8379+ p = au_hdentry(dinfo, bindex);
8380+ for (; bindex <= bbot; bindex++, p++) {
027c5e7a 8381+ if (!p->hd_dentry)
1facf9fc 8382+ continue;
8383+
027c5e7a
AM
8384+ new_bindex = au_br_index(sb, p->hd_id);
8385+ if (new_bindex == bindex)
1facf9fc 8386+ continue;
1facf9fc 8387+
1facf9fc 8388+ if (dinfo->di_bwh == bindex)
8389+ bwh = new_bindex;
8390+ if (dinfo->di_bdiropq == bindex)
8391+ bdiropq = new_bindex;
8392+ if (new_bindex < 0) {
8393+ au_hdput(p);
8394+ p->hd_dentry = NULL;
8395+ continue;
8396+ }
8397+
8398+ /* swap two lower dentries, and loop again */
5afbbe0d 8399+ q = au_hdentry(dinfo, new_bindex);
1facf9fc 8400+ tmp = *q;
8401+ *q = *p;
8402+ *p = tmp;
8403+ if (tmp.hd_dentry) {
8404+ bindex--;
8405+ p--;
8406+ }
8407+ }
8408+
1facf9fc 8409+ dinfo->di_bwh = -1;
5afbbe0d 8410+ if (bwh >= 0 && bwh <= au_sbbot(sb) && au_sbr_whable(sb, bwh))
1facf9fc 8411+ dinfo->di_bwh = bwh;
8412+
8413+ dinfo->di_bdiropq = -1;
8414+ if (bdiropq >= 0
5afbbe0d 8415+ && bdiropq <= au_sbbot(sb)
1facf9fc 8416+ && au_sbr_whable(sb, bdiropq))
8417+ dinfo->di_bdiropq = bdiropq;
8418+
027c5e7a 8419+ err = -EIO;
5afbbe0d
AM
8420+ dinfo->di_btop = -1;
8421+ dinfo->di_bbot = -1;
8422+ bbot = au_dbbot(parent);
8423+ bindex = 0;
8424+ p = au_hdentry(dinfo, bindex);
8425+ for (; bindex <= bbot; bindex++, p++)
1facf9fc 8426+ if (p->hd_dentry) {
5afbbe0d 8427+ dinfo->di_btop = bindex;
1facf9fc 8428+ break;
8429+ }
8430+
5afbbe0d
AM
8431+ if (dinfo->di_btop >= 0) {
8432+ bindex = bbot;
8433+ p = au_hdentry(dinfo, bindex);
8434+ for (; bindex >= 0; bindex--, p--)
027c5e7a 8435+ if (p->hd_dentry) {
5afbbe0d 8436+ dinfo->di_bbot = bindex;
027c5e7a
AM
8437+ err = 0;
8438+ break;
8439+ }
8440+ }
8441+
8442+ return err;
1facf9fc 8443+}
8444+
027c5e7a 8445+static void au_do_hide(struct dentry *dentry)
1facf9fc 8446+{
027c5e7a 8447+ struct inode *inode;
1facf9fc 8448+
5527c038
JR
8449+ if (d_really_is_positive(dentry)) {
8450+ inode = d_inode(dentry);
8451+ if (!d_is_dir(dentry)) {
027c5e7a
AM
8452+ if (inode->i_nlink && !d_unhashed(dentry))
8453+ drop_nlink(inode);
8454+ } else {
8455+ clear_nlink(inode);
8456+ /* stop next lookup */
8457+ inode->i_flags |= S_DEAD;
8458+ }
8459+ smp_mb(); /* necessary? */
8460+ }
8461+ d_drop(dentry);
8462+}
1308ab2a 8463+
027c5e7a
AM
8464+static int au_hide_children(struct dentry *parent)
8465+{
8466+ int err, i, j, ndentry;
8467+ struct au_dcsub_pages dpages;
8468+ struct au_dpage *dpage;
8469+ struct dentry *dentry;
1facf9fc 8470+
027c5e7a 8471+ err = au_dpages_init(&dpages, GFP_NOFS);
1facf9fc 8472+ if (unlikely(err))
8473+ goto out;
027c5e7a
AM
8474+ err = au_dcsub_pages(&dpages, parent, NULL, NULL);
8475+ if (unlikely(err))
8476+ goto out_dpages;
1facf9fc 8477+
027c5e7a
AM
8478+ /* in reverse order */
8479+ for (i = dpages.ndpage - 1; i >= 0; i--) {
8480+ dpage = dpages.dpages + i;
8481+ ndentry = dpage->ndentry;
8482+ for (j = ndentry - 1; j >= 0; j--) {
8483+ dentry = dpage->dentries[j];
8484+ if (dentry != parent)
8485+ au_do_hide(dentry);
8486+ }
8487+ }
1facf9fc 8488+
027c5e7a
AM
8489+out_dpages:
8490+ au_dpages_free(&dpages);
4f0767ce 8491+out:
027c5e7a 8492+ return err;
1facf9fc 8493+}
8494+
027c5e7a 8495+static void au_hide(struct dentry *dentry)
1facf9fc 8496+{
027c5e7a 8497+ int err;
1facf9fc 8498+
027c5e7a 8499+ AuDbgDentry(dentry);
2000de60 8500+ if (d_is_dir(dentry)) {
027c5e7a
AM
8501+ /* shrink_dcache_parent(dentry); */
8502+ err = au_hide_children(dentry);
8503+ if (unlikely(err))
523b37e3
AM
8504+ AuIOErr("%pd, failed hiding children, ignored %d\n",
8505+ dentry, err);
027c5e7a
AM
8506+ }
8507+ au_do_hide(dentry);
8508+}
1facf9fc 8509+
027c5e7a
AM
8510+/*
8511+ * By adding a dirty branch, a cached dentry may be affected in various ways.
8512+ *
8513+ * a dirty branch is added
8514+ * - on the top of layers
8515+ * - in the middle of layers
8516+ * - to the bottom of layers
8517+ *
8518+ * on the added branch there exists
8519+ * - a whiteout
8520+ * - a diropq
8521+ * - a same named entry
8522+ * + exist
8523+ * * negative --> positive
8524+ * * positive --> positive
8525+ * - type is unchanged
8526+ * - type is changed
8527+ * + doesn't exist
8528+ * * negative --> negative
8529+ * * positive --> negative (rejected by au_br_del() for non-dir case)
8530+ * - none
8531+ */
8532+static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
8533+ struct au_dinfo *tmp)
8534+{
8535+ int err;
5afbbe0d 8536+ aufs_bindex_t bindex, bbot;
027c5e7a
AM
8537+ struct {
8538+ struct dentry *dentry;
8539+ struct inode *inode;
8540+ mode_t mode;
be52b249
AM
8541+ } orig_h, tmp_h = {
8542+ .dentry = NULL
8543+ };
027c5e7a
AM
8544+ struct au_hdentry *hd;
8545+ struct inode *inode, *h_inode;
8546+ struct dentry *h_dentry;
8547+
8548+ err = 0;
5afbbe0d 8549+ AuDebugOn(dinfo->di_btop < 0);
027c5e7a 8550+ orig_h.mode = 0;
5afbbe0d 8551+ orig_h.dentry = au_hdentry(dinfo, dinfo->di_btop)->hd_dentry;
5527c038
JR
8552+ orig_h.inode = NULL;
8553+ if (d_is_positive(orig_h.dentry)) {
8554+ orig_h.inode = d_inode(orig_h.dentry);
027c5e7a 8555+ orig_h.mode = orig_h.inode->i_mode & S_IFMT;
5527c038 8556+ }
5afbbe0d
AM
8557+ if (tmp->di_btop >= 0) {
8558+ tmp_h.dentry = au_hdentry(tmp, tmp->di_btop)->hd_dentry;
5527c038
JR
8559+ if (d_is_positive(tmp_h.dentry)) {
8560+ tmp_h.inode = d_inode(tmp_h.dentry);
027c5e7a 8561+ tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
5527c038 8562+ }
027c5e7a
AM
8563+ }
8564+
5527c038
JR
8565+ inode = NULL;
8566+ if (d_really_is_positive(dentry))
8567+ inode = d_inode(dentry);
027c5e7a
AM
8568+ if (!orig_h.inode) {
8569+ AuDbg("nagative originally\n");
8570+ if (inode) {
8571+ au_hide(dentry);
8572+ goto out;
8573+ }
8574+ AuDebugOn(inode);
5afbbe0d 8575+ AuDebugOn(dinfo->di_btop != dinfo->di_bbot);
027c5e7a
AM
8576+ AuDebugOn(dinfo->di_bdiropq != -1);
8577+
8578+ if (!tmp_h.inode) {
8579+ AuDbg("negative --> negative\n");
8580+ /* should have only one negative lower */
5afbbe0d
AM
8581+ if (tmp->di_btop >= 0
8582+ && tmp->di_btop < dinfo->di_btop) {
8583+ AuDebugOn(tmp->di_btop != tmp->di_bbot);
8584+ AuDebugOn(dinfo->di_btop != dinfo->di_bbot);
8585+ au_set_h_dptr(dentry, dinfo->di_btop, NULL);
027c5e7a 8586+ au_di_cp(dinfo, tmp);
5afbbe0d
AM
8587+ hd = au_hdentry(tmp, tmp->di_btop);
8588+ au_set_h_dptr(dentry, tmp->di_btop,
027c5e7a
AM
8589+ dget(hd->hd_dentry));
8590+ }
8591+ au_dbg_verify_dinode(dentry);
8592+ } else {
8593+ AuDbg("negative --> positive\n");
8594+ /*
8595+ * similar to the behaviour of creating with bypassing
8596+ * aufs.
8597+ * unhash it in order to force an error in the
8598+ * succeeding create operation.
8599+ * we should not set S_DEAD here.
8600+ */
8601+ d_drop(dentry);
8602+ /* au_di_swap(tmp, dinfo); */
8603+ au_dbg_verify_dinode(dentry);
8604+ }
8605+ } else {
8606+ AuDbg("positive originally\n");
8607+ /* inode may be NULL */
8608+ AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode);
8609+ if (!tmp_h.inode) {
8610+ AuDbg("positive --> negative\n");
8611+ /* or bypassing aufs */
8612+ au_hide(dentry);
5afbbe0d 8613+ if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_btop)
027c5e7a
AM
8614+ dinfo->di_bwh = tmp->di_bwh;
8615+ if (inode)
8616+ err = au_refresh_hinode_self(inode);
8617+ au_dbg_verify_dinode(dentry);
8618+ } else if (orig_h.mode == tmp_h.mode) {
8619+ AuDbg("positive --> positive, same type\n");
8620+ if (!S_ISDIR(orig_h.mode)
5afbbe0d 8621+ && dinfo->di_btop > tmp->di_btop) {
027c5e7a
AM
8622+ /*
8623+ * similar to the behaviour of removing and
8624+ * creating.
8625+ */
8626+ au_hide(dentry);
8627+ if (inode)
8628+ err = au_refresh_hinode_self(inode);
8629+ au_dbg_verify_dinode(dentry);
8630+ } else {
8631+ /* fill empty slots */
5afbbe0d
AM
8632+ if (dinfo->di_btop > tmp->di_btop)
8633+ dinfo->di_btop = tmp->di_btop;
8634+ if (dinfo->di_bbot < tmp->di_bbot)
8635+ dinfo->di_bbot = tmp->di_bbot;
027c5e7a
AM
8636+ dinfo->di_bwh = tmp->di_bwh;
8637+ dinfo->di_bdiropq = tmp->di_bdiropq;
5afbbe0d
AM
8638+ bbot = dinfo->di_bbot;
8639+ bindex = tmp->di_btop;
8640+ hd = au_hdentry(tmp, bindex);
8641+ for (; bindex <= bbot; bindex++, hd++) {
027c5e7a
AM
8642+ if (au_h_dptr(dentry, bindex))
8643+ continue;
5afbbe0d 8644+ h_dentry = hd->hd_dentry;
027c5e7a
AM
8645+ if (!h_dentry)
8646+ continue;
5527c038
JR
8647+ AuDebugOn(d_is_negative(h_dentry));
8648+ h_inode = d_inode(h_dentry);
027c5e7a
AM
8649+ AuDebugOn(orig_h.mode
8650+ != (h_inode->i_mode
8651+ & S_IFMT));
8652+ au_set_h_dptr(dentry, bindex,
8653+ dget(h_dentry));
8654+ }
5afbbe0d
AM
8655+ if (inode)
8656+ err = au_refresh_hinode(inode, dentry);
027c5e7a
AM
8657+ au_dbg_verify_dinode(dentry);
8658+ }
8659+ } else {
8660+ AuDbg("positive --> positive, different type\n");
8661+ /* similar to the behaviour of removing and creating */
8662+ au_hide(dentry);
8663+ if (inode)
8664+ err = au_refresh_hinode_self(inode);
8665+ au_dbg_verify_dinode(dentry);
8666+ }
8667+ }
8668+
8669+out:
8670+ return err;
8671+}
8672+
79b8bda9
AM
8673+void au_refresh_dop(struct dentry *dentry, int force_reval)
8674+{
8675+ const struct dentry_operations *dop
8676+ = force_reval ? &aufs_dop : dentry->d_sb->s_d_op;
8677+ static const unsigned int mask
8678+ = DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE;
8679+
8680+ BUILD_BUG_ON(sizeof(mask) != sizeof(dentry->d_flags));
8681+
8682+ if (dentry->d_op == dop)
8683+ return;
8684+
8685+ AuDbg("%pd\n", dentry);
8686+ spin_lock(&dentry->d_lock);
8687+ if (dop == &aufs_dop)
8688+ dentry->d_flags |= mask;
8689+ else
8690+ dentry->d_flags &= ~mask;
8691+ dentry->d_op = dop;
8692+ spin_unlock(&dentry->d_lock);
8693+}
8694+
027c5e7a
AM
8695+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
8696+{
e2f27e51 8697+ int err, ebrange, nbr;
027c5e7a
AM
8698+ unsigned int sigen;
8699+ struct au_dinfo *dinfo, *tmp;
8700+ struct super_block *sb;
8701+ struct inode *inode;
8702+
8703+ DiMustWriteLock(dentry);
8704+ AuDebugOn(IS_ROOT(dentry));
5527c038 8705+ AuDebugOn(d_really_is_negative(parent));
027c5e7a
AM
8706+
8707+ sb = dentry->d_sb;
027c5e7a
AM
8708+ sigen = au_sigen(sb);
8709+ err = au_digen_test(parent, sigen);
8710+ if (unlikely(err))
8711+ goto out;
8712+
e2f27e51 8713+ nbr = au_sbbot(sb) + 1;
027c5e7a 8714+ dinfo = au_di(dentry);
e2f27e51 8715+ err = au_di_realloc(dinfo, nbr, /*may_shrink*/0);
027c5e7a
AM
8716+ if (unlikely(err))
8717+ goto out;
8718+ ebrange = au_dbrange_test(dentry);
8719+ if (!ebrange)
8720+ ebrange = au_do_refresh_hdentry(dentry, parent);
8721+
38d290e6 8722+ if (d_unhashed(dentry) || ebrange /* || dinfo->di_tmpfile */) {
5afbbe0d 8723+ AuDebugOn(au_dbtop(dentry) < 0 && au_dbbot(dentry) >= 0);
5527c038
JR
8724+ if (d_really_is_positive(dentry)) {
8725+ inode = d_inode(dentry);
027c5e7a 8726+ err = au_refresh_hinode_self(inode);
5527c038 8727+ }
027c5e7a
AM
8728+ au_dbg_verify_dinode(dentry);
8729+ if (!err)
8730+ goto out_dgen; /* success */
8731+ goto out;
8732+ }
8733+
8734+ /* temporary dinfo */
8735+ AuDbgDentry(dentry);
8736+ err = -ENOMEM;
8737+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
8738+ if (unlikely(!tmp))
8739+ goto out;
8740+ au_di_swap(tmp, dinfo);
8741+ /* returns the number of positive dentries */
8742+ /*
8743+ * if current working dir is removed, it returns an error.
8744+ * but the dentry is legal.
8745+ */
5afbbe0d 8746+ err = au_lkup_dentry(dentry, /*btop*/0, AuLkup_ALLOW_NEG);
027c5e7a
AM
8747+ AuDbgDentry(dentry);
8748+ au_di_swap(tmp, dinfo);
8749+ if (err == -ENOENT)
8750+ err = 0;
8751+ if (err >= 0) {
8752+ /* compare/refresh by dinfo */
8753+ AuDbgDentry(dentry);
8754+ err = au_refresh_by_dinfo(dentry, dinfo, tmp);
8755+ au_dbg_verify_dinode(dentry);
8756+ AuTraceErr(err);
8757+ }
e2f27e51 8758+ au_di_realloc(dinfo, nbr, /*may_shrink*/1); /* harmless if err */
027c5e7a
AM
8759+ au_rw_write_unlock(&tmp->di_rwsem);
8760+ au_di_free(tmp);
8761+ if (unlikely(err))
8762+ goto out;
8763+
8764+out_dgen:
8765+ au_update_digen(dentry);
8766+out:
8767+ if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) {
523b37e3 8768+ AuIOErr("failed refreshing %pd, %d\n", dentry, err);
027c5e7a
AM
8769+ AuDbgDentry(dentry);
8770+ }
8771+ AuTraceErr(err);
8772+ return err;
8773+}
8774+
b4510431
AM
8775+static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags,
8776+ struct dentry *dentry, aufs_bindex_t bindex)
027c5e7a
AM
8777+{
8778+ int err, valid;
027c5e7a
AM
8779+
8780+ err = 0;
8781+ if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE))
8782+ goto out;
027c5e7a
AM
8783+
8784+ AuDbg("b%d\n", bindex);
b4510431
AM
8785+ /*
8786+ * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
8787+ * due to whiteout and branch permission.
8788+ */
8789+ flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
8790+ | LOOKUP_FOLLOW | LOOKUP_EXCL);
8791+ /* it may return tri-state */
8792+ valid = h_dentry->d_op->d_revalidate(h_dentry, flags);
1facf9fc 8793+
8794+ if (unlikely(valid < 0))
8795+ err = valid;
8796+ else if (!valid)
8797+ err = -EINVAL;
8798+
4f0767ce 8799+out:
1facf9fc 8800+ AuTraceErr(err);
8801+ return err;
8802+}
8803+
8804+/* todo: remove this */
8805+static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
ae9dfd79 8806+ unsigned int flags, int do_udba, int dirren)
1facf9fc 8807+{
8808+ int err;
8809+ umode_t mode, h_mode;
5afbbe0d 8810+ aufs_bindex_t bindex, btail, btop, ibs, ibe;
38d290e6 8811+ unsigned char plus, unhashed, is_root, h_plus, h_nfs, tmpfile;
4a4d8108 8812+ struct inode *h_inode, *h_cached_inode;
1facf9fc 8813+ struct dentry *h_dentry;
8814+ struct qstr *name, *h_name;
8815+
8816+ err = 0;
8817+ plus = 0;
8818+ mode = 0;
1facf9fc 8819+ ibs = -1;
8820+ ibe = -1;
8821+ unhashed = !!d_unhashed(dentry);
8822+ is_root = !!IS_ROOT(dentry);
8823+ name = &dentry->d_name;
38d290e6 8824+ tmpfile = au_di(dentry)->di_tmpfile;
1facf9fc 8825+
8826+ /*
7f207e10
AM
8827+ * Theoretically, REVAL test should be unnecessary in case of
8828+ * {FS,I}NOTIFY.
8829+ * But {fs,i}notify doesn't fire some necessary events,
1facf9fc 8830+ * IN_ATTRIB for atime/nlink/pageio
1facf9fc 8831+ * Let's do REVAL test too.
8832+ */
8833+ if (do_udba && inode) {
8834+ mode = (inode->i_mode & S_IFMT);
8835+ plus = (inode->i_nlink > 0);
5afbbe0d
AM
8836+ ibs = au_ibtop(inode);
8837+ ibe = au_ibbot(inode);
1facf9fc 8838+ }
8839+
5afbbe0d
AM
8840+ btop = au_dbtop(dentry);
8841+ btail = btop;
1facf9fc 8842+ if (inode && S_ISDIR(inode->i_mode))
8843+ btail = au_dbtaildir(dentry);
5afbbe0d 8844+ for (bindex = btop; bindex <= btail; bindex++) {
1facf9fc 8845+ h_dentry = au_h_dptr(dentry, bindex);
8846+ if (!h_dentry)
8847+ continue;
8848+
523b37e3
AM
8849+ AuDbg("b%d, %pd\n", bindex, h_dentry);
8850+ h_nfs = !!au_test_nfs(h_dentry->d_sb);
027c5e7a 8851+ spin_lock(&h_dentry->d_lock);
1facf9fc 8852+ h_name = &h_dentry->d_name;
8853+ if (unlikely(do_udba
8854+ && !is_root
523b37e3
AM
8855+ && ((!h_nfs
8856+ && (unhashed != !!d_unhashed(h_dentry)
ae9dfd79 8857+ || (!tmpfile && !dirren
38d290e6
JR
8858+ && !au_qstreq(name, h_name))
8859+ ))
523b37e3
AM
8860+ || (h_nfs
8861+ && !(flags & LOOKUP_OPEN)
8862+ && (h_dentry->d_flags
8863+ & DCACHE_NFSFS_RENAMED)))
1facf9fc 8864+ )) {
38d290e6
JR
8865+ int h_unhashed;
8866+
8867+ h_unhashed = d_unhashed(h_dentry);
027c5e7a 8868+ spin_unlock(&h_dentry->d_lock);
38d290e6
JR
8869+ AuDbg("unhash 0x%x 0x%x, %pd %pd\n",
8870+ unhashed, h_unhashed, dentry, h_dentry);
1facf9fc 8871+ goto err;
8872+ }
027c5e7a 8873+ spin_unlock(&h_dentry->d_lock);
1facf9fc 8874+
b4510431 8875+ err = au_do_h_d_reval(h_dentry, flags, dentry, bindex);
1facf9fc 8876+ if (unlikely(err))
8877+ /* do not goto err, to keep the errno */
8878+ break;
8879+
8880+ /* todo: plink too? */
8881+ if (!do_udba)
8882+ continue;
8883+
8884+ /* UDBA tests */
5527c038 8885+ if (unlikely(!!inode != d_is_positive(h_dentry)))
1facf9fc 8886+ goto err;
8887+
5527c038
JR
8888+ h_inode = NULL;
8889+ if (d_is_positive(h_dentry))
8890+ h_inode = d_inode(h_dentry);
1facf9fc 8891+ h_plus = plus;
8892+ h_mode = mode;
8893+ h_cached_inode = h_inode;
8894+ if (h_inode) {
8895+ h_mode = (h_inode->i_mode & S_IFMT);
8896+ h_plus = (h_inode->i_nlink > 0);
8897+ }
8898+ if (inode && ibs <= bindex && bindex <= ibe)
8899+ h_cached_inode = au_h_iptr(inode, bindex);
8900+
523b37e3 8901+ if (!h_nfs) {
38d290e6 8902+ if (unlikely(plus != h_plus && !tmpfile))
523b37e3
AM
8903+ goto err;
8904+ } else {
8905+ if (unlikely(!(h_dentry->d_flags & DCACHE_NFSFS_RENAMED)
8906+ && !is_root
8907+ && !IS_ROOT(h_dentry)
8908+ && unhashed != d_unhashed(h_dentry)))
8909+ goto err;
8910+ }
8911+ if (unlikely(mode != h_mode
1facf9fc 8912+ || h_cached_inode != h_inode))
8913+ goto err;
8914+ continue;
8915+
f6b6e03d 8916+err:
1facf9fc 8917+ err = -EINVAL;
8918+ break;
8919+ }
8920+
523b37e3 8921+ AuTraceErr(err);
1facf9fc 8922+ return err;
8923+}
8924+
027c5e7a 8925+/* todo: consolidate with do_refresh() and au_reval_for_attr() */
1facf9fc 8926+static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
8927+{
8928+ int err;
8929+ struct dentry *parent;
1facf9fc 8930+
027c5e7a 8931+ if (!au_digen_test(dentry, sigen))
1facf9fc 8932+ return 0;
8933+
8934+ parent = dget_parent(dentry);
8935+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 8936+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 8937+ au_dbg_verify_gen(parent, sigen);
027c5e7a 8938+ err = au_refresh_dentry(dentry, parent);
1facf9fc 8939+ di_read_unlock(parent, AuLock_IR);
8940+ dput(parent);
027c5e7a 8941+ AuTraceErr(err);
1facf9fc 8942+ return err;
8943+}
8944+
8945+int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
8946+{
8947+ int err;
8948+ struct dentry *d, *parent;
1facf9fc 8949+
027c5e7a 8950+ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
1facf9fc 8951+ return simple_reval_dpath(dentry, sigen);
8952+
8953+ /* slow loop, keep it simple and stupid */
8954+ /* cf: au_cpup_dirs() */
8955+ err = 0;
8956+ parent = NULL;
027c5e7a 8957+ while (au_digen_test(dentry, sigen)) {
1facf9fc 8958+ d = dentry;
8959+ while (1) {
8960+ dput(parent);
8961+ parent = dget_parent(d);
027c5e7a 8962+ if (!au_digen_test(parent, sigen))
1facf9fc 8963+ break;
8964+ d = parent;
8965+ }
8966+
1facf9fc 8967+ if (d != dentry)
027c5e7a 8968+ di_write_lock_child2(d);
1facf9fc 8969+
8970+ /* someone might update our dentry while we were sleeping */
027c5e7a
AM
8971+ if (au_digen_test(d, sigen)) {
8972+ /*
8973+ * todo: consolidate with simple_reval_dpath(),
8974+ * do_refresh() and au_reval_for_attr().
8975+ */
1facf9fc 8976+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 8977+ err = au_refresh_dentry(d, parent);
1facf9fc 8978+ di_read_unlock(parent, AuLock_IR);
8979+ }
8980+
8981+ if (d != dentry)
8982+ di_write_unlock(d);
8983+ dput(parent);
8984+ if (unlikely(err))
8985+ break;
8986+ }
8987+
8988+ return err;
8989+}
8990+
8991+/*
8992+ * if valid returns 1, otherwise 0.
8993+ */
b4510431 8994+static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags)
1facf9fc 8995+{
8996+ int valid, err;
8997+ unsigned int sigen;
ae9dfd79 8998+ unsigned char do_udba, dirren;
1facf9fc 8999+ struct super_block *sb;
9000+ struct inode *inode;
9001+
027c5e7a 9002+ /* todo: support rcu-walk? */
b4510431 9003+ if (flags & LOOKUP_RCU)
027c5e7a
AM
9004+ return -ECHILD;
9005+
9006+ valid = 0;
9007+ if (unlikely(!au_di(dentry)))
9008+ goto out;
9009+
e49829fe 9010+ valid = 1;
1facf9fc 9011+ sb = dentry->d_sb;
e49829fe
JR
9012+ /*
9013+ * todo: very ugly
9014+ * i_mutex of parent dir may be held,
9015+ * but we should not return 'invalid' due to busy.
9016+ */
9017+ err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM);
9018+ if (unlikely(err)) {
9019+ valid = err;
027c5e7a 9020+ AuTraceErr(err);
e49829fe
JR
9021+ goto out;
9022+ }
5527c038
JR
9023+ inode = NULL;
9024+ if (d_really_is_positive(dentry))
9025+ inode = d_inode(dentry);
5afbbe0d 9026+ if (unlikely(inode && au_is_bad_inode(inode))) {
c1595e42
JR
9027+ err = -EINVAL;
9028+ AuTraceErr(err);
9029+ goto out_dgrade;
9030+ }
027c5e7a
AM
9031+ if (unlikely(au_dbrange_test(dentry))) {
9032+ err = -EINVAL;
9033+ AuTraceErr(err);
9034+ goto out_dgrade;
1facf9fc 9035+ }
027c5e7a
AM
9036+
9037+ sigen = au_sigen(sb);
9038+ if (au_digen_test(dentry, sigen)) {
1facf9fc 9039+ AuDebugOn(IS_ROOT(dentry));
027c5e7a
AM
9040+ err = au_reval_dpath(dentry, sigen);
9041+ if (unlikely(err)) {
9042+ AuTraceErr(err);
1facf9fc 9043+ goto out_dgrade;
027c5e7a 9044+ }
1facf9fc 9045+ }
9046+ di_downgrade_lock(dentry, AuLock_IR);
9047+
1facf9fc 9048+ err = -EINVAL;
c1595e42 9049+ if (!(flags & (LOOKUP_OPEN | LOOKUP_EMPTY))
523b37e3 9050+ && inode
38d290e6 9051+ && !(inode->i_state && I_LINKABLE)
79b8bda9
AM
9052+ && (IS_DEADDIR(inode) || !inode->i_nlink)) {
9053+ AuTraceErr(err);
027c5e7a 9054+ goto out_inval;
79b8bda9 9055+ }
027c5e7a 9056+
1facf9fc 9057+ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
9058+ if (do_udba && inode) {
5afbbe0d 9059+ aufs_bindex_t btop = au_ibtop(inode);
027c5e7a 9060+ struct inode *h_inode;
1facf9fc 9061+
5afbbe0d
AM
9062+ if (btop >= 0) {
9063+ h_inode = au_h_iptr(inode, btop);
79b8bda9
AM
9064+ if (h_inode && au_test_higen(inode, h_inode)) {
9065+ AuTraceErr(err);
027c5e7a 9066+ goto out_inval;
79b8bda9 9067+ }
027c5e7a 9068+ }
1facf9fc 9069+ }
9070+
ae9dfd79
AM
9071+ dirren = !!au_opt_test(au_mntflags(sb), DIRREN);
9072+ err = h_d_revalidate(dentry, inode, flags, do_udba, dirren);
5afbbe0d 9073+ if (unlikely(!err && do_udba && au_dbtop(dentry) < 0)) {
1facf9fc 9074+ err = -EIO;
523b37e3
AM
9075+ AuDbg("both of real entry and whiteout found, %p, err %d\n",
9076+ dentry, err);
027c5e7a 9077+ }
e49829fe 9078+ goto out_inval;
1facf9fc 9079+
4f0767ce 9080+out_dgrade:
1facf9fc 9081+ di_downgrade_lock(dentry, AuLock_IR);
e49829fe 9082+out_inval:
1facf9fc 9083+ aufs_read_unlock(dentry, AuLock_IR);
9084+ AuTraceErr(err);
9085+ valid = !err;
e49829fe 9086+out:
027c5e7a 9087+ if (!valid) {
523b37e3 9088+ AuDbg("%pd invalid, %d\n", dentry, valid);
027c5e7a
AM
9089+ d_drop(dentry);
9090+ }
1facf9fc 9091+ return valid;
9092+}
9093+
9094+static void aufs_d_release(struct dentry *dentry)
9095+{
027c5e7a 9096+ if (au_di(dentry)) {
4a4d8108
AM
9097+ au_di_fin(dentry);
9098+ au_hn_di_reinit(dentry);
1facf9fc 9099+ }
1facf9fc 9100+}
9101+
4a4d8108 9102+const struct dentry_operations aufs_dop = {
c06a8ce3
AM
9103+ .d_revalidate = aufs_d_revalidate,
9104+ .d_weak_revalidate = aufs_d_revalidate,
9105+ .d_release = aufs_d_release
1facf9fc 9106+};
79b8bda9
AM
9107+
9108+/* aufs_dop without d_revalidate */
9109+const struct dentry_operations aufs_dop_noreval = {
9110+ .d_release = aufs_d_release
9111+};
7f207e10
AM
9112diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
9113--- /usr/share/empty/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
9114+++ linux/fs/aufs/dentry.h 2018-04-15 08:49:13.397817296 +0200
9115@@ -0,0 +1,266 @@
1facf9fc 9116+/*
ae9dfd79 9117+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 9118+ *
9119+ * This program, aufs is free software; you can redistribute it and/or modify
9120+ * it under the terms of the GNU General Public License as published by
9121+ * the Free Software Foundation; either version 2 of the License, or
9122+ * (at your option) any later version.
dece6358
AM
9123+ *
9124+ * This program is distributed in the hope that it will be useful,
9125+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9126+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9127+ * GNU General Public License for more details.
9128+ *
9129+ * You should have received a copy of the GNU General Public License
523b37e3 9130+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9131+ */
9132+
9133+/*
9134+ * lookup and dentry operations
9135+ */
9136+
9137+#ifndef __AUFS_DENTRY_H__
9138+#define __AUFS_DENTRY_H__
9139+
9140+#ifdef __KERNEL__
9141+
dece6358 9142+#include <linux/dcache.h>
ae9dfd79 9143+#include "dirren.h"
1facf9fc 9144+#include "rwsem.h"
9145+
1facf9fc 9146+struct au_hdentry {
9147+ struct dentry *hd_dentry;
027c5e7a 9148+ aufs_bindex_t hd_id;
1facf9fc 9149+};
9150+
9151+struct au_dinfo {
9152+ atomic_t di_generation;
9153+
dece6358 9154+ struct au_rwsem di_rwsem;
5afbbe0d 9155+ aufs_bindex_t di_btop, di_bbot, di_bwh, di_bdiropq;
38d290e6 9156+ unsigned char di_tmpfile; /* to allow the different name */
ae9dfd79 9157+ struct au_hdentry *di_hdentry;
4a4d8108 9158+} ____cacheline_aligned_in_smp;
1facf9fc 9159+
9160+/* ---------------------------------------------------------------------- */
9161+
5afbbe0d
AM
9162+/* flags for au_lkup_dentry() */
9163+#define AuLkup_ALLOW_NEG 1
9164+#define AuLkup_IGNORE_PERM (1 << 1)
ae9dfd79 9165+#define AuLkup_DIRREN (1 << 2)
5afbbe0d
AM
9166+#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name)
9167+#define au_fset_lkup(flags, name) \
9168+ do { (flags) |= AuLkup_##name; } while (0)
9169+#define au_fclr_lkup(flags, name) \
9170+ do { (flags) &= ~AuLkup_##name; } while (0)
9171+
ae9dfd79
AM
9172+#ifndef CONFIG_AUFS_DIRREN
9173+#undef AuLkup_DIRREN
9174+#define AuLkup_DIRREN 0
9175+#endif
9176+
9177+struct au_do_lookup_args {
9178+ unsigned int flags;
9179+ mode_t type;
9180+ struct qstr whname, *name;
9181+ struct au_dr_lookup dirren;
9182+};
9183+
5afbbe0d
AM
9184+/* ---------------------------------------------------------------------- */
9185+
1facf9fc 9186+/* dentry.c */
79b8bda9 9187+extern const struct dentry_operations aufs_dop, aufs_dop_noreval;
1facf9fc 9188+struct au_branch;
076b876e 9189+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent);
1facf9fc 9190+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
9191+ struct dentry *h_parent, struct au_branch *br);
9192+
5afbbe0d
AM
9193+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop,
9194+ unsigned int flags);
86dc4139 9195+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh);
027c5e7a 9196+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
1facf9fc 9197+int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
79b8bda9 9198+void au_refresh_dop(struct dentry *dentry, int force_reval);
1facf9fc 9199+
9200+/* dinfo.c */
4a4d8108 9201+void au_di_init_once(void *_di);
027c5e7a
AM
9202+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
9203+void au_di_free(struct au_dinfo *dinfo);
9204+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
9205+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
4a4d8108
AM
9206+int au_di_init(struct dentry *dentry);
9207+void au_di_fin(struct dentry *dentry);
e2f27e51 9208+int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink);
1facf9fc 9209+
9210+void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
9211+void di_read_unlock(struct dentry *d, int flags);
9212+void di_downgrade_lock(struct dentry *d, int flags);
9213+void di_write_lock(struct dentry *d, unsigned int lsc);
9214+void di_write_unlock(struct dentry *d);
9215+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
9216+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
9217+void di_write_unlock2(struct dentry *d1, struct dentry *d2);
9218+
9219+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
2cbb1c4b 9220+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
1facf9fc 9221+aufs_bindex_t au_dbtail(struct dentry *dentry);
9222+aufs_bindex_t au_dbtaildir(struct dentry *dentry);
9223+
9224+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
9225+ struct dentry *h_dentry);
027c5e7a
AM
9226+int au_digen_test(struct dentry *dentry, unsigned int sigen);
9227+int au_dbrange_test(struct dentry *dentry);
1facf9fc 9228+void au_update_digen(struct dentry *dentry);
9229+void au_update_dbrange(struct dentry *dentry, int do_put_zero);
5afbbe0d
AM
9230+void au_update_dbtop(struct dentry *dentry);
9231+void au_update_dbbot(struct dentry *dentry);
1facf9fc 9232+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
9233+
9234+/* ---------------------------------------------------------------------- */
9235+
9236+static inline struct au_dinfo *au_di(struct dentry *dentry)
9237+{
9238+ return dentry->d_fsdata;
9239+}
9240+
9241+/* ---------------------------------------------------------------------- */
9242+
9243+/* lock subclass for dinfo */
9244+enum {
9245+ AuLsc_DI_CHILD, /* child first */
4a4d8108 9246+ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */
1facf9fc 9247+ AuLsc_DI_CHILD3, /* copyup dirs */
9248+ AuLsc_DI_PARENT,
9249+ AuLsc_DI_PARENT2,
027c5e7a
AM
9250+ AuLsc_DI_PARENT3,
9251+ AuLsc_DI_TMP /* temp for replacing dinfo */
1facf9fc 9252+};
9253+
9254+/*
9255+ * di_read_lock_child, di_write_lock_child,
9256+ * di_read_lock_child2, di_write_lock_child2,
9257+ * di_read_lock_child3, di_write_lock_child3,
9258+ * di_read_lock_parent, di_write_lock_parent,
9259+ * di_read_lock_parent2, di_write_lock_parent2,
9260+ * di_read_lock_parent3, di_write_lock_parent3,
9261+ */
9262+#define AuReadLockFunc(name, lsc) \
9263+static inline void di_read_lock_##name(struct dentry *d, int flags) \
9264+{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
9265+
9266+#define AuWriteLockFunc(name, lsc) \
9267+static inline void di_write_lock_##name(struct dentry *d) \
9268+{ di_write_lock(d, AuLsc_DI_##lsc); }
9269+
9270+#define AuRWLockFuncs(name, lsc) \
9271+ AuReadLockFunc(name, lsc) \
9272+ AuWriteLockFunc(name, lsc)
9273+
9274+AuRWLockFuncs(child, CHILD);
9275+AuRWLockFuncs(child2, CHILD2);
9276+AuRWLockFuncs(child3, CHILD3);
9277+AuRWLockFuncs(parent, PARENT);
9278+AuRWLockFuncs(parent2, PARENT2);
9279+AuRWLockFuncs(parent3, PARENT3);
9280+
9281+#undef AuReadLockFunc
9282+#undef AuWriteLockFunc
9283+#undef AuRWLockFuncs
9284+
9285+#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
dece6358
AM
9286+#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
9287+#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
1facf9fc 9288+
9289+/* ---------------------------------------------------------------------- */
9290+
9291+/* todo: memory barrier? */
9292+static inline unsigned int au_digen(struct dentry *d)
9293+{
9294+ return atomic_read(&au_di(d)->di_generation);
9295+}
9296+
9297+static inline void au_h_dentry_init(struct au_hdentry *hdentry)
9298+{
9299+ hdentry->hd_dentry = NULL;
9300+}
9301+
5afbbe0d
AM
9302+static inline struct au_hdentry *au_hdentry(struct au_dinfo *di,
9303+ aufs_bindex_t bindex)
9304+{
9305+ return di->di_hdentry + bindex;
9306+}
9307+
1facf9fc 9308+static inline void au_hdput(struct au_hdentry *hd)
9309+{
4a4d8108
AM
9310+ if (hd)
9311+ dput(hd->hd_dentry);
1facf9fc 9312+}
9313+
5afbbe0d 9314+static inline aufs_bindex_t au_dbtop(struct dentry *dentry)
1facf9fc 9315+{
1308ab2a 9316+ DiMustAnyLock(dentry);
5afbbe0d 9317+ return au_di(dentry)->di_btop;
1facf9fc 9318+}
9319+
5afbbe0d 9320+static inline aufs_bindex_t au_dbbot(struct dentry *dentry)
1facf9fc 9321+{
1308ab2a 9322+ DiMustAnyLock(dentry);
5afbbe0d 9323+ return au_di(dentry)->di_bbot;
1facf9fc 9324+}
9325+
9326+static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
9327+{
1308ab2a 9328+ DiMustAnyLock(dentry);
1facf9fc 9329+ return au_di(dentry)->di_bwh;
9330+}
9331+
9332+static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
9333+{
1308ab2a 9334+ DiMustAnyLock(dentry);
1facf9fc 9335+ return au_di(dentry)->di_bdiropq;
9336+}
9337+
9338+/* todo: hard/soft set? */
5afbbe0d 9339+static inline void au_set_dbtop(struct dentry *dentry, aufs_bindex_t bindex)
1facf9fc 9340+{
1308ab2a 9341+ DiMustWriteLock(dentry);
5afbbe0d 9342+ au_di(dentry)->di_btop = bindex;
1facf9fc 9343+}
9344+
5afbbe0d 9345+static inline void au_set_dbbot(struct dentry *dentry, aufs_bindex_t bindex)
1facf9fc 9346+{
1308ab2a 9347+ DiMustWriteLock(dentry);
5afbbe0d 9348+ au_di(dentry)->di_bbot = bindex;
1facf9fc 9349+}
9350+
9351+static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
9352+{
1308ab2a 9353+ DiMustWriteLock(dentry);
5afbbe0d 9354+ /* dbwh can be outside of btop - bbot range */
1facf9fc 9355+ au_di(dentry)->di_bwh = bindex;
9356+}
9357+
9358+static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
9359+{
1308ab2a 9360+ DiMustWriteLock(dentry);
1facf9fc 9361+ au_di(dentry)->di_bdiropq = bindex;
9362+}
9363+
9364+/* ---------------------------------------------------------------------- */
9365+
4a4d8108 9366+#ifdef CONFIG_AUFS_HNOTIFY
1facf9fc 9367+static inline void au_digen_dec(struct dentry *d)
9368+{
e49829fe 9369+ atomic_dec(&au_di(d)->di_generation);
1facf9fc 9370+}
9371+
4a4d8108 9372+static inline void au_hn_di_reinit(struct dentry *dentry)
1facf9fc 9373+{
9374+ dentry->d_fsdata = NULL;
9375+}
9376+#else
4a4d8108
AM
9377+AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
9378+#endif /* CONFIG_AUFS_HNOTIFY */
1facf9fc 9379+
9380+#endif /* __KERNEL__ */
9381+#endif /* __AUFS_DENTRY_H__ */
7f207e10
AM
9382diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
9383--- /usr/share/empty/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 9384+++ linux/fs/aufs/dinfo.c 2018-04-15 08:49:13.397817296 +0200
e2f27e51 9385@@ -0,0 +1,553 @@
1facf9fc 9386+/*
ae9dfd79 9387+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 9388+ *
9389+ * This program, aufs is free software; you can redistribute it and/or modify
9390+ * it under the terms of the GNU General Public License as published by
9391+ * the Free Software Foundation; either version 2 of the License, or
9392+ * (at your option) any later version.
dece6358
AM
9393+ *
9394+ * This program is distributed in the hope that it will be useful,
9395+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9396+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9397+ * GNU General Public License for more details.
9398+ *
9399+ * You should have received a copy of the GNU General Public License
523b37e3 9400+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9401+ */
9402+
9403+/*
9404+ * dentry private data
9405+ */
9406+
9407+#include "aufs.h"
9408+
e49829fe 9409+void au_di_init_once(void *_dinfo)
4a4d8108 9410+{
e49829fe 9411+ struct au_dinfo *dinfo = _dinfo;
4a4d8108 9412+
e49829fe 9413+ au_rw_init(&dinfo->di_rwsem);
4a4d8108
AM
9414+}
9415+
027c5e7a 9416+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
1facf9fc 9417+{
9418+ struct au_dinfo *dinfo;
027c5e7a 9419+ int nbr, i;
1facf9fc 9420+
9421+ dinfo = au_cache_alloc_dinfo();
9422+ if (unlikely(!dinfo))
9423+ goto out;
9424+
5afbbe0d 9425+ nbr = au_sbbot(sb) + 1;
1facf9fc 9426+ if (nbr <= 0)
9427+ nbr = 1;
9428+ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
027c5e7a
AM
9429+ if (dinfo->di_hdentry) {
9430+ au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
5afbbe0d
AM
9431+ dinfo->di_btop = -1;
9432+ dinfo->di_bbot = -1;
027c5e7a
AM
9433+ dinfo->di_bwh = -1;
9434+ dinfo->di_bdiropq = -1;
38d290e6 9435+ dinfo->di_tmpfile = 0;
027c5e7a
AM
9436+ for (i = 0; i < nbr; i++)
9437+ dinfo->di_hdentry[i].hd_id = -1;
9438+ goto out;
9439+ }
1facf9fc 9440+
ae9dfd79 9441+ au_cache_free_dinfo(dinfo);
027c5e7a
AM
9442+ dinfo = NULL;
9443+
4f0767ce 9444+out:
027c5e7a 9445+ return dinfo;
1facf9fc 9446+}
9447+
027c5e7a 9448+void au_di_free(struct au_dinfo *dinfo)
4a4d8108 9449+{
4a4d8108 9450+ struct au_hdentry *p;
5afbbe0d 9451+ aufs_bindex_t bbot, bindex;
4a4d8108
AM
9452+
9453+ /* dentry may not be revalidated */
5afbbe0d 9454+ bindex = dinfo->di_btop;
4a4d8108 9455+ if (bindex >= 0) {
5afbbe0d
AM
9456+ bbot = dinfo->di_bbot;
9457+ p = au_hdentry(dinfo, bindex);
9458+ while (bindex++ <= bbot)
4a4d8108
AM
9459+ au_hdput(p++);
9460+ }
ae9dfd79
AM
9461+ kfree(dinfo->di_hdentry);
9462+ au_cache_free_dinfo(dinfo);
027c5e7a
AM
9463+}
9464+
9465+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
9466+{
9467+ struct au_hdentry *p;
9468+ aufs_bindex_t bi;
9469+
9470+ AuRwMustWriteLock(&a->di_rwsem);
9471+ AuRwMustWriteLock(&b->di_rwsem);
9472+
9473+#define DiSwap(v, name) \
9474+ do { \
9475+ v = a->di_##name; \
9476+ a->di_##name = b->di_##name; \
9477+ b->di_##name = v; \
9478+ } while (0)
9479+
9480+ DiSwap(p, hdentry);
5afbbe0d
AM
9481+ DiSwap(bi, btop);
9482+ DiSwap(bi, bbot);
027c5e7a
AM
9483+ DiSwap(bi, bwh);
9484+ DiSwap(bi, bdiropq);
9485+ /* smp_mb(); */
9486+
9487+#undef DiSwap
9488+}
9489+
9490+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
9491+{
9492+ AuRwMustWriteLock(&dst->di_rwsem);
9493+ AuRwMustWriteLock(&src->di_rwsem);
9494+
5afbbe0d
AM
9495+ dst->di_btop = src->di_btop;
9496+ dst->di_bbot = src->di_bbot;
027c5e7a
AM
9497+ dst->di_bwh = src->di_bwh;
9498+ dst->di_bdiropq = src->di_bdiropq;
9499+ /* smp_mb(); */
9500+}
9501+
9502+int au_di_init(struct dentry *dentry)
9503+{
9504+ int err;
9505+ struct super_block *sb;
9506+ struct au_dinfo *dinfo;
9507+
9508+ err = 0;
9509+ sb = dentry->d_sb;
9510+ dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
9511+ if (dinfo) {
9512+ atomic_set(&dinfo->di_generation, au_sigen(sb));
9513+ /* smp_mb(); */ /* atomic_set */
9514+ dentry->d_fsdata = dinfo;
9515+ } else
9516+ err = -ENOMEM;
9517+
9518+ return err;
9519+}
9520+
9521+void au_di_fin(struct dentry *dentry)
9522+{
9523+ struct au_dinfo *dinfo;
9524+
9525+ dinfo = au_di(dentry);
9526+ AuRwDestroy(&dinfo->di_rwsem);
9527+ au_di_free(dinfo);
4a4d8108
AM
9528+}
9529+
e2f27e51 9530+int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink)
1facf9fc 9531+{
9532+ int err, sz;
9533+ struct au_hdentry *hdp;
9534+
1308ab2a 9535+ AuRwMustWriteLock(&dinfo->di_rwsem);
9536+
1facf9fc 9537+ err = -ENOMEM;
5afbbe0d 9538+ sz = sizeof(*hdp) * (dinfo->di_bbot + 1);
1facf9fc 9539+ if (!sz)
9540+ sz = sizeof(*hdp);
e2f27e51
AM
9541+ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS,
9542+ may_shrink);
1facf9fc 9543+ if (hdp) {
9544+ dinfo->di_hdentry = hdp;
9545+ err = 0;
9546+ }
9547+
9548+ return err;
9549+}
9550+
9551+/* ---------------------------------------------------------------------- */
9552+
9553+static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
9554+{
9555+ switch (lsc) {
9556+ case AuLsc_DI_CHILD:
9557+ ii_write_lock_child(inode);
9558+ break;
9559+ case AuLsc_DI_CHILD2:
9560+ ii_write_lock_child2(inode);
9561+ break;
9562+ case AuLsc_DI_CHILD3:
9563+ ii_write_lock_child3(inode);
9564+ break;
9565+ case AuLsc_DI_PARENT:
9566+ ii_write_lock_parent(inode);
9567+ break;
9568+ case AuLsc_DI_PARENT2:
9569+ ii_write_lock_parent2(inode);
9570+ break;
9571+ case AuLsc_DI_PARENT3:
9572+ ii_write_lock_parent3(inode);
9573+ break;
9574+ default:
9575+ BUG();
9576+ }
9577+}
9578+
9579+static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
9580+{
9581+ switch (lsc) {
9582+ case AuLsc_DI_CHILD:
9583+ ii_read_lock_child(inode);
9584+ break;
9585+ case AuLsc_DI_CHILD2:
9586+ ii_read_lock_child2(inode);
9587+ break;
9588+ case AuLsc_DI_CHILD3:
9589+ ii_read_lock_child3(inode);
9590+ break;
9591+ case AuLsc_DI_PARENT:
9592+ ii_read_lock_parent(inode);
9593+ break;
9594+ case AuLsc_DI_PARENT2:
9595+ ii_read_lock_parent2(inode);
9596+ break;
9597+ case AuLsc_DI_PARENT3:
9598+ ii_read_lock_parent3(inode);
9599+ break;
9600+ default:
9601+ BUG();
9602+ }
9603+}
9604+
9605+void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
9606+{
5527c038
JR
9607+ struct inode *inode;
9608+
dece6358 9609+ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
5527c038
JR
9610+ if (d_really_is_positive(d)) {
9611+ inode = d_inode(d);
1facf9fc 9612+ if (au_ftest_lock(flags, IW))
5527c038 9613+ do_ii_write_lock(inode, lsc);
1facf9fc 9614+ else if (au_ftest_lock(flags, IR))
5527c038 9615+ do_ii_read_lock(inode, lsc);
1facf9fc 9616+ }
9617+}
9618+
9619+void di_read_unlock(struct dentry *d, int flags)
9620+{
5527c038
JR
9621+ struct inode *inode;
9622+
9623+ if (d_really_is_positive(d)) {
9624+ inode = d_inode(d);
027c5e7a
AM
9625+ if (au_ftest_lock(flags, IW)) {
9626+ au_dbg_verify_dinode(d);
5527c038 9627+ ii_write_unlock(inode);
027c5e7a
AM
9628+ } else if (au_ftest_lock(flags, IR)) {
9629+ au_dbg_verify_dinode(d);
5527c038 9630+ ii_read_unlock(inode);
027c5e7a 9631+ }
1facf9fc 9632+ }
dece6358 9633+ au_rw_read_unlock(&au_di(d)->di_rwsem);
1facf9fc 9634+}
9635+
9636+void di_downgrade_lock(struct dentry *d, int flags)
9637+{
5527c038
JR
9638+ if (d_really_is_positive(d) && au_ftest_lock(flags, IR))
9639+ ii_downgrade_lock(d_inode(d));
dece6358 9640+ au_rw_dgrade_lock(&au_di(d)->di_rwsem);
1facf9fc 9641+}
9642+
9643+void di_write_lock(struct dentry *d, unsigned int lsc)
9644+{
dece6358 9645+ au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
5527c038
JR
9646+ if (d_really_is_positive(d))
9647+ do_ii_write_lock(d_inode(d), lsc);
1facf9fc 9648+}
9649+
9650+void di_write_unlock(struct dentry *d)
9651+{
027c5e7a 9652+ au_dbg_verify_dinode(d);
5527c038
JR
9653+ if (d_really_is_positive(d))
9654+ ii_write_unlock(d_inode(d));
dece6358 9655+ au_rw_write_unlock(&au_di(d)->di_rwsem);
1facf9fc 9656+}
9657+
9658+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
9659+{
9660+ AuDebugOn(d1 == d2
5527c038 9661+ || d_inode(d1) == d_inode(d2)
1facf9fc 9662+ || d1->d_sb != d2->d_sb);
9663+
ae9dfd79
AM
9664+ if ((isdir && au_test_subdir(d1, d2))
9665+ || d1 < d2) {
1facf9fc 9666+ di_write_lock_child(d1);
9667+ di_write_lock_child2(d2);
9668+ } else {
1facf9fc 9669+ di_write_lock_child(d2);
9670+ di_write_lock_child2(d1);
9671+ }
9672+}
9673+
9674+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
9675+{
9676+ AuDebugOn(d1 == d2
5527c038 9677+ || d_inode(d1) == d_inode(d2)
1facf9fc 9678+ || d1->d_sb != d2->d_sb);
9679+
ae9dfd79
AM
9680+ if ((isdir && au_test_subdir(d1, d2))
9681+ || d1 < d2) {
1facf9fc 9682+ di_write_lock_parent(d1);
9683+ di_write_lock_parent2(d2);
9684+ } else {
1facf9fc 9685+ di_write_lock_parent(d2);
9686+ di_write_lock_parent2(d1);
9687+ }
9688+}
9689+
9690+void di_write_unlock2(struct dentry *d1, struct dentry *d2)
9691+{
9692+ di_write_unlock(d1);
5527c038 9693+ if (d_inode(d1) == d_inode(d2))
dece6358 9694+ au_rw_write_unlock(&au_di(d2)->di_rwsem);
1facf9fc 9695+ else
9696+ di_write_unlock(d2);
9697+}
9698+
9699+/* ---------------------------------------------------------------------- */
9700+
9701+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
9702+{
9703+ struct dentry *d;
9704+
1308ab2a 9705+ DiMustAnyLock(dentry);
9706+
5afbbe0d 9707+ if (au_dbtop(dentry) < 0 || bindex < au_dbtop(dentry))
1facf9fc 9708+ return NULL;
9709+ AuDebugOn(bindex < 0);
5afbbe0d 9710+ d = au_hdentry(au_di(dentry), bindex)->hd_dentry;
c1595e42 9711+ AuDebugOn(d && au_dcount(d) <= 0);
1facf9fc 9712+ return d;
9713+}
9714+
2cbb1c4b
JR
9715+/*
9716+ * extended version of au_h_dptr().
38d290e6
JR
9717+ * returns a hashed and positive (or linkable) h_dentry in bindex, NULL, or
9718+ * error.
2cbb1c4b
JR
9719+ */
9720+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
9721+{
9722+ struct dentry *h_dentry;
9723+ struct inode *inode, *h_inode;
9724+
5527c038 9725+ AuDebugOn(d_really_is_negative(dentry));
2cbb1c4b
JR
9726+
9727+ h_dentry = NULL;
5afbbe0d
AM
9728+ if (au_dbtop(dentry) <= bindex
9729+ && bindex <= au_dbbot(dentry))
2cbb1c4b 9730+ h_dentry = au_h_dptr(dentry, bindex);
38d290e6 9731+ if (h_dentry && !au_d_linkable(h_dentry)) {
2cbb1c4b
JR
9732+ dget(h_dentry);
9733+ goto out; /* success */
9734+ }
9735+
5527c038 9736+ inode = d_inode(dentry);
5afbbe0d
AM
9737+ AuDebugOn(bindex < au_ibtop(inode));
9738+ AuDebugOn(au_ibbot(inode) < bindex);
2cbb1c4b
JR
9739+ h_inode = au_h_iptr(inode, bindex);
9740+ h_dentry = d_find_alias(h_inode);
9741+ if (h_dentry) {
9742+ if (!IS_ERR(h_dentry)) {
38d290e6 9743+ if (!au_d_linkable(h_dentry))
2cbb1c4b
JR
9744+ goto out; /* success */
9745+ dput(h_dentry);
9746+ } else
9747+ goto out;
9748+ }
9749+
9750+ if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
9751+ h_dentry = au_plink_lkup(inode, bindex);
9752+ AuDebugOn(!h_dentry);
9753+ if (!IS_ERR(h_dentry)) {
9754+ if (!au_d_hashed_positive(h_dentry))
9755+ goto out; /* success */
9756+ dput(h_dentry);
9757+ h_dentry = NULL;
9758+ }
9759+ }
9760+
9761+out:
9762+ AuDbgDentry(h_dentry);
9763+ return h_dentry;
9764+}
9765+
1facf9fc 9766+aufs_bindex_t au_dbtail(struct dentry *dentry)
9767+{
5afbbe0d 9768+ aufs_bindex_t bbot, bwh;
1facf9fc 9769+
5afbbe0d
AM
9770+ bbot = au_dbbot(dentry);
9771+ if (0 <= bbot) {
1facf9fc 9772+ bwh = au_dbwh(dentry);
9773+ if (!bwh)
9774+ return bwh;
5afbbe0d 9775+ if (0 < bwh && bwh < bbot)
1facf9fc 9776+ return bwh - 1;
9777+ }
5afbbe0d 9778+ return bbot;
1facf9fc 9779+}
9780+
9781+aufs_bindex_t au_dbtaildir(struct dentry *dentry)
9782+{
5afbbe0d 9783+ aufs_bindex_t bbot, bopq;
1facf9fc 9784+
5afbbe0d
AM
9785+ bbot = au_dbtail(dentry);
9786+ if (0 <= bbot) {
1facf9fc 9787+ bopq = au_dbdiropq(dentry);
5afbbe0d
AM
9788+ if (0 <= bopq && bopq < bbot)
9789+ bbot = bopq;
1facf9fc 9790+ }
5afbbe0d 9791+ return bbot;
1facf9fc 9792+}
9793+
9794+/* ---------------------------------------------------------------------- */
9795+
9796+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
9797+ struct dentry *h_dentry)
9798+{
5afbbe0d
AM
9799+ struct au_dinfo *dinfo;
9800+ struct au_hdentry *hd;
027c5e7a 9801+ struct au_branch *br;
1facf9fc 9802+
1308ab2a 9803+ DiMustWriteLock(dentry);
9804+
5afbbe0d
AM
9805+ dinfo = au_di(dentry);
9806+ hd = au_hdentry(dinfo, bindex);
4a4d8108 9807+ au_hdput(hd);
1facf9fc 9808+ hd->hd_dentry = h_dentry;
027c5e7a
AM
9809+ if (h_dentry) {
9810+ br = au_sbr(dentry->d_sb, bindex);
9811+ hd->hd_id = br->br_id;
9812+ }
9813+}
9814+
9815+int au_dbrange_test(struct dentry *dentry)
9816+{
9817+ int err;
5afbbe0d 9818+ aufs_bindex_t btop, bbot;
027c5e7a
AM
9819+
9820+ err = 0;
5afbbe0d
AM
9821+ btop = au_dbtop(dentry);
9822+ bbot = au_dbbot(dentry);
9823+ if (btop >= 0)
9824+ AuDebugOn(bbot < 0 && btop > bbot);
027c5e7a
AM
9825+ else {
9826+ err = -EIO;
5afbbe0d 9827+ AuDebugOn(bbot >= 0);
027c5e7a
AM
9828+ }
9829+
9830+ return err;
9831+}
9832+
9833+int au_digen_test(struct dentry *dentry, unsigned int sigen)
9834+{
9835+ int err;
9836+
9837+ err = 0;
9838+ if (unlikely(au_digen(dentry) != sigen
5527c038 9839+ || au_iigen_test(d_inode(dentry), sigen)))
027c5e7a
AM
9840+ err = -EIO;
9841+
9842+ return err;
1facf9fc 9843+}
9844+
9845+void au_update_digen(struct dentry *dentry)
9846+{
9847+ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
9848+ /* smp_mb(); */ /* atomic_set */
9849+}
9850+
9851+void au_update_dbrange(struct dentry *dentry, int do_put_zero)
9852+{
9853+ struct au_dinfo *dinfo;
9854+ struct dentry *h_d;
4a4d8108 9855+ struct au_hdentry *hdp;
5afbbe0d 9856+ aufs_bindex_t bindex, bbot;
1facf9fc 9857+
1308ab2a 9858+ DiMustWriteLock(dentry);
9859+
1facf9fc 9860+ dinfo = au_di(dentry);
5afbbe0d 9861+ if (!dinfo || dinfo->di_btop < 0)
1facf9fc 9862+ return;
9863+
9864+ if (do_put_zero) {
5afbbe0d
AM
9865+ bbot = dinfo->di_bbot;
9866+ bindex = dinfo->di_btop;
9867+ hdp = au_hdentry(dinfo, bindex);
9868+ for (; bindex <= bbot; bindex++, hdp++) {
9869+ h_d = hdp->hd_dentry;
5527c038 9870+ if (h_d && d_is_negative(h_d))
1facf9fc 9871+ au_set_h_dptr(dentry, bindex, NULL);
9872+ }
9873+ }
9874+
5afbbe0d
AM
9875+ dinfo->di_btop = 0;
9876+ hdp = au_hdentry(dinfo, dinfo->di_btop);
9877+ for (; dinfo->di_btop <= dinfo->di_bbot; dinfo->di_btop++, hdp++)
9878+ if (hdp->hd_dentry)
1facf9fc 9879+ break;
5afbbe0d
AM
9880+ if (dinfo->di_btop > dinfo->di_bbot) {
9881+ dinfo->di_btop = -1;
9882+ dinfo->di_bbot = -1;
1facf9fc 9883+ return;
9884+ }
9885+
5afbbe0d
AM
9886+ hdp = au_hdentry(dinfo, dinfo->di_bbot);
9887+ for (; dinfo->di_bbot >= 0; dinfo->di_bbot--, hdp--)
9888+ if (hdp->hd_dentry)
1facf9fc 9889+ break;
5afbbe0d 9890+ AuDebugOn(dinfo->di_btop > dinfo->di_bbot || dinfo->di_bbot < 0);
1facf9fc 9891+}
9892+
5afbbe0d 9893+void au_update_dbtop(struct dentry *dentry)
1facf9fc 9894+{
5afbbe0d 9895+ aufs_bindex_t bindex, bbot;
1facf9fc 9896+ struct dentry *h_dentry;
9897+
5afbbe0d
AM
9898+ bbot = au_dbbot(dentry);
9899+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++) {
1facf9fc 9900+ h_dentry = au_h_dptr(dentry, bindex);
9901+ if (!h_dentry)
9902+ continue;
5527c038 9903+ if (d_is_positive(h_dentry)) {
5afbbe0d 9904+ au_set_dbtop(dentry, bindex);
1facf9fc 9905+ return;
9906+ }
9907+ au_set_h_dptr(dentry, bindex, NULL);
9908+ }
9909+}
9910+
5afbbe0d 9911+void au_update_dbbot(struct dentry *dentry)
1facf9fc 9912+{
5afbbe0d 9913+ aufs_bindex_t bindex, btop;
1facf9fc 9914+ struct dentry *h_dentry;
9915+
5afbbe0d
AM
9916+ btop = au_dbtop(dentry);
9917+ for (bindex = au_dbbot(dentry); bindex >= btop; bindex--) {
1facf9fc 9918+ h_dentry = au_h_dptr(dentry, bindex);
9919+ if (!h_dentry)
9920+ continue;
5527c038 9921+ if (d_is_positive(h_dentry)) {
5afbbe0d 9922+ au_set_dbbot(dentry, bindex);
1facf9fc 9923+ return;
9924+ }
9925+ au_set_h_dptr(dentry, bindex, NULL);
9926+ }
9927+}
9928+
9929+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
9930+{
5afbbe0d 9931+ aufs_bindex_t bindex, bbot;
1facf9fc 9932+
5afbbe0d
AM
9933+ bbot = au_dbbot(dentry);
9934+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++)
1facf9fc 9935+ if (au_h_dptr(dentry, bindex) == h_dentry)
9936+ return bindex;
9937+ return -1;
9938+}
7f207e10
AM
9939diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
9940--- /usr/share/empty/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
9941+++ linux/fs/aufs/dir.c 2018-04-15 08:49:13.397817296 +0200
9942@@ -0,0 +1,759 @@
1facf9fc 9943+/*
ae9dfd79 9944+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 9945+ *
9946+ * This program, aufs is free software; you can redistribute it and/or modify
9947+ * it under the terms of the GNU General Public License as published by
9948+ * the Free Software Foundation; either version 2 of the License, or
9949+ * (at your option) any later version.
dece6358
AM
9950+ *
9951+ * This program is distributed in the hope that it will be useful,
9952+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9953+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9954+ * GNU General Public License for more details.
9955+ *
9956+ * You should have received a copy of the GNU General Public License
523b37e3 9957+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9958+ */
9959+
9960+/*
9961+ * directory operations
9962+ */
9963+
9964+#include <linux/fs_stack.h>
9965+#include "aufs.h"
9966+
9967+void au_add_nlink(struct inode *dir, struct inode *h_dir)
9968+{
9dbd164d
AM
9969+ unsigned int nlink;
9970+
1facf9fc 9971+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
9972+
9dbd164d
AM
9973+ nlink = dir->i_nlink;
9974+ nlink += h_dir->i_nlink - 2;
1facf9fc 9975+ if (h_dir->i_nlink < 2)
9dbd164d 9976+ nlink += 2;
f6b6e03d 9977+ smp_mb(); /* for i_nlink */
7eafdf33 9978+ /* 0 can happen in revaliding */
92d182d2 9979+ set_nlink(dir, nlink);
1facf9fc 9980+}
9981+
9982+void au_sub_nlink(struct inode *dir, struct inode *h_dir)
9983+{
9dbd164d
AM
9984+ unsigned int nlink;
9985+
1facf9fc 9986+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
9987+
9dbd164d
AM
9988+ nlink = dir->i_nlink;
9989+ nlink -= h_dir->i_nlink - 2;
1facf9fc 9990+ if (h_dir->i_nlink < 2)
9dbd164d 9991+ nlink -= 2;
f6b6e03d 9992+ smp_mb(); /* for i_nlink */
92d182d2 9993+ /* nlink == 0 means the branch-fs is broken */
9dbd164d 9994+ set_nlink(dir, nlink);
1facf9fc 9995+}
9996+
1308ab2a 9997+loff_t au_dir_size(struct file *file, struct dentry *dentry)
9998+{
9999+ loff_t sz;
5afbbe0d 10000+ aufs_bindex_t bindex, bbot;
1308ab2a 10001+ struct file *h_file;
10002+ struct dentry *h_dentry;
10003+
10004+ sz = 0;
10005+ if (file) {
2000de60 10006+ AuDebugOn(!d_is_dir(file->f_path.dentry));
1308ab2a 10007+
5afbbe0d
AM
10008+ bbot = au_fbbot_dir(file);
10009+ for (bindex = au_fbtop(file);
10010+ bindex <= bbot && sz < KMALLOC_MAX_SIZE;
1308ab2a 10011+ bindex++) {
4a4d8108 10012+ h_file = au_hf_dir(file, bindex);
c06a8ce3
AM
10013+ if (h_file && file_inode(h_file))
10014+ sz += vfsub_f_size_read(h_file);
1308ab2a 10015+ }
10016+ } else {
10017+ AuDebugOn(!dentry);
2000de60 10018+ AuDebugOn(!d_is_dir(dentry));
1308ab2a 10019+
5afbbe0d
AM
10020+ bbot = au_dbtaildir(dentry);
10021+ for (bindex = au_dbtop(dentry);
10022+ bindex <= bbot && sz < KMALLOC_MAX_SIZE;
1308ab2a 10023+ bindex++) {
10024+ h_dentry = au_h_dptr(dentry, bindex);
5527c038
JR
10025+ if (h_dentry && d_is_positive(h_dentry))
10026+ sz += i_size_read(d_inode(h_dentry));
1308ab2a 10027+ }
10028+ }
10029+ if (sz < KMALLOC_MAX_SIZE)
10030+ sz = roundup_pow_of_two(sz);
10031+ if (sz > KMALLOC_MAX_SIZE)
10032+ sz = KMALLOC_MAX_SIZE;
10033+ else if (sz < NAME_MAX) {
10034+ BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX);
10035+ sz = AUFS_RDBLK_DEF;
10036+ }
10037+ return sz;
10038+}
10039+
b912730e
AM
10040+struct au_dir_ts_arg {
10041+ struct dentry *dentry;
10042+ aufs_bindex_t brid;
10043+};
10044+
10045+static void au_do_dir_ts(void *arg)
10046+{
10047+ struct au_dir_ts_arg *a = arg;
10048+ struct au_dtime dt;
10049+ struct path h_path;
10050+ struct inode *dir, *h_dir;
10051+ struct super_block *sb;
10052+ struct au_branch *br;
10053+ struct au_hinode *hdir;
10054+ int err;
5afbbe0d 10055+ aufs_bindex_t btop, bindex;
b912730e
AM
10056+
10057+ sb = a->dentry->d_sb;
5527c038 10058+ if (d_really_is_negative(a->dentry))
b912730e 10059+ goto out;
5527c038 10060+ /* no dir->i_mutex lock */
b95c5147
AM
10061+ aufs_read_lock(a->dentry, AuLock_DW); /* noflush */
10062+
5527c038 10063+ dir = d_inode(a->dentry);
5afbbe0d 10064+ btop = au_ibtop(dir);
b912730e 10065+ bindex = au_br_index(sb, a->brid);
5afbbe0d 10066+ if (bindex < btop)
b912730e
AM
10067+ goto out_unlock;
10068+
10069+ br = au_sbr(sb, bindex);
10070+ h_path.dentry = au_h_dptr(a->dentry, bindex);
10071+ if (!h_path.dentry)
10072+ goto out_unlock;
10073+ h_path.mnt = au_br_mnt(br);
10074+ au_dtime_store(&dt, a->dentry, &h_path);
10075+
5afbbe0d 10076+ br = au_sbr(sb, btop);
b912730e
AM
10077+ if (!au_br_writable(br->br_perm))
10078+ goto out_unlock;
5afbbe0d 10079+ h_path.dentry = au_h_dptr(a->dentry, btop);
b912730e
AM
10080+ h_path.mnt = au_br_mnt(br);
10081+ err = vfsub_mnt_want_write(h_path.mnt);
10082+ if (err)
10083+ goto out_unlock;
5afbbe0d
AM
10084+ hdir = au_hi(dir, btop);
10085+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
10086+ h_dir = au_h_iptr(dir, btop);
b912730e
AM
10087+ if (h_dir->i_nlink
10088+ && timespec_compare(&h_dir->i_mtime, &dt.dt_mtime) < 0) {
10089+ dt.dt_h_path = h_path;
10090+ au_dtime_revert(&dt);
10091+ }
5afbbe0d 10092+ au_hn_inode_unlock(hdir);
b912730e
AM
10093+ vfsub_mnt_drop_write(h_path.mnt);
10094+ au_cpup_attr_timesizes(dir);
10095+
10096+out_unlock:
10097+ aufs_read_unlock(a->dentry, AuLock_DW);
10098+out:
10099+ dput(a->dentry);
10100+ au_nwt_done(&au_sbi(sb)->si_nowait);
ae9dfd79 10101+ kfree(arg);
b912730e
AM
10102+}
10103+
10104+void au_dir_ts(struct inode *dir, aufs_bindex_t bindex)
10105+{
10106+ int perm, wkq_err;
5afbbe0d 10107+ aufs_bindex_t btop;
b912730e
AM
10108+ struct au_dir_ts_arg *arg;
10109+ struct dentry *dentry;
10110+ struct super_block *sb;
10111+
10112+ IMustLock(dir);
10113+
10114+ dentry = d_find_any_alias(dir);
10115+ AuDebugOn(!dentry);
10116+ sb = dentry->d_sb;
5afbbe0d
AM
10117+ btop = au_ibtop(dir);
10118+ if (btop == bindex) {
b912730e
AM
10119+ au_cpup_attr_timesizes(dir);
10120+ goto out;
10121+ }
10122+
5afbbe0d 10123+ perm = au_sbr_perm(sb, btop);
b912730e
AM
10124+ if (!au_br_writable(perm))
10125+ goto out;
10126+
10127+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
10128+ if (!arg)
10129+ goto out;
10130+
10131+ arg->dentry = dget(dentry); /* will be dput-ted by au_do_dir_ts() */
10132+ arg->brid = au_sbr_id(sb, bindex);
10133+ wkq_err = au_wkq_nowait(au_do_dir_ts, arg, sb, /*flags*/0);
10134+ if (unlikely(wkq_err)) {
10135+ pr_err("wkq %d\n", wkq_err);
10136+ dput(dentry);
ae9dfd79 10137+ kfree(arg);
b912730e
AM
10138+ }
10139+
10140+out:
10141+ dput(dentry);
10142+}
10143+
1facf9fc 10144+/* ---------------------------------------------------------------------- */
10145+
10146+static int reopen_dir(struct file *file)
10147+{
10148+ int err;
10149+ unsigned int flags;
5afbbe0d 10150+ aufs_bindex_t bindex, btail, btop;
1facf9fc 10151+ struct dentry *dentry, *h_dentry;
10152+ struct file *h_file;
10153+
10154+ /* open all lower dirs */
2000de60 10155+ dentry = file->f_path.dentry;
5afbbe0d
AM
10156+ btop = au_dbtop(dentry);
10157+ for (bindex = au_fbtop(file); bindex < btop; bindex++)
1facf9fc 10158+ au_set_h_fptr(file, bindex, NULL);
5afbbe0d 10159+ au_set_fbtop(file, btop);
1facf9fc 10160+
10161+ btail = au_dbtaildir(dentry);
5afbbe0d 10162+ for (bindex = au_fbbot_dir(file); btail < bindex; bindex--)
1facf9fc 10163+ au_set_h_fptr(file, bindex, NULL);
5afbbe0d 10164+ au_set_fbbot_dir(file, btail);
1facf9fc 10165+
4a4d8108 10166+ flags = vfsub_file_flags(file);
5afbbe0d 10167+ for (bindex = btop; bindex <= btail; bindex++) {
1facf9fc 10168+ h_dentry = au_h_dptr(dentry, bindex);
10169+ if (!h_dentry)
10170+ continue;
4a4d8108 10171+ h_file = au_hf_dir(file, bindex);
1facf9fc 10172+ if (h_file)
10173+ continue;
10174+
392086de 10175+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 10176+ err = PTR_ERR(h_file);
10177+ if (IS_ERR(h_file))
10178+ goto out; /* close all? */
10179+ au_set_h_fptr(file, bindex, h_file);
10180+ }
10181+ au_update_figen(file);
10182+ /* todo: necessary? */
10183+ /* file->f_ra = h_file->f_ra; */
10184+ err = 0;
10185+
4f0767ce 10186+out:
1facf9fc 10187+ return err;
10188+}
10189+
b912730e 10190+static int do_open_dir(struct file *file, int flags, struct file *h_file)
1facf9fc 10191+{
10192+ int err;
10193+ aufs_bindex_t bindex, btail;
10194+ struct dentry *dentry, *h_dentry;
8cdd5066 10195+ struct vfsmount *mnt;
1facf9fc 10196+
1308ab2a 10197+ FiMustWriteLock(file);
b912730e 10198+ AuDebugOn(h_file);
1308ab2a 10199+
523b37e3 10200+ err = 0;
8cdd5066 10201+ mnt = file->f_path.mnt;
2000de60 10202+ dentry = file->f_path.dentry;
5527c038 10203+ file->f_version = d_inode(dentry)->i_version;
5afbbe0d
AM
10204+ bindex = au_dbtop(dentry);
10205+ au_set_fbtop(file, bindex);
1facf9fc 10206+ btail = au_dbtaildir(dentry);
5afbbe0d 10207+ au_set_fbbot_dir(file, btail);
1facf9fc 10208+ for (; !err && bindex <= btail; bindex++) {
10209+ h_dentry = au_h_dptr(dentry, bindex);
10210+ if (!h_dentry)
10211+ continue;
10212+
8cdd5066
JR
10213+ err = vfsub_test_mntns(mnt, h_dentry->d_sb);
10214+ if (unlikely(err))
10215+ break;
392086de 10216+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 10217+ if (IS_ERR(h_file)) {
10218+ err = PTR_ERR(h_file);
10219+ break;
10220+ }
10221+ au_set_h_fptr(file, bindex, h_file);
10222+ }
10223+ au_update_figen(file);
10224+ /* todo: necessary? */
10225+ /* file->f_ra = h_file->f_ra; */
10226+ if (!err)
10227+ return 0; /* success */
10228+
10229+ /* close all */
5afbbe0d 10230+ for (bindex = au_fbtop(file); bindex <= btail; bindex++)
1facf9fc 10231+ au_set_h_fptr(file, bindex, NULL);
5afbbe0d
AM
10232+ au_set_fbtop(file, -1);
10233+ au_set_fbbot_dir(file, -1);
4a4d8108 10234+
1facf9fc 10235+ return err;
10236+}
10237+
10238+static int aufs_open_dir(struct inode *inode __maybe_unused,
10239+ struct file *file)
10240+{
4a4d8108
AM
10241+ int err;
10242+ struct super_block *sb;
10243+ struct au_fidir *fidir;
10244+
10245+ err = -ENOMEM;
2000de60 10246+ sb = file->f_path.dentry->d_sb;
4a4d8108 10247+ si_read_lock(sb, AuLock_FLUSH);
e49829fe 10248+ fidir = au_fidir_alloc(sb);
4a4d8108 10249+ if (fidir) {
b912730e
AM
10250+ struct au_do_open_args args = {
10251+ .open = do_open_dir,
10252+ .fidir = fidir
10253+ };
10254+ err = au_do_open(file, &args);
4a4d8108 10255+ if (unlikely(err))
ae9dfd79 10256+ kfree(fidir);
4a4d8108
AM
10257+ }
10258+ si_read_unlock(sb);
10259+ return err;
1facf9fc 10260+}
10261+
10262+static int aufs_release_dir(struct inode *inode __maybe_unused,
10263+ struct file *file)
10264+{
10265+ struct au_vdir *vdir_cache;
4a4d8108
AM
10266+ struct au_finfo *finfo;
10267+ struct au_fidir *fidir;
f0c0a007 10268+ struct au_hfile *hf;
5afbbe0d 10269+ aufs_bindex_t bindex, bbot;
1facf9fc 10270+
4a4d8108
AM
10271+ finfo = au_fi(file);
10272+ fidir = finfo->fi_hdir;
10273+ if (fidir) {
ae9dfd79
AM
10274+ au_hbl_del(&finfo->fi_hlist,
10275+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
4a4d8108
AM
10276+ vdir_cache = fidir->fd_vdir_cache; /* lock-free */
10277+ if (vdir_cache)
ae9dfd79 10278+ au_vdir_free(vdir_cache);
4a4d8108
AM
10279+
10280+ bindex = finfo->fi_btop;
10281+ if (bindex >= 0) {
f0c0a007 10282+ hf = fidir->fd_hfile + bindex;
4a4d8108
AM
10283+ /*
10284+ * calls fput() instead of filp_close(),
10285+ * since no dnotify or lock for the lower file.
10286+ */
5afbbe0d 10287+ bbot = fidir->fd_bbot;
f0c0a007
AM
10288+ for (; bindex <= bbot; bindex++, hf++)
10289+ if (hf->hf_file)
ae9dfd79 10290+ au_hfput(hf, /*execed*/0);
4a4d8108 10291+ }
ae9dfd79 10292+ kfree(fidir);
4a4d8108 10293+ finfo->fi_hdir = NULL;
1facf9fc 10294+ }
ae9dfd79 10295+ au_finfo_fin(file);
1facf9fc 10296+ return 0;
10297+}
10298+
10299+/* ---------------------------------------------------------------------- */
10300+
4a4d8108
AM
10301+static int au_do_flush_dir(struct file *file, fl_owner_t id)
10302+{
10303+ int err;
5afbbe0d 10304+ aufs_bindex_t bindex, bbot;
4a4d8108
AM
10305+ struct file *h_file;
10306+
10307+ err = 0;
5afbbe0d
AM
10308+ bbot = au_fbbot_dir(file);
10309+ for (bindex = au_fbtop(file); !err && bindex <= bbot; bindex++) {
4a4d8108
AM
10310+ h_file = au_hf_dir(file, bindex);
10311+ if (h_file)
10312+ err = vfsub_flush(h_file, id);
10313+ }
10314+ return err;
10315+}
10316+
10317+static int aufs_flush_dir(struct file *file, fl_owner_t id)
10318+{
10319+ return au_do_flush(file, id, au_do_flush_dir);
10320+}
10321+
10322+/* ---------------------------------------------------------------------- */
10323+
1facf9fc 10324+static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
10325+{
10326+ int err;
5afbbe0d 10327+ aufs_bindex_t bbot, bindex;
1facf9fc 10328+ struct inode *inode;
10329+ struct super_block *sb;
10330+
10331+ err = 0;
10332+ sb = dentry->d_sb;
5527c038 10333+ inode = d_inode(dentry);
1facf9fc 10334+ IMustLock(inode);
5afbbe0d
AM
10335+ bbot = au_dbbot(dentry);
10336+ for (bindex = au_dbtop(dentry); !err && bindex <= bbot; bindex++) {
1facf9fc 10337+ struct path h_path;
1facf9fc 10338+
10339+ if (au_test_ro(sb, bindex, inode))
10340+ continue;
10341+ h_path.dentry = au_h_dptr(dentry, bindex);
10342+ if (!h_path.dentry)
10343+ continue;
1facf9fc 10344+
1facf9fc 10345+ h_path.mnt = au_sbr_mnt(sb, bindex);
53392da6 10346+ err = vfsub_fsync(NULL, &h_path, datasync);
1facf9fc 10347+ }
10348+
10349+ return err;
10350+}
10351+
10352+static int au_do_fsync_dir(struct file *file, int datasync)
10353+{
10354+ int err;
5afbbe0d 10355+ aufs_bindex_t bbot, bindex;
1facf9fc 10356+ struct file *h_file;
10357+ struct super_block *sb;
10358+ struct inode *inode;
1facf9fc 10359+
ae9dfd79 10360+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1, /*fi_lsc*/0);
1facf9fc 10361+ if (unlikely(err))
10362+ goto out;
10363+
c06a8ce3 10364+ inode = file_inode(file);
b912730e 10365+ sb = inode->i_sb;
5afbbe0d
AM
10366+ bbot = au_fbbot_dir(file);
10367+ for (bindex = au_fbtop(file); !err && bindex <= bbot; bindex++) {
4a4d8108 10368+ h_file = au_hf_dir(file, bindex);
1facf9fc 10369+ if (!h_file || au_test_ro(sb, bindex, inode))
10370+ continue;
10371+
53392da6 10372+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
1facf9fc 10373+ }
10374+
4f0767ce 10375+out:
1facf9fc 10376+ return err;
10377+}
10378+
10379+/*
10380+ * @file may be NULL
10381+ */
1e00d052
AM
10382+static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end,
10383+ int datasync)
1facf9fc 10384+{
10385+ int err;
b752ccd1 10386+ struct dentry *dentry;
5527c038 10387+ struct inode *inode;
1facf9fc 10388+ struct super_block *sb;
1facf9fc 10389+
10390+ err = 0;
2000de60 10391+ dentry = file->f_path.dentry;
5527c038 10392+ inode = d_inode(dentry);
febd17d6 10393+ inode_lock(inode);
1facf9fc 10394+ sb = dentry->d_sb;
10395+ si_noflush_read_lock(sb);
10396+ if (file)
10397+ err = au_do_fsync_dir(file, datasync);
10398+ else {
10399+ di_write_lock_child(dentry);
10400+ err = au_do_fsync_dir_no_file(dentry, datasync);
10401+ }
5527c038 10402+ au_cpup_attr_timesizes(inode);
1facf9fc 10403+ di_write_unlock(dentry);
10404+ if (file)
10405+ fi_write_unlock(file);
10406+
10407+ si_read_unlock(sb);
febd17d6 10408+ inode_unlock(inode);
1facf9fc 10409+ return err;
10410+}
10411+
10412+/* ---------------------------------------------------------------------- */
10413+
5afbbe0d 10414+static int aufs_iterate_shared(struct file *file, struct dir_context *ctx)
1facf9fc 10415+{
10416+ int err;
10417+ struct dentry *dentry;
9dbd164d 10418+ struct inode *inode, *h_inode;
1facf9fc 10419+ struct super_block *sb;
10420+
523b37e3 10421+ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
392086de 10422+
2000de60 10423+ dentry = file->f_path.dentry;
5527c038 10424+ inode = d_inode(dentry);
1facf9fc 10425+ IMustLock(inode);
10426+
10427+ sb = dentry->d_sb;
10428+ si_read_lock(sb, AuLock_FLUSH);
ae9dfd79 10429+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1, /*fi_lsc*/0);
1facf9fc 10430+ if (unlikely(err))
10431+ goto out;
027c5e7a
AM
10432+ err = au_alive_dir(dentry);
10433+ if (!err)
10434+ err = au_vdir_init(file);
1facf9fc 10435+ di_downgrade_lock(dentry, AuLock_IR);
10436+ if (unlikely(err))
10437+ goto out_unlock;
10438+
5afbbe0d 10439+ h_inode = au_h_iptr(inode, au_ibtop(inode));
b752ccd1 10440+ if (!au_test_nfsd()) {
392086de 10441+ err = au_vdir_fill_de(file, ctx);
9dbd164d 10442+ fsstack_copy_attr_atime(inode, h_inode);
1facf9fc 10443+ } else {
10444+ /*
10445+ * nfsd filldir may call lookup_one_len(), vfs_getattr(),
10446+ * encode_fh() and others.
10447+ */
9dbd164d 10448+ atomic_inc(&h_inode->i_count);
1facf9fc 10449+ di_read_unlock(dentry, AuLock_IR);
10450+ si_read_unlock(sb);
392086de 10451+ err = au_vdir_fill_de(file, ctx);
1facf9fc 10452+ fsstack_copy_attr_atime(inode, h_inode);
10453+ fi_write_unlock(file);
9dbd164d 10454+ iput(h_inode);
1facf9fc 10455+
10456+ AuTraceErr(err);
10457+ return err;
10458+ }
10459+
4f0767ce 10460+out_unlock:
1facf9fc 10461+ di_read_unlock(dentry, AuLock_IR);
10462+ fi_write_unlock(file);
4f0767ce 10463+out:
1facf9fc 10464+ si_read_unlock(sb);
10465+ return err;
10466+}
10467+
10468+/* ---------------------------------------------------------------------- */
10469+
10470+#define AuTestEmpty_WHONLY 1
dece6358
AM
10471+#define AuTestEmpty_CALLED (1 << 1)
10472+#define AuTestEmpty_SHWH (1 << 2)
1facf9fc 10473+#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
7f207e10
AM
10474+#define au_fset_testempty(flags, name) \
10475+ do { (flags) |= AuTestEmpty_##name; } while (0)
10476+#define au_fclr_testempty(flags, name) \
10477+ do { (flags) &= ~AuTestEmpty_##name; } while (0)
1facf9fc 10478+
dece6358
AM
10479+#ifndef CONFIG_AUFS_SHWH
10480+#undef AuTestEmpty_SHWH
10481+#define AuTestEmpty_SHWH 0
10482+#endif
10483+
1facf9fc 10484+struct test_empty_arg {
392086de 10485+ struct dir_context ctx;
1308ab2a 10486+ struct au_nhash *whlist;
1facf9fc 10487+ unsigned int flags;
10488+ int err;
10489+ aufs_bindex_t bindex;
10490+};
10491+
392086de
AM
10492+static int test_empty_cb(struct dir_context *ctx, const char *__name,
10493+ int namelen, loff_t offset __maybe_unused, u64 ino,
dece6358 10494+ unsigned int d_type)
1facf9fc 10495+{
392086de
AM
10496+ struct test_empty_arg *arg = container_of(ctx, struct test_empty_arg,
10497+ ctx);
1facf9fc 10498+ char *name = (void *)__name;
10499+
10500+ arg->err = 0;
10501+ au_fset_testempty(arg->flags, CALLED);
10502+ /* smp_mb(); */
10503+ if (name[0] == '.'
10504+ && (namelen == 1 || (name[1] == '.' && namelen == 2)))
10505+ goto out; /* success */
10506+
10507+ if (namelen <= AUFS_WH_PFX_LEN
10508+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
10509+ if (au_ftest_testempty(arg->flags, WHONLY)
1308ab2a 10510+ && !au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 10511+ arg->err = -ENOTEMPTY;
10512+ goto out;
10513+ }
10514+
10515+ name += AUFS_WH_PFX_LEN;
10516+ namelen -= AUFS_WH_PFX_LEN;
1308ab2a 10517+ if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 10518+ arg->err = au_nhash_append_wh
1308ab2a 10519+ (arg->whlist, name, namelen, ino, d_type, arg->bindex,
dece6358 10520+ au_ftest_testempty(arg->flags, SHWH));
1facf9fc 10521+
4f0767ce 10522+out:
1facf9fc 10523+ /* smp_mb(); */
10524+ AuTraceErr(arg->err);
10525+ return arg->err;
10526+}
10527+
10528+static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
10529+{
10530+ int err;
10531+ struct file *h_file;
10532+
10533+ h_file = au_h_open(dentry, arg->bindex,
10534+ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
392086de 10535+ /*file*/NULL, /*force_wr*/0);
1facf9fc 10536+ err = PTR_ERR(h_file);
10537+ if (IS_ERR(h_file))
10538+ goto out;
10539+
10540+ err = 0;
10541+ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
c06a8ce3 10542+ && !file_inode(h_file)->i_nlink)
1facf9fc 10543+ goto out_put;
10544+
10545+ do {
10546+ arg->err = 0;
10547+ au_fclr_testempty(arg->flags, CALLED);
10548+ /* smp_mb(); */
392086de 10549+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1facf9fc 10550+ if (err >= 0)
10551+ err = arg->err;
10552+ } while (!err && au_ftest_testempty(arg->flags, CALLED));
10553+
4f0767ce 10554+out_put:
1facf9fc 10555+ fput(h_file);
10556+ au_sbr_put(dentry->d_sb, arg->bindex);
4f0767ce 10557+out:
1facf9fc 10558+ return err;
10559+}
10560+
10561+struct do_test_empty_args {
10562+ int *errp;
10563+ struct dentry *dentry;
10564+ struct test_empty_arg *arg;
10565+};
10566+
10567+static void call_do_test_empty(void *args)
10568+{
10569+ struct do_test_empty_args *a = args;
10570+ *a->errp = do_test_empty(a->dentry, a->arg);
10571+}
10572+
10573+static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
10574+{
10575+ int err, wkq_err;
10576+ struct dentry *h_dentry;
10577+ struct inode *h_inode;
10578+
10579+ h_dentry = au_h_dptr(dentry, arg->bindex);
5527c038 10580+ h_inode = d_inode(h_dentry);
53392da6 10581+ /* todo: i_mode changes anytime? */
ae9dfd79 10582+ vfsub_inode_lock_shared_nested(h_inode, AuLsc_I_CHILD);
1facf9fc 10583+ err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
ae9dfd79 10584+ inode_unlock_shared(h_inode);
1facf9fc 10585+ if (!err)
10586+ err = do_test_empty(dentry, arg);
10587+ else {
10588+ struct do_test_empty_args args = {
10589+ .errp = &err,
10590+ .dentry = dentry,
10591+ .arg = arg
10592+ };
10593+ unsigned int flags = arg->flags;
10594+
10595+ wkq_err = au_wkq_wait(call_do_test_empty, &args);
10596+ if (unlikely(wkq_err))
10597+ err = wkq_err;
10598+ arg->flags = flags;
10599+ }
10600+
10601+ return err;
10602+}
10603+
10604+int au_test_empty_lower(struct dentry *dentry)
10605+{
10606+ int err;
1308ab2a 10607+ unsigned int rdhash;
5afbbe0d 10608+ aufs_bindex_t bindex, btop, btail;
1308ab2a 10609+ struct au_nhash whlist;
392086de
AM
10610+ struct test_empty_arg arg = {
10611+ .ctx = {
2000de60 10612+ .actor = test_empty_cb
392086de
AM
10613+ }
10614+ };
076b876e 10615+ int (*test_empty)(struct dentry *dentry, struct test_empty_arg *arg);
1facf9fc 10616+
dece6358
AM
10617+ SiMustAnyLock(dentry->d_sb);
10618+
1308ab2a 10619+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
10620+ if (!rdhash)
10621+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry));
10622+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
dece6358 10623+ if (unlikely(err))
1facf9fc 10624+ goto out;
10625+
1facf9fc 10626+ arg.flags = 0;
1308ab2a 10627+ arg.whlist = &whlist;
5afbbe0d 10628+ btop = au_dbtop(dentry);
dece6358
AM
10629+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
10630+ au_fset_testempty(arg.flags, SHWH);
076b876e
AM
10631+ test_empty = do_test_empty;
10632+ if (au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1))
10633+ test_empty = sio_test_empty;
5afbbe0d 10634+ arg.bindex = btop;
076b876e 10635+ err = test_empty(dentry, &arg);
1facf9fc 10636+ if (unlikely(err))
10637+ goto out_whlist;
10638+
10639+ au_fset_testempty(arg.flags, WHONLY);
10640+ btail = au_dbtaildir(dentry);
5afbbe0d 10641+ for (bindex = btop + 1; !err && bindex <= btail; bindex++) {
1facf9fc 10642+ struct dentry *h_dentry;
10643+
10644+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 10645+ if (h_dentry && d_is_positive(h_dentry)) {
1facf9fc 10646+ arg.bindex = bindex;
076b876e 10647+ err = test_empty(dentry, &arg);
1facf9fc 10648+ }
10649+ }
10650+
4f0767ce 10651+out_whlist:
1308ab2a 10652+ au_nhash_wh_free(&whlist);
4f0767ce 10653+out:
1facf9fc 10654+ return err;
10655+}
10656+
10657+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
10658+{
10659+ int err;
392086de
AM
10660+ struct test_empty_arg arg = {
10661+ .ctx = {
2000de60 10662+ .actor = test_empty_cb
392086de
AM
10663+ }
10664+ };
1facf9fc 10665+ aufs_bindex_t bindex, btail;
10666+
10667+ err = 0;
1308ab2a 10668+ arg.whlist = whlist;
1facf9fc 10669+ arg.flags = AuTestEmpty_WHONLY;
dece6358
AM
10670+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
10671+ au_fset_testempty(arg.flags, SHWH);
1facf9fc 10672+ btail = au_dbtaildir(dentry);
5afbbe0d 10673+ for (bindex = au_dbtop(dentry); !err && bindex <= btail; bindex++) {
1facf9fc 10674+ struct dentry *h_dentry;
10675+
10676+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 10677+ if (h_dentry && d_is_positive(h_dentry)) {
1facf9fc 10678+ arg.bindex = bindex;
10679+ err = sio_test_empty(dentry, &arg);
10680+ }
10681+ }
10682+
10683+ return err;
10684+}
10685+
10686+/* ---------------------------------------------------------------------- */
10687+
10688+const struct file_operations aufs_dir_fop = {
4a4d8108 10689+ .owner = THIS_MODULE,
027c5e7a 10690+ .llseek = default_llseek,
1facf9fc 10691+ .read = generic_read_dir,
5afbbe0d 10692+ .iterate_shared = aufs_iterate_shared,
1facf9fc 10693+ .unlocked_ioctl = aufs_ioctl_dir,
b752ccd1
AM
10694+#ifdef CONFIG_COMPAT
10695+ .compat_ioctl = aufs_compat_ioctl_dir,
10696+#endif
1facf9fc 10697+ .open = aufs_open_dir,
10698+ .release = aufs_release_dir,
4a4d8108 10699+ .flush = aufs_flush_dir,
1facf9fc 10700+ .fsync = aufs_fsync_dir
10701+};
7f207e10
AM
10702diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
10703--- /usr/share/empty/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
10704+++ linux/fs/aufs/dir.h 2018-04-15 08:49:13.397817296 +0200
10705@@ -0,0 +1,131 @@
1facf9fc 10706+/*
ae9dfd79 10707+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 10708+ *
10709+ * This program, aufs is free software; you can redistribute it and/or modify
10710+ * it under the terms of the GNU General Public License as published by
10711+ * the Free Software Foundation; either version 2 of the License, or
10712+ * (at your option) any later version.
dece6358
AM
10713+ *
10714+ * This program is distributed in the hope that it will be useful,
10715+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10716+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10717+ * GNU General Public License for more details.
10718+ *
10719+ * You should have received a copy of the GNU General Public License
523b37e3 10720+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 10721+ */
10722+
10723+/*
10724+ * directory operations
10725+ */
10726+
10727+#ifndef __AUFS_DIR_H__
10728+#define __AUFS_DIR_H__
10729+
10730+#ifdef __KERNEL__
10731+
10732+#include <linux/fs.h>
1facf9fc 10733+
10734+/* ---------------------------------------------------------------------- */
10735+
10736+/* need to be faster and smaller */
10737+
10738+struct au_nhash {
dece6358
AM
10739+ unsigned int nh_num;
10740+ struct hlist_head *nh_head;
1facf9fc 10741+};
10742+
10743+struct au_vdir_destr {
10744+ unsigned char len;
10745+ unsigned char name[0];
10746+} __packed;
10747+
10748+struct au_vdir_dehstr {
10749+ struct hlist_node hash;
ae9dfd79 10750+ struct au_vdir_destr *str;
4a4d8108 10751+} ____cacheline_aligned_in_smp;
1facf9fc 10752+
10753+struct au_vdir_de {
10754+ ino_t de_ino;
10755+ unsigned char de_type;
10756+ /* caution: packed */
10757+ struct au_vdir_destr de_str;
10758+} __packed;
10759+
10760+struct au_vdir_wh {
10761+ struct hlist_node wh_hash;
dece6358
AM
10762+#ifdef CONFIG_AUFS_SHWH
10763+ ino_t wh_ino;
1facf9fc 10764+ aufs_bindex_t wh_bindex;
dece6358
AM
10765+ unsigned char wh_type;
10766+#else
10767+ aufs_bindex_t wh_bindex;
10768+#endif
10769+ /* caution: packed */
1facf9fc 10770+ struct au_vdir_destr wh_str;
10771+} __packed;
10772+
10773+union au_vdir_deblk_p {
10774+ unsigned char *deblk;
10775+ struct au_vdir_de *de;
10776+};
10777+
10778+struct au_vdir {
10779+ unsigned char **vd_deblk;
10780+ unsigned long vd_nblk;
1facf9fc 10781+ struct {
10782+ unsigned long ul;
10783+ union au_vdir_deblk_p p;
10784+ } vd_last;
10785+
10786+ unsigned long vd_version;
dece6358 10787+ unsigned int vd_deblk_sz;
ae9dfd79 10788+ unsigned long vd_jiffy;
4a4d8108 10789+} ____cacheline_aligned_in_smp;
1facf9fc 10790+
10791+/* ---------------------------------------------------------------------- */
10792+
10793+/* dir.c */
10794+extern const struct file_operations aufs_dir_fop;
10795+void au_add_nlink(struct inode *dir, struct inode *h_dir);
10796+void au_sub_nlink(struct inode *dir, struct inode *h_dir);
1308ab2a 10797+loff_t au_dir_size(struct file *file, struct dentry *dentry);
b912730e 10798+void au_dir_ts(struct inode *dir, aufs_bindex_t bsrc);
1facf9fc 10799+int au_test_empty_lower(struct dentry *dentry);
10800+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
10801+
10802+/* vdir.c */
1308ab2a 10803+unsigned int au_rdhash_est(loff_t sz);
dece6358
AM
10804+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
10805+void au_nhash_wh_free(struct au_nhash *whlist);
1facf9fc 10806+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
10807+ int limit);
dece6358
AM
10808+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
10809+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
10810+ unsigned int d_type, aufs_bindex_t bindex,
10811+ unsigned char shwh);
ae9dfd79 10812+void au_vdir_free(struct au_vdir *vdir);
1facf9fc 10813+int au_vdir_init(struct file *file);
392086de 10814+int au_vdir_fill_de(struct file *file, struct dir_context *ctx);
1facf9fc 10815+
10816+/* ioctl.c */
10817+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
10818+
1308ab2a 10819+#ifdef CONFIG_AUFS_RDU
10820+/* rdu.c */
10821+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
10822+#ifdef CONFIG_COMPAT
10823+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
10824+ unsigned long arg);
10825+#endif
1308ab2a 10826+#else
c1595e42
JR
10827+AuStub(long, au_rdu_ioctl, return -EINVAL, struct file *file,
10828+ unsigned int cmd, unsigned long arg)
b752ccd1 10829+#ifdef CONFIG_COMPAT
c1595e42
JR
10830+AuStub(long, au_rdu_compat_ioctl, return -EINVAL, struct file *file,
10831+ unsigned int cmd, unsigned long arg)
b752ccd1 10832+#endif
1308ab2a 10833+#endif
10834+
1facf9fc 10835+#endif /* __KERNEL__ */
10836+#endif /* __AUFS_DIR_H__ */
ae9dfd79
AM
10837diff -urN /usr/share/empty/fs/aufs/dirren.c linux/fs/aufs/dirren.c
10838--- /usr/share/empty/fs/aufs/dirren.c 1970-01-01 01:00:00.000000000 +0100
10839+++ linux/fs/aufs/dirren.c 2018-04-15 08:49:13.397817296 +0200
10840@@ -0,0 +1,1314 @@
10841+/*
10842+ * Copyright (C) 2017-2018 Junjiro R. Okajima
10843+ *
10844+ * This program, aufs is free software; you can redistribute it and/or modify
10845+ * it under the terms of the GNU General Public License as published by
10846+ * the Free Software Foundation; either version 2 of the License, or
10847+ * (at your option) any later version.
10848+ *
10849+ * This program is distributed in the hope that it will be useful,
10850+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10851+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10852+ * GNU General Public License for more details.
10853+ *
10854+ * You should have received a copy of the GNU General Public License
10855+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
10856+ */
10857+
10858+/*
10859+ * special handling in renaming a directoy
10860+ * in order to support looking-up the before-renamed name on the lower readonly
10861+ * branches
10862+ */
10863+
10864+#include <linux/byteorder/generic.h>
10865+#include "aufs.h"
10866+
10867+static void au_dr_hino_del(struct au_dr_br *dr, struct au_dr_hino *ent)
10868+{
10869+ int idx;
10870+
10871+ idx = au_dr_ihash(ent->dr_h_ino);
10872+ au_hbl_del(&ent->dr_hnode, dr->dr_h_ino + idx);
10873+}
10874+
10875+static int au_dr_hino_test_empty(struct au_dr_br *dr)
10876+{
10877+ int ret, i;
10878+ struct hlist_bl_head *hbl;
10879+
10880+ ret = 1;
10881+ for (i = 0; ret && i < AuDirren_NHASH; i++) {
10882+ hbl = dr->dr_h_ino + i;
10883+ hlist_bl_lock(hbl);
10884+ ret &= hlist_bl_empty(hbl);
10885+ hlist_bl_unlock(hbl);
10886+ }
10887+
10888+ return ret;
10889+}
10890+
10891+static struct au_dr_hino *au_dr_hino_find(struct au_dr_br *dr, ino_t ino)
10892+{
10893+ struct au_dr_hino *found, *ent;
10894+ struct hlist_bl_head *hbl;
10895+ struct hlist_bl_node *pos;
10896+ int idx;
10897+
10898+ found = NULL;
10899+ idx = au_dr_ihash(ino);
10900+ hbl = dr->dr_h_ino + idx;
10901+ hlist_bl_lock(hbl);
10902+ hlist_bl_for_each_entry(ent, pos, hbl, dr_hnode)
10903+ if (ent->dr_h_ino == ino) {
10904+ found = ent;
10905+ break;
10906+ }
10907+ hlist_bl_unlock(hbl);
10908+
10909+ return found;
10910+}
10911+
10912+int au_dr_hino_test_add(struct au_dr_br *dr, ino_t ino,
10913+ struct au_dr_hino *add_ent)
10914+{
10915+ int found, idx;
10916+ struct hlist_bl_head *hbl;
10917+ struct hlist_bl_node *pos;
10918+ struct au_dr_hino *ent;
10919+
10920+ found = 0;
10921+ idx = au_dr_ihash(ino);
10922+ hbl = dr->dr_h_ino + idx;
10923+#if 0
10924+ {
10925+ struct hlist_bl_node *tmp;
10926+
10927+ hlist_bl_for_each_entry_safe(ent, pos, tmp, hbl, dr_hnode)
10928+ AuDbg("hi%llu\n", (unsigned long long)ent->dr_h_ino);
10929+ }
10930+#endif
10931+ hlist_bl_lock(hbl);
10932+ hlist_bl_for_each_entry(ent, pos, hbl, dr_hnode)
10933+ if (ent->dr_h_ino == ino) {
10934+ found = 1;
10935+ break;
10936+ }
10937+ if (!found && add_ent)
10938+ hlist_bl_add_head(&add_ent->dr_hnode, hbl);
10939+ hlist_bl_unlock(hbl);
10940+
10941+ if (!found && add_ent)
10942+ AuDbg("i%llu added\n", (unsigned long long)add_ent->dr_h_ino);
10943+
10944+ return found;
10945+}
10946+
10947+void au_dr_hino_free(struct au_dr_br *dr)
10948+{
10949+ int i;
10950+ struct hlist_bl_head *hbl;
10951+ struct hlist_bl_node *pos, *tmp;
10952+ struct au_dr_hino *ent;
10953+
10954+ /* SiMustWriteLock(sb); */
10955+
10956+ for (i = 0; i < AuDirren_NHASH; i++) {
10957+ hbl = dr->dr_h_ino + i;
10958+ /* no spinlock since sbinfo must be write-locked */
10959+ hlist_bl_for_each_entry_safe(ent, pos, tmp, hbl, dr_hnode)
10960+ kfree(ent);
10961+ INIT_HLIST_BL_HEAD(hbl);
10962+ }
10963+}
10964+
10965+/* returns the number of inodes or an error */
10966+static int au_dr_hino_store(struct super_block *sb, struct au_branch *br,
10967+ struct file *hinofile)
10968+{
10969+ int err, i;
10970+ ssize_t ssz;
10971+ loff_t pos, oldsize;
10972+ uint64_t u64;
10973+ struct inode *hinoinode;
10974+ struct hlist_bl_head *hbl;
10975+ struct hlist_bl_node *n1, *n2;
10976+ struct au_dr_hino *ent;
10977+
10978+ SiMustWriteLock(sb);
10979+ AuDebugOn(!au_br_writable(br->br_perm));
10980+
10981+ hinoinode = file_inode(hinofile);
10982+ oldsize = i_size_read(hinoinode);
10983+
10984+ err = 0;
10985+ pos = 0;
10986+ hbl = br->br_dirren.dr_h_ino;
10987+ for (i = 0; !err && i < AuDirren_NHASH; i++, hbl++) {
10988+ /* no bit-lock since sbinfo must be write-locked */
10989+ hlist_bl_for_each_entry_safe(ent, n1, n2, hbl, dr_hnode) {
10990+ AuDbg("hi%llu, %pD2\n",
10991+ (unsigned long long)ent->dr_h_ino, hinofile);
10992+ u64 = cpu_to_be64(ent->dr_h_ino);
10993+ ssz = vfsub_write_k(hinofile, &u64, sizeof(u64), &pos);
10994+ if (ssz == sizeof(u64))
10995+ continue;
10996+
10997+ /* write error */
10998+ pr_err("ssz %zd, %pD2\n", ssz, hinofile);
10999+ err = -ENOSPC;
11000+ if (ssz < 0)
11001+ err = ssz;
11002+ break;
11003+ }
11004+ }
11005+ /* regardless the error */
11006+ if (pos < oldsize) {
11007+ err = vfsub_trunc(&hinofile->f_path, pos, /*attr*/0, hinofile);
11008+ AuTraceErr(err);
11009+ }
11010+
11011+ AuTraceErr(err);
11012+ return err;
11013+}
11014+
11015+static int au_dr_hino_load(struct au_dr_br *dr, struct file *hinofile)
11016+{
11017+ int err, hidx;
11018+ ssize_t ssz;
11019+ size_t sz, n;
11020+ loff_t pos;
11021+ uint64_t u64;
11022+ struct au_dr_hino *ent;
11023+ struct inode *hinoinode;
11024+ struct hlist_bl_head *hbl;
11025+
11026+ err = 0;
11027+ pos = 0;
11028+ hbl = dr->dr_h_ino;
11029+ hinoinode = file_inode(hinofile);
11030+ sz = i_size_read(hinoinode);
11031+ AuDebugOn(sz % sizeof(u64));
11032+ n = sz / sizeof(u64);
11033+ while (n--) {
11034+ ssz = vfsub_read_k(hinofile, &u64, sizeof(u64), &pos);
11035+ if (unlikely(ssz != sizeof(u64))) {
11036+ pr_err("ssz %zd, %pD2\n", ssz, hinofile);
11037+ err = -EINVAL;
11038+ if (ssz < 0)
11039+ err = ssz;
11040+ goto out_free;
11041+ }
11042+
11043+ ent = kmalloc(sizeof(*ent), GFP_NOFS);
11044+ if (!ent) {
11045+ err = -ENOMEM;
11046+ AuTraceErr(err);
11047+ goto out_free;
11048+ }
11049+ ent->dr_h_ino = be64_to_cpu(u64);
11050+ AuDbg("hi%llu, %pD2\n",
11051+ (unsigned long long)ent->dr_h_ino, hinofile);
11052+ hidx = au_dr_ihash(ent->dr_h_ino);
11053+ au_hbl_add(&ent->dr_hnode, hbl + hidx);
11054+ }
11055+ goto out; /* success */
11056+
11057+out_free:
11058+ au_dr_hino_free(dr);
11059+out:
11060+ AuTraceErr(err);
11061+ return err;
11062+}
11063+
11064+/*
11065+ * @bindex/@br is a switch to distinguish whether suspending hnotify or not.
11066+ * @path is a switch to distinguish load and store.
11067+ */
11068+static int au_dr_hino(struct super_block *sb, aufs_bindex_t bindex,
11069+ struct au_branch *br, const struct path *path)
11070+{
11071+ int err, flags;
11072+ unsigned char load, suspend;
11073+ struct file *hinofile;
11074+ struct au_hinode *hdir;
11075+ struct inode *dir, *delegated;
11076+ struct path hinopath;
11077+ struct qstr hinoname = QSTR_INIT(AUFS_WH_DR_BRHINO,
11078+ sizeof(AUFS_WH_DR_BRHINO) - 1);
11079+
11080+ AuDebugOn(bindex < 0 && !br);
11081+ AuDebugOn(bindex >= 0 && br);
11082+
11083+ err = -EINVAL;
11084+ suspend = !br;
11085+ if (suspend)
11086+ br = au_sbr(sb, bindex);
11087+ load = !!path;
11088+ if (!load) {
11089+ path = &br->br_path;
11090+ AuDebugOn(!au_br_writable(br->br_perm));
11091+ if (unlikely(!au_br_writable(br->br_perm)))
11092+ goto out;
11093+ }
11094+
11095+ hdir = NULL;
11096+ if (suspend) {
11097+ dir = d_inode(sb->s_root);
11098+ hdir = au_hinode(au_ii(dir), bindex);
11099+ dir = hdir->hi_inode;
11100+ au_hn_inode_lock_nested(hdir, AuLsc_I_CHILD);
11101+ } else {
11102+ dir = d_inode(path->dentry);
11103+ inode_lock_nested(dir, AuLsc_I_CHILD);
11104+ }
11105+ hinopath.dentry = vfsub_lkup_one(&hinoname, path->dentry);
11106+ err = PTR_ERR(hinopath.dentry);
11107+ if (IS_ERR(hinopath.dentry))
11108+ goto out_unlock;
11109+
11110+ err = 0;
11111+ flags = O_RDONLY;
11112+ if (load) {
11113+ if (d_is_negative(hinopath.dentry))
11114+ goto out_dput; /* success */
11115+ } else {
11116+ if (au_dr_hino_test_empty(&br->br_dirren)) {
11117+ if (d_is_positive(hinopath.dentry)) {
11118+ delegated = NULL;
11119+ err = vfsub_unlink(dir, &hinopath, &delegated,
11120+ /*force*/0);
11121+ AuTraceErr(err);
11122+ if (unlikely(err))
11123+ pr_err("ignored err %d, %pd2\n",
11124+ err, hinopath.dentry);
11125+ if (unlikely(err == -EWOULDBLOCK))
11126+ iput(delegated);
11127+ err = 0;
11128+ }
11129+ goto out_dput;
11130+ } else if (!d_is_positive(hinopath.dentry)) {
11131+ err = vfsub_create(dir, &hinopath, 0600,
11132+ /*want_excl*/false);
11133+ AuTraceErr(err);
11134+ if (unlikely(err))
11135+ goto out_dput;
11136+ }
11137+ flags = O_WRONLY;
11138+ }
11139+ hinopath.mnt = path->mnt;
11140+ hinofile = vfsub_dentry_open(&hinopath, flags);
11141+ if (suspend)
11142+ au_hn_inode_unlock(hdir);
11143+ else
11144+ inode_unlock(dir);
11145+ dput(hinopath.dentry);
11146+ AuTraceErrPtr(hinofile);
11147+ if (IS_ERR(hinofile)) {
11148+ err = PTR_ERR(hinofile);
11149+ goto out;
11150+ }
11151+
11152+ if (load)
11153+ err = au_dr_hino_load(&br->br_dirren, hinofile);
11154+ else
11155+ err = au_dr_hino_store(sb, br, hinofile);
11156+ fput(hinofile);
11157+ goto out;
11158+
11159+out_dput:
11160+ dput(hinopath.dentry);
11161+out_unlock:
11162+ if (suspend)
11163+ au_hn_inode_unlock(hdir);
11164+ else
11165+ inode_unlock(dir);
11166+out:
11167+ AuTraceErr(err);
11168+ return err;
11169+}
11170+
11171+/* ---------------------------------------------------------------------- */
11172+
11173+static int au_dr_brid_init(struct au_dr_brid *brid, const struct path *path)
11174+{
11175+ int err;
11176+ struct kstatfs kstfs;
11177+ dev_t dev;
11178+ struct dentry *dentry;
11179+ struct super_block *sb;
11180+
11181+ err = vfs_statfs((void *)path, &kstfs);
11182+ AuTraceErr(err);
11183+ if (unlikely(err))
11184+ goto out;
11185+
11186+ /* todo: support for UUID */
11187+
11188+ if (kstfs.f_fsid.val[0] || kstfs.f_fsid.val[1]) {
11189+ brid->type = AuBrid_FSID;
11190+ brid->fsid = kstfs.f_fsid;
11191+ } else {
11192+ dentry = path->dentry;
11193+ sb = dentry->d_sb;
11194+ dev = sb->s_dev;
11195+ if (dev) {
11196+ brid->type = AuBrid_DEV;
11197+ brid->dev = dev;
11198+ }
11199+ }
11200+
11201+out:
11202+ return err;
11203+}
11204+
11205+int au_dr_br_init(struct super_block *sb, struct au_branch *br,
11206+ const struct path *path)
11207+{
11208+ int err, i;
11209+ struct au_dr_br *dr;
11210+ struct hlist_bl_head *hbl;
11211+
11212+ dr = &br->br_dirren;
11213+ hbl = dr->dr_h_ino;
11214+ for (i = 0; i < AuDirren_NHASH; i++, hbl++)
11215+ INIT_HLIST_BL_HEAD(hbl);
11216+
11217+ err = au_dr_brid_init(&dr->dr_brid, path);
11218+ if (unlikely(err))
11219+ goto out;
11220+
11221+ if (au_opt_test(au_mntflags(sb), DIRREN))
11222+ err = au_dr_hino(sb, /*bindex*/-1, br, path);
11223+
11224+out:
11225+ AuTraceErr(err);
11226+ return err;
11227+}
11228+
11229+int au_dr_br_fin(struct super_block *sb, struct au_branch *br)
11230+{
11231+ int err;
11232+
11233+ err = 0;
11234+ if (au_br_writable(br->br_perm))
11235+ err = au_dr_hino(sb, /*bindex*/-1, br, /*path*/NULL);
11236+ if (!err)
11237+ au_dr_hino_free(&br->br_dirren);
11238+
11239+ return err;
11240+}
11241+
11242+/* ---------------------------------------------------------------------- */
11243+
11244+static int au_brid_str(struct au_dr_brid *brid, struct inode *h_inode,
11245+ char *buf, size_t sz)
11246+{
11247+ int err;
11248+ unsigned int major, minor;
11249+ char *p;
11250+
11251+ p = buf;
11252+ err = snprintf(p, sz, "%d_", brid->type);
11253+ AuDebugOn(err > sz);
11254+ p += err;
11255+ sz -= err;
11256+ switch (brid->type) {
11257+ case AuBrid_Unset:
11258+ return -EINVAL;
11259+ case AuBrid_UUID:
11260+ err = snprintf(p, sz, "%pU", brid->uuid.__u_bits);
11261+ break;
11262+ case AuBrid_FSID:
11263+ err = snprintf(p, sz, "%08x-%08x",
11264+ brid->fsid.val[0], brid->fsid.val[1]);
11265+ break;
11266+ case AuBrid_DEV:
11267+ major = MAJOR(brid->dev);
11268+ minor = MINOR(brid->dev);
11269+ if (major <= 0xff && minor <= 0xff)
11270+ err = snprintf(p, sz, "%02x%02x", major, minor);
11271+ else
11272+ err = snprintf(p, sz, "%03x:%05x", major, minor);
11273+ break;
11274+ }
11275+ AuDebugOn(err > sz);
11276+ p += err;
11277+ sz -= err;
11278+ err = snprintf(p, sz, "_%llu", (unsigned long long)h_inode->i_ino);
11279+ AuDebugOn(err > sz);
11280+ p += err;
11281+ sz -= err;
11282+
11283+ return p - buf;
11284+}
11285+
11286+static int au_drinfo_name(struct au_branch *br, char *name, int len)
11287+{
11288+ int rlen;
11289+ struct dentry *br_dentry;
11290+ struct inode *br_inode;
11291+
11292+ br_dentry = au_br_dentry(br);
11293+ br_inode = d_inode(br_dentry);
11294+ rlen = au_brid_str(&br->br_dirren.dr_brid, br_inode, name, len);
11295+ AuDebugOn(rlen >= AUFS_DIRREN_ENV_VAL_SZ);
11296+ AuDebugOn(rlen > len);
11297+
11298+ return rlen;
11299+}
11300+
11301+/* ---------------------------------------------------------------------- */
11302+
11303+/*
11304+ * from the given @h_dentry, construct drinfo at @*fdata.
11305+ * when the size of @*fdata is not enough, reallocate and return new @fdata and
11306+ * @allocated.
11307+ */
11308+static int au_drinfo_construct(struct au_drinfo_fdata **fdata,
11309+ struct dentry *h_dentry,
11310+ unsigned char *allocated)
11311+{
11312+ int err, v;
11313+ struct au_drinfo_fdata *f, *p;
11314+ struct au_drinfo *drinfo;
11315+ struct inode *h_inode;
11316+ struct qstr *qname;
11317+
11318+ err = 0;
11319+ f = *fdata;
11320+ h_inode = d_inode(h_dentry);
11321+ qname = &h_dentry->d_name;
11322+ drinfo = &f->drinfo;
11323+ drinfo->ino = cpu_to_be64(h_inode->i_ino);
11324+ drinfo->oldnamelen = qname->len;
11325+ if (*allocated < sizeof(*f) + qname->len) {
11326+ v = roundup_pow_of_two(*allocated + qname->len);
11327+ p = au_krealloc(f, v, GFP_NOFS, /*may_shrink*/0);
11328+ if (unlikely(!p)) {
11329+ err = -ENOMEM;
11330+ AuTraceErr(err);
11331+ goto out;
11332+ }
11333+ f = p;
11334+ *fdata = f;
11335+ *allocated = v;
11336+ drinfo = &f->drinfo;
11337+ }
11338+ memcpy(drinfo->oldname, qname->name, qname->len);
11339+ AuDbg("i%llu, %.*s\n",
11340+ be64_to_cpu(drinfo->ino), drinfo->oldnamelen, drinfo->oldname);
11341+
11342+out:
11343+ AuTraceErr(err);
11344+ return err;
11345+}
11346+
11347+/* callers have to free the return value */
11348+static struct au_drinfo *au_drinfo_read_k(struct file *file, ino_t h_ino)
11349+{
11350+ struct au_drinfo *ret, *drinfo;
11351+ struct au_drinfo_fdata fdata;
11352+ int len;
11353+ loff_t pos;
11354+ ssize_t ssz;
11355+
11356+ ret = ERR_PTR(-EIO);
11357+ pos = 0;
11358+ ssz = vfsub_read_k(file, &fdata, sizeof(fdata), &pos);
11359+ if (unlikely(ssz != sizeof(fdata))) {
11360+ AuIOErr("ssz %zd, %u, %pD2\n",
11361+ ssz, (unsigned int)sizeof(fdata), file);
11362+ goto out;
11363+ }
11364+
11365+ fdata.magic = ntohl(fdata.magic);
11366+ switch (fdata.magic) {
11367+ case AUFS_DRINFO_MAGIC_V1:
11368+ break;
11369+ default:
11370+ AuIOErr("magic-num 0x%x, 0x%x, %pD2\n",
11371+ fdata.magic, AUFS_DRINFO_MAGIC_V1, file);
11372+ goto out;
11373+ }
11374+
11375+ drinfo = &fdata.drinfo;
11376+ len = drinfo->oldnamelen;
11377+ if (!len) {
11378+ AuIOErr("broken drinfo %pD2\n", file);
11379+ goto out;
11380+ }
11381+
11382+ ret = NULL;
11383+ drinfo->ino = be64_to_cpu(drinfo->ino);
11384+ if (unlikely(h_ino && drinfo->ino != h_ino)) {
11385+ AuDbg("ignored i%llu, i%llu, %pD2\n",
11386+ (unsigned long long)drinfo->ino,
11387+ (unsigned long long)h_ino, file);
11388+ goto out; /* success */
11389+ }
11390+
11391+ ret = kmalloc(sizeof(*ret) + len, GFP_NOFS);
11392+ if (unlikely(!ret)) {
11393+ ret = ERR_PTR(-ENOMEM);
11394+ AuTraceErrPtr(ret);
11395+ goto out;
11396+ }
11397+
11398+ *ret = *drinfo;
11399+ ssz = vfsub_read_k(file, (void *)ret->oldname, len, &pos);
11400+ if (unlikely(ssz != len)) {
11401+ kfree(ret);
11402+ ret = ERR_PTR(-EIO);
11403+ AuIOErr("ssz %zd, %u, %pD2\n", ssz, len, file);
11404+ goto out;
11405+ }
11406+
11407+ AuDbg("oldname %.*s\n", ret->oldnamelen, ret->oldname);
11408+
11409+out:
11410+ return ret;
11411+}
11412+
11413+/* ---------------------------------------------------------------------- */
11414+
11415+/* in order to be revertible */
11416+struct au_drinfo_rev_elm {
11417+ int created;
11418+ struct dentry *info_dentry;
11419+ struct au_drinfo *info_last;
11420+};
11421+
11422+struct au_drinfo_rev {
11423+ unsigned char already;
11424+ aufs_bindex_t nelm;
11425+ struct au_drinfo_rev_elm elm[0];
11426+};
11427+
11428+/* todo: isn't it too large? */
11429+struct au_drinfo_store {
11430+ struct path h_ppath;
11431+ struct dentry *h_dentry;
11432+ struct au_drinfo_fdata *fdata;
11433+ char *infoname; /* inside of whname, just after PFX */
11434+ char whname[sizeof(AUFS_WH_DR_INFO_PFX) + AUFS_DIRREN_ENV_VAL_SZ];
11435+ aufs_bindex_t btgt, btail;
11436+ unsigned char no_sio,
11437+ allocated, /* current size of *fdata */
11438+ infonamelen, /* room size for p */
11439+ whnamelen, /* length of the genarated name */
11440+ renameback; /* renamed back */
11441+};
11442+
11443+/* on rename(2) error, the caller should revert it using @elm */
11444+static int au_drinfo_do_store(struct au_drinfo_store *w,
11445+ struct au_drinfo_rev_elm *elm)
11446+{
11447+ int err, len;
11448+ ssize_t ssz;
11449+ loff_t pos;
11450+ struct path infopath = {
11451+ .mnt = w->h_ppath.mnt
11452+ };
11453+ struct inode *h_dir, *h_inode, *delegated;
11454+ struct file *infofile;
11455+ struct qstr *qname;
11456+
11457+ AuDebugOn(elm
11458+ && memcmp(elm, page_address(ZERO_PAGE(0)), sizeof(*elm)));
11459+
11460+ infopath.dentry = vfsub_lookup_one_len(w->whname, w->h_ppath.dentry,
11461+ w->whnamelen);
11462+ AuTraceErrPtr(infopath.dentry);
11463+ if (IS_ERR(infopath.dentry)) {
11464+ err = PTR_ERR(infopath.dentry);
11465+ goto out;
11466+ }
11467+
11468+ err = 0;
11469+ h_dir = d_inode(w->h_ppath.dentry);
11470+ if (elm && d_is_negative(infopath.dentry)) {
11471+ err = vfsub_create(h_dir, &infopath, 0600, /*want_excl*/true);
11472+ AuTraceErr(err);
11473+ if (unlikely(err))
11474+ goto out_dput;
11475+ elm->created = 1;
11476+ elm->info_dentry = dget(infopath.dentry);
11477+ }
11478+
11479+ infofile = vfsub_dentry_open(&infopath, O_RDWR);
11480+ AuTraceErrPtr(infofile);
11481+ if (IS_ERR(infofile)) {
11482+ err = PTR_ERR(infofile);
11483+ goto out_dput;
11484+ }
11485+
11486+ h_inode = d_inode(infopath.dentry);
11487+ if (elm && i_size_read(h_inode)) {
11488+ h_inode = d_inode(w->h_dentry);
11489+ elm->info_last = au_drinfo_read_k(infofile, h_inode->i_ino);
11490+ AuTraceErrPtr(elm->info_last);
11491+ if (IS_ERR(elm->info_last)) {
11492+ err = PTR_ERR(elm->info_last);
11493+ elm->info_last = NULL;
11494+ AuDebugOn(elm->info_dentry);
11495+ goto out_fput;
11496+ }
11497+ }
11498+
11499+ if (elm && w->renameback) {
11500+ delegated = NULL;
11501+ err = vfsub_unlink(h_dir, &infopath, &delegated, /*force*/0);
11502+ AuTraceErr(err);
11503+ if (unlikely(err == -EWOULDBLOCK))
11504+ iput(delegated);
11505+ goto out_fput;
11506+ }
11507+
11508+ pos = 0;
11509+ qname = &w->h_dentry->d_name;
11510+ len = sizeof(*w->fdata) + qname->len;
11511+ if (!elm)
11512+ len = sizeof(*w->fdata) + w->fdata->drinfo.oldnamelen;
11513+ ssz = vfsub_write_k(infofile, w->fdata, len, &pos);
11514+ if (ssz == len) {
11515+ AuDbg("hi%llu, %.*s\n", w->fdata->drinfo.ino,
11516+ w->fdata->drinfo.oldnamelen, w->fdata->drinfo.oldname);
11517+ goto out_fput; /* success */
11518+ } else {
11519+ err = -EIO;
11520+ if (ssz < 0)
11521+ err = ssz;
11522+ /* the caller should revert it using @elm */
11523+ }
11524+
11525+out_fput:
11526+ fput(infofile);
11527+out_dput:
11528+ dput(infopath.dentry);
11529+out:
11530+ AuTraceErr(err);
11531+ return err;
11532+}
11533+
11534+struct au_call_drinfo_do_store_args {
11535+ int *errp;
11536+ struct au_drinfo_store *w;
11537+ struct au_drinfo_rev_elm *elm;
11538+};
11539+
11540+static void au_call_drinfo_do_store(void *args)
11541+{
11542+ struct au_call_drinfo_do_store_args *a = args;
11543+
11544+ *a->errp = au_drinfo_do_store(a->w, a->elm);
11545+}
11546+
11547+static int au_drinfo_store_sio(struct au_drinfo_store *w,
11548+ struct au_drinfo_rev_elm *elm)
11549+{
11550+ int err, wkq_err;
11551+
11552+ if (w->no_sio)
11553+ err = au_drinfo_do_store(w, elm);
11554+ else {
11555+ struct au_call_drinfo_do_store_args a = {
11556+ .errp = &err,
11557+ .w = w,
11558+ .elm = elm
11559+ };
11560+ wkq_err = au_wkq_wait(au_call_drinfo_do_store, &a);
11561+ if (unlikely(wkq_err))
11562+ err = wkq_err;
11563+ }
11564+ AuTraceErr(err);
11565+
11566+ return err;
11567+}
11568+
11569+static int au_drinfo_store_work_init(struct au_drinfo_store *w,
11570+ aufs_bindex_t btgt)
11571+{
11572+ int err;
11573+
11574+ memset(w, 0, sizeof(*w));
11575+ w->allocated = roundup_pow_of_two(sizeof(*w->fdata) + 40);
11576+ strcpy(w->whname, AUFS_WH_DR_INFO_PFX);
11577+ w->infoname = w->whname + sizeof(AUFS_WH_DR_INFO_PFX) - 1;
11578+ w->infonamelen = sizeof(w->whname) - sizeof(AUFS_WH_DR_INFO_PFX);
11579+ w->btgt = btgt;
11580+ w->no_sio = !!uid_eq(current_fsuid(), GLOBAL_ROOT_UID);
11581+
11582+ err = -ENOMEM;
11583+ w->fdata = kcalloc(1, w->allocated, GFP_NOFS);
11584+ if (unlikely(!w->fdata)) {
11585+ AuTraceErr(err);
11586+ goto out;
11587+ }
11588+ w->fdata->magic = htonl(AUFS_DRINFO_MAGIC_V1);
11589+ err = 0;
11590+
11591+out:
11592+ return err;
11593+}
11594+
11595+static void au_drinfo_store_work_fin(struct au_drinfo_store *w)
11596+{
11597+ kfree(w->fdata);
11598+}
11599+
11600+static void au_drinfo_store_rev(struct au_drinfo_rev *rev,
11601+ struct au_drinfo_store *w)
11602+{
11603+ struct au_drinfo_rev_elm *elm;
11604+ struct inode *h_dir, *delegated;
11605+ int err, nelm;
11606+ struct path infopath = {
11607+ .mnt = w->h_ppath.mnt
11608+ };
11609+
11610+ h_dir = d_inode(w->h_ppath.dentry);
11611+ IMustLock(h_dir);
11612+
11613+ err = 0;
11614+ elm = rev->elm;
11615+ for (nelm = rev->nelm; nelm > 0; nelm--, elm++) {
11616+ AuDebugOn(elm->created && elm->info_last);
11617+ if (elm->created) {
11618+ AuDbg("here\n");
11619+ delegated = NULL;
11620+ infopath.dentry = elm->info_dentry;
11621+ err = vfsub_unlink(h_dir, &infopath, &delegated,
11622+ !w->no_sio);
11623+ AuTraceErr(err);
11624+ if (unlikely(err == -EWOULDBLOCK))
11625+ iput(delegated);
11626+ dput(elm->info_dentry);
11627+ } else if (elm->info_last) {
11628+ AuDbg("here\n");
11629+ w->fdata->drinfo = *elm->info_last;
11630+ memcpy(w->fdata->drinfo.oldname,
11631+ elm->info_last->oldname,
11632+ elm->info_last->oldnamelen);
11633+ err = au_drinfo_store_sio(w, /*elm*/NULL);
11634+ kfree(elm->info_last);
11635+ }
11636+ if (unlikely(err))
11637+ AuIOErr("%d, %s\n", err, w->whname);
11638+ /* go on even if err */
11639+ }
11640+}
11641+
11642+/* caller has to call au_dr_rename_fin() later */
11643+static int au_drinfo_store(struct dentry *dentry, aufs_bindex_t btgt,
11644+ struct qstr *dst_name, void *_rev)
11645+{
11646+ int err, sz, nelm;
11647+ aufs_bindex_t bindex, btail;
11648+ struct au_drinfo_store work;
11649+ struct au_drinfo_rev *rev, **p;
11650+ struct au_drinfo_rev_elm *elm;
11651+ struct super_block *sb;
11652+ struct au_branch *br;
11653+ struct au_hinode *hdir;
11654+
11655+ err = au_drinfo_store_work_init(&work, btgt);
11656+ AuTraceErr(err);
11657+ if (unlikely(err))
11658+ goto out;
11659+
11660+ err = -ENOMEM;
11661+ btail = au_dbtaildir(dentry);
11662+ nelm = btail - btgt;
11663+ sz = sizeof(*rev) + sizeof(*elm) * nelm;
11664+ rev = kcalloc(1, sz, GFP_NOFS);
11665+ if (unlikely(!rev)) {
11666+ AuTraceErr(err);
11667+ goto out_args;
11668+ }
11669+ rev->nelm = nelm;
11670+ elm = rev->elm;
11671+ p = _rev;
11672+ *p = rev;
11673+
11674+ err = 0;
11675+ sb = dentry->d_sb;
11676+ work.h_ppath.dentry = au_h_dptr(dentry, btgt);
11677+ work.h_ppath.mnt = au_sbr_mnt(sb, btgt);
11678+ hdir = au_hi(d_inode(dentry), btgt);
11679+ au_hn_inode_lock_nested(hdir, AuLsc_I_CHILD);
11680+ for (bindex = btgt + 1; bindex <= btail; bindex++, elm++) {
11681+ work.h_dentry = au_h_dptr(dentry, bindex);
11682+ if (!work.h_dentry)
11683+ continue;
11684+
11685+ err = au_drinfo_construct(&work.fdata, work.h_dentry,
11686+ &work.allocated);
11687+ AuTraceErr(err);
11688+ if (unlikely(err))
11689+ break;
11690+
11691+ work.renameback = au_qstreq(&work.h_dentry->d_name, dst_name);
11692+ br = au_sbr(sb, bindex);
11693+ work.whnamelen = sizeof(AUFS_WH_DR_INFO_PFX) - 1;
11694+ work.whnamelen += au_drinfo_name(br, work.infoname,
11695+ work.infonamelen);
11696+ AuDbg("whname %.*s, i%llu, %.*s\n",
11697+ work.whnamelen, work.whname,
11698+ be64_to_cpu(work.fdata->drinfo.ino),
11699+ work.fdata->drinfo.oldnamelen,
11700+ work.fdata->drinfo.oldname);
11701+
11702+ err = au_drinfo_store_sio(&work, elm);
11703+ AuTraceErr(err);
11704+ if (unlikely(err))
11705+ break;
11706+ }
11707+ if (unlikely(err)) {
11708+ /* revert all drinfo */
11709+ au_drinfo_store_rev(rev, &work);
11710+ kfree(rev);
11711+ *p = NULL;
11712+ }
11713+ au_hn_inode_unlock(hdir);
11714+
11715+out_args:
11716+ au_drinfo_store_work_fin(&work);
11717+out:
11718+ return err;
11719+}
11720+
11721+/* ---------------------------------------------------------------------- */
11722+
11723+int au_dr_rename(struct dentry *src, aufs_bindex_t bindex,
11724+ struct qstr *dst_name, void *_rev)
11725+{
11726+ int err, already;
11727+ ino_t ino;
11728+ struct super_block *sb;
11729+ struct au_branch *br;
11730+ struct au_dr_br *dr;
11731+ struct dentry *h_dentry;
11732+ struct inode *h_inode;
11733+ struct au_dr_hino *ent;
11734+ struct au_drinfo_rev *rev, **p;
11735+
11736+ AuDbg("bindex %d\n", bindex);
11737+
11738+ err = -ENOMEM;
11739+ ent = kmalloc(sizeof(*ent), GFP_NOFS);
11740+ if (unlikely(!ent))
11741+ goto out;
11742+
11743+ sb = src->d_sb;
11744+ br = au_sbr(sb, bindex);
11745+ dr = &br->br_dirren;
11746+ h_dentry = au_h_dptr(src, bindex);
11747+ h_inode = d_inode(h_dentry);
11748+ ino = h_inode->i_ino;
11749+ ent->dr_h_ino = ino;
11750+ already = au_dr_hino_test_add(dr, ino, ent);
11751+ AuDbg("b%d, hi%llu, already %d\n",
11752+ bindex, (unsigned long long)ino, already);
11753+
11754+ err = au_drinfo_store(src, bindex, dst_name, _rev);
11755+ AuTraceErr(err);
11756+ if (!err) {
11757+ p = _rev;
11758+ rev = *p;
11759+ rev->already = already;
11760+ goto out; /* success */
11761+ }
11762+
11763+ /* revert */
11764+ if (!already)
11765+ au_dr_hino_del(dr, ent);
11766+ kfree(ent);
11767+
11768+out:
11769+ AuTraceErr(err);
11770+ return err;
11771+}
11772+
11773+void au_dr_rename_fin(struct dentry *src, aufs_bindex_t btgt, void *_rev)
11774+{
11775+ struct au_drinfo_rev *rev;
11776+ struct au_drinfo_rev_elm *elm;
11777+ int nelm;
11778+
11779+ rev = _rev;
11780+ elm = rev->elm;
11781+ for (nelm = rev->nelm; nelm > 0; nelm--, elm++) {
11782+ dput(elm->info_dentry);
11783+ kfree(elm->info_last);
11784+ }
11785+ kfree(rev);
11786+}
11787+
11788+void au_dr_rename_rev(struct dentry *src, aufs_bindex_t btgt, void *_rev)
11789+{
11790+ int err;
11791+ struct au_drinfo_store work;
11792+ struct au_drinfo_rev *rev = _rev;
11793+ struct super_block *sb;
11794+ struct au_branch *br;
11795+ struct inode *h_inode;
11796+ struct au_dr_br *dr;
11797+ struct au_dr_hino *ent;
11798+
11799+ err = au_drinfo_store_work_init(&work, btgt);
11800+ if (unlikely(err))
11801+ goto out;
11802+
11803+ sb = src->d_sb;
11804+ br = au_sbr(sb, btgt);
11805+ work.h_ppath.dentry = au_h_dptr(src, btgt);
11806+ work.h_ppath.mnt = au_br_mnt(br);
11807+ au_drinfo_store_rev(rev, &work);
11808+ au_drinfo_store_work_fin(&work);
11809+ if (rev->already)
11810+ goto out;
11811+
11812+ dr = &br->br_dirren;
11813+ h_inode = d_inode(work.h_ppath.dentry);
11814+ ent = au_dr_hino_find(dr, h_inode->i_ino);
11815+ BUG_ON(!ent);
11816+ au_dr_hino_del(dr, ent);
11817+ kfree(ent);
11818+
11819+out:
11820+ kfree(rev);
11821+ if (unlikely(err))
11822+ pr_err("failed to remove dirren info\n");
11823+}
11824+
11825+/* ---------------------------------------------------------------------- */
11826+
11827+static struct au_drinfo *au_drinfo_do_load(struct path *h_ppath,
11828+ char *whname, int whnamelen,
11829+ struct dentry **info_dentry)
11830+{
11831+ struct au_drinfo *drinfo;
11832+ struct file *f;
11833+ struct inode *h_dir;
11834+ struct path infopath;
11835+ int unlocked;
11836+
11837+ AuDbg("%pd/%.*s\n", h_ppath->dentry, whnamelen, whname);
11838+
11839+ *info_dentry = NULL;
11840+ drinfo = NULL;
11841+ unlocked = 0;
11842+ h_dir = d_inode(h_ppath->dentry);
11843+ vfsub_inode_lock_shared_nested(h_dir, AuLsc_I_PARENT);
11844+ infopath.dentry = vfsub_lookup_one_len(whname, h_ppath->dentry,
11845+ whnamelen);
11846+ if (IS_ERR(infopath.dentry)) {
11847+ drinfo = (void *)infopath.dentry;
11848+ goto out;
11849+ }
11850+
11851+ if (d_is_negative(infopath.dentry))
11852+ goto out_dput; /* success */
11853+
11854+ infopath.mnt = h_ppath->mnt;
11855+ f = vfsub_dentry_open(&infopath, O_RDONLY);
11856+ inode_unlock_shared(h_dir);
11857+ unlocked = 1;
11858+ if (IS_ERR(f)) {
11859+ drinfo = (void *)f;
11860+ goto out_dput;
11861+ }
11862+
11863+ drinfo = au_drinfo_read_k(f, /*h_ino*/0);
11864+ if (IS_ERR_OR_NULL(drinfo))
11865+ goto out_fput;
11866+
11867+ AuDbg("oldname %.*s\n", drinfo->oldnamelen, drinfo->oldname);
11868+ *info_dentry = dget(infopath.dentry); /* keep it alive */
11869+
11870+out_fput:
11871+ fput(f);
11872+out_dput:
11873+ dput(infopath.dentry);
11874+out:
11875+ if (!unlocked)
11876+ inode_unlock_shared(h_dir);
11877+ AuTraceErrPtr(drinfo);
11878+ return drinfo;
11879+}
11880+
11881+struct au_drinfo_do_load_args {
11882+ struct au_drinfo **drinfop;
11883+ struct path *h_ppath;
11884+ char *whname;
11885+ int whnamelen;
11886+ struct dentry **info_dentry;
11887+};
11888+
11889+static void au_call_drinfo_do_load(void *args)
11890+{
11891+ struct au_drinfo_do_load_args *a = args;
11892+
11893+ *a->drinfop = au_drinfo_do_load(a->h_ppath, a->whname, a->whnamelen,
11894+ a->info_dentry);
11895+}
11896+
11897+struct au_drinfo_load {
11898+ struct path h_ppath;
11899+ struct qstr *qname;
11900+ unsigned char no_sio;
11901+
11902+ aufs_bindex_t ninfo;
11903+ struct au_drinfo **drinfo;
11904+};
11905+
11906+static int au_drinfo_load(struct au_drinfo_load *w, aufs_bindex_t bindex,
11907+ struct au_branch *br)
11908+{
11909+ int err, wkq_err, whnamelen, e;
11910+ char whname[sizeof(AUFS_WH_DR_INFO_PFX) + AUFS_DIRREN_ENV_VAL_SZ]
11911+ = AUFS_WH_DR_INFO_PFX;
11912+ struct au_drinfo *drinfo;
11913+ struct qstr oldname;
11914+ struct inode *h_dir, *delegated;
11915+ struct dentry *info_dentry;
11916+ struct path infopath;
11917+
11918+ whnamelen = sizeof(AUFS_WH_DR_INFO_PFX) - 1;
11919+ whnamelen += au_drinfo_name(br, whname + whnamelen,
11920+ sizeof(whname) - whnamelen);
11921+ if (w->no_sio)
11922+ drinfo = au_drinfo_do_load(&w->h_ppath, whname, whnamelen,
11923+ &info_dentry);
11924+ else {
11925+ struct au_drinfo_do_load_args args = {
11926+ .drinfop = &drinfo,
11927+ .h_ppath = &w->h_ppath,
11928+ .whname = whname,
11929+ .whnamelen = whnamelen,
11930+ .info_dentry = &info_dentry
11931+ };
11932+ wkq_err = au_wkq_wait(au_call_drinfo_do_load, &args);
11933+ if (unlikely(wkq_err))
11934+ drinfo = ERR_PTR(wkq_err);
11935+ }
11936+ err = PTR_ERR(drinfo);
11937+ if (IS_ERR_OR_NULL(drinfo))
11938+ goto out;
11939+
11940+ err = 0;
11941+ oldname.len = drinfo->oldnamelen;
11942+ oldname.name = drinfo->oldname;
11943+ if (au_qstreq(w->qname, &oldname)) {
11944+ /* the name is renamed back */
11945+ kfree(drinfo);
11946+ drinfo = NULL;
11947+
11948+ infopath.dentry = info_dentry;
11949+ infopath.mnt = w->h_ppath.mnt;
11950+ h_dir = d_inode(w->h_ppath.dentry);
11951+ delegated = NULL;
11952+ inode_lock_nested(h_dir, AuLsc_I_PARENT);
11953+ e = vfsub_unlink(h_dir, &infopath, &delegated, !w->no_sio);
11954+ inode_unlock(h_dir);
11955+ if (unlikely(e))
11956+ AuIOErr("ignored %d, %pd2\n", e, &infopath.dentry);
11957+ if (unlikely(e == -EWOULDBLOCK))
11958+ iput(delegated);
11959+ }
11960+ kfree(w->drinfo[bindex]);
11961+ w->drinfo[bindex] = drinfo;
11962+ dput(info_dentry);
11963+
11964+out:
11965+ AuTraceErr(err);
11966+ return err;
11967+}
11968+
11969+/* ---------------------------------------------------------------------- */
11970+
11971+static void au_dr_lkup_free(struct au_drinfo **drinfo, int n)
11972+{
11973+ struct au_drinfo **p = drinfo;
11974+
11975+ while (n-- > 0)
11976+ kfree(*drinfo++);
11977+ kfree(p);
11978+}
11979+
11980+int au_dr_lkup(struct au_do_lookup_args *lkup, struct dentry *dentry,
11981+ aufs_bindex_t btgt)
11982+{
11983+ int err, ninfo;
11984+ struct au_drinfo_load w;
11985+ aufs_bindex_t bindex, bbot;
11986+ struct au_branch *br;
11987+ struct inode *h_dir;
11988+ struct au_dr_hino *ent;
11989+ struct super_block *sb;
11990+
11991+ AuDbg("%.*s, name %.*s, whname %.*s, b%d\n",
11992+ AuLNPair(&dentry->d_name), AuLNPair(&lkup->dirren.dr_name),
11993+ AuLNPair(&lkup->whname), btgt);
11994+
11995+ sb = dentry->d_sb;
11996+ bbot = au_sbbot(sb);
11997+ w.ninfo = bbot + 1;
11998+ if (!lkup->dirren.drinfo) {
11999+ lkup->dirren.drinfo = kcalloc(w.ninfo,
12000+ sizeof(*lkup->dirren.drinfo),
12001+ GFP_NOFS);
12002+ if (unlikely(!lkup->dirren.drinfo)) {
12003+ err = -ENOMEM;
12004+ goto out;
12005+ }
12006+ lkup->dirren.ninfo = w.ninfo;
12007+ }
12008+ w.drinfo = lkup->dirren.drinfo;
12009+ w.no_sio = !!uid_eq(current_fsuid(), GLOBAL_ROOT_UID);
12010+ w.h_ppath.dentry = au_h_dptr(dentry, btgt);
12011+ AuDebugOn(!w.h_ppath.dentry);
12012+ w.h_ppath.mnt = au_sbr_mnt(sb, btgt);
12013+ w.qname = &dentry->d_name;
12014+
12015+ ninfo = 0;
12016+ for (bindex = btgt + 1; bindex <= bbot; bindex++) {
12017+ br = au_sbr(sb, bindex);
12018+ err = au_drinfo_load(&w, bindex, br);
12019+ if (unlikely(err))
12020+ goto out_free;
12021+ if (w.drinfo[bindex])
12022+ ninfo++;
12023+ }
12024+ if (!ninfo) {
12025+ br = au_sbr(sb, btgt);
12026+ h_dir = d_inode(w.h_ppath.dentry);
12027+ ent = au_dr_hino_find(&br->br_dirren, h_dir->i_ino);
12028+ AuDebugOn(!ent);
12029+ au_dr_hino_del(&br->br_dirren, ent);
12030+ kfree(ent);
12031+ }
12032+ goto out; /* success */
12033+
12034+out_free:
12035+ au_dr_lkup_free(lkup->dirren.drinfo, lkup->dirren.ninfo);
12036+ lkup->dirren.ninfo = 0;
12037+ lkup->dirren.drinfo = NULL;
12038+out:
12039+ AuTraceErr(err);
12040+ return err;
12041+}
12042+
12043+void au_dr_lkup_fin(struct au_do_lookup_args *lkup)
12044+{
12045+ au_dr_lkup_free(lkup->dirren.drinfo, lkup->dirren.ninfo);
12046+}
12047+
12048+int au_dr_lkup_name(struct au_do_lookup_args *lkup, aufs_bindex_t btgt)
12049+{
12050+ int err;
12051+ struct au_drinfo *drinfo;
12052+
12053+ err = 0;
12054+ if (!lkup->dirren.drinfo)
12055+ goto out;
12056+ AuDebugOn(lkup->dirren.ninfo < btgt + 1);
12057+ drinfo = lkup->dirren.drinfo[btgt + 1];
12058+ if (!drinfo)
12059+ goto out;
12060+
12061+ kfree(lkup->whname.name);
12062+ lkup->whname.name = NULL;
12063+ lkup->dirren.dr_name.len = drinfo->oldnamelen;
12064+ lkup->dirren.dr_name.name = drinfo->oldname;
12065+ lkup->name = &lkup->dirren.dr_name;
12066+ err = au_wh_name_alloc(&lkup->whname, lkup->name);
12067+ if (!err)
12068+ AuDbg("name %.*s, whname %.*s, b%d\n",
12069+ AuLNPair(lkup->name), AuLNPair(&lkup->whname),
12070+ btgt);
12071+
12072+out:
12073+ AuTraceErr(err);
12074+ return err;
12075+}
12076+
12077+int au_dr_lkup_h_ino(struct au_do_lookup_args *lkup, aufs_bindex_t bindex,
12078+ ino_t h_ino)
12079+{
12080+ int match;
12081+ struct au_drinfo *drinfo;
12082+
12083+ match = 1;
12084+ if (!lkup->dirren.drinfo)
12085+ goto out;
12086+ AuDebugOn(lkup->dirren.ninfo < bindex + 1);
12087+ drinfo = lkup->dirren.drinfo[bindex + 1];
12088+ if (!drinfo)
12089+ goto out;
12090+
12091+ match = (drinfo->ino == h_ino);
12092+ AuDbg("match %d\n", match);
12093+
12094+out:
12095+ return match;
12096+}
12097+
12098+/* ---------------------------------------------------------------------- */
12099+
12100+int au_dr_opt_set(struct super_block *sb)
12101+{
12102+ int err;
12103+ aufs_bindex_t bindex, bbot;
12104+ struct au_branch *br;
12105+
12106+ err = 0;
12107+ bbot = au_sbbot(sb);
12108+ for (bindex = 0; !err && bindex <= bbot; bindex++) {
12109+ br = au_sbr(sb, bindex);
12110+ err = au_dr_hino(sb, bindex, /*br*/NULL, &br->br_path);
12111+ }
12112+
12113+ return err;
12114+}
12115+
12116+int au_dr_opt_flush(struct super_block *sb)
12117+{
12118+ int err;
12119+ aufs_bindex_t bindex, bbot;
12120+ struct au_branch *br;
12121+
12122+ err = 0;
12123+ bbot = au_sbbot(sb);
12124+ for (bindex = 0; !err && bindex <= bbot; bindex++) {
12125+ br = au_sbr(sb, bindex);
12126+ if (au_br_writable(br->br_perm))
12127+ err = au_dr_hino(sb, bindex, /*br*/NULL, /*path*/NULL);
12128+ }
12129+
12130+ return err;
12131+}
12132+
12133+int au_dr_opt_clr(struct super_block *sb, int no_flush)
12134+{
12135+ int err;
12136+ aufs_bindex_t bindex, bbot;
12137+ struct au_branch *br;
12138+
12139+ err = 0;
12140+ if (!no_flush) {
12141+ err = au_dr_opt_flush(sb);
12142+ if (unlikely(err))
12143+ goto out;
12144+ }
12145+
12146+ bbot = au_sbbot(sb);
12147+ for (bindex = 0; bindex <= bbot; bindex++) {
12148+ br = au_sbr(sb, bindex);
12149+ au_dr_hino_free(&br->br_dirren);
12150+ }
12151+
12152+out:
12153+ return err;
12154+}
12155diff -urN /usr/share/empty/fs/aufs/dirren.h linux/fs/aufs/dirren.h
12156--- /usr/share/empty/fs/aufs/dirren.h 1970-01-01 01:00:00.000000000 +0100
12157+++ linux/fs/aufs/dirren.h 2018-04-15 08:49:13.397817296 +0200
12158@@ -0,0 +1,145 @@
12159+/*
12160+ * Copyright (C) 2017-2018 Junjiro R. Okajima
12161+ *
12162+ * This program, aufs is free software; you can redistribute it and/or modify
12163+ * it under the terms of the GNU General Public License as published by
12164+ * the Free Software Foundation; either version 2 of the License, or
12165+ * (at your option) any later version.
12166+ *
12167+ * This program is distributed in the hope that it will be useful,
12168+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12169+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12170+ * GNU General Public License for more details.
12171+ *
12172+ * You should have received a copy of the GNU General Public License
12173+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
12174+ */
12175+
12176+/*
12177+ * renamed dir info
12178+ */
12179+
12180+#ifndef __AUFS_DIRREN_H__
12181+#define __AUFS_DIRREN_H__
12182+
12183+#ifdef __KERNEL__
12184+
12185+#include <linux/dcache.h>
12186+#include <linux/statfs.h>
12187+#include "hbl.h"
12188+
12189+#define AuDirren_NHASH 100
12190+
12191+#ifdef CONFIG_AUFS_DIRREN
12192+/* copied from linux/fs/xfs/uuid.h */
12193+typedef struct {
12194+ unsigned char __u_bits[16];
12195+} uuid_t;
12196+
12197+#define __UUID_TMPLT "01234567-0123-4567-0123-456701234567"
12198+
12199+enum au_brid_type {
12200+ AuBrid_Unset,
12201+ AuBrid_UUID,
12202+ AuBrid_FSID,
12203+ AuBrid_DEV
12204+};
12205+
12206+struct au_dr_brid {
12207+ enum au_brid_type type;
12208+ union {
12209+ uuid_t uuid; /* unimplemented yet */
12210+ fsid_t fsid;
12211+ dev_t dev;
12212+ };
12213+};
12214+
12215+/* 20 is the max digits length of ulong 64 */
12216+/* brid-type "_" uuid "_" inum */
12217+#define AUFS_DIRREN_FNAME_SZ (1 + 1 + sizeof(__UUID_TMPLT) + 20)
12218+#define AUFS_DIRREN_ENV_VAL_SZ (AUFS_DIRREN_FNAME_SZ + 1 + 20)
12219+
12220+struct au_dr_hino {
12221+ struct hlist_bl_node dr_hnode;
12222+ ino_t dr_h_ino;
12223+};
12224+
12225+struct au_dr_br {
12226+ struct hlist_bl_head dr_h_ino[AuDirren_NHASH];
12227+ struct au_dr_brid dr_brid;
12228+};
12229+
12230+struct au_dr_lookup {
12231+ /* dr_name is pointed by struct au_do_lookup_args.name */
12232+ struct qstr dr_name; /* subset of dr_info */
12233+ aufs_bindex_t ninfo;
12234+ struct au_drinfo **drinfo;
12235+};
12236+#else
12237+struct au_dr_hino;
12238+/* empty */
12239+struct au_dr_br { };
12240+struct au_dr_lookup { };
12241+#endif
12242+
12243+/* ---------------------------------------------------------------------- */
12244+
12245+struct au_branch;
12246+struct au_do_lookup_args;
12247+struct au_hinode;
12248+#ifdef CONFIG_AUFS_DIRREN
12249+int au_dr_hino_test_add(struct au_dr_br *dr, ino_t h_ino,
12250+ struct au_dr_hino *add_ent);
12251+void au_dr_hino_free(struct au_dr_br *dr);
12252+int au_dr_br_init(struct super_block *sb, struct au_branch *br,
12253+ const struct path *path);
12254+int au_dr_br_fin(struct super_block *sb, struct au_branch *br);
12255+int au_dr_rename(struct dentry *src, aufs_bindex_t bindex,
12256+ struct qstr *dst_name, void *_rev);
12257+void au_dr_rename_fin(struct dentry *src, aufs_bindex_t btgt, void *rev);
12258+void au_dr_rename_rev(struct dentry *src, aufs_bindex_t bindex, void *rev);
12259+int au_dr_lkup(struct au_do_lookup_args *lkup, struct dentry *dentry,
12260+ aufs_bindex_t bindex);
12261+int au_dr_lkup_name(struct au_do_lookup_args *lkup, aufs_bindex_t btgt);
12262+int au_dr_lkup_h_ino(struct au_do_lookup_args *lkup, aufs_bindex_t bindex,
12263+ ino_t h_ino);
12264+void au_dr_lkup_fin(struct au_do_lookup_args *lkup);
12265+int au_dr_opt_set(struct super_block *sb);
12266+int au_dr_opt_flush(struct super_block *sb);
12267+int au_dr_opt_clr(struct super_block *sb, int no_flush);
12268+#else
12269+AuStubInt0(au_dr_hino_test_add, struct au_dr_br *dr, ino_t h_ino,
12270+ struct au_dr_hino *add_ent);
12271+AuStubVoid(au_dr_hino_free, struct au_dr_br *dr);
12272+AuStubInt0(au_dr_br_init, struct super_block *sb, struct au_branch *br,
12273+ const struct path *path);
12274+AuStubInt0(au_dr_br_fin, struct super_block *sb, struct au_branch *br);
12275+AuStubInt0(au_dr_rename, struct dentry *src, aufs_bindex_t bindex,
12276+ struct qstr *dst_name, void *_rev);
12277+AuStubVoid(au_dr_rename_fin, struct dentry *src, aufs_bindex_t btgt, void *rev);
12278+AuStubVoid(au_dr_rename_rev, struct dentry *src, aufs_bindex_t bindex,
12279+ void *rev);
12280+AuStubInt0(au_dr_lkup, struct au_do_lookup_args *lkup, struct dentry *dentry,
12281+ aufs_bindex_t bindex);
12282+AuStubInt0(au_dr_lkup_name, struct au_do_lookup_args *lkup, aufs_bindex_t btgt);
12283+AuStubInt0(au_dr_lkup_h_ino, struct au_do_lookup_args *lkup,
12284+ aufs_bindex_t bindex, ino_t h_ino);
12285+AuStubVoid(au_dr_lkup_fin, struct au_do_lookup_args *lkup);
12286+AuStubInt0(au_dr_opt_set, struct super_block *sb);
12287+AuStubInt0(au_dr_opt_flush, struct super_block *sb);
12288+AuStubInt0(au_dr_opt_clr, struct super_block *sb, int no_flush);
12289+#endif
12290+
12291+/* ---------------------------------------------------------------------- */
12292+
12293+#ifdef CONFIG_AUFS_DIRREN
12294+static inline int au_dr_ihash(ino_t h_ino)
12295+{
12296+ return h_ino % AuDirren_NHASH;
12297+}
12298+#else
12299+AuStubInt0(au_dr_ihash, ino_t h_ino);
12300+#endif
12301+
12302+#endif /* __KERNEL__ */
12303+#endif /* __AUFS_DIRREN_H__ */
7f207e10
AM
12304diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
12305--- /usr/share/empty/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
12306+++ linux/fs/aufs/dynop.c 2018-04-15 08:49:13.397817296 +0200
12307@@ -0,0 +1,369 @@
1facf9fc 12308+/*
ae9dfd79 12309+ * Copyright (C) 2010-2018 Junjiro R. Okajima
1facf9fc 12310+ *
12311+ * This program, aufs is free software; you can redistribute it and/or modify
12312+ * it under the terms of the GNU General Public License as published by
12313+ * the Free Software Foundation; either version 2 of the License, or
12314+ * (at your option) any later version.
dece6358
AM
12315+ *
12316+ * This program is distributed in the hope that it will be useful,
12317+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12318+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12319+ * GNU General Public License for more details.
12320+ *
12321+ * You should have received a copy of the GNU General Public License
523b37e3 12322+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 12323+ */
12324+
12325+/*
4a4d8108 12326+ * dynamically customizable operations for regular files
1facf9fc 12327+ */
12328+
1facf9fc 12329+#include "aufs.h"
12330+
4a4d8108 12331+#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop)
1facf9fc 12332+
4a4d8108
AM
12333+/*
12334+ * How large will these lists be?
12335+ * Usually just a few elements, 20-30 at most for each, I guess.
12336+ */
ae9dfd79 12337+static struct hlist_bl_head dynop[AuDyLast];
4a4d8108 12338+
ae9dfd79
AM
12339+static struct au_dykey *dy_gfind_get(struct hlist_bl_head *hbl,
12340+ const void *h_op)
1facf9fc 12341+{
4a4d8108 12342+ struct au_dykey *key, *tmp;
ae9dfd79 12343+ struct hlist_bl_node *pos;
1facf9fc 12344+
4a4d8108 12345+ key = NULL;
ae9dfd79
AM
12346+ hlist_bl_lock(hbl);
12347+ hlist_bl_for_each_entry(tmp, pos, hbl, dk_hnode)
4a4d8108
AM
12348+ if (tmp->dk_op.dy_hop == h_op) {
12349+ key = tmp;
12350+ kref_get(&key->dk_kref);
12351+ break;
12352+ }
ae9dfd79 12353+ hlist_bl_unlock(hbl);
4a4d8108
AM
12354+
12355+ return key;
1facf9fc 12356+}
12357+
4a4d8108 12358+static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
1facf9fc 12359+{
4a4d8108
AM
12360+ struct au_dykey **k, *found;
12361+ const void *h_op = key->dk_op.dy_hop;
12362+ int i;
1facf9fc 12363+
4a4d8108
AM
12364+ found = NULL;
12365+ k = br->br_dykey;
12366+ for (i = 0; i < AuBrDynOp; i++)
12367+ if (k[i]) {
12368+ if (k[i]->dk_op.dy_hop == h_op) {
12369+ found = k[i];
12370+ break;
12371+ }
12372+ } else
12373+ break;
12374+ if (!found) {
12375+ spin_lock(&br->br_dykey_lock);
12376+ for (; i < AuBrDynOp; i++)
12377+ if (k[i]) {
12378+ if (k[i]->dk_op.dy_hop == h_op) {
12379+ found = k[i];
12380+ break;
12381+ }
12382+ } else {
12383+ k[i] = key;
12384+ break;
12385+ }
12386+ spin_unlock(&br->br_dykey_lock);
12387+ BUG_ON(i == AuBrDynOp); /* expand the array */
12388+ }
12389+
12390+ return found;
1facf9fc 12391+}
12392+
4a4d8108 12393+/* kref_get() if @key is already added */
ae9dfd79 12394+static struct au_dykey *dy_gadd(struct hlist_bl_head *hbl, struct au_dykey *key)
4a4d8108
AM
12395+{
12396+ struct au_dykey *tmp, *found;
ae9dfd79 12397+ struct hlist_bl_node *pos;
4a4d8108 12398+ const void *h_op = key->dk_op.dy_hop;
1facf9fc 12399+
4a4d8108 12400+ found = NULL;
ae9dfd79
AM
12401+ hlist_bl_lock(hbl);
12402+ hlist_bl_for_each_entry(tmp, pos, hbl, dk_hnode)
4a4d8108
AM
12403+ if (tmp->dk_op.dy_hop == h_op) {
12404+ kref_get(&tmp->dk_kref);
12405+ found = tmp;
12406+ break;
12407+ }
12408+ if (!found)
ae9dfd79
AM
12409+ hlist_bl_add_head(&key->dk_hnode, hbl);
12410+ hlist_bl_unlock(hbl);
1facf9fc 12411+
4a4d8108
AM
12412+ if (!found)
12413+ DyPrSym(key);
12414+ return found;
12415+}
12416+
12417+static void dy_free_rcu(struct rcu_head *rcu)
1facf9fc 12418+{
4a4d8108
AM
12419+ struct au_dykey *key;
12420+
12421+ key = container_of(rcu, struct au_dykey, dk_rcu);
12422+ DyPrSym(key);
ae9dfd79 12423+ kfree(key);
1facf9fc 12424+}
12425+
4a4d8108
AM
12426+static void dy_free(struct kref *kref)
12427+{
12428+ struct au_dykey *key;
ae9dfd79 12429+ struct hlist_bl_head *hbl;
1facf9fc 12430+
4a4d8108 12431+ key = container_of(kref, struct au_dykey, dk_kref);
ae9dfd79
AM
12432+ hbl = dynop + key->dk_op.dy_type;
12433+ au_hbl_del(&key->dk_hnode, hbl);
4a4d8108
AM
12434+ call_rcu(&key->dk_rcu, dy_free_rcu);
12435+}
12436+
12437+void au_dy_put(struct au_dykey *key)
1facf9fc 12438+{
4a4d8108
AM
12439+ kref_put(&key->dk_kref, dy_free);
12440+}
1facf9fc 12441+
4a4d8108
AM
12442+/* ---------------------------------------------------------------------- */
12443+
12444+#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *))
12445+
12446+#ifdef CONFIG_AUFS_DEBUG
12447+#define DyDbgDeclare(cnt) unsigned int cnt = 0
4f0767ce 12448+#define DyDbgInc(cnt) do { cnt++; } while (0)
4a4d8108
AM
12449+#else
12450+#define DyDbgDeclare(cnt) do {} while (0)
12451+#define DyDbgInc(cnt) do {} while (0)
12452+#endif
12453+
12454+#define DySet(func, dst, src, h_op, h_sb) do { \
12455+ DyDbgInc(cnt); \
12456+ if (h_op->func) { \
12457+ if (src.func) \
12458+ dst.func = src.func; \
12459+ else \
12460+ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \
12461+ } \
12462+} while (0)
12463+
12464+#define DySetForce(func, dst, src) do { \
12465+ AuDebugOn(!src.func); \
12466+ DyDbgInc(cnt); \
12467+ dst.func = src.func; \
12468+} while (0)
12469+
12470+#define DySetAop(func) \
12471+ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
12472+#define DySetAopForce(func) \
12473+ DySetForce(func, dyaop->da_op, aufs_aop)
12474+
12475+static void dy_aop(struct au_dykey *key, const void *h_op,
12476+ struct super_block *h_sb __maybe_unused)
12477+{
12478+ struct au_dyaop *dyaop = (void *)key;
12479+ const struct address_space_operations *h_aop = h_op;
12480+ DyDbgDeclare(cnt);
12481+
12482+ AuDbg("%s\n", au_sbtype(h_sb));
12483+
12484+ DySetAop(writepage);
12485+ DySetAopForce(readpage); /* force */
4a4d8108
AM
12486+ DySetAop(writepages);
12487+ DySetAop(set_page_dirty);
12488+ DySetAop(readpages);
12489+ DySetAop(write_begin);
12490+ DySetAop(write_end);
12491+ DySetAop(bmap);
12492+ DySetAop(invalidatepage);
12493+ DySetAop(releasepage);
027c5e7a 12494+ DySetAop(freepage);
7e9cd9fe 12495+ /* this one will be changed according to an aufs mount option */
4a4d8108 12496+ DySetAop(direct_IO);
4a4d8108 12497+ DySetAop(migratepage);
e2f27e51
AM
12498+ DySetAop(isolate_page);
12499+ DySetAop(putback_page);
4a4d8108
AM
12500+ DySetAop(launder_page);
12501+ DySetAop(is_partially_uptodate);
392086de 12502+ DySetAop(is_dirty_writeback);
4a4d8108 12503+ DySetAop(error_remove_page);
b4510431
AM
12504+ DySetAop(swap_activate);
12505+ DySetAop(swap_deactivate);
4a4d8108
AM
12506+
12507+ DyDbgSize(cnt, *h_aop);
4a4d8108
AM
12508+}
12509+
4a4d8108
AM
12510+/* ---------------------------------------------------------------------- */
12511+
12512+static void dy_bug(struct kref *kref)
12513+{
12514+ BUG();
12515+}
12516+
12517+static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
12518+{
12519+ struct au_dykey *key, *old;
ae9dfd79 12520+ struct hlist_bl_head *hbl;
b752ccd1 12521+ struct op {
4a4d8108 12522+ unsigned int sz;
b752ccd1
AM
12523+ void (*set)(struct au_dykey *key, const void *h_op,
12524+ struct super_block *h_sb __maybe_unused);
12525+ };
12526+ static const struct op a[] = {
4a4d8108
AM
12527+ [AuDy_AOP] = {
12528+ .sz = sizeof(struct au_dyaop),
b752ccd1 12529+ .set = dy_aop
4a4d8108 12530+ }
b752ccd1
AM
12531+ };
12532+ const struct op *p;
4a4d8108 12533+
ae9dfd79
AM
12534+ hbl = dynop + op->dy_type;
12535+ key = dy_gfind_get(hbl, op->dy_hop);
4a4d8108
AM
12536+ if (key)
12537+ goto out_add; /* success */
12538+
12539+ p = a + op->dy_type;
12540+ key = kzalloc(p->sz, GFP_NOFS);
12541+ if (unlikely(!key)) {
12542+ key = ERR_PTR(-ENOMEM);
12543+ goto out;
12544+ }
12545+
12546+ key->dk_op.dy_hop = op->dy_hop;
12547+ kref_init(&key->dk_kref);
86dc4139 12548+ p->set(key, op->dy_hop, au_br_sb(br));
ae9dfd79 12549+ old = dy_gadd(hbl, key);
4a4d8108 12550+ if (old) {
ae9dfd79 12551+ kfree(key);
4a4d8108
AM
12552+ key = old;
12553+ }
12554+
12555+out_add:
12556+ old = dy_bradd(br, key);
12557+ if (old)
12558+ /* its ref-count should never be zero here */
12559+ kref_put(&key->dk_kref, dy_bug);
12560+out:
12561+ return key;
12562+}
12563+
12564+/* ---------------------------------------------------------------------- */
12565+/*
12566+ * Aufs prohibits O_DIRECT by defaut even if the branch supports it.
c1595e42 12567+ * This behaviour is necessary to return an error from open(O_DIRECT) instead
4a4d8108
AM
12568+ * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
12569+ * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
12570+ * See the aufs manual in detail.
4a4d8108
AM
12571+ */
12572+static void dy_adx(struct au_dyaop *dyaop, int do_dx)
12573+{
7e9cd9fe 12574+ if (!do_dx)
4a4d8108 12575+ dyaop->da_op.direct_IO = NULL;
7e9cd9fe 12576+ else
4a4d8108 12577+ dyaop->da_op.direct_IO = aufs_aop.direct_IO;
4a4d8108
AM
12578+}
12579+
12580+static struct au_dyaop *dy_aget(struct au_branch *br,
12581+ const struct address_space_operations *h_aop,
12582+ int do_dx)
12583+{
12584+ struct au_dyaop *dyaop;
12585+ struct au_dynop op;
12586+
12587+ op.dy_type = AuDy_AOP;
12588+ op.dy_haop = h_aop;
12589+ dyaop = (void *)dy_get(&op, br);
12590+ if (IS_ERR(dyaop))
12591+ goto out;
12592+ dy_adx(dyaop, do_dx);
12593+
12594+out:
12595+ return dyaop;
12596+}
12597+
12598+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
12599+ struct inode *h_inode)
12600+{
12601+ int err, do_dx;
12602+ struct super_block *sb;
12603+ struct au_branch *br;
12604+ struct au_dyaop *dyaop;
12605+
12606+ AuDebugOn(!S_ISREG(h_inode->i_mode));
12607+ IiMustWriteLock(inode);
12608+
12609+ sb = inode->i_sb;
12610+ br = au_sbr(sb, bindex);
12611+ do_dx = !!au_opt_test(au_mntflags(sb), DIO);
12612+ dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
12613+ err = PTR_ERR(dyaop);
12614+ if (IS_ERR(dyaop))
12615+ /* unnecessary to call dy_fput() */
12616+ goto out;
12617+
12618+ err = 0;
12619+ inode->i_mapping->a_ops = &dyaop->da_op;
12620+
12621+out:
12622+ return err;
12623+}
12624+
b752ccd1
AM
12625+/*
12626+ * Is it safe to replace a_ops during the inode/file is in operation?
12627+ * Yes, I hope so.
12628+ */
12629+int au_dy_irefresh(struct inode *inode)
12630+{
12631+ int err;
5afbbe0d 12632+ aufs_bindex_t btop;
b752ccd1
AM
12633+ struct inode *h_inode;
12634+
12635+ err = 0;
12636+ if (S_ISREG(inode->i_mode)) {
5afbbe0d
AM
12637+ btop = au_ibtop(inode);
12638+ h_inode = au_h_iptr(inode, btop);
12639+ err = au_dy_iaop(inode, btop, h_inode);
b752ccd1
AM
12640+ }
12641+ return err;
12642+}
12643+
4a4d8108
AM
12644+void au_dy_arefresh(int do_dx)
12645+{
ae9dfd79
AM
12646+ struct hlist_bl_head *hbl;
12647+ struct hlist_bl_node *pos;
4a4d8108
AM
12648+ struct au_dykey *key;
12649+
ae9dfd79
AM
12650+ hbl = dynop + AuDy_AOP;
12651+ hlist_bl_lock(hbl);
12652+ hlist_bl_for_each_entry(key, pos, hbl, dk_hnode)
4a4d8108 12653+ dy_adx((void *)key, do_dx);
ae9dfd79 12654+ hlist_bl_unlock(hbl);
4a4d8108
AM
12655+}
12656+
4a4d8108
AM
12657+/* ---------------------------------------------------------------------- */
12658+
12659+void __init au_dy_init(void)
12660+{
12661+ int i;
12662+
12663+ /* make sure that 'struct au_dykey *' can be any type */
12664+ BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
4a4d8108
AM
12665+
12666+ for (i = 0; i < AuDyLast; i++)
ae9dfd79 12667+ INIT_HLIST_BL_HEAD(dynop + i);
4a4d8108
AM
12668+}
12669+
12670+void au_dy_fin(void)
12671+{
12672+ int i;
12673+
12674+ for (i = 0; i < AuDyLast; i++)
ae9dfd79 12675+ WARN_ON(!hlist_bl_empty(dynop + i));
4a4d8108 12676+}
7f207e10
AM
12677diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
12678--- /usr/share/empty/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 12679+++ linux/fs/aufs/dynop.h 2018-04-15 08:49:13.397817296 +0200
7e9cd9fe 12680@@ -0,0 +1,74 @@
4a4d8108 12681+/*
ae9dfd79 12682+ * Copyright (C) 2010-2018 Junjiro R. Okajima
4a4d8108
AM
12683+ *
12684+ * This program, aufs is free software; you can redistribute it and/or modify
12685+ * it under the terms of the GNU General Public License as published by
12686+ * the Free Software Foundation; either version 2 of the License, or
12687+ * (at your option) any later version.
12688+ *
12689+ * This program is distributed in the hope that it will be useful,
12690+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12691+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12692+ * GNU General Public License for more details.
12693+ *
12694+ * You should have received a copy of the GNU General Public License
523b37e3 12695+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
12696+ */
12697+
12698+/*
12699+ * dynamically customizable operations (for regular files only)
12700+ */
12701+
12702+#ifndef __AUFS_DYNOP_H__
12703+#define __AUFS_DYNOP_H__
12704+
12705+#ifdef __KERNEL__
12706+
7e9cd9fe
AM
12707+#include <linux/fs.h>
12708+#include <linux/kref.h>
4a4d8108 12709+
2cbb1c4b 12710+enum {AuDy_AOP, AuDyLast};
4a4d8108
AM
12711+
12712+struct au_dynop {
12713+ int dy_type;
12714+ union {
12715+ const void *dy_hop;
12716+ const struct address_space_operations *dy_haop;
4a4d8108
AM
12717+ };
12718+};
12719+
12720+struct au_dykey {
12721+ union {
ae9dfd79 12722+ struct hlist_bl_node dk_hnode;
4a4d8108
AM
12723+ struct rcu_head dk_rcu;
12724+ };
12725+ struct au_dynop dk_op;
12726+
12727+ /*
12728+ * during I am in the branch local array, kref is gotten. when the
12729+ * branch is removed, kref is put.
12730+ */
12731+ struct kref dk_kref;
12732+};
12733+
12734+/* stop unioning since their sizes are very different from each other */
12735+struct au_dyaop {
12736+ struct au_dykey da_key;
12737+ struct address_space_operations da_op; /* not const */
4a4d8108
AM
12738+};
12739+
4a4d8108
AM
12740+/* ---------------------------------------------------------------------- */
12741+
12742+/* dynop.c */
12743+struct au_branch;
12744+void au_dy_put(struct au_dykey *key);
12745+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
12746+ struct inode *h_inode);
b752ccd1 12747+int au_dy_irefresh(struct inode *inode);
4a4d8108 12748+void au_dy_arefresh(int do_dio);
4a4d8108
AM
12749+
12750+void __init au_dy_init(void);
12751+void au_dy_fin(void);
12752+
4a4d8108
AM
12753+#endif /* __KERNEL__ */
12754+#endif /* __AUFS_DYNOP_H__ */
7f207e10
AM
12755diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
12756--- /usr/share/empty/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 12757+++ linux/fs/aufs/export.c 2018-04-15 08:49:13.397817296 +0200
f2c43d5f 12758@@ -0,0 +1,836 @@
4a4d8108 12759+/*
ae9dfd79 12760+ * Copyright (C) 2005-2018 Junjiro R. Okajima
4a4d8108
AM
12761+ *
12762+ * This program, aufs is free software; you can redistribute it and/or modify
12763+ * it under the terms of the GNU General Public License as published by
12764+ * the Free Software Foundation; either version 2 of the License, or
12765+ * (at your option) any later version.
12766+ *
12767+ * This program is distributed in the hope that it will be useful,
12768+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12769+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12770+ * GNU General Public License for more details.
12771+ *
12772+ * You should have received a copy of the GNU General Public License
523b37e3 12773+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
12774+ */
12775+
12776+/*
12777+ * export via nfs
12778+ */
12779+
12780+#include <linux/exportfs.h>
7eafdf33 12781+#include <linux/fs_struct.h>
4a4d8108
AM
12782+#include <linux/namei.h>
12783+#include <linux/nsproxy.h>
12784+#include <linux/random.h>
12785+#include <linux/writeback.h>
12786+#include "aufs.h"
12787+
12788+union conv {
12789+#ifdef CONFIG_AUFS_INO_T_64
12790+ __u32 a[2];
12791+#else
12792+ __u32 a[1];
12793+#endif
12794+ ino_t ino;
12795+};
12796+
12797+static ino_t decode_ino(__u32 *a)
12798+{
12799+ union conv u;
12800+
12801+ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
12802+ u.a[0] = a[0];
12803+#ifdef CONFIG_AUFS_INO_T_64
12804+ u.a[1] = a[1];
12805+#endif
12806+ return u.ino;
12807+}
12808+
12809+static void encode_ino(__u32 *a, ino_t ino)
12810+{
12811+ union conv u;
12812+
12813+ u.ino = ino;
12814+ a[0] = u.a[0];
12815+#ifdef CONFIG_AUFS_INO_T_64
12816+ a[1] = u.a[1];
12817+#endif
12818+}
12819+
12820+/* NFS file handle */
12821+enum {
12822+ Fh_br_id,
12823+ Fh_sigen,
12824+#ifdef CONFIG_AUFS_INO_T_64
12825+ /* support 64bit inode number */
12826+ Fh_ino1,
12827+ Fh_ino2,
12828+ Fh_dir_ino1,
12829+ Fh_dir_ino2,
12830+#else
12831+ Fh_ino1,
12832+ Fh_dir_ino1,
12833+#endif
12834+ Fh_igen,
12835+ Fh_h_type,
12836+ Fh_tail,
12837+
12838+ Fh_ino = Fh_ino1,
12839+ Fh_dir_ino = Fh_dir_ino1
12840+};
12841+
12842+static int au_test_anon(struct dentry *dentry)
12843+{
027c5e7a 12844+ /* note: read d_flags without d_lock */
4a4d8108
AM
12845+ return !!(dentry->d_flags & DCACHE_DISCONNECTED);
12846+}
12847+
a2a7ad62
AM
12848+int au_test_nfsd(void)
12849+{
12850+ int ret;
12851+ struct task_struct *tsk = current;
12852+ char comm[sizeof(tsk->comm)];
12853+
12854+ ret = 0;
12855+ if (tsk->flags & PF_KTHREAD) {
12856+ get_task_comm(comm, tsk);
12857+ ret = !strcmp(comm, "nfsd");
12858+ }
12859+
12860+ return ret;
12861+}
12862+
4a4d8108
AM
12863+/* ---------------------------------------------------------------------- */
12864+/* inode generation external table */
12865+
b752ccd1 12866+void au_xigen_inc(struct inode *inode)
4a4d8108 12867+{
4a4d8108
AM
12868+ loff_t pos;
12869+ ssize_t sz;
12870+ __u32 igen;
12871+ struct super_block *sb;
12872+ struct au_sbinfo *sbinfo;
12873+
4a4d8108 12874+ sb = inode->i_sb;
b752ccd1 12875+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
1facf9fc 12876+
b752ccd1 12877+ sbinfo = au_sbi(sb);
1facf9fc 12878+ pos = inode->i_ino;
12879+ pos *= sizeof(igen);
12880+ igen = inode->i_generation + 1;
1facf9fc 12881+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
12882+ sizeof(igen), &pos);
12883+ if (sz == sizeof(igen))
b752ccd1 12884+ return; /* success */
1facf9fc 12885+
b752ccd1 12886+ if (unlikely(sz >= 0))
1facf9fc 12887+ AuIOErr("xigen error (%zd)\n", sz);
1facf9fc 12888+}
12889+
12890+int au_xigen_new(struct inode *inode)
12891+{
12892+ int err;
12893+ loff_t pos;
12894+ ssize_t sz;
12895+ struct super_block *sb;
12896+ struct au_sbinfo *sbinfo;
12897+ struct file *file;
12898+
12899+ err = 0;
12900+ /* todo: dirty, at mount time */
12901+ if (inode->i_ino == AUFS_ROOT_INO)
12902+ goto out;
12903+ sb = inode->i_sb;
dece6358 12904+ SiMustAnyLock(sb);
1facf9fc 12905+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
12906+ goto out;
12907+
12908+ err = -EFBIG;
12909+ pos = inode->i_ino;
12910+ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
12911+ AuIOErr1("too large i%lld\n", pos);
12912+ goto out;
12913+ }
12914+ pos *= sizeof(inode->i_generation);
12915+
12916+ err = 0;
12917+ sbinfo = au_sbi(sb);
12918+ file = sbinfo->si_xigen;
12919+ BUG_ON(!file);
12920+
c06a8ce3 12921+ if (vfsub_f_size_read(file)
1facf9fc 12922+ < pos + sizeof(inode->i_generation)) {
12923+ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
12924+ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
12925+ sizeof(inode->i_generation), &pos);
12926+ } else
12927+ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
12928+ sizeof(inode->i_generation), &pos);
12929+ if (sz == sizeof(inode->i_generation))
12930+ goto out; /* success */
12931+
12932+ err = sz;
12933+ if (unlikely(sz >= 0)) {
12934+ err = -EIO;
12935+ AuIOErr("xigen error (%zd)\n", sz);
12936+ }
12937+
4f0767ce 12938+out:
1facf9fc 12939+ return err;
12940+}
12941+
12942+int au_xigen_set(struct super_block *sb, struct file *base)
12943+{
12944+ int err;
12945+ struct au_sbinfo *sbinfo;
12946+ struct file *file;
12947+
dece6358
AM
12948+ SiMustWriteLock(sb);
12949+
1facf9fc 12950+ sbinfo = au_sbi(sb);
12951+ file = au_xino_create2(base, sbinfo->si_xigen);
12952+ err = PTR_ERR(file);
12953+ if (IS_ERR(file))
12954+ goto out;
12955+ err = 0;
12956+ if (sbinfo->si_xigen)
12957+ fput(sbinfo->si_xigen);
12958+ sbinfo->si_xigen = file;
12959+
4f0767ce 12960+out:
1facf9fc 12961+ return err;
12962+}
12963+
12964+void au_xigen_clr(struct super_block *sb)
12965+{
12966+ struct au_sbinfo *sbinfo;
12967+
dece6358
AM
12968+ SiMustWriteLock(sb);
12969+
1facf9fc 12970+ sbinfo = au_sbi(sb);
12971+ if (sbinfo->si_xigen) {
12972+ fput(sbinfo->si_xigen);
12973+ sbinfo->si_xigen = NULL;
12974+ }
12975+}
12976+
12977+/* ---------------------------------------------------------------------- */
12978+
12979+static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
12980+ ino_t dir_ino)
12981+{
12982+ struct dentry *dentry, *d;
12983+ struct inode *inode;
12984+ unsigned int sigen;
12985+
12986+ dentry = NULL;
12987+ inode = ilookup(sb, ino);
12988+ if (!inode)
12989+ goto out;
12990+
12991+ dentry = ERR_PTR(-ESTALE);
12992+ sigen = au_sigen(sb);
5afbbe0d 12993+ if (unlikely(au_is_bad_inode(inode)
1facf9fc 12994+ || IS_DEADDIR(inode)
537831f9 12995+ || sigen != au_iigen(inode, NULL)))
1facf9fc 12996+ goto out_iput;
12997+
12998+ dentry = NULL;
12999+ if (!dir_ino || S_ISDIR(inode->i_mode))
13000+ dentry = d_find_alias(inode);
13001+ else {
027c5e7a 13002+ spin_lock(&inode->i_lock);
c1595e42 13003+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
027c5e7a 13004+ spin_lock(&d->d_lock);
1facf9fc 13005+ if (!au_test_anon(d)
5527c038 13006+ && d_inode(d->d_parent)->i_ino == dir_ino) {
027c5e7a
AM
13007+ dentry = dget_dlock(d);
13008+ spin_unlock(&d->d_lock);
1facf9fc 13009+ break;
13010+ }
027c5e7a
AM
13011+ spin_unlock(&d->d_lock);
13012+ }
13013+ spin_unlock(&inode->i_lock);
1facf9fc 13014+ }
027c5e7a 13015+ if (unlikely(dentry && au_digen_test(dentry, sigen))) {
2cbb1c4b 13016+ /* need to refresh */
1facf9fc 13017+ dput(dentry);
2cbb1c4b 13018+ dentry = NULL;
1facf9fc 13019+ }
13020+
4f0767ce 13021+out_iput:
1facf9fc 13022+ iput(inode);
4f0767ce 13023+out:
2cbb1c4b 13024+ AuTraceErrPtr(dentry);
1facf9fc 13025+ return dentry;
13026+}
13027+
13028+/* ---------------------------------------------------------------------- */
13029+
13030+/* todo: dirty? */
13031+/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
4a4d8108
AM
13032+
13033+struct au_compare_mnt_args {
13034+ /* input */
13035+ struct super_block *sb;
13036+
13037+ /* output */
13038+ struct vfsmount *mnt;
13039+};
13040+
13041+static int au_compare_mnt(struct vfsmount *mnt, void *arg)
13042+{
13043+ struct au_compare_mnt_args *a = arg;
13044+
13045+ if (mnt->mnt_sb != a->sb)
13046+ return 0;
13047+ a->mnt = mntget(mnt);
13048+ return 1;
13049+}
13050+
1facf9fc 13051+static struct vfsmount *au_mnt_get(struct super_block *sb)
13052+{
4a4d8108 13053+ int err;
7eafdf33 13054+ struct path root;
4a4d8108
AM
13055+ struct au_compare_mnt_args args = {
13056+ .sb = sb
13057+ };
1facf9fc 13058+
7eafdf33 13059+ get_fs_root(current->fs, &root);
523b37e3 13060+ rcu_read_lock();
7eafdf33 13061+ err = iterate_mounts(au_compare_mnt, &args, root.mnt);
523b37e3 13062+ rcu_read_unlock();
7eafdf33 13063+ path_put(&root);
4a4d8108
AM
13064+ AuDebugOn(!err);
13065+ AuDebugOn(!args.mnt);
13066+ return args.mnt;
1facf9fc 13067+}
13068+
13069+struct au_nfsd_si_lock {
4a4d8108 13070+ unsigned int sigen;
027c5e7a 13071+ aufs_bindex_t bindex, br_id;
1facf9fc 13072+ unsigned char force_lock;
13073+};
13074+
027c5e7a
AM
13075+static int si_nfsd_read_lock(struct super_block *sb,
13076+ struct au_nfsd_si_lock *nsi_lock)
1facf9fc 13077+{
027c5e7a 13078+ int err;
1facf9fc 13079+ aufs_bindex_t bindex;
13080+
13081+ si_read_lock(sb, AuLock_FLUSH);
13082+
13083+ /* branch id may be wrapped around */
027c5e7a 13084+ err = 0;
1facf9fc 13085+ bindex = au_br_index(sb, nsi_lock->br_id);
13086+ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
13087+ goto out; /* success */
13088+
027c5e7a
AM
13089+ err = -ESTALE;
13090+ bindex = -1;
1facf9fc 13091+ if (!nsi_lock->force_lock)
13092+ si_read_unlock(sb);
1facf9fc 13093+
4f0767ce 13094+out:
027c5e7a
AM
13095+ nsi_lock->bindex = bindex;
13096+ return err;
1facf9fc 13097+}
13098+
13099+struct find_name_by_ino {
392086de 13100+ struct dir_context ctx;
1facf9fc 13101+ int called, found;
13102+ ino_t ino;
13103+ char *name;
13104+ int namelen;
13105+};
13106+
13107+static int
392086de
AM
13108+find_name_by_ino(struct dir_context *ctx, const char *name, int namelen,
13109+ loff_t offset, u64 ino, unsigned int d_type)
1facf9fc 13110+{
392086de
AM
13111+ struct find_name_by_ino *a = container_of(ctx, struct find_name_by_ino,
13112+ ctx);
1facf9fc 13113+
13114+ a->called++;
13115+ if (a->ino != ino)
13116+ return 0;
13117+
13118+ memcpy(a->name, name, namelen);
13119+ a->namelen = namelen;
13120+ a->found = 1;
13121+ return 1;
13122+}
13123+
13124+static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
13125+ struct au_nfsd_si_lock *nsi_lock)
13126+{
13127+ struct dentry *dentry, *parent;
13128+ struct file *file;
13129+ struct inode *dir;
392086de
AM
13130+ struct find_name_by_ino arg = {
13131+ .ctx = {
2000de60 13132+ .actor = find_name_by_ino
392086de
AM
13133+ }
13134+ };
1facf9fc 13135+ int err;
13136+
13137+ parent = path->dentry;
13138+ if (nsi_lock)
13139+ si_read_unlock(parent->d_sb);
4a4d8108 13140+ file = vfsub_dentry_open(path, au_dir_roflags);
1facf9fc 13141+ dentry = (void *)file;
13142+ if (IS_ERR(file))
13143+ goto out;
13144+
13145+ dentry = ERR_PTR(-ENOMEM);
537831f9 13146+ arg.name = (void *)__get_free_page(GFP_NOFS);
1facf9fc 13147+ if (unlikely(!arg.name))
13148+ goto out_file;
13149+ arg.ino = ino;
13150+ arg.found = 0;
13151+ do {
13152+ arg.called = 0;
13153+ /* smp_mb(); */
392086de 13154+ err = vfsub_iterate_dir(file, &arg.ctx);
1facf9fc 13155+ } while (!err && !arg.found && arg.called);
13156+ dentry = ERR_PTR(err);
13157+ if (unlikely(err))
13158+ goto out_name;
1716fcea
AM
13159+ /* instead of ENOENT */
13160+ dentry = ERR_PTR(-ESTALE);
1facf9fc 13161+ if (!arg.found)
13162+ goto out_name;
13163+
b4510431 13164+ /* do not call vfsub_lkup_one() */
5527c038 13165+ dir = d_inode(parent);
febd17d6 13166+ dentry = vfsub_lookup_one_len_unlocked(arg.name, parent, arg.namelen);
1facf9fc 13167+ AuTraceErrPtr(dentry);
13168+ if (IS_ERR(dentry))
13169+ goto out_name;
13170+ AuDebugOn(au_test_anon(dentry));
5527c038 13171+ if (unlikely(d_really_is_negative(dentry))) {
1facf9fc 13172+ dput(dentry);
13173+ dentry = ERR_PTR(-ENOENT);
13174+ }
13175+
4f0767ce 13176+out_name:
ae9dfd79 13177+ free_page((unsigned long)arg.name);
4f0767ce 13178+out_file:
1facf9fc 13179+ fput(file);
4f0767ce 13180+out:
1facf9fc 13181+ if (unlikely(nsi_lock
13182+ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
13183+ if (!IS_ERR(dentry)) {
13184+ dput(dentry);
13185+ dentry = ERR_PTR(-ESTALE);
13186+ }
13187+ AuTraceErrPtr(dentry);
13188+ return dentry;
13189+}
13190+
13191+static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
13192+ ino_t dir_ino,
13193+ struct au_nfsd_si_lock *nsi_lock)
13194+{
13195+ struct dentry *dentry;
13196+ struct path path;
13197+
13198+ if (dir_ino != AUFS_ROOT_INO) {
13199+ path.dentry = decode_by_ino(sb, dir_ino, 0);
13200+ dentry = path.dentry;
13201+ if (!path.dentry || IS_ERR(path.dentry))
13202+ goto out;
13203+ AuDebugOn(au_test_anon(path.dentry));
13204+ } else
13205+ path.dentry = dget(sb->s_root);
13206+
13207+ path.mnt = au_mnt_get(sb);
13208+ dentry = au_lkup_by_ino(&path, ino, nsi_lock);
13209+ path_put(&path);
13210+
4f0767ce 13211+out:
1facf9fc 13212+ AuTraceErrPtr(dentry);
13213+ return dentry;
13214+}
13215+
13216+/* ---------------------------------------------------------------------- */
13217+
13218+static int h_acceptable(void *expv, struct dentry *dentry)
13219+{
13220+ return 1;
13221+}
13222+
13223+static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
13224+ char *buf, int len, struct super_block *sb)
13225+{
13226+ char *p;
13227+ int n;
13228+ struct path path;
13229+
13230+ p = d_path(h_rootpath, buf, len);
13231+ if (IS_ERR(p))
13232+ goto out;
13233+ n = strlen(p);
13234+
13235+ path.mnt = h_rootpath->mnt;
13236+ path.dentry = h_parent;
13237+ p = d_path(&path, buf, len);
13238+ if (IS_ERR(p))
13239+ goto out;
13240+ if (n != 1)
13241+ p += n;
13242+
13243+ path.mnt = au_mnt_get(sb);
13244+ path.dentry = sb->s_root;
13245+ p = d_path(&path, buf, len - strlen(p));
13246+ mntput(path.mnt);
13247+ if (IS_ERR(p))
13248+ goto out;
13249+ if (n != 1)
13250+ p[strlen(p)] = '/';
13251+
4f0767ce 13252+out:
1facf9fc 13253+ AuTraceErrPtr(p);
13254+ return p;
13255+}
13256+
13257+static
027c5e7a
AM
13258+struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
13259+ int fh_len, struct au_nfsd_si_lock *nsi_lock)
1facf9fc 13260+{
13261+ struct dentry *dentry, *h_parent, *root;
13262+ struct super_block *h_sb;
13263+ char *pathname, *p;
13264+ struct vfsmount *h_mnt;
13265+ struct au_branch *br;
13266+ int err;
13267+ struct path path;
13268+
027c5e7a 13269+ br = au_sbr(sb, nsi_lock->bindex);
86dc4139 13270+ h_mnt = au_br_mnt(br);
1facf9fc 13271+ h_sb = h_mnt->mnt_sb;
13272+ /* todo: call lower fh_to_dentry()? fh_to_parent()? */
5afbbe0d 13273+ lockdep_off();
1facf9fc 13274+ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
13275+ fh_len - Fh_tail, fh[Fh_h_type],
13276+ h_acceptable, /*context*/NULL);
5afbbe0d 13277+ lockdep_on();
1facf9fc 13278+ dentry = h_parent;
13279+ if (unlikely(!h_parent || IS_ERR(h_parent))) {
13280+ AuWarn1("%s decode_fh failed, %ld\n",
13281+ au_sbtype(h_sb), PTR_ERR(h_parent));
13282+ goto out;
13283+ }
13284+ dentry = NULL;
13285+ if (unlikely(au_test_anon(h_parent))) {
13286+ AuWarn1("%s decode_fh returned a disconnected dentry\n",
13287+ au_sbtype(h_sb));
13288+ goto out_h_parent;
13289+ }
13290+
13291+ dentry = ERR_PTR(-ENOMEM);
13292+ pathname = (void *)__get_free_page(GFP_NOFS);
13293+ if (unlikely(!pathname))
13294+ goto out_h_parent;
13295+
13296+ root = sb->s_root;
13297+ path.mnt = h_mnt;
13298+ di_read_lock_parent(root, !AuLock_IR);
027c5e7a 13299+ path.dentry = au_h_dptr(root, nsi_lock->bindex);
1facf9fc 13300+ di_read_unlock(root, !AuLock_IR);
13301+ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
13302+ dentry = (void *)p;
13303+ if (IS_ERR(p))
13304+ goto out_pathname;
13305+
13306+ si_read_unlock(sb);
13307+ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
13308+ dentry = ERR_PTR(err);
13309+ if (unlikely(err))
13310+ goto out_relock;
13311+
13312+ dentry = ERR_PTR(-ENOENT);
13313+ AuDebugOn(au_test_anon(path.dentry));
5527c038 13314+ if (unlikely(d_really_is_negative(path.dentry)))
1facf9fc 13315+ goto out_path;
13316+
5527c038 13317+ if (ino != d_inode(path.dentry)->i_ino)
1facf9fc 13318+ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
13319+ else
13320+ dentry = dget(path.dentry);
13321+
4f0767ce 13322+out_path:
1facf9fc 13323+ path_put(&path);
4f0767ce 13324+out_relock:
1facf9fc 13325+ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
13326+ if (!IS_ERR(dentry)) {
13327+ dput(dentry);
13328+ dentry = ERR_PTR(-ESTALE);
13329+ }
4f0767ce 13330+out_pathname:
ae9dfd79 13331+ free_page((unsigned long)pathname);
4f0767ce 13332+out_h_parent:
1facf9fc 13333+ dput(h_parent);
4f0767ce 13334+out:
1facf9fc 13335+ AuTraceErrPtr(dentry);
13336+ return dentry;
13337+}
13338+
13339+/* ---------------------------------------------------------------------- */
13340+
13341+static struct dentry *
13342+aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
13343+ int fh_type)
13344+{
13345+ struct dentry *dentry;
13346+ __u32 *fh = fid->raw;
027c5e7a 13347+ struct au_branch *br;
1facf9fc 13348+ ino_t ino, dir_ino;
1facf9fc 13349+ struct au_nfsd_si_lock nsi_lock = {
1facf9fc 13350+ .force_lock = 0
13351+ };
13352+
1facf9fc 13353+ dentry = ERR_PTR(-ESTALE);
4a4d8108
AM
13354+ /* it should never happen, but the file handle is unreliable */
13355+ if (unlikely(fh_len < Fh_tail))
13356+ goto out;
13357+ nsi_lock.sigen = fh[Fh_sigen];
13358+ nsi_lock.br_id = fh[Fh_br_id];
13359+
1facf9fc 13360+ /* branch id may be wrapped around */
027c5e7a
AM
13361+ br = NULL;
13362+ if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
1facf9fc 13363+ goto out;
13364+ nsi_lock.force_lock = 1;
13365+
13366+ /* is this inode still cached? */
13367+ ino = decode_ino(fh + Fh_ino);
4a4d8108
AM
13368+ /* it should never happen */
13369+ if (unlikely(ino == AUFS_ROOT_INO))
8cdd5066 13370+ goto out_unlock;
4a4d8108 13371+
1facf9fc 13372+ dir_ino = decode_ino(fh + Fh_dir_ino);
13373+ dentry = decode_by_ino(sb, ino, dir_ino);
13374+ if (IS_ERR(dentry))
13375+ goto out_unlock;
13376+ if (dentry)
13377+ goto accept;
13378+
13379+ /* is the parent dir cached? */
027c5e7a 13380+ br = au_sbr(sb, nsi_lock.bindex);
5afbbe0d 13381+ au_br_get(br);
1facf9fc 13382+ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
13383+ if (IS_ERR(dentry))
13384+ goto out_unlock;
13385+ if (dentry)
13386+ goto accept;
13387+
13388+ /* lookup path */
027c5e7a 13389+ dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
1facf9fc 13390+ if (IS_ERR(dentry))
13391+ goto out_unlock;
13392+ if (unlikely(!dentry))
13393+ /* todo?: make it ESTALE */
13394+ goto out_unlock;
13395+
4f0767ce 13396+accept:
027c5e7a 13397+ if (!au_digen_test(dentry, au_sigen(sb))
5527c038 13398+ && d_inode(dentry)->i_generation == fh[Fh_igen])
1facf9fc 13399+ goto out_unlock; /* success */
13400+
13401+ dput(dentry);
13402+ dentry = ERR_PTR(-ESTALE);
4f0767ce 13403+out_unlock:
027c5e7a 13404+ if (br)
5afbbe0d 13405+ au_br_put(br);
1facf9fc 13406+ si_read_unlock(sb);
4f0767ce 13407+out:
1facf9fc 13408+ AuTraceErrPtr(dentry);
13409+ return dentry;
13410+}
13411+
13412+#if 0 /* reserved for future use */
13413+/* support subtreecheck option */
13414+static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
13415+ int fh_len, int fh_type)
13416+{
13417+ struct dentry *parent;
13418+ __u32 *fh = fid->raw;
13419+ ino_t dir_ino;
13420+
13421+ dir_ino = decode_ino(fh + Fh_dir_ino);
13422+ parent = decode_by_ino(sb, dir_ino, 0);
13423+ if (IS_ERR(parent))
13424+ goto out;
13425+ if (!parent)
13426+ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
13427+ dir_ino, fh, fh_len);
13428+
4f0767ce 13429+out:
1facf9fc 13430+ AuTraceErrPtr(parent);
13431+ return parent;
13432+}
13433+#endif
13434+
13435+/* ---------------------------------------------------------------------- */
13436+
0c3ec466
AM
13437+static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
13438+ struct inode *dir)
1facf9fc 13439+{
13440+ int err;
0c3ec466 13441+ aufs_bindex_t bindex;
1facf9fc 13442+ struct super_block *sb, *h_sb;
0c3ec466
AM
13443+ struct dentry *dentry, *parent, *h_parent;
13444+ struct inode *h_dir;
1facf9fc 13445+ struct au_branch *br;
13446+
1facf9fc 13447+ err = -ENOSPC;
13448+ if (unlikely(*max_len <= Fh_tail)) {
13449+ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
13450+ goto out;
13451+ }
13452+
13453+ err = FILEID_ROOT;
0c3ec466
AM
13454+ if (inode->i_ino == AUFS_ROOT_INO) {
13455+ AuDebugOn(inode->i_ino != AUFS_ROOT_INO);
1facf9fc 13456+ goto out;
13457+ }
13458+
1facf9fc 13459+ h_parent = NULL;
0c3ec466
AM
13460+ sb = inode->i_sb;
13461+ err = si_read_lock(sb, AuLock_FLUSH);
027c5e7a
AM
13462+ if (unlikely(err))
13463+ goto out;
13464+
1facf9fc 13465+#ifdef CONFIG_AUFS_DEBUG
13466+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
13467+ AuWarn1("NFS-exporting requires xino\n");
13468+#endif
027c5e7a 13469+ err = -EIO;
0c3ec466
AM
13470+ parent = NULL;
13471+ ii_read_lock_child(inode);
5afbbe0d 13472+ bindex = au_ibtop(inode);
0c3ec466 13473+ if (!dir) {
c1595e42 13474+ dentry = d_find_any_alias(inode);
0c3ec466
AM
13475+ if (unlikely(!dentry))
13476+ goto out_unlock;
13477+ AuDebugOn(au_test_anon(dentry));
13478+ parent = dget_parent(dentry);
13479+ dput(dentry);
13480+ if (unlikely(!parent))
13481+ goto out_unlock;
5527c038
JR
13482+ if (d_really_is_positive(parent))
13483+ dir = d_inode(parent);
1facf9fc 13484+ }
0c3ec466
AM
13485+
13486+ ii_read_lock_parent(dir);
13487+ h_dir = au_h_iptr(dir, bindex);
13488+ ii_read_unlock(dir);
13489+ if (unlikely(!h_dir))
13490+ goto out_parent;
c1595e42 13491+ h_parent = d_find_any_alias(h_dir);
1facf9fc 13492+ if (unlikely(!h_parent))
0c3ec466 13493+ goto out_hparent;
1facf9fc 13494+
13495+ err = -EPERM;
13496+ br = au_sbr(sb, bindex);
86dc4139 13497+ h_sb = au_br_sb(br);
1facf9fc 13498+ if (unlikely(!h_sb->s_export_op)) {
13499+ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
0c3ec466 13500+ goto out_hparent;
1facf9fc 13501+ }
13502+
13503+ fh[Fh_br_id] = br->br_id;
13504+ fh[Fh_sigen] = au_sigen(sb);
13505+ encode_ino(fh + Fh_ino, inode->i_ino);
0c3ec466 13506+ encode_ino(fh + Fh_dir_ino, dir->i_ino);
1facf9fc 13507+ fh[Fh_igen] = inode->i_generation;
13508+
13509+ *max_len -= Fh_tail;
13510+ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
13511+ max_len,
13512+ /*connectable or subtreecheck*/0);
13513+ err = fh[Fh_h_type];
13514+ *max_len += Fh_tail;
13515+ /* todo: macros? */
1716fcea 13516+ if (err != FILEID_INVALID)
1facf9fc 13517+ err = 99;
13518+ else
13519+ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
13520+
0c3ec466 13521+out_hparent:
1facf9fc 13522+ dput(h_parent);
0c3ec466 13523+out_parent:
1facf9fc 13524+ dput(parent);
0c3ec466
AM
13525+out_unlock:
13526+ ii_read_unlock(inode);
13527+ si_read_unlock(sb);
4f0767ce 13528+out:
1facf9fc 13529+ if (unlikely(err < 0))
1716fcea 13530+ err = FILEID_INVALID;
1facf9fc 13531+ return err;
13532+}
13533+
13534+/* ---------------------------------------------------------------------- */
13535+
4a4d8108
AM
13536+static int aufs_commit_metadata(struct inode *inode)
13537+{
13538+ int err;
13539+ aufs_bindex_t bindex;
13540+ struct super_block *sb;
13541+ struct inode *h_inode;
13542+ int (*f)(struct inode *inode);
13543+
13544+ sb = inode->i_sb;
e49829fe 13545+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108 13546+ ii_write_lock_child(inode);
5afbbe0d 13547+ bindex = au_ibtop(inode);
4a4d8108
AM
13548+ AuDebugOn(bindex < 0);
13549+ h_inode = au_h_iptr(inode, bindex);
13550+
13551+ f = h_inode->i_sb->s_export_op->commit_metadata;
13552+ if (f)
13553+ err = f(h_inode);
13554+ else {
13555+ struct writeback_control wbc = {
13556+ .sync_mode = WB_SYNC_ALL,
13557+ .nr_to_write = 0 /* metadata only */
13558+ };
13559+
13560+ err = sync_inode(h_inode, &wbc);
13561+ }
13562+
13563+ au_cpup_attr_timesizes(inode);
13564+ ii_write_unlock(inode);
13565+ si_read_unlock(sb);
13566+ return err;
13567+}
13568+
13569+/* ---------------------------------------------------------------------- */
13570+
1facf9fc 13571+static struct export_operations aufs_export_op = {
4a4d8108 13572+ .fh_to_dentry = aufs_fh_to_dentry,
1facf9fc 13573+ /* .fh_to_parent = aufs_fh_to_parent, */
4a4d8108
AM
13574+ .encode_fh = aufs_encode_fh,
13575+ .commit_metadata = aufs_commit_metadata
1facf9fc 13576+};
13577+
13578+void au_export_init(struct super_block *sb)
13579+{
13580+ struct au_sbinfo *sbinfo;
13581+ __u32 u;
13582+
5afbbe0d
AM
13583+ BUILD_BUG_ON_MSG(IS_BUILTIN(CONFIG_AUFS_FS)
13584+ && IS_MODULE(CONFIG_EXPORTFS),
13585+ AUFS_NAME ": unsupported configuration "
13586+ "CONFIG_EXPORTFS=m and CONFIG_AUFS_FS=y");
13587+
1facf9fc 13588+ sb->s_export_op = &aufs_export_op;
13589+ sbinfo = au_sbi(sb);
13590+ sbinfo->si_xigen = NULL;
13591+ get_random_bytes(&u, sizeof(u));
13592+ BUILD_BUG_ON(sizeof(u) != sizeof(int));
13593+ atomic_set(&sbinfo->si_xigen_next, u);
13594+}
076b876e
AM
13595diff -urN /usr/share/empty/fs/aufs/fhsm.c linux/fs/aufs/fhsm.c
13596--- /usr/share/empty/fs/aufs/fhsm.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
13597+++ linux/fs/aufs/fhsm.c 2018-04-15 08:49:13.397817296 +0200
13598@@ -0,0 +1,427 @@
076b876e 13599+/*
ae9dfd79 13600+ * Copyright (C) 2011-2018 Junjiro R. Okajima
076b876e
AM
13601+ *
13602+ * This program, aufs is free software; you can redistribute it and/or modify
13603+ * it under the terms of the GNU General Public License as published by
13604+ * the Free Software Foundation; either version 2 of the License, or
13605+ * (at your option) any later version.
13606+ *
13607+ * This program is distributed in the hope that it will be useful,
13608+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13609+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13610+ * GNU General Public License for more details.
13611+ *
13612+ * You should have received a copy of the GNU General Public License
13613+ * along with this program; if not, write to the Free Software
13614+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13615+ */
13616+
13617+/*
13618+ * File-based Hierarchy Storage Management
13619+ */
13620+
13621+#include <linux/anon_inodes.h>
13622+#include <linux/poll.h>
13623+#include <linux/seq_file.h>
13624+#include <linux/statfs.h>
13625+#include "aufs.h"
13626+
c1595e42
JR
13627+static aufs_bindex_t au_fhsm_bottom(struct super_block *sb)
13628+{
13629+ struct au_sbinfo *sbinfo;
13630+ struct au_fhsm *fhsm;
13631+
13632+ SiMustAnyLock(sb);
13633+
13634+ sbinfo = au_sbi(sb);
13635+ fhsm = &sbinfo->si_fhsm;
13636+ AuDebugOn(!fhsm);
13637+ return fhsm->fhsm_bottom;
13638+}
13639+
13640+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex)
13641+{
13642+ struct au_sbinfo *sbinfo;
13643+ struct au_fhsm *fhsm;
13644+
13645+ SiMustWriteLock(sb);
13646+
13647+ sbinfo = au_sbi(sb);
13648+ fhsm = &sbinfo->si_fhsm;
13649+ AuDebugOn(!fhsm);
13650+ fhsm->fhsm_bottom = bindex;
13651+}
13652+
13653+/* ---------------------------------------------------------------------- */
13654+
076b876e
AM
13655+static int au_fhsm_test_jiffy(struct au_sbinfo *sbinfo, struct au_branch *br)
13656+{
13657+ struct au_br_fhsm *bf;
13658+
13659+ bf = br->br_fhsm;
13660+ MtxMustLock(&bf->bf_lock);
13661+
13662+ return !bf->bf_readable
13663+ || time_after(jiffies,
13664+ bf->bf_jiffy + sbinfo->si_fhsm.fhsm_expire);
13665+}
13666+
13667+/* ---------------------------------------------------------------------- */
13668+
13669+static void au_fhsm_notify(struct super_block *sb, int val)
13670+{
13671+ struct au_sbinfo *sbinfo;
13672+ struct au_fhsm *fhsm;
13673+
13674+ SiMustAnyLock(sb);
13675+
13676+ sbinfo = au_sbi(sb);
13677+ fhsm = &sbinfo->si_fhsm;
13678+ if (au_fhsm_pid(fhsm)
13679+ && atomic_read(&fhsm->fhsm_readable) != -1) {
13680+ atomic_set(&fhsm->fhsm_readable, val);
13681+ if (val)
13682+ wake_up(&fhsm->fhsm_wqh);
13683+ }
13684+}
13685+
13686+static int au_fhsm_stfs(struct super_block *sb, aufs_bindex_t bindex,
13687+ struct aufs_stfs *rstfs, int do_lock, int do_notify)
13688+{
13689+ int err;
13690+ struct au_branch *br;
13691+ struct au_br_fhsm *bf;
13692+
13693+ br = au_sbr(sb, bindex);
13694+ AuDebugOn(au_br_rdonly(br));
13695+ bf = br->br_fhsm;
13696+ AuDebugOn(!bf);
13697+
13698+ if (do_lock)
13699+ mutex_lock(&bf->bf_lock);
13700+ else
13701+ MtxMustLock(&bf->bf_lock);
13702+
13703+ /* sb->s_root for NFS is unreliable */
13704+ err = au_br_stfs(br, &bf->bf_stfs);
13705+ if (unlikely(err)) {
13706+ AuErr1("FHSM failed (%d), b%d, ignored.\n", bindex, err);
13707+ goto out;
13708+ }
13709+
13710+ bf->bf_jiffy = jiffies;
13711+ bf->bf_readable = 1;
13712+ if (do_notify)
13713+ au_fhsm_notify(sb, /*val*/1);
13714+ if (rstfs)
13715+ *rstfs = bf->bf_stfs;
13716+
13717+out:
13718+ if (do_lock)
13719+ mutex_unlock(&bf->bf_lock);
13720+ au_fhsm_notify(sb, /*val*/1);
13721+
13722+ return err;
13723+}
13724+
13725+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force)
13726+{
13727+ int err;
076b876e
AM
13728+ struct au_sbinfo *sbinfo;
13729+ struct au_fhsm *fhsm;
13730+ struct au_branch *br;
13731+ struct au_br_fhsm *bf;
13732+
13733+ AuDbg("b%d, force %d\n", bindex, force);
13734+ SiMustAnyLock(sb);
13735+
13736+ sbinfo = au_sbi(sb);
13737+ fhsm = &sbinfo->si_fhsm;
c1595e42
JR
13738+ if (!au_ftest_si(sbinfo, FHSM)
13739+ || fhsm->fhsm_bottom == bindex)
076b876e
AM
13740+ return;
13741+
13742+ br = au_sbr(sb, bindex);
13743+ bf = br->br_fhsm;
13744+ AuDebugOn(!bf);
13745+ mutex_lock(&bf->bf_lock);
13746+ if (force
13747+ || au_fhsm_pid(fhsm)
13748+ || au_fhsm_test_jiffy(sbinfo, br))
13749+ err = au_fhsm_stfs(sb, bindex, /*rstfs*/NULL, /*do_lock*/0,
13750+ /*do_notify*/1);
13751+ mutex_unlock(&bf->bf_lock);
13752+}
13753+
13754+void au_fhsm_wrote_all(struct super_block *sb, int force)
13755+{
5afbbe0d 13756+ aufs_bindex_t bindex, bbot;
076b876e
AM
13757+ struct au_branch *br;
13758+
13759+ /* exclude the bottom */
5afbbe0d
AM
13760+ bbot = au_fhsm_bottom(sb);
13761+ for (bindex = 0; bindex < bbot; bindex++) {
076b876e
AM
13762+ br = au_sbr(sb, bindex);
13763+ if (au_br_fhsm(br->br_perm))
13764+ au_fhsm_wrote(sb, bindex, force);
13765+ }
13766+}
13767+
13768+/* ---------------------------------------------------------------------- */
13769+
13770+static unsigned int au_fhsm_poll(struct file *file,
13771+ struct poll_table_struct *wait)
13772+{
13773+ unsigned int mask;
13774+ struct au_sbinfo *sbinfo;
13775+ struct au_fhsm *fhsm;
13776+
13777+ mask = 0;
13778+ sbinfo = file->private_data;
13779+ fhsm = &sbinfo->si_fhsm;
13780+ poll_wait(file, &fhsm->fhsm_wqh, wait);
13781+ if (atomic_read(&fhsm->fhsm_readable))
13782+ mask = POLLIN /* | POLLRDNORM */;
13783+
ae9dfd79
AM
13784+ if (!mask)
13785+ AuDbg("mask 0x%x\n", mask);
076b876e
AM
13786+ return mask;
13787+}
13788+
13789+static int au_fhsm_do_read_one(struct aufs_stbr __user *stbr,
13790+ struct aufs_stfs *stfs, __s16 brid)
13791+{
13792+ int err;
13793+
13794+ err = copy_to_user(&stbr->stfs, stfs, sizeof(*stfs));
13795+ if (!err)
13796+ err = __put_user(brid, &stbr->brid);
13797+ if (unlikely(err))
13798+ err = -EFAULT;
13799+
13800+ return err;
13801+}
13802+
13803+static ssize_t au_fhsm_do_read(struct super_block *sb,
13804+ struct aufs_stbr __user *stbr, size_t count)
13805+{
13806+ ssize_t err;
13807+ int nstbr;
5afbbe0d 13808+ aufs_bindex_t bindex, bbot;
076b876e
AM
13809+ struct au_branch *br;
13810+ struct au_br_fhsm *bf;
13811+
13812+ /* except the bottom branch */
13813+ err = 0;
13814+ nstbr = 0;
5afbbe0d
AM
13815+ bbot = au_fhsm_bottom(sb);
13816+ for (bindex = 0; !err && bindex < bbot; bindex++) {
076b876e
AM
13817+ br = au_sbr(sb, bindex);
13818+ if (!au_br_fhsm(br->br_perm))
13819+ continue;
13820+
13821+ bf = br->br_fhsm;
13822+ mutex_lock(&bf->bf_lock);
13823+ if (bf->bf_readable) {
13824+ err = -EFAULT;
13825+ if (count >= sizeof(*stbr))
13826+ err = au_fhsm_do_read_one(stbr++, &bf->bf_stfs,
13827+ br->br_id);
13828+ if (!err) {
13829+ bf->bf_readable = 0;
13830+ count -= sizeof(*stbr);
13831+ nstbr++;
13832+ }
13833+ }
13834+ mutex_unlock(&bf->bf_lock);
13835+ }
13836+ if (!err)
13837+ err = sizeof(*stbr) * nstbr;
13838+
13839+ return err;
13840+}
13841+
13842+static ssize_t au_fhsm_read(struct file *file, char __user *buf, size_t count,
13843+ loff_t *pos)
13844+{
13845+ ssize_t err;
13846+ int readable;
5afbbe0d 13847+ aufs_bindex_t nfhsm, bindex, bbot;
076b876e
AM
13848+ struct au_sbinfo *sbinfo;
13849+ struct au_fhsm *fhsm;
13850+ struct au_branch *br;
13851+ struct super_block *sb;
13852+
13853+ err = 0;
13854+ sbinfo = file->private_data;
13855+ fhsm = &sbinfo->si_fhsm;
13856+need_data:
13857+ spin_lock_irq(&fhsm->fhsm_wqh.lock);
13858+ if (!atomic_read(&fhsm->fhsm_readable)) {
13859+ if (vfsub_file_flags(file) & O_NONBLOCK)
13860+ err = -EAGAIN;
13861+ else
13862+ err = wait_event_interruptible_locked_irq
13863+ (fhsm->fhsm_wqh,
13864+ atomic_read(&fhsm->fhsm_readable));
13865+ }
13866+ spin_unlock_irq(&fhsm->fhsm_wqh.lock);
13867+ if (unlikely(err))
13868+ goto out;
13869+
13870+ /* sb may already be dead */
13871+ au_rw_read_lock(&sbinfo->si_rwsem);
13872+ readable = atomic_read(&fhsm->fhsm_readable);
13873+ if (readable > 0) {
13874+ sb = sbinfo->si_sb;
13875+ AuDebugOn(!sb);
13876+ /* exclude the bottom branch */
13877+ nfhsm = 0;
5afbbe0d
AM
13878+ bbot = au_fhsm_bottom(sb);
13879+ for (bindex = 0; bindex < bbot; bindex++) {
076b876e
AM
13880+ br = au_sbr(sb, bindex);
13881+ if (au_br_fhsm(br->br_perm))
13882+ nfhsm++;
13883+ }
13884+ err = -EMSGSIZE;
13885+ if (nfhsm * sizeof(struct aufs_stbr) <= count) {
13886+ atomic_set(&fhsm->fhsm_readable, 0);
13887+ err = au_fhsm_do_read(sbinfo->si_sb, (void __user *)buf,
13888+ count);
13889+ }
13890+ }
13891+ au_rw_read_unlock(&sbinfo->si_rwsem);
13892+ if (!readable)
13893+ goto need_data;
13894+
13895+out:
13896+ return err;
13897+}
13898+
13899+static int au_fhsm_release(struct inode *inode, struct file *file)
13900+{
13901+ struct au_sbinfo *sbinfo;
13902+ struct au_fhsm *fhsm;
13903+
13904+ /* sb may already be dead */
13905+ sbinfo = file->private_data;
13906+ fhsm = &sbinfo->si_fhsm;
13907+ spin_lock(&fhsm->fhsm_spin);
13908+ fhsm->fhsm_pid = 0;
13909+ spin_unlock(&fhsm->fhsm_spin);
13910+ kobject_put(&sbinfo->si_kobj);
13911+
13912+ return 0;
13913+}
13914+
13915+static const struct file_operations au_fhsm_fops = {
13916+ .owner = THIS_MODULE,
13917+ .llseek = noop_llseek,
13918+ .read = au_fhsm_read,
13919+ .poll = au_fhsm_poll,
13920+ .release = au_fhsm_release
13921+};
13922+
13923+int au_fhsm_fd(struct super_block *sb, int oflags)
13924+{
13925+ int err, fd;
13926+ struct au_sbinfo *sbinfo;
13927+ struct au_fhsm *fhsm;
13928+
13929+ err = -EPERM;
13930+ if (unlikely(!capable(CAP_SYS_ADMIN)))
13931+ goto out;
13932+
13933+ err = -EINVAL;
13934+ if (unlikely(oflags & ~(O_CLOEXEC | O_NONBLOCK)))
13935+ goto out;
13936+
13937+ err = 0;
13938+ sbinfo = au_sbi(sb);
13939+ fhsm = &sbinfo->si_fhsm;
13940+ spin_lock(&fhsm->fhsm_spin);
13941+ if (!fhsm->fhsm_pid)
13942+ fhsm->fhsm_pid = current->pid;
13943+ else
13944+ err = -EBUSY;
13945+ spin_unlock(&fhsm->fhsm_spin);
13946+ if (unlikely(err))
13947+ goto out;
13948+
13949+ oflags |= O_RDONLY;
13950+ /* oflags |= FMODE_NONOTIFY; */
13951+ fd = anon_inode_getfd("[aufs_fhsm]", &au_fhsm_fops, sbinfo, oflags);
13952+ err = fd;
13953+ if (unlikely(fd < 0))
13954+ goto out_pid;
13955+
13956+ /* succeed reglardless 'fhsm' status */
13957+ kobject_get(&sbinfo->si_kobj);
13958+ si_noflush_read_lock(sb);
13959+ if (au_ftest_si(sbinfo, FHSM))
13960+ au_fhsm_wrote_all(sb, /*force*/0);
13961+ si_read_unlock(sb);
13962+ goto out; /* success */
13963+
13964+out_pid:
13965+ spin_lock(&fhsm->fhsm_spin);
13966+ fhsm->fhsm_pid = 0;
13967+ spin_unlock(&fhsm->fhsm_spin);
13968+out:
13969+ AuTraceErr(err);
13970+ return err;
13971+}
13972+
13973+/* ---------------------------------------------------------------------- */
13974+
13975+int au_fhsm_br_alloc(struct au_branch *br)
13976+{
13977+ int err;
13978+
13979+ err = 0;
13980+ br->br_fhsm = kmalloc(sizeof(*br->br_fhsm), GFP_NOFS);
13981+ if (br->br_fhsm)
13982+ au_br_fhsm_init(br->br_fhsm);
13983+ else
13984+ err = -ENOMEM;
13985+
13986+ return err;
13987+}
13988+
13989+/* ---------------------------------------------------------------------- */
13990+
13991+void au_fhsm_fin(struct super_block *sb)
13992+{
13993+ au_fhsm_notify(sb, /*val*/-1);
13994+}
13995+
13996+void au_fhsm_init(struct au_sbinfo *sbinfo)
13997+{
13998+ struct au_fhsm *fhsm;
13999+
14000+ fhsm = &sbinfo->si_fhsm;
14001+ spin_lock_init(&fhsm->fhsm_spin);
14002+ init_waitqueue_head(&fhsm->fhsm_wqh);
14003+ atomic_set(&fhsm->fhsm_readable, 0);
14004+ fhsm->fhsm_expire
14005+ = msecs_to_jiffies(AUFS_FHSM_CACHE_DEF_SEC * MSEC_PER_SEC);
c1595e42 14006+ fhsm->fhsm_bottom = -1;
076b876e
AM
14007+}
14008+
14009+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec)
14010+{
14011+ sbinfo->si_fhsm.fhsm_expire
14012+ = msecs_to_jiffies(sec * MSEC_PER_SEC);
14013+}
14014+
14015+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo)
14016+{
14017+ unsigned int u;
14018+
14019+ if (!au_ftest_si(sbinfo, FHSM))
14020+ return;
14021+
14022+ u = jiffies_to_msecs(sbinfo->si_fhsm.fhsm_expire) / MSEC_PER_SEC;
14023+ if (u != AUFS_FHSM_CACHE_DEF_SEC)
14024+ seq_printf(seq, ",fhsm_sec=%u", u);
14025+}
7f207e10
AM
14026diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
14027--- /usr/share/empty/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
14028+++ linux/fs/aufs/file.c 2018-04-15 08:49:13.397817296 +0200
14029@@ -0,0 +1,848 @@
1facf9fc 14030+/*
ae9dfd79 14031+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 14032+ *
14033+ * This program, aufs is free software; you can redistribute it and/or modify
14034+ * it under the terms of the GNU General Public License as published by
14035+ * the Free Software Foundation; either version 2 of the License, or
14036+ * (at your option) any later version.
dece6358
AM
14037+ *
14038+ * This program is distributed in the hope that it will be useful,
14039+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14040+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14041+ * GNU General Public License for more details.
14042+ *
14043+ * You should have received a copy of the GNU General Public License
523b37e3 14044+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 14045+ */
14046+
14047+/*
4a4d8108 14048+ * handling file/dir, and address_space operation
1facf9fc 14049+ */
14050+
7eafdf33
AM
14051+#ifdef CONFIG_AUFS_DEBUG
14052+#include <linux/migrate.h>
14053+#endif
4a4d8108 14054+#include <linux/pagemap.h>
1facf9fc 14055+#include "aufs.h"
14056+
4a4d8108
AM
14057+/* drop flags for writing */
14058+unsigned int au_file_roflags(unsigned int flags)
14059+{
14060+ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
14061+ flags |= O_RDONLY | O_NOATIME;
14062+ return flags;
14063+}
14064+
14065+/* common functions to regular file and dir */
14066+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 14067+ struct file *file, int force_wr)
1facf9fc 14068+{
1308ab2a 14069+ struct file *h_file;
4a4d8108
AM
14070+ struct dentry *h_dentry;
14071+ struct inode *h_inode;
14072+ struct super_block *sb;
14073+ struct au_branch *br;
14074+ struct path h_path;
b912730e 14075+ int err;
1facf9fc 14076+
4a4d8108
AM
14077+ /* a race condition can happen between open and unlink/rmdir */
14078+ h_file = ERR_PTR(-ENOENT);
14079+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 14080+ if (au_test_nfsd() && (!h_dentry || d_is_negative(h_dentry)))
4a4d8108 14081+ goto out;
5527c038 14082+ h_inode = d_inode(h_dentry);
027c5e7a
AM
14083+ spin_lock(&h_dentry->d_lock);
14084+ err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
5527c038 14085+ /* || !d_inode(dentry)->i_nlink */
027c5e7a
AM
14086+ ;
14087+ spin_unlock(&h_dentry->d_lock);
14088+ if (unlikely(err))
4a4d8108 14089+ goto out;
1facf9fc 14090+
4a4d8108
AM
14091+ sb = dentry->d_sb;
14092+ br = au_sbr(sb, bindex);
b912730e
AM
14093+ err = au_br_test_oflag(flags, br);
14094+ h_file = ERR_PTR(err);
14095+ if (unlikely(err))
027c5e7a 14096+ goto out;
1facf9fc 14097+
4a4d8108 14098+ /* drop flags for writing */
5527c038 14099+ if (au_test_ro(sb, bindex, d_inode(dentry))) {
392086de
AM
14100+ if (force_wr && !(flags & O_WRONLY))
14101+ force_wr = 0;
4a4d8108 14102+ flags = au_file_roflags(flags);
392086de
AM
14103+ if (force_wr) {
14104+ h_file = ERR_PTR(-EROFS);
14105+ flags = au_file_roflags(flags);
14106+ if (unlikely(vfsub_native_ro(h_inode)
14107+ || IS_APPEND(h_inode)))
14108+ goto out;
14109+ flags &= ~O_ACCMODE;
14110+ flags |= O_WRONLY;
14111+ }
14112+ }
4a4d8108 14113+ flags &= ~O_CREAT;
5afbbe0d 14114+ au_br_get(br);
4a4d8108 14115+ h_path.dentry = h_dentry;
86dc4139 14116+ h_path.mnt = au_br_mnt(br);
38d290e6 14117+ h_file = vfsub_dentry_open(&h_path, flags);
4a4d8108
AM
14118+ if (IS_ERR(h_file))
14119+ goto out_br;
dece6358 14120+
b912730e 14121+ if (flags & __FMODE_EXEC) {
4a4d8108
AM
14122+ err = deny_write_access(h_file);
14123+ if (unlikely(err)) {
14124+ fput(h_file);
14125+ h_file = ERR_PTR(err);
14126+ goto out_br;
14127+ }
14128+ }
953406b4 14129+ fsnotify_open(h_file);
4a4d8108 14130+ goto out; /* success */
1facf9fc 14131+
4f0767ce 14132+out_br:
5afbbe0d 14133+ au_br_put(br);
4f0767ce 14134+out:
4a4d8108
AM
14135+ return h_file;
14136+}
1308ab2a 14137+
076b876e
AM
14138+static int au_cmoo(struct dentry *dentry)
14139+{
ae9dfd79 14140+ int err, cmoo, matched;
076b876e
AM
14141+ unsigned int udba;
14142+ struct path h_path;
14143+ struct au_pin pin;
14144+ struct au_cp_generic cpg = {
14145+ .dentry = dentry,
14146+ .bdst = -1,
14147+ .bsrc = -1,
14148+ .len = -1,
14149+ .pin = &pin,
14150+ .flags = AuCpup_DTIME | AuCpup_HOPEN
14151+ };
7e9cd9fe 14152+ struct inode *delegated;
076b876e
AM
14153+ struct super_block *sb;
14154+ struct au_sbinfo *sbinfo;
14155+ struct au_fhsm *fhsm;
14156+ pid_t pid;
14157+ struct au_branch *br;
14158+ struct dentry *parent;
14159+ struct au_hinode *hdir;
14160+
14161+ DiMustWriteLock(dentry);
5527c038 14162+ IiMustWriteLock(d_inode(dentry));
076b876e
AM
14163+
14164+ err = 0;
14165+ if (IS_ROOT(dentry))
14166+ goto out;
5afbbe0d 14167+ cpg.bsrc = au_dbtop(dentry);
076b876e
AM
14168+ if (!cpg.bsrc)
14169+ goto out;
14170+
14171+ sb = dentry->d_sb;
14172+ sbinfo = au_sbi(sb);
14173+ fhsm = &sbinfo->si_fhsm;
14174+ pid = au_fhsm_pid(fhsm);
ae9dfd79
AM
14175+ rcu_read_lock();
14176+ matched = (pid
14177+ && (current->pid == pid
14178+ || rcu_dereference(current->real_parent)->pid == pid));
14179+ rcu_read_unlock();
14180+ if (matched)
076b876e
AM
14181+ goto out;
14182+
14183+ br = au_sbr(sb, cpg.bsrc);
14184+ cmoo = au_br_cmoo(br->br_perm);
14185+ if (!cmoo)
14186+ goto out;
7e9cd9fe 14187+ if (!d_is_reg(dentry))
076b876e
AM
14188+ cmoo &= AuBrAttr_COO_ALL;
14189+ if (!cmoo)
14190+ goto out;
14191+
14192+ parent = dget_parent(dentry);
14193+ di_write_lock_parent(parent);
14194+ err = au_wbr_do_copyup_bu(dentry, cpg.bsrc - 1);
14195+ cpg.bdst = err;
14196+ if (unlikely(err < 0)) {
14197+ err = 0; /* there is no upper writable branch */
14198+ goto out_dgrade;
14199+ }
14200+ AuDbg("bsrc %d, bdst %d\n", cpg.bsrc, cpg.bdst);
14201+
14202+ /* do not respect the coo attrib for the target branch */
14203+ err = au_cpup_dirs(dentry, cpg.bdst);
14204+ if (unlikely(err))
14205+ goto out_dgrade;
14206+
14207+ di_downgrade_lock(parent, AuLock_IR);
14208+ udba = au_opt_udba(sb);
14209+ err = au_pin(&pin, dentry, cpg.bdst, udba,
14210+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
14211+ if (unlikely(err))
14212+ goto out_parent;
14213+
14214+ err = au_sio_cpup_simple(&cpg);
14215+ au_unpin(&pin);
14216+ if (unlikely(err))
14217+ goto out_parent;
14218+ if (!(cmoo & AuBrWAttr_MOO))
14219+ goto out_parent; /* success */
14220+
14221+ err = au_pin(&pin, dentry, cpg.bsrc, udba,
14222+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
14223+ if (unlikely(err))
14224+ goto out_parent;
14225+
14226+ h_path.mnt = au_br_mnt(br);
14227+ h_path.dentry = au_h_dptr(dentry, cpg.bsrc);
5527c038 14228+ hdir = au_hi(d_inode(parent), cpg.bsrc);
076b876e
AM
14229+ delegated = NULL;
14230+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, /*force*/1);
14231+ au_unpin(&pin);
14232+ /* todo: keep h_dentry or not? */
14233+ if (unlikely(err == -EWOULDBLOCK)) {
14234+ pr_warn("cannot retry for NFSv4 delegation"
14235+ " for an internal unlink\n");
14236+ iput(delegated);
14237+ }
14238+ if (unlikely(err)) {
14239+ pr_err("unlink %pd after coo failed (%d), ignored\n",
14240+ dentry, err);
14241+ err = 0;
14242+ }
14243+ goto out_parent; /* success */
14244+
14245+out_dgrade:
14246+ di_downgrade_lock(parent, AuLock_IR);
14247+out_parent:
14248+ di_read_unlock(parent, AuLock_IR);
14249+ dput(parent);
14250+out:
14251+ AuTraceErr(err);
14252+ return err;
14253+}
14254+
b912730e 14255+int au_do_open(struct file *file, struct au_do_open_args *args)
1facf9fc 14256+{
ae9dfd79 14257+ int err, aopen = args->aopen;
1facf9fc 14258+ struct dentry *dentry;
076b876e 14259+ struct au_finfo *finfo;
1308ab2a 14260+
ae9dfd79 14261+ if (!aopen)
b912730e
AM
14262+ err = au_finfo_init(file, args->fidir);
14263+ else {
14264+ lockdep_off();
14265+ err = au_finfo_init(file, args->fidir);
14266+ lockdep_on();
14267+ }
4a4d8108
AM
14268+ if (unlikely(err))
14269+ goto out;
1facf9fc 14270+
2000de60 14271+ dentry = file->f_path.dentry;
b912730e 14272+ AuDebugOn(IS_ERR_OR_NULL(dentry));
ae9dfd79
AM
14273+ di_write_lock_child(dentry);
14274+ err = au_cmoo(dentry);
14275+ di_downgrade_lock(dentry, AuLock_IR);
14276+ if (!err)
14277+ err = args->open(file, vfsub_file_flags(file), NULL);
14278+ di_read_unlock(dentry, AuLock_IR);
1facf9fc 14279+
076b876e
AM
14280+ finfo = au_fi(file);
14281+ if (!err) {
14282+ finfo->fi_file = file;
ae9dfd79
AM
14283+ au_hbl_add(&finfo->fi_hlist,
14284+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
076b876e 14285+ }
ae9dfd79 14286+ if (!aopen)
b912730e
AM
14287+ fi_write_unlock(file);
14288+ else {
14289+ lockdep_off();
14290+ fi_write_unlock(file);
14291+ lockdep_on();
14292+ }
4a4d8108 14293+ if (unlikely(err)) {
076b876e 14294+ finfo->fi_hdir = NULL;
ae9dfd79 14295+ au_finfo_fin(file);
1308ab2a 14296+ }
4a4d8108 14297+
4f0767ce 14298+out:
1308ab2a 14299+ return err;
14300+}
dece6358 14301+
4a4d8108 14302+int au_reopen_nondir(struct file *file)
1308ab2a 14303+{
4a4d8108 14304+ int err;
5afbbe0d 14305+ aufs_bindex_t btop;
4a4d8108
AM
14306+ struct dentry *dentry;
14307+ struct file *h_file, *h_file_tmp;
1308ab2a 14308+
2000de60 14309+ dentry = file->f_path.dentry;
5afbbe0d 14310+ btop = au_dbtop(dentry);
4a4d8108 14311+ h_file_tmp = NULL;
5afbbe0d 14312+ if (au_fbtop(file) == btop) {
4a4d8108
AM
14313+ h_file = au_hf_top(file);
14314+ if (file->f_mode == h_file->f_mode)
14315+ return 0; /* success */
14316+ h_file_tmp = h_file;
14317+ get_file(h_file_tmp);
5afbbe0d 14318+ au_set_h_fptr(file, btop, NULL);
4a4d8108
AM
14319+ }
14320+ AuDebugOn(au_fi(file)->fi_hdir);
86dc4139
AM
14321+ /*
14322+ * it can happen
14323+ * file exists on both of rw and ro
5afbbe0d 14324+ * open --> dbtop and fbtop are both 0
86dc4139
AM
14325+ * prepend a branch as rw, "rw" become ro
14326+ * remove rw/file
14327+ * delete the top branch, "rw" becomes rw again
5afbbe0d
AM
14328+ * --> dbtop is 1, fbtop is still 0
14329+ * write --> fbtop is 0 but dbtop is 1
86dc4139 14330+ */
5afbbe0d 14331+ /* AuDebugOn(au_fbtop(file) < btop); */
1308ab2a 14332+
5afbbe0d 14333+ h_file = au_h_open(dentry, btop, vfsub_file_flags(file) & ~O_TRUNC,
392086de 14334+ file, /*force_wr*/0);
4a4d8108 14335+ err = PTR_ERR(h_file);
86dc4139
AM
14336+ if (IS_ERR(h_file)) {
14337+ if (h_file_tmp) {
5afbbe0d
AM
14338+ au_sbr_get(dentry->d_sb, btop);
14339+ au_set_h_fptr(file, btop, h_file_tmp);
86dc4139
AM
14340+ h_file_tmp = NULL;
14341+ }
4a4d8108 14342+ goto out; /* todo: close all? */
86dc4139 14343+ }
4a4d8108
AM
14344+
14345+ err = 0;
5afbbe0d
AM
14346+ au_set_fbtop(file, btop);
14347+ au_set_h_fptr(file, btop, h_file);
4a4d8108
AM
14348+ au_update_figen(file);
14349+ /* todo: necessary? */
14350+ /* file->f_ra = h_file->f_ra; */
14351+
4f0767ce 14352+out:
4a4d8108
AM
14353+ if (h_file_tmp)
14354+ fput(h_file_tmp);
14355+ return err;
1facf9fc 14356+}
14357+
1308ab2a 14358+/* ---------------------------------------------------------------------- */
14359+
4a4d8108
AM
14360+static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
14361+ struct dentry *hi_wh)
1facf9fc 14362+{
4a4d8108 14363+ int err;
5afbbe0d 14364+ aufs_bindex_t btop;
4a4d8108
AM
14365+ struct au_dinfo *dinfo;
14366+ struct dentry *h_dentry;
14367+ struct au_hdentry *hdp;
1facf9fc 14368+
2000de60 14369+ dinfo = au_di(file->f_path.dentry);
4a4d8108 14370+ AuRwMustWriteLock(&dinfo->di_rwsem);
dece6358 14371+
5afbbe0d
AM
14372+ btop = dinfo->di_btop;
14373+ dinfo->di_btop = btgt;
14374+ hdp = au_hdentry(dinfo, btgt);
14375+ h_dentry = hdp->hd_dentry;
14376+ hdp->hd_dentry = hi_wh;
4a4d8108 14377+ err = au_reopen_nondir(file);
5afbbe0d
AM
14378+ hdp->hd_dentry = h_dentry;
14379+ dinfo->di_btop = btop;
1facf9fc 14380+
1facf9fc 14381+ return err;
14382+}
14383+
4a4d8108 14384+static int au_ready_to_write_wh(struct file *file, loff_t len,
86dc4139 14385+ aufs_bindex_t bcpup, struct au_pin *pin)
1facf9fc 14386+{
4a4d8108 14387+ int err;
027c5e7a 14388+ struct inode *inode, *h_inode;
c2b27bf2
AM
14389+ struct dentry *h_dentry, *hi_wh;
14390+ struct au_cp_generic cpg = {
2000de60 14391+ .dentry = file->f_path.dentry,
c2b27bf2
AM
14392+ .bdst = bcpup,
14393+ .bsrc = -1,
14394+ .len = len,
14395+ .pin = pin
14396+ };
1facf9fc 14397+
5afbbe0d 14398+ au_update_dbtop(cpg.dentry);
5527c038 14399+ inode = d_inode(cpg.dentry);
027c5e7a 14400+ h_inode = NULL;
5afbbe0d
AM
14401+ if (au_dbtop(cpg.dentry) <= bcpup
14402+ && au_dbbot(cpg.dentry) >= bcpup) {
c2b27bf2 14403+ h_dentry = au_h_dptr(cpg.dentry, bcpup);
5527c038
JR
14404+ if (h_dentry && d_is_positive(h_dentry))
14405+ h_inode = d_inode(h_dentry);
027c5e7a 14406+ }
4a4d8108 14407+ hi_wh = au_hi_wh(inode, bcpup);
027c5e7a 14408+ if (!hi_wh && !h_inode)
c2b27bf2 14409+ err = au_sio_cpup_wh(&cpg, file);
4a4d8108
AM
14410+ else
14411+ /* already copied-up after unlink */
14412+ err = au_reopen_wh(file, bcpup, hi_wh);
1facf9fc 14413+
4a4d8108 14414+ if (!err
38d290e6
JR
14415+ && (inode->i_nlink > 1
14416+ || (inode->i_state & I_LINKABLE))
c2b27bf2
AM
14417+ && au_opt_test(au_mntflags(cpg.dentry->d_sb), PLINK))
14418+ au_plink_append(inode, bcpup, au_h_dptr(cpg.dentry, bcpup));
1308ab2a 14419+
dece6358 14420+ return err;
1facf9fc 14421+}
14422+
4a4d8108
AM
14423+/*
14424+ * prepare the @file for writing.
14425+ */
14426+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
1facf9fc 14427+{
4a4d8108 14428+ int err;
5afbbe0d 14429+ aufs_bindex_t dbtop;
c1595e42 14430+ struct dentry *parent;
86dc4139 14431+ struct inode *inode;
1facf9fc 14432+ struct super_block *sb;
4a4d8108 14433+ struct file *h_file;
c2b27bf2 14434+ struct au_cp_generic cpg = {
2000de60 14435+ .dentry = file->f_path.dentry,
c2b27bf2
AM
14436+ .bdst = -1,
14437+ .bsrc = -1,
14438+ .len = len,
14439+ .pin = pin,
14440+ .flags = AuCpup_DTIME
14441+ };
1facf9fc 14442+
c2b27bf2 14443+ sb = cpg.dentry->d_sb;
5527c038 14444+ inode = d_inode(cpg.dentry);
5afbbe0d 14445+ cpg.bsrc = au_fbtop(file);
c2b27bf2 14446+ err = au_test_ro(sb, cpg.bsrc, inode);
4a4d8108 14447+ if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
c2b27bf2
AM
14448+ err = au_pin(pin, cpg.dentry, cpg.bsrc, AuOpt_UDBA_NONE,
14449+ /*flags*/0);
1facf9fc 14450+ goto out;
4a4d8108 14451+ }
1facf9fc 14452+
027c5e7a 14453+ /* need to cpup or reopen */
c2b27bf2 14454+ parent = dget_parent(cpg.dentry);
4a4d8108 14455+ di_write_lock_parent(parent);
c2b27bf2
AM
14456+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
14457+ cpg.bdst = err;
4a4d8108
AM
14458+ if (unlikely(err < 0))
14459+ goto out_dgrade;
14460+ err = 0;
14461+
c2b27bf2
AM
14462+ if (!d_unhashed(cpg.dentry) && !au_h_dptr(parent, cpg.bdst)) {
14463+ err = au_cpup_dirs(cpg.dentry, cpg.bdst);
1facf9fc 14464+ if (unlikely(err))
4a4d8108
AM
14465+ goto out_dgrade;
14466+ }
14467+
c2b27bf2 14468+ err = au_pin(pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108
AM
14469+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
14470+ if (unlikely(err))
14471+ goto out_dgrade;
14472+
5afbbe0d
AM
14473+ dbtop = au_dbtop(cpg.dentry);
14474+ if (dbtop <= cpg.bdst)
c2b27bf2 14475+ cpg.bsrc = cpg.bdst;
027c5e7a 14476+
5afbbe0d 14477+ if (dbtop <= cpg.bdst /* just reopen */
c2b27bf2 14478+ || !d_unhashed(cpg.dentry) /* copyup and reopen */
027c5e7a 14479+ ) {
392086de 14480+ h_file = au_h_open_pre(cpg.dentry, cpg.bsrc, /*force_wr*/0);
86dc4139 14481+ if (IS_ERR(h_file))
027c5e7a 14482+ err = PTR_ERR(h_file);
86dc4139 14483+ else {
027c5e7a 14484+ di_downgrade_lock(parent, AuLock_IR);
5afbbe0d 14485+ if (dbtop > cpg.bdst)
c2b27bf2 14486+ err = au_sio_cpup_simple(&cpg);
027c5e7a
AM
14487+ if (!err)
14488+ err = au_reopen_nondir(file);
c2b27bf2 14489+ au_h_open_post(cpg.dentry, cpg.bsrc, h_file);
027c5e7a 14490+ }
027c5e7a
AM
14491+ } else { /* copyup as wh and reopen */
14492+ /*
14493+ * since writable hfsplus branch is not supported,
14494+ * h_open_pre/post() are unnecessary.
14495+ */
c2b27bf2 14496+ err = au_ready_to_write_wh(file, len, cpg.bdst, pin);
4a4d8108 14497+ di_downgrade_lock(parent, AuLock_IR);
4a4d8108 14498+ }
4a4d8108
AM
14499+
14500+ if (!err) {
14501+ au_pin_set_parent_lflag(pin, /*lflag*/0);
14502+ goto out_dput; /* success */
14503+ }
14504+ au_unpin(pin);
14505+ goto out_unlock;
1facf9fc 14506+
4f0767ce 14507+out_dgrade:
4a4d8108 14508+ di_downgrade_lock(parent, AuLock_IR);
4f0767ce 14509+out_unlock:
4a4d8108 14510+ di_read_unlock(parent, AuLock_IR);
4f0767ce 14511+out_dput:
4a4d8108 14512+ dput(parent);
4f0767ce 14513+out:
1facf9fc 14514+ return err;
14515+}
14516+
4a4d8108
AM
14517+/* ---------------------------------------------------------------------- */
14518+
14519+int au_do_flush(struct file *file, fl_owner_t id,
14520+ int (*flush)(struct file *file, fl_owner_t id))
1facf9fc 14521+{
4a4d8108 14522+ int err;
1facf9fc 14523+ struct super_block *sb;
4a4d8108 14524+ struct inode *inode;
1facf9fc 14525+
c06a8ce3
AM
14526+ inode = file_inode(file);
14527+ sb = inode->i_sb;
4a4d8108
AM
14528+ si_noflush_read_lock(sb);
14529+ fi_read_lock(file);
b752ccd1 14530+ ii_read_lock_child(inode);
1facf9fc 14531+
4a4d8108
AM
14532+ err = flush(file, id);
14533+ au_cpup_attr_timesizes(inode);
1facf9fc 14534+
b752ccd1 14535+ ii_read_unlock(inode);
4a4d8108 14536+ fi_read_unlock(file);
1308ab2a 14537+ si_read_unlock(sb);
dece6358 14538+ return err;
1facf9fc 14539+}
14540+
4a4d8108
AM
14541+/* ---------------------------------------------------------------------- */
14542+
14543+static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
1facf9fc 14544+{
4a4d8108 14545+ int err;
4a4d8108
AM
14546+ struct au_pin pin;
14547+ struct au_finfo *finfo;
c2b27bf2 14548+ struct dentry *parent, *hi_wh;
4a4d8108 14549+ struct inode *inode;
1facf9fc 14550+ struct super_block *sb;
c2b27bf2 14551+ struct au_cp_generic cpg = {
2000de60 14552+ .dentry = file->f_path.dentry,
c2b27bf2
AM
14553+ .bdst = -1,
14554+ .bsrc = -1,
14555+ .len = -1,
14556+ .pin = &pin,
14557+ .flags = AuCpup_DTIME
14558+ };
1facf9fc 14559+
4a4d8108
AM
14560+ FiMustWriteLock(file);
14561+
14562+ err = 0;
14563+ finfo = au_fi(file);
c2b27bf2 14564+ sb = cpg.dentry->d_sb;
5527c038 14565+ inode = d_inode(cpg.dentry);
5afbbe0d 14566+ cpg.bdst = au_ibtop(inode);
c2b27bf2 14567+ if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry))
1308ab2a 14568+ goto out;
dece6358 14569+
c2b27bf2
AM
14570+ parent = dget_parent(cpg.dentry);
14571+ if (au_test_ro(sb, cpg.bdst, inode)) {
4a4d8108 14572+ di_read_lock_parent(parent, !AuLock_IR);
c2b27bf2
AM
14573+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
14574+ cpg.bdst = err;
4a4d8108
AM
14575+ di_read_unlock(parent, !AuLock_IR);
14576+ if (unlikely(err < 0))
14577+ goto out_parent;
14578+ err = 0;
1facf9fc 14579+ }
1facf9fc 14580+
4a4d8108 14581+ di_read_lock_parent(parent, AuLock_IR);
c2b27bf2 14582+ hi_wh = au_hi_wh(inode, cpg.bdst);
7f207e10
AM
14583+ if (!S_ISDIR(inode->i_mode)
14584+ && au_opt_test(au_mntflags(sb), PLINK)
4a4d8108 14585+ && au_plink_test(inode)
c2b27bf2 14586+ && !d_unhashed(cpg.dentry)
5afbbe0d 14587+ && cpg.bdst < au_dbtop(cpg.dentry)) {
c2b27bf2 14588+ err = au_test_and_cpup_dirs(cpg.dentry, cpg.bdst);
4a4d8108
AM
14589+ if (unlikely(err))
14590+ goto out_unlock;
14591+
14592+ /* always superio. */
c2b27bf2 14593+ err = au_pin(&pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108 14594+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 14595+ if (!err) {
c2b27bf2 14596+ err = au_sio_cpup_simple(&cpg);
367653fa
AM
14597+ au_unpin(&pin);
14598+ }
4a4d8108
AM
14599+ } else if (hi_wh) {
14600+ /* already copied-up after unlink */
c2b27bf2 14601+ err = au_reopen_wh(file, cpg.bdst, hi_wh);
4a4d8108
AM
14602+ *need_reopen = 0;
14603+ }
1facf9fc 14604+
4f0767ce 14605+out_unlock:
4a4d8108 14606+ di_read_unlock(parent, AuLock_IR);
4f0767ce 14607+out_parent:
4a4d8108 14608+ dput(parent);
4f0767ce 14609+out:
1308ab2a 14610+ return err;
dece6358 14611+}
1facf9fc 14612+
4a4d8108 14613+static void au_do_refresh_dir(struct file *file)
dece6358 14614+{
5afbbe0d 14615+ aufs_bindex_t bindex, bbot, new_bindex, brid;
4a4d8108
AM
14616+ struct au_hfile *p, tmp, *q;
14617+ struct au_finfo *finfo;
1308ab2a 14618+ struct super_block *sb;
4a4d8108 14619+ struct au_fidir *fidir;
1facf9fc 14620+
4a4d8108 14621+ FiMustWriteLock(file);
1facf9fc 14622+
2000de60 14623+ sb = file->f_path.dentry->d_sb;
4a4d8108
AM
14624+ finfo = au_fi(file);
14625+ fidir = finfo->fi_hdir;
14626+ AuDebugOn(!fidir);
14627+ p = fidir->fd_hfile + finfo->fi_btop;
14628+ brid = p->hf_br->br_id;
5afbbe0d
AM
14629+ bbot = fidir->fd_bbot;
14630+ for (bindex = finfo->fi_btop; bindex <= bbot; bindex++, p++) {
4a4d8108
AM
14631+ if (!p->hf_file)
14632+ continue;
1308ab2a 14633+
4a4d8108
AM
14634+ new_bindex = au_br_index(sb, p->hf_br->br_id);
14635+ if (new_bindex == bindex)
14636+ continue;
14637+ if (new_bindex < 0) {
14638+ au_set_h_fptr(file, bindex, NULL);
14639+ continue;
14640+ }
1308ab2a 14641+
4a4d8108
AM
14642+ /* swap two lower inode, and loop again */
14643+ q = fidir->fd_hfile + new_bindex;
14644+ tmp = *q;
14645+ *q = *p;
14646+ *p = tmp;
14647+ if (tmp.hf_file) {
14648+ bindex--;
14649+ p--;
14650+ }
14651+ }
1308ab2a 14652+
4a4d8108 14653+ p = fidir->fd_hfile;
2000de60 14654+ if (!au_test_mmapped(file) && !d_unlinked(file->f_path.dentry)) {
5afbbe0d
AM
14655+ bbot = au_sbbot(sb);
14656+ for (finfo->fi_btop = 0; finfo->fi_btop <= bbot;
4a4d8108
AM
14657+ finfo->fi_btop++, p++)
14658+ if (p->hf_file) {
c06a8ce3 14659+ if (file_inode(p->hf_file))
4a4d8108 14660+ break;
ae9dfd79 14661+ au_hfput(p, /*execed*/0);
4a4d8108
AM
14662+ }
14663+ } else {
5afbbe0d
AM
14664+ bbot = au_br_index(sb, brid);
14665+ for (finfo->fi_btop = 0; finfo->fi_btop < bbot;
4a4d8108
AM
14666+ finfo->fi_btop++, p++)
14667+ if (p->hf_file)
ae9dfd79 14668+ au_hfput(p, /*execed*/0);
5afbbe0d 14669+ bbot = au_sbbot(sb);
4a4d8108 14670+ }
1308ab2a 14671+
5afbbe0d
AM
14672+ p = fidir->fd_hfile + bbot;
14673+ for (fidir->fd_bbot = bbot; fidir->fd_bbot >= finfo->fi_btop;
4a4d8108
AM
14674+ fidir->fd_bbot--, p--)
14675+ if (p->hf_file) {
c06a8ce3 14676+ if (file_inode(p->hf_file))
4a4d8108 14677+ break;
ae9dfd79 14678+ au_hfput(p, /*execed*/0);
4a4d8108
AM
14679+ }
14680+ AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
1308ab2a 14681+}
14682+
4a4d8108
AM
14683+/*
14684+ * after branch manipulating, refresh the file.
14685+ */
14686+static int refresh_file(struct file *file, int (*reopen)(struct file *file))
1facf9fc 14687+{
e2f27e51 14688+ int err, need_reopen, nbr;
5afbbe0d 14689+ aufs_bindex_t bbot, bindex;
4a4d8108 14690+ struct dentry *dentry;
e2f27e51 14691+ struct super_block *sb;
1308ab2a 14692+ struct au_finfo *finfo;
4a4d8108 14693+ struct au_hfile *hfile;
1facf9fc 14694+
2000de60 14695+ dentry = file->f_path.dentry;
e2f27e51
AM
14696+ sb = dentry->d_sb;
14697+ nbr = au_sbbot(sb) + 1;
1308ab2a 14698+ finfo = au_fi(file);
4a4d8108
AM
14699+ if (!finfo->fi_hdir) {
14700+ hfile = &finfo->fi_htop;
14701+ AuDebugOn(!hfile->hf_file);
e2f27e51 14702+ bindex = au_br_index(sb, hfile->hf_br->br_id);
4a4d8108
AM
14703+ AuDebugOn(bindex < 0);
14704+ if (bindex != finfo->fi_btop)
5afbbe0d 14705+ au_set_fbtop(file, bindex);
4a4d8108 14706+ } else {
e2f27e51 14707+ err = au_fidir_realloc(finfo, nbr, /*may_shrink*/0);
4a4d8108
AM
14708+ if (unlikely(err))
14709+ goto out;
14710+ au_do_refresh_dir(file);
14711+ }
1facf9fc 14712+
4a4d8108
AM
14713+ err = 0;
14714+ need_reopen = 1;
14715+ if (!au_test_mmapped(file))
14716+ err = au_file_refresh_by_inode(file, &need_reopen);
e2f27e51
AM
14717+ if (finfo->fi_hdir)
14718+ /* harmless if err */
14719+ au_fidir_realloc(finfo, nbr, /*may_shrink*/1);
027c5e7a 14720+ if (!err && need_reopen && !d_unlinked(dentry))
4a4d8108
AM
14721+ err = reopen(file);
14722+ if (!err) {
14723+ au_update_figen(file);
14724+ goto out; /* success */
14725+ }
14726+
14727+ /* error, close all lower files */
14728+ if (finfo->fi_hdir) {
5afbbe0d
AM
14729+ bbot = au_fbbot_dir(file);
14730+ for (bindex = au_fbtop(file); bindex <= bbot; bindex++)
4a4d8108
AM
14731+ au_set_h_fptr(file, bindex, NULL);
14732+ }
1facf9fc 14733+
4f0767ce 14734+out:
1facf9fc 14735+ return err;
14736+}
14737+
4a4d8108
AM
14738+/* common function to regular file and dir */
14739+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
ae9dfd79 14740+ int wlock, unsigned int fi_lsc)
dece6358 14741+{
1308ab2a 14742+ int err;
4a4d8108 14743+ unsigned int sigen, figen;
5afbbe0d 14744+ aufs_bindex_t btop;
4a4d8108
AM
14745+ unsigned char pseudo_link;
14746+ struct dentry *dentry;
14747+ struct inode *inode;
1facf9fc 14748+
4a4d8108 14749+ err = 0;
2000de60 14750+ dentry = file->f_path.dentry;
5527c038 14751+ inode = d_inode(dentry);
4a4d8108 14752+ sigen = au_sigen(dentry->d_sb);
ae9dfd79 14753+ fi_write_lock_nested(file, fi_lsc);
4a4d8108 14754+ figen = au_figen(file);
ae9dfd79
AM
14755+ if (!fi_lsc)
14756+ di_write_lock_child(dentry);
14757+ else
14758+ di_write_lock_child2(dentry);
5afbbe0d
AM
14759+ btop = au_dbtop(dentry);
14760+ pseudo_link = (btop != au_ibtop(inode));
14761+ if (sigen == figen && !pseudo_link && au_fbtop(file) == btop) {
4a4d8108
AM
14762+ if (!wlock) {
14763+ di_downgrade_lock(dentry, AuLock_IR);
14764+ fi_downgrade_lock(file);
14765+ }
14766+ goto out; /* success */
14767+ }
dece6358 14768+
4a4d8108 14769+ AuDbg("sigen %d, figen %d\n", sigen, figen);
027c5e7a 14770+ if (au_digen_test(dentry, sigen)) {
4a4d8108 14771+ err = au_reval_dpath(dentry, sigen);
027c5e7a 14772+ AuDebugOn(!err && au_digen_test(dentry, sigen));
4a4d8108 14773+ }
dece6358 14774+
027c5e7a
AM
14775+ if (!err)
14776+ err = refresh_file(file, reopen);
4a4d8108
AM
14777+ if (!err) {
14778+ if (!wlock) {
14779+ di_downgrade_lock(dentry, AuLock_IR);
14780+ fi_downgrade_lock(file);
14781+ }
14782+ } else {
14783+ di_write_unlock(dentry);
14784+ fi_write_unlock(file);
14785+ }
1facf9fc 14786+
4f0767ce 14787+out:
1308ab2a 14788+ return err;
14789+}
1facf9fc 14790+
4a4d8108
AM
14791+/* ---------------------------------------------------------------------- */
14792+
14793+/* cf. aufs_nopage() */
14794+/* for madvise(2) */
14795+static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
1308ab2a 14796+{
4a4d8108
AM
14797+ unlock_page(page);
14798+ return 0;
14799+}
1facf9fc 14800+
4a4d8108 14801+/* it will never be called, but necessary to support O_DIRECT */
5afbbe0d 14802+static ssize_t aufs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
4a4d8108 14803+{ BUG(); return 0; }
1facf9fc 14804+
4a4d8108
AM
14805+/* they will never be called. */
14806+#ifdef CONFIG_AUFS_DEBUG
14807+static int aufs_write_begin(struct file *file, struct address_space *mapping,
14808+ loff_t pos, unsigned len, unsigned flags,
14809+ struct page **pagep, void **fsdata)
14810+{ AuUnsupport(); return 0; }
14811+static int aufs_write_end(struct file *file, struct address_space *mapping,
14812+ loff_t pos, unsigned len, unsigned copied,
14813+ struct page *page, void *fsdata)
14814+{ AuUnsupport(); return 0; }
14815+static int aufs_writepage(struct page *page, struct writeback_control *wbc)
14816+{ AuUnsupport(); return 0; }
1308ab2a 14817+
4a4d8108
AM
14818+static int aufs_set_page_dirty(struct page *page)
14819+{ AuUnsupport(); return 0; }
392086de
AM
14820+static void aufs_invalidatepage(struct page *page, unsigned int offset,
14821+ unsigned int length)
4a4d8108
AM
14822+{ AuUnsupport(); }
14823+static int aufs_releasepage(struct page *page, gfp_t gfp)
14824+{ AuUnsupport(); return 0; }
79b8bda9 14825+#if 0 /* called by memory compaction regardless file */
4a4d8108 14826+static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
7eafdf33 14827+ struct page *page, enum migrate_mode mode)
4a4d8108 14828+{ AuUnsupport(); return 0; }
79b8bda9 14829+#endif
e2f27e51
AM
14830+static bool aufs_isolate_page(struct page *page, isolate_mode_t mode)
14831+{ AuUnsupport(); return true; }
14832+static void aufs_putback_page(struct page *page)
14833+{ AuUnsupport(); }
4a4d8108
AM
14834+static int aufs_launder_page(struct page *page)
14835+{ AuUnsupport(); return 0; }
14836+static int aufs_is_partially_uptodate(struct page *page,
38d290e6
JR
14837+ unsigned long from,
14838+ unsigned long count)
4a4d8108 14839+{ AuUnsupport(); return 0; }
392086de
AM
14840+static void aufs_is_dirty_writeback(struct page *page, bool *dirty,
14841+ bool *writeback)
14842+{ AuUnsupport(); }
4a4d8108
AM
14843+static int aufs_error_remove_page(struct address_space *mapping,
14844+ struct page *page)
14845+{ AuUnsupport(); return 0; }
b4510431
AM
14846+static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file,
14847+ sector_t *span)
14848+{ AuUnsupport(); return 0; }
14849+static void aufs_swap_deactivate(struct file *file)
14850+{ AuUnsupport(); }
4a4d8108
AM
14851+#endif /* CONFIG_AUFS_DEBUG */
14852+
14853+const struct address_space_operations aufs_aop = {
14854+ .readpage = aufs_readpage,
14855+ .direct_IO = aufs_direct_IO,
4a4d8108
AM
14856+#ifdef CONFIG_AUFS_DEBUG
14857+ .writepage = aufs_writepage,
4a4d8108
AM
14858+ /* no writepages, because of writepage */
14859+ .set_page_dirty = aufs_set_page_dirty,
14860+ /* no readpages, because of readpage */
14861+ .write_begin = aufs_write_begin,
14862+ .write_end = aufs_write_end,
14863+ /* no bmap, no block device */
14864+ .invalidatepage = aufs_invalidatepage,
14865+ .releasepage = aufs_releasepage,
79b8bda9
AM
14866+ /* is fallback_migrate_page ok? */
14867+ /* .migratepage = aufs_migratepage, */
e2f27e51
AM
14868+ .isolate_page = aufs_isolate_page,
14869+ .putback_page = aufs_putback_page,
4a4d8108
AM
14870+ .launder_page = aufs_launder_page,
14871+ .is_partially_uptodate = aufs_is_partially_uptodate,
392086de 14872+ .is_dirty_writeback = aufs_is_dirty_writeback,
b4510431
AM
14873+ .error_remove_page = aufs_error_remove_page,
14874+ .swap_activate = aufs_swap_activate,
14875+ .swap_deactivate = aufs_swap_deactivate
4a4d8108 14876+#endif /* CONFIG_AUFS_DEBUG */
dece6358 14877+};
7f207e10
AM
14878diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
14879--- /usr/share/empty/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
14880+++ linux/fs/aufs/file.h 2018-04-15 08:49:13.397817296 +0200
14881@@ -0,0 +1,330 @@
4a4d8108 14882+/*
ae9dfd79 14883+ * Copyright (C) 2005-2018 Junjiro R. Okajima
4a4d8108
AM
14884+ *
14885+ * This program, aufs is free software; you can redistribute it and/or modify
14886+ * it under the terms of the GNU General Public License as published by
14887+ * the Free Software Foundation; either version 2 of the License, or
14888+ * (at your option) any later version.
14889+ *
14890+ * This program is distributed in the hope that it will be useful,
14891+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14892+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14893+ * GNU General Public License for more details.
14894+ *
14895+ * You should have received a copy of the GNU General Public License
523b37e3 14896+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 14897+ */
1facf9fc 14898+
4a4d8108
AM
14899+/*
14900+ * file operations
14901+ */
1facf9fc 14902+
4a4d8108
AM
14903+#ifndef __AUFS_FILE_H__
14904+#define __AUFS_FILE_H__
1facf9fc 14905+
4a4d8108 14906+#ifdef __KERNEL__
1facf9fc 14907+
2cbb1c4b 14908+#include <linux/file.h>
4a4d8108
AM
14909+#include <linux/fs.h>
14910+#include <linux/poll.h>
4a4d8108 14911+#include "rwsem.h"
1facf9fc 14912+
4a4d8108
AM
14913+struct au_branch;
14914+struct au_hfile {
14915+ struct file *hf_file;
14916+ struct au_branch *hf_br;
14917+};
1facf9fc 14918+
4a4d8108
AM
14919+struct au_vdir;
14920+struct au_fidir {
14921+ aufs_bindex_t fd_bbot;
14922+ aufs_bindex_t fd_nent;
14923+ struct au_vdir *fd_vdir_cache;
14924+ struct au_hfile fd_hfile[];
14925+};
1facf9fc 14926+
4a4d8108 14927+static inline int au_fidir_sz(int nent)
dece6358 14928+{
4f0767ce
JR
14929+ AuDebugOn(nent < 0);
14930+ return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
4a4d8108 14931+}
1facf9fc 14932+
4a4d8108
AM
14933+struct au_finfo {
14934+ atomic_t fi_generation;
dece6358 14935+
4a4d8108
AM
14936+ struct au_rwsem fi_rwsem;
14937+ aufs_bindex_t fi_btop;
14938+
14939+ /* do not union them */
14940+ struct { /* for non-dir */
14941+ struct au_hfile fi_htop;
2cbb1c4b 14942+ atomic_t fi_mmapped;
4a4d8108
AM
14943+ };
14944+ struct au_fidir *fi_hdir; /* for dir only */
523b37e3 14945+
ae9dfd79
AM
14946+ struct hlist_bl_node fi_hlist;
14947+ struct file *fi_file; /* very ugly */
4a4d8108 14948+} ____cacheline_aligned_in_smp;
1facf9fc 14949+
4a4d8108 14950+/* ---------------------------------------------------------------------- */
1facf9fc 14951+
4a4d8108
AM
14952+/* file.c */
14953+extern const struct address_space_operations aufs_aop;
14954+unsigned int au_file_roflags(unsigned int flags);
14955+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 14956+ struct file *file, int force_wr);
b912730e 14957+struct au_do_open_args {
ae9dfd79 14958+ int aopen;
b912730e
AM
14959+ int (*open)(struct file *file, int flags,
14960+ struct file *h_file);
14961+ struct au_fidir *fidir;
14962+ struct file *h_file;
14963+};
14964+int au_do_open(struct file *file, struct au_do_open_args *args);
4a4d8108
AM
14965+int au_reopen_nondir(struct file *file);
14966+struct au_pin;
14967+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
14968+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
ae9dfd79 14969+ int wlock, unsigned int fi_lsc);
4a4d8108
AM
14970+int au_do_flush(struct file *file, fl_owner_t id,
14971+ int (*flush)(struct file *file, fl_owner_t id));
1facf9fc 14972+
4a4d8108
AM
14973+/* poll.c */
14974+#ifdef CONFIG_AUFS_POLL
14975+unsigned int aufs_poll(struct file *file, poll_table *wait);
14976+#endif
1facf9fc 14977+
4a4d8108
AM
14978+#ifdef CONFIG_AUFS_BR_HFSPLUS
14979+/* hfsplus.c */
392086de
AM
14980+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
14981+ int force_wr);
4a4d8108
AM
14982+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
14983+ struct file *h_file);
14984+#else
c1595e42
JR
14985+AuStub(struct file *, au_h_open_pre, return NULL, struct dentry *dentry,
14986+ aufs_bindex_t bindex, int force_wr)
4a4d8108
AM
14987+AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
14988+ struct file *h_file);
14989+#endif
1facf9fc 14990+
4a4d8108
AM
14991+/* f_op.c */
14992+extern const struct file_operations aufs_file_fop;
b912730e 14993+int au_do_open_nondir(struct file *file, int flags, struct file *h_file);
4a4d8108 14994+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
ae9dfd79 14995+struct file *au_read_pre(struct file *file, int keep_fi, unsigned int lsc);
4a4d8108 14996+
4a4d8108 14997+/* finfo.c */
f0c0a007 14998+void au_hfput(struct au_hfile *hf, int execed);
4a4d8108
AM
14999+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
15000+ struct file *h_file);
1facf9fc 15001+
4a4d8108 15002+void au_update_figen(struct file *file);
4a4d8108 15003+struct au_fidir *au_fidir_alloc(struct super_block *sb);
e2f27e51 15004+int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink);
1facf9fc 15005+
4a4d8108 15006+void au_fi_init_once(void *_fi);
ae9dfd79 15007+void au_finfo_fin(struct file *file);
4a4d8108 15008+int au_finfo_init(struct file *file, struct au_fidir *fidir);
1facf9fc 15009+
4a4d8108
AM
15010+/* ioctl.c */
15011+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
15012+#ifdef CONFIG_COMPAT
15013+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
15014+ unsigned long arg);
c2b27bf2
AM
15015+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
15016+ unsigned long arg);
b752ccd1 15017+#endif
1facf9fc 15018+
4a4d8108 15019+/* ---------------------------------------------------------------------- */
1facf9fc 15020+
4a4d8108
AM
15021+static inline struct au_finfo *au_fi(struct file *file)
15022+{
38d290e6 15023+ return file->private_data;
4a4d8108 15024+}
1facf9fc 15025+
4a4d8108 15026+/* ---------------------------------------------------------------------- */
1facf9fc 15027+
4a4d8108
AM
15028+/*
15029+ * fi_read_lock, fi_write_lock,
15030+ * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
15031+ */
15032+AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
1308ab2a 15033+
ae9dfd79
AM
15034+/* lock subclass for finfo */
15035+enum {
15036+ AuLsc_FI_1,
15037+ AuLsc_FI_2
15038+};
15039+
15040+static inline void fi_read_lock_nested(struct file *f, unsigned int lsc)
15041+{
15042+ au_rw_read_lock_nested(&au_fi(f)->fi_rwsem, lsc);
15043+}
15044+
15045+static inline void fi_write_lock_nested(struct file *f, unsigned int lsc)
15046+{
15047+ au_rw_write_lock_nested(&au_fi(f)->fi_rwsem, lsc);
15048+}
15049+
15050+/*
15051+ * fi_read_lock_1, fi_write_lock_1,
15052+ * fi_read_lock_2, fi_write_lock_2
15053+ */
15054+#define AuReadLockFunc(name) \
15055+static inline void fi_read_lock_##name(struct file *f) \
15056+{ fi_read_lock_nested(f, AuLsc_FI_##name); }
15057+
15058+#define AuWriteLockFunc(name) \
15059+static inline void fi_write_lock_##name(struct file *f) \
15060+{ fi_write_lock_nested(f, AuLsc_FI_##name); }
15061+
15062+#define AuRWLockFuncs(name) \
15063+ AuReadLockFunc(name) \
15064+ AuWriteLockFunc(name)
15065+
15066+AuRWLockFuncs(1);
15067+AuRWLockFuncs(2);
15068+
15069+#undef AuReadLockFunc
15070+#undef AuWriteLockFunc
15071+#undef AuRWLockFuncs
15072+
4a4d8108
AM
15073+#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
15074+#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
15075+#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
1facf9fc 15076+
1308ab2a 15077+/* ---------------------------------------------------------------------- */
15078+
4a4d8108 15079+/* todo: hard/soft set? */
5afbbe0d 15080+static inline aufs_bindex_t au_fbtop(struct file *file)
dece6358 15081+{
4a4d8108
AM
15082+ FiMustAnyLock(file);
15083+ return au_fi(file)->fi_btop;
15084+}
dece6358 15085+
5afbbe0d 15086+static inline aufs_bindex_t au_fbbot_dir(struct file *file)
4a4d8108
AM
15087+{
15088+ FiMustAnyLock(file);
15089+ AuDebugOn(!au_fi(file)->fi_hdir);
15090+ return au_fi(file)->fi_hdir->fd_bbot;
15091+}
1facf9fc 15092+
4a4d8108
AM
15093+static inline struct au_vdir *au_fvdir_cache(struct file *file)
15094+{
15095+ FiMustAnyLock(file);
15096+ AuDebugOn(!au_fi(file)->fi_hdir);
15097+ return au_fi(file)->fi_hdir->fd_vdir_cache;
15098+}
1facf9fc 15099+
5afbbe0d 15100+static inline void au_set_fbtop(struct file *file, aufs_bindex_t bindex)
4a4d8108
AM
15101+{
15102+ FiMustWriteLock(file);
15103+ au_fi(file)->fi_btop = bindex;
15104+}
1facf9fc 15105+
5afbbe0d 15106+static inline void au_set_fbbot_dir(struct file *file, aufs_bindex_t bindex)
4a4d8108
AM
15107+{
15108+ FiMustWriteLock(file);
15109+ AuDebugOn(!au_fi(file)->fi_hdir);
15110+ au_fi(file)->fi_hdir->fd_bbot = bindex;
15111+}
1308ab2a 15112+
4a4d8108
AM
15113+static inline void au_set_fvdir_cache(struct file *file,
15114+ struct au_vdir *vdir_cache)
15115+{
15116+ FiMustWriteLock(file);
15117+ AuDebugOn(!au_fi(file)->fi_hdir);
15118+ au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
15119+}
dece6358 15120+
4a4d8108
AM
15121+static inline struct file *au_hf_top(struct file *file)
15122+{
15123+ FiMustAnyLock(file);
15124+ AuDebugOn(au_fi(file)->fi_hdir);
15125+ return au_fi(file)->fi_htop.hf_file;
15126+}
1facf9fc 15127+
4a4d8108
AM
15128+static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
15129+{
15130+ FiMustAnyLock(file);
15131+ AuDebugOn(!au_fi(file)->fi_hdir);
15132+ return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
dece6358
AM
15133+}
15134+
4a4d8108
AM
15135+/* todo: memory barrier? */
15136+static inline unsigned int au_figen(struct file *f)
dece6358 15137+{
4a4d8108
AM
15138+ return atomic_read(&au_fi(f)->fi_generation);
15139+}
dece6358 15140+
2cbb1c4b
JR
15141+static inline void au_set_mmapped(struct file *f)
15142+{
15143+ if (atomic_inc_return(&au_fi(f)->fi_mmapped))
15144+ return;
0c3ec466 15145+ pr_warn("fi_mmapped wrapped around\n");
2cbb1c4b
JR
15146+ while (!atomic_inc_return(&au_fi(f)->fi_mmapped))
15147+ ;
15148+}
15149+
15150+static inline void au_unset_mmapped(struct file *f)
15151+{
15152+ atomic_dec(&au_fi(f)->fi_mmapped);
15153+}
15154+
4a4d8108
AM
15155+static inline int au_test_mmapped(struct file *f)
15156+{
2cbb1c4b
JR
15157+ return atomic_read(&au_fi(f)->fi_mmapped);
15158+}
15159+
15160+/* customize vma->vm_file */
15161+
15162+static inline void au_do_vm_file_reset(struct vm_area_struct *vma,
15163+ struct file *file)
15164+{
53392da6
AM
15165+ struct file *f;
15166+
15167+ f = vma->vm_file;
2cbb1c4b
JR
15168+ get_file(file);
15169+ vma->vm_file = file;
53392da6 15170+ fput(f);
2cbb1c4b
JR
15171+}
15172+
15173+#ifdef CONFIG_MMU
15174+#define AuDbgVmRegion(file, vma) do {} while (0)
15175+
15176+static inline void au_vm_file_reset(struct vm_area_struct *vma,
15177+ struct file *file)
15178+{
15179+ au_do_vm_file_reset(vma, file);
15180+}
15181+#else
15182+#define AuDbgVmRegion(file, vma) \
15183+ AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
15184+
15185+static inline void au_vm_file_reset(struct vm_area_struct *vma,
15186+ struct file *file)
15187+{
53392da6
AM
15188+ struct file *f;
15189+
2cbb1c4b 15190+ au_do_vm_file_reset(vma, file);
53392da6 15191+ f = vma->vm_region->vm_file;
2cbb1c4b
JR
15192+ get_file(file);
15193+ vma->vm_region->vm_file = file;
53392da6 15194+ fput(f);
2cbb1c4b
JR
15195+}
15196+#endif /* CONFIG_MMU */
15197+
15198+/* handle vma->vm_prfile */
fb47a38f 15199+static inline void au_vm_prfile_set(struct vm_area_struct *vma,
2cbb1c4b
JR
15200+ struct file *file)
15201+{
2cbb1c4b
JR
15202+ get_file(file);
15203+ vma->vm_prfile = file;
15204+#ifndef CONFIG_MMU
15205+ get_file(file);
15206+ vma->vm_region->vm_prfile = file;
15207+#endif
fb47a38f 15208+}
1308ab2a 15209+
4a4d8108
AM
15210+#endif /* __KERNEL__ */
15211+#endif /* __AUFS_FILE_H__ */
7f207e10
AM
15212diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
15213--- /usr/share/empty/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
15214+++ linux/fs/aufs/finfo.c 2018-04-15 08:49:13.397817296 +0200
15215@@ -0,0 +1,148 @@
4a4d8108 15216+/*
ae9dfd79 15217+ * Copyright (C) 2005-2018 Junjiro R. Okajima
4a4d8108
AM
15218+ *
15219+ * This program, aufs is free software; you can redistribute it and/or modify
15220+ * it under the terms of the GNU General Public License as published by
15221+ * the Free Software Foundation; either version 2 of the License, or
15222+ * (at your option) any later version.
15223+ *
15224+ * This program is distributed in the hope that it will be useful,
15225+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15226+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15227+ * GNU General Public License for more details.
15228+ *
15229+ * You should have received a copy of the GNU General Public License
523b37e3 15230+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 15231+ */
1308ab2a 15232+
4a4d8108
AM
15233+/*
15234+ * file private data
15235+ */
1facf9fc 15236+
4a4d8108 15237+#include "aufs.h"
1facf9fc 15238+
f0c0a007 15239+void au_hfput(struct au_hfile *hf, int execed)
4a4d8108 15240+{
f0c0a007 15241+ if (execed)
4a4d8108
AM
15242+ allow_write_access(hf->hf_file);
15243+ fput(hf->hf_file);
15244+ hf->hf_file = NULL;
5afbbe0d 15245+ au_br_put(hf->hf_br);
4a4d8108
AM
15246+ hf->hf_br = NULL;
15247+}
1facf9fc 15248+
4a4d8108
AM
15249+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
15250+{
15251+ struct au_finfo *finfo = au_fi(file);
15252+ struct au_hfile *hf;
15253+ struct au_fidir *fidir;
15254+
15255+ fidir = finfo->fi_hdir;
15256+ if (!fidir) {
15257+ AuDebugOn(finfo->fi_btop != bindex);
15258+ hf = &finfo->fi_htop;
15259+ } else
15260+ hf = fidir->fd_hfile + bindex;
15261+
15262+ if (hf && hf->hf_file)
f0c0a007 15263+ au_hfput(hf, vfsub_file_execed(file));
4a4d8108
AM
15264+ if (val) {
15265+ FiMustWriteLock(file);
b912730e 15266+ AuDebugOn(IS_ERR_OR_NULL(file->f_path.dentry));
4a4d8108 15267+ hf->hf_file = val;
2000de60 15268+ hf->hf_br = au_sbr(file->f_path.dentry->d_sb, bindex);
1308ab2a 15269+ }
4a4d8108 15270+}
1facf9fc 15271+
4a4d8108
AM
15272+void au_update_figen(struct file *file)
15273+{
2000de60 15274+ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_path.dentry));
4a4d8108 15275+ /* smp_mb(); */ /* atomic_set */
1facf9fc 15276+}
15277+
4a4d8108
AM
15278+/* ---------------------------------------------------------------------- */
15279+
4a4d8108
AM
15280+struct au_fidir *au_fidir_alloc(struct super_block *sb)
15281+{
15282+ struct au_fidir *fidir;
15283+ int nbr;
15284+
5afbbe0d 15285+ nbr = au_sbbot(sb) + 1;
4a4d8108
AM
15286+ if (nbr < 2)
15287+ nbr = 2; /* initial allocate for 2 branches */
15288+ fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS);
15289+ if (fidir) {
15290+ fidir->fd_bbot = -1;
15291+ fidir->fd_nent = nbr;
4a4d8108
AM
15292+ }
15293+
15294+ return fidir;
15295+}
15296+
e2f27e51 15297+int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink)
4a4d8108
AM
15298+{
15299+ int err;
15300+ struct au_fidir *fidir, *p;
15301+
15302+ AuRwMustWriteLock(&finfo->fi_rwsem);
15303+ fidir = finfo->fi_hdir;
15304+ AuDebugOn(!fidir);
15305+
15306+ err = -ENOMEM;
15307+ p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr),
e2f27e51 15308+ GFP_NOFS, may_shrink);
4a4d8108
AM
15309+ if (p) {
15310+ p->fd_nent = nbr;
15311+ finfo->fi_hdir = p;
15312+ err = 0;
15313+ }
1facf9fc 15314+
dece6358 15315+ return err;
1facf9fc 15316+}
1308ab2a 15317+
15318+/* ---------------------------------------------------------------------- */
15319+
ae9dfd79 15320+void au_finfo_fin(struct file *file)
1308ab2a 15321+{
4a4d8108
AM
15322+ struct au_finfo *finfo;
15323+
2000de60 15324+ au_nfiles_dec(file->f_path.dentry->d_sb);
7f207e10 15325+
4a4d8108
AM
15326+ finfo = au_fi(file);
15327+ AuDebugOn(finfo->fi_hdir);
15328+ AuRwDestroy(&finfo->fi_rwsem);
ae9dfd79 15329+ au_cache_free_finfo(finfo);
1308ab2a 15330+}
1308ab2a 15331+
e49829fe 15332+void au_fi_init_once(void *_finfo)
4a4d8108 15333+{
e49829fe 15334+ struct au_finfo *finfo = _finfo;
1308ab2a 15335+
e49829fe 15336+ au_rw_init(&finfo->fi_rwsem);
4a4d8108 15337+}
1308ab2a 15338+
4a4d8108
AM
15339+int au_finfo_init(struct file *file, struct au_fidir *fidir)
15340+{
1716fcea 15341+ int err;
4a4d8108
AM
15342+ struct au_finfo *finfo;
15343+ struct dentry *dentry;
15344+
15345+ err = -ENOMEM;
2000de60 15346+ dentry = file->f_path.dentry;
4a4d8108
AM
15347+ finfo = au_cache_alloc_finfo();
15348+ if (unlikely(!finfo))
15349+ goto out;
15350+
15351+ err = 0;
7f207e10 15352+ au_nfiles_inc(dentry->d_sb);
4a4d8108
AM
15353+ au_rw_write_lock(&finfo->fi_rwsem);
15354+ finfo->fi_btop = -1;
15355+ finfo->fi_hdir = fidir;
15356+ atomic_set(&finfo->fi_generation, au_digen(dentry));
15357+ /* smp_mb(); */ /* atomic_set */
15358+
15359+ file->private_data = finfo;
15360+
15361+out:
15362+ return err;
15363+}
7f207e10
AM
15364diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
15365--- /usr/share/empty/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
15366+++ linux/fs/aufs/f_op.c 2018-04-15 08:49:13.397817296 +0200
15367@@ -0,0 +1,817 @@
dece6358 15368+/*
ae9dfd79 15369+ * Copyright (C) 2005-2018 Junjiro R. Okajima
dece6358
AM
15370+ *
15371+ * This program, aufs is free software; you can redistribute it and/or modify
15372+ * it under the terms of the GNU General Public License as published by
15373+ * the Free Software Foundation; either version 2 of the License, or
15374+ * (at your option) any later version.
15375+ *
15376+ * This program is distributed in the hope that it will be useful,
15377+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15378+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15379+ * GNU General Public License for more details.
15380+ *
15381+ * You should have received a copy of the GNU General Public License
523b37e3 15382+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 15383+ */
1facf9fc 15384+
15385+/*
4a4d8108 15386+ * file and vm operations
1facf9fc 15387+ */
dece6358 15388+
86dc4139 15389+#include <linux/aio.h>
4a4d8108
AM
15390+#include <linux/fs_stack.h>
15391+#include <linux/mman.h>
4a4d8108 15392+#include <linux/security.h>
dece6358
AM
15393+#include "aufs.h"
15394+
b912730e 15395+int au_do_open_nondir(struct file *file, int flags, struct file *h_file)
1facf9fc 15396+{
4a4d8108
AM
15397+ int err;
15398+ aufs_bindex_t bindex;
8cdd5066 15399+ struct dentry *dentry, *h_dentry;
4a4d8108 15400+ struct au_finfo *finfo;
38d290e6 15401+ struct inode *h_inode;
4a4d8108
AM
15402+
15403+ FiMustWriteLock(file);
15404+
523b37e3 15405+ err = 0;
2000de60 15406+ dentry = file->f_path.dentry;
b912730e 15407+ AuDebugOn(IS_ERR_OR_NULL(dentry));
4a4d8108
AM
15408+ finfo = au_fi(file);
15409+ memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
2cbb1c4b 15410+ atomic_set(&finfo->fi_mmapped, 0);
5afbbe0d 15411+ bindex = au_dbtop(dentry);
8cdd5066
JR
15412+ if (!h_file) {
15413+ h_dentry = au_h_dptr(dentry, bindex);
15414+ err = vfsub_test_mntns(file->f_path.mnt, h_dentry->d_sb);
15415+ if (unlikely(err))
15416+ goto out;
b912730e 15417+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
8cdd5066
JR
15418+ } else {
15419+ h_dentry = h_file->f_path.dentry;
15420+ err = vfsub_test_mntns(file->f_path.mnt, h_dentry->d_sb);
15421+ if (unlikely(err))
15422+ goto out;
b912730e 15423+ get_file(h_file);
8cdd5066 15424+ }
4a4d8108
AM
15425+ if (IS_ERR(h_file))
15426+ err = PTR_ERR(h_file);
15427+ else {
38d290e6
JR
15428+ if ((flags & __O_TMPFILE)
15429+ && !(flags & O_EXCL)) {
15430+ h_inode = file_inode(h_file);
15431+ spin_lock(&h_inode->i_lock);
15432+ h_inode->i_state |= I_LINKABLE;
15433+ spin_unlock(&h_inode->i_lock);
15434+ }
5afbbe0d 15435+ au_set_fbtop(file, bindex);
4a4d8108
AM
15436+ au_set_h_fptr(file, bindex, h_file);
15437+ au_update_figen(file);
15438+ /* todo: necessary? */
15439+ /* file->f_ra = h_file->f_ra; */
15440+ }
027c5e7a 15441+
8cdd5066 15442+out:
4a4d8108 15443+ return err;
1facf9fc 15444+}
15445+
4a4d8108
AM
15446+static int aufs_open_nondir(struct inode *inode __maybe_unused,
15447+ struct file *file)
1facf9fc 15448+{
4a4d8108 15449+ int err;
1308ab2a 15450+ struct super_block *sb;
b912730e
AM
15451+ struct au_do_open_args args = {
15452+ .open = au_do_open_nondir
15453+ };
1facf9fc 15454+
523b37e3
AM
15455+ AuDbg("%pD, f_flags 0x%x, f_mode 0x%x\n",
15456+ file, vfsub_file_flags(file), file->f_mode);
1facf9fc 15457+
2000de60 15458+ sb = file->f_path.dentry->d_sb;
4a4d8108 15459+ si_read_lock(sb, AuLock_FLUSH);
b912730e 15460+ err = au_do_open(file, &args);
4a4d8108
AM
15461+ si_read_unlock(sb);
15462+ return err;
15463+}
1facf9fc 15464+
4a4d8108
AM
15465+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
15466+{
15467+ struct au_finfo *finfo;
15468+ aufs_bindex_t bindex;
1facf9fc 15469+
4a4d8108 15470+ finfo = au_fi(file);
ae9dfd79
AM
15471+ au_hbl_del(&finfo->fi_hlist,
15472+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
4a4d8108 15473+ bindex = finfo->fi_btop;
b4510431 15474+ if (bindex >= 0)
4a4d8108 15475+ au_set_h_fptr(file, bindex, NULL);
7f207e10 15476+
ae9dfd79 15477+ au_finfo_fin(file);
4a4d8108 15478+ return 0;
1facf9fc 15479+}
15480+
4a4d8108
AM
15481+/* ---------------------------------------------------------------------- */
15482+
15483+static int au_do_flush_nondir(struct file *file, fl_owner_t id)
dece6358 15484+{
1308ab2a 15485+ int err;
4a4d8108
AM
15486+ struct file *h_file;
15487+
15488+ err = 0;
15489+ h_file = au_hf_top(file);
15490+ if (h_file)
15491+ err = vfsub_flush(h_file, id);
15492+ return err;
15493+}
15494+
15495+static int aufs_flush_nondir(struct file *file, fl_owner_t id)
15496+{
15497+ return au_do_flush(file, id, au_do_flush_nondir);
15498+}
15499+
15500+/* ---------------------------------------------------------------------- */
9dbd164d
AM
15501+/*
15502+ * read and write functions acquire [fdi]_rwsem once, but release before
15503+ * mmap_sem. This is because to stop a race condition between mmap(2).
15504+ * Releasing these aufs-rwsem should be safe, no branch-mamagement (by keeping
15505+ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in
15506+ * read functions after [fdi]_rwsem are released, but it should be harmless.
15507+ */
4a4d8108 15508+
b912730e 15509+/* Callers should call au_read_post() or fput() in the end */
ae9dfd79 15510+struct file *au_read_pre(struct file *file, int keep_fi, unsigned int lsc)
4a4d8108 15511+{
4a4d8108 15512+ struct file *h_file;
b912730e 15513+ int err;
1facf9fc 15514+
ae9dfd79 15515+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0, lsc);
b912730e
AM
15516+ if (!err) {
15517+ di_read_unlock(file->f_path.dentry, AuLock_IR);
15518+ h_file = au_hf_top(file);
15519+ get_file(h_file);
15520+ if (!keep_fi)
15521+ fi_read_unlock(file);
15522+ } else
15523+ h_file = ERR_PTR(err);
15524+
15525+ return h_file;
15526+}
15527+
15528+static void au_read_post(struct inode *inode, struct file *h_file)
15529+{
15530+ /* update without lock, I don't think it a problem */
15531+ fsstack_copy_attr_atime(inode, file_inode(h_file));
15532+ fput(h_file);
15533+}
15534+
15535+struct au_write_pre {
ae9dfd79
AM
15536+ /* input */
15537+ unsigned int lsc;
15538+
15539+ /* output */
b912730e 15540+ blkcnt_t blks;
5afbbe0d 15541+ aufs_bindex_t btop;
b912730e
AM
15542+};
15543+
15544+/*
15545+ * return with iinfo is write-locked
15546+ * callers should call au_write_post() or iinfo_write_unlock() + fput() in the
15547+ * end
15548+ */
15549+static struct file *au_write_pre(struct file *file, int do_ready,
15550+ struct au_write_pre *wpre)
15551+{
15552+ struct file *h_file;
15553+ struct dentry *dentry;
15554+ int err;
ae9dfd79 15555+ unsigned int lsc;
b912730e
AM
15556+ struct au_pin pin;
15557+
ae9dfd79
AM
15558+ lsc = 0;
15559+ if (wpre)
15560+ lsc = wpre->lsc;
15561+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1, lsc);
b912730e 15562+ h_file = ERR_PTR(err);
dece6358
AM
15563+ if (unlikely(err))
15564+ goto out;
1facf9fc 15565+
b912730e
AM
15566+ dentry = file->f_path.dentry;
15567+ if (do_ready) {
15568+ err = au_ready_to_write(file, -1, &pin);
15569+ if (unlikely(err)) {
15570+ h_file = ERR_PTR(err);
15571+ di_write_unlock(dentry);
15572+ goto out_fi;
15573+ }
15574+ }
15575+
15576+ di_downgrade_lock(dentry, /*flags*/0);
15577+ if (wpre)
5afbbe0d 15578+ wpre->btop = au_fbtop(file);
4a4d8108 15579+ h_file = au_hf_top(file);
9dbd164d 15580+ get_file(h_file);
b912730e
AM
15581+ if (wpre)
15582+ wpre->blks = file_inode(h_file)->i_blocks;
15583+ if (do_ready)
15584+ au_unpin(&pin);
15585+ di_read_unlock(dentry, /*flags*/0);
15586+
15587+out_fi:
15588+ fi_write_unlock(file);
15589+out:
15590+ return h_file;
15591+}
15592+
15593+static void au_write_post(struct inode *inode, struct file *h_file,
15594+ struct au_write_pre *wpre, ssize_t written)
15595+{
15596+ struct inode *h_inode;
15597+
15598+ au_cpup_attr_timesizes(inode);
5afbbe0d 15599+ AuDebugOn(au_ibtop(inode) != wpre->btop);
b912730e
AM
15600+ h_inode = file_inode(h_file);
15601+ inode->i_mode = h_inode->i_mode;
15602+ ii_write_unlock(inode);
b912730e
AM
15603+ /* AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks); */
15604+ if (written > 0)
5afbbe0d 15605+ au_fhsm_wrote(inode->i_sb, wpre->btop,
b912730e 15606+ /*force*/h_inode->i_blocks > wpre->blks);
ae9dfd79 15607+ fput(h_file);
b912730e
AM
15608+}
15609+
15610+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
15611+ loff_t *ppos)
15612+{
15613+ ssize_t err;
15614+ struct inode *inode;
15615+ struct file *h_file;
15616+ struct super_block *sb;
15617+
15618+ inode = file_inode(file);
15619+ sb = inode->i_sb;
15620+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
15621+
ae9dfd79 15622+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
b912730e
AM
15623+ err = PTR_ERR(h_file);
15624+ if (IS_ERR(h_file))
15625+ goto out;
9dbd164d
AM
15626+
15627+ /* filedata may be obsoleted by concurrent copyup, but no problem */
4a4d8108
AM
15628+ err = vfsub_read_u(h_file, buf, count, ppos);
15629+ /* todo: necessary? */
15630+ /* file->f_ra = h_file->f_ra; */
b912730e 15631+ au_read_post(inode, h_file);
1308ab2a 15632+
4f0767ce 15633+out:
dece6358
AM
15634+ si_read_unlock(sb);
15635+ return err;
15636+}
1facf9fc 15637+
e49829fe
JR
15638+/*
15639+ * todo: very ugly
15640+ * it locks both of i_mutex and si_rwsem for read in safe.
15641+ * if the plink maintenance mode continues forever (that is the problem),
15642+ * may loop forever.
15643+ */
15644+static void au_mtx_and_read_lock(struct inode *inode)
15645+{
15646+ int err;
15647+ struct super_block *sb = inode->i_sb;
15648+
15649+ while (1) {
febd17d6 15650+ inode_lock(inode);
e49829fe
JR
15651+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
15652+ if (!err)
15653+ break;
febd17d6 15654+ inode_unlock(inode);
e49829fe
JR
15655+ si_read_lock(sb, AuLock_NOPLMW);
15656+ si_read_unlock(sb);
15657+ }
15658+}
15659+
4a4d8108
AM
15660+static ssize_t aufs_write(struct file *file, const char __user *ubuf,
15661+ size_t count, loff_t *ppos)
dece6358 15662+{
4a4d8108 15663+ ssize_t err;
b912730e
AM
15664+ struct au_write_pre wpre;
15665+ struct inode *inode;
4a4d8108
AM
15666+ struct file *h_file;
15667+ char __user *buf = (char __user *)ubuf;
1facf9fc 15668+
b912730e 15669+ inode = file_inode(file);
e49829fe 15670+ au_mtx_and_read_lock(inode);
1facf9fc 15671+
ae9dfd79 15672+ wpre.lsc = 0;
b912730e
AM
15673+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
15674+ err = PTR_ERR(h_file);
15675+ if (IS_ERR(h_file))
9dbd164d 15676+ goto out;
9dbd164d 15677+
4a4d8108 15678+ err = vfsub_write_u(h_file, buf, count, ppos);
b912730e 15679+ au_write_post(inode, h_file, &wpre, err);
1facf9fc 15680+
4f0767ce 15681+out:
b912730e 15682+ si_read_unlock(inode->i_sb);
febd17d6 15683+ inode_unlock(inode);
dece6358
AM
15684+ return err;
15685+}
1facf9fc 15686+
076b876e
AM
15687+static ssize_t au_do_iter(struct file *h_file, int rw, struct kiocb *kio,
15688+ struct iov_iter *iov_iter)
dece6358 15689+{
4a4d8108
AM
15690+ ssize_t err;
15691+ struct file *file;
076b876e 15692+ ssize_t (*iter)(struct kiocb *, struct iov_iter *);
1facf9fc 15693+
4a4d8108
AM
15694+ err = security_file_permission(h_file, rw);
15695+ if (unlikely(err))
15696+ goto out;
1facf9fc 15697+
4a4d8108 15698+ err = -ENOSYS;
076b876e 15699+ iter = NULL;
5527c038 15700+ if (rw == MAY_READ)
076b876e 15701+ iter = h_file->f_op->read_iter;
5527c038 15702+ else if (rw == MAY_WRITE)
076b876e 15703+ iter = h_file->f_op->write_iter;
076b876e
AM
15704+
15705+ file = kio->ki_filp;
15706+ kio->ki_filp = h_file;
15707+ if (iter) {
2cbb1c4b 15708+ lockdep_off();
076b876e
AM
15709+ err = iter(kio, iov_iter);
15710+ lockdep_on();
4a4d8108
AM
15711+ } else
15712+ /* currently there is no such fs */
15713+ WARN_ON_ONCE(1);
076b876e 15714+ kio->ki_filp = file;
1facf9fc 15715+
4f0767ce 15716+out:
dece6358
AM
15717+ return err;
15718+}
1facf9fc 15719+
076b876e 15720+static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter)
1facf9fc 15721+{
4a4d8108
AM
15722+ ssize_t err;
15723+ struct file *file, *h_file;
b912730e 15724+ struct inode *inode;
dece6358 15725+ struct super_block *sb;
1facf9fc 15726+
4a4d8108 15727+ file = kio->ki_filp;
b912730e
AM
15728+ inode = file_inode(file);
15729+ sb = inode->i_sb;
e49829fe 15730+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108 15731+
ae9dfd79 15732+ h_file = au_read_pre(file, /*keep_fi*/1, /*lsc*/0);
b912730e
AM
15733+ err = PTR_ERR(h_file);
15734+ if (IS_ERR(h_file))
15735+ goto out;
9dbd164d 15736+
5afbbe0d
AM
15737+ if (au_test_loopback_kthread()) {
15738+ au_warn_loopback(h_file->f_path.dentry->d_sb);
15739+ if (file->f_mapping != h_file->f_mapping) {
15740+ file->f_mapping = h_file->f_mapping;
15741+ smp_mb(); /* unnecessary? */
15742+ }
15743+ }
15744+ fi_read_unlock(file);
15745+
076b876e 15746+ err = au_do_iter(h_file, MAY_READ, kio, iov_iter);
4a4d8108
AM
15747+ /* todo: necessary? */
15748+ /* file->f_ra = h_file->f_ra; */
b912730e 15749+ au_read_post(inode, h_file);
1facf9fc 15750+
4f0767ce 15751+out:
4a4d8108 15752+ si_read_unlock(sb);
1308ab2a 15753+ return err;
15754+}
1facf9fc 15755+
076b876e 15756+static ssize_t aufs_write_iter(struct kiocb *kio, struct iov_iter *iov_iter)
1308ab2a 15757+{
4a4d8108 15758+ ssize_t err;
b912730e
AM
15759+ struct au_write_pre wpre;
15760+ struct inode *inode;
4a4d8108 15761+ struct file *file, *h_file;
1308ab2a 15762+
4a4d8108 15763+ file = kio->ki_filp;
b912730e 15764+ inode = file_inode(file);
e49829fe
JR
15765+ au_mtx_and_read_lock(inode);
15766+
ae9dfd79 15767+ wpre.lsc = 0;
b912730e
AM
15768+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
15769+ err = PTR_ERR(h_file);
15770+ if (IS_ERR(h_file))
9dbd164d 15771+ goto out;
9dbd164d 15772+
076b876e 15773+ err = au_do_iter(h_file, MAY_WRITE, kio, iov_iter);
b912730e 15774+ au_write_post(inode, h_file, &wpre, err);
1facf9fc 15775+
4f0767ce 15776+out:
b912730e 15777+ si_read_unlock(inode->i_sb);
febd17d6 15778+ inode_unlock(inode);
dece6358 15779+ return err;
1facf9fc 15780+}
15781+
4a4d8108
AM
15782+static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
15783+ struct pipe_inode_info *pipe, size_t len,
15784+ unsigned int flags)
1facf9fc 15785+{
4a4d8108
AM
15786+ ssize_t err;
15787+ struct file *h_file;
b912730e 15788+ struct inode *inode;
dece6358 15789+ struct super_block *sb;
1facf9fc 15790+
b912730e
AM
15791+ inode = file_inode(file);
15792+ sb = inode->i_sb;
e49829fe 15793+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
b912730e 15794+
ae9dfd79 15795+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
b912730e
AM
15796+ err = PTR_ERR(h_file);
15797+ if (IS_ERR(h_file))
dece6358 15798+ goto out;
1facf9fc 15799+
4a4d8108
AM
15800+ err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
15801+ /* todo: necessasry? */
15802+ /* file->f_ra = h_file->f_ra; */
b912730e 15803+ au_read_post(inode, h_file);
1facf9fc 15804+
4f0767ce 15805+out:
4a4d8108 15806+ si_read_unlock(sb);
dece6358 15807+ return err;
1facf9fc 15808+}
15809+
4a4d8108
AM
15810+static ssize_t
15811+aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
15812+ size_t len, unsigned int flags)
1facf9fc 15813+{
4a4d8108 15814+ ssize_t err;
b912730e
AM
15815+ struct au_write_pre wpre;
15816+ struct inode *inode;
076b876e 15817+ struct file *h_file;
1facf9fc 15818+
b912730e 15819+ inode = file_inode(file);
e49829fe 15820+ au_mtx_and_read_lock(inode);
9dbd164d 15821+
ae9dfd79 15822+ wpre.lsc = 0;
b912730e
AM
15823+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
15824+ err = PTR_ERR(h_file);
15825+ if (IS_ERR(h_file))
9dbd164d 15826+ goto out;
9dbd164d 15827+
4a4d8108 15828+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
b912730e 15829+ au_write_post(inode, h_file, &wpre, err);
1facf9fc 15830+
4f0767ce 15831+out:
b912730e 15832+ si_read_unlock(inode->i_sb);
febd17d6 15833+ inode_unlock(inode);
4a4d8108
AM
15834+ return err;
15835+}
1facf9fc 15836+
38d290e6
JR
15837+static long aufs_fallocate(struct file *file, int mode, loff_t offset,
15838+ loff_t len)
15839+{
15840+ long err;
b912730e 15841+ struct au_write_pre wpre;
38d290e6
JR
15842+ struct inode *inode;
15843+ struct file *h_file;
15844+
b912730e 15845+ inode = file_inode(file);
38d290e6
JR
15846+ au_mtx_and_read_lock(inode);
15847+
ae9dfd79 15848+ wpre.lsc = 0;
b912730e
AM
15849+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
15850+ err = PTR_ERR(h_file);
15851+ if (IS_ERR(h_file))
38d290e6 15852+ goto out;
38d290e6
JR
15853+
15854+ lockdep_off();
03673fb0 15855+ err = vfs_fallocate(h_file, mode, offset, len);
38d290e6 15856+ lockdep_on();
b912730e 15857+ au_write_post(inode, h_file, &wpre, /*written*/1);
38d290e6
JR
15858+
15859+out:
b912730e 15860+ si_read_unlock(inode->i_sb);
febd17d6 15861+ inode_unlock(inode);
38d290e6
JR
15862+ return err;
15863+}
15864+
ae9dfd79
AM
15865+static ssize_t aufs_copy_file_range(struct file *src, loff_t src_pos,
15866+ struct file *dst, loff_t dst_pos,
15867+ size_t len, unsigned int flags)
15868+{
15869+ ssize_t err;
15870+ struct au_write_pre wpre;
15871+ enum { SRC, DST };
15872+ struct {
15873+ struct inode *inode;
15874+ struct file *h_file;
15875+ struct super_block *h_sb;
15876+ } a[2];
15877+#define a_src a[SRC]
15878+#define a_dst a[DST]
15879+
15880+ err = -EINVAL;
15881+ a_src.inode = file_inode(src);
15882+ if (unlikely(!S_ISREG(a_src.inode->i_mode)))
15883+ goto out;
15884+ a_dst.inode = file_inode(dst);
15885+ if (unlikely(!S_ISREG(a_dst.inode->i_mode)))
15886+ goto out;
15887+
15888+ au_mtx_and_read_lock(a_dst.inode);
15889+ /*
15890+ * in order to match the order in di_write_lock2_{child,parent}(),
15891+ * use f_path.dentry for this comparision.
15892+ */
15893+ if (src->f_path.dentry < dst->f_path.dentry) {
15894+ a_src.h_file = au_read_pre(src, /*keep_fi*/1, AuLsc_FI_1);
15895+ err = PTR_ERR(a_src.h_file);
15896+ if (IS_ERR(a_src.h_file))
15897+ goto out_si;
15898+
15899+ wpre.lsc = AuLsc_FI_2;
15900+ a_dst.h_file = au_write_pre(dst, /*do_ready*/1, &wpre);
15901+ err = PTR_ERR(a_dst.h_file);
15902+ if (IS_ERR(a_dst.h_file)) {
15903+ au_read_post(a_src.inode, a_src.h_file);
15904+ goto out_si;
15905+ }
15906+ } else {
15907+ wpre.lsc = AuLsc_FI_1;
15908+ a_dst.h_file = au_write_pre(dst, /*do_ready*/1, &wpre);
15909+ err = PTR_ERR(a_dst.h_file);
15910+ if (IS_ERR(a_dst.h_file))
15911+ goto out_si;
15912+
15913+ a_src.h_file = au_read_pre(src, /*keep_fi*/1, AuLsc_FI_2);
15914+ err = PTR_ERR(a_src.h_file);
15915+ if (IS_ERR(a_src.h_file)) {
15916+ au_write_post(a_dst.inode, a_dst.h_file, &wpre,
15917+ /*written*/0);
15918+ goto out_si;
15919+ }
15920+ }
15921+
15922+ err = -EXDEV;
15923+ a_src.h_sb = file_inode(a_src.h_file)->i_sb;
15924+ a_dst.h_sb = file_inode(a_dst.h_file)->i_sb;
15925+ if (unlikely(a_src.h_sb != a_dst.h_sb)) {
15926+ AuDbgFile(src);
15927+ AuDbgFile(dst);
15928+ goto out_file;
15929+ }
15930+
15931+ err = vfsub_copy_file_range(a_src.h_file, src_pos, a_dst.h_file,
15932+ dst_pos, len, flags);
15933+
15934+out_file:
15935+ au_write_post(a_dst.inode, a_dst.h_file, &wpre, err);
15936+ fi_read_unlock(src);
15937+ au_read_post(a_src.inode, a_src.h_file);
15938+out_si:
15939+ si_read_unlock(a_dst.inode->i_sb);
15940+ inode_unlock(a_dst.inode);
15941+out:
15942+ return err;
15943+#undef a_src
15944+#undef a_dst
15945+}
15946+
4a4d8108
AM
15947+/* ---------------------------------------------------------------------- */
15948+
9dbd164d
AM
15949+/*
15950+ * The locking order around current->mmap_sem.
15951+ * - in most and regular cases
15952+ * file I/O syscall -- aufs_read() or something
15953+ * -- si_rwsem for read -- mmap_sem
15954+ * (Note that [fdi]i_rwsem are released before mmap_sem).
15955+ * - in mmap case
15956+ * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem
15957+ * This AB-BA order is definitly bad, but is not a problem since "si_rwsem for
15958+ * read" allows muliple processes to acquire it and [fdi]i_rwsem are not held in
15959+ * file I/O. Aufs needs to stop lockdep in aufs_mmap() though.
15960+ * It means that when aufs acquires si_rwsem for write, the process should never
15961+ * acquire mmap_sem.
15962+ *
392086de 15963+ * Actually aufs_iterate() holds [fdi]i_rwsem before mmap_sem, but this is not a
9dbd164d
AM
15964+ * problem either since any directory is not able to be mmap-ed.
15965+ * The similar scenario is applied to aufs_readlink() too.
15966+ */
15967+
38d290e6 15968+#if 0 /* stop calling security_file_mmap() */
2dfbb274
AM
15969+/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
15970+#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b)
15971+
15972+static unsigned long au_arch_prot_conv(unsigned long flags)
15973+{
15974+ /* currently ppc64 only */
15975+#ifdef CONFIG_PPC64
15976+ /* cf. linux/arch/powerpc/include/asm/mman.h */
15977+ AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO);
15978+ return AuConv_VM_PROT(flags, SAO);
15979+#else
15980+ AuDebugOn(arch_calc_vm_prot_bits(-1));
15981+ return 0;
15982+#endif
15983+}
15984+
15985+static unsigned long au_prot_conv(unsigned long flags)
15986+{
15987+ return AuConv_VM_PROT(flags, READ)
15988+ | AuConv_VM_PROT(flags, WRITE)
15989+ | AuConv_VM_PROT(flags, EXEC)
15990+ | au_arch_prot_conv(flags);
15991+}
15992+
15993+/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */
15994+#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b)
15995+
15996+static unsigned long au_flag_conv(unsigned long flags)
15997+{
15998+ return AuConv_VM_MAP(flags, GROWSDOWN)
15999+ | AuConv_VM_MAP(flags, DENYWRITE)
2dfbb274
AM
16000+ | AuConv_VM_MAP(flags, LOCKED);
16001+}
38d290e6 16002+#endif
2dfbb274 16003+
9dbd164d 16004+static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
dece6358 16005+{
4a4d8108 16006+ int err;
4a4d8108 16007+ const unsigned char wlock
9dbd164d 16008+ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
4a4d8108 16009+ struct super_block *sb;
9dbd164d 16010+ struct file *h_file;
b912730e 16011+ struct inode *inode;
9dbd164d
AM
16012+
16013+ AuDbgVmRegion(file, vma);
1308ab2a 16014+
b912730e
AM
16015+ inode = file_inode(file);
16016+ sb = inode->i_sb;
9dbd164d 16017+ lockdep_off();
e49829fe 16018+ si_read_lock(sb, AuLock_NOPLMW);
4a4d8108 16019+
b912730e 16020+ h_file = au_write_pre(file, wlock, /*wpre*/NULL);
9dbd164d 16021+ lockdep_on();
b912730e
AM
16022+ err = PTR_ERR(h_file);
16023+ if (IS_ERR(h_file))
16024+ goto out;
1308ab2a 16025+
b912730e
AM
16026+ err = 0;
16027+ au_set_mmapped(file);
9dbd164d 16028+ au_vm_file_reset(vma, h_file);
38d290e6
JR
16029+ /*
16030+ * we cannot call security_mmap_file() here since it may acquire
16031+ * mmap_sem or i_mutex.
16032+ *
16033+ * err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
16034+ * au_flag_conv(vma->vm_flags));
16035+ */
9dbd164d
AM
16036+ if (!err)
16037+ err = h_file->f_op->mmap(h_file, vma);
b912730e
AM
16038+ if (!err) {
16039+ au_vm_prfile_set(vma, file);
16040+ fsstack_copy_attr_atime(inode, file_inode(h_file));
16041+ goto out_fput; /* success */
16042+ }
2cbb1c4b
JR
16043+ au_unset_mmapped(file);
16044+ au_vm_file_reset(vma, file);
b912730e 16045+
2cbb1c4b 16046+out_fput:
9dbd164d 16047+ lockdep_off();
b912730e
AM
16048+ ii_write_unlock(inode);
16049+ lockdep_on();
16050+ fput(h_file);
4f0767ce 16051+out:
b912730e 16052+ lockdep_off();
9dbd164d
AM
16053+ si_read_unlock(sb);
16054+ lockdep_on();
16055+ AuTraceErr(err);
4a4d8108
AM
16056+ return err;
16057+}
16058+
16059+/* ---------------------------------------------------------------------- */
16060+
1e00d052
AM
16061+static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end,
16062+ int datasync)
4a4d8108
AM
16063+{
16064+ int err;
b912730e 16065+ struct au_write_pre wpre;
4a4d8108
AM
16066+ struct inode *inode;
16067+ struct file *h_file;
4a4d8108
AM
16068+
16069+ err = 0; /* -EBADF; */ /* posix? */
16070+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
b912730e 16071+ goto out;
4a4d8108 16072+
b912730e
AM
16073+ inode = file_inode(file);
16074+ au_mtx_and_read_lock(inode);
16075+
ae9dfd79 16076+ wpre.lsc = 0;
b912730e
AM
16077+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
16078+ err = PTR_ERR(h_file);
16079+ if (IS_ERR(h_file))
4a4d8108 16080+ goto out_unlock;
4a4d8108 16081+
53392da6 16082+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
b912730e 16083+ au_write_post(inode, h_file, &wpre, /*written*/0);
4a4d8108 16084+
4f0767ce 16085+out_unlock:
b912730e 16086+ si_read_unlock(inode->i_sb);
febd17d6 16087+ inode_unlock(inode);
b912730e 16088+out:
4a4d8108 16089+ return err;
dece6358
AM
16090+}
16091+
4a4d8108 16092+static int aufs_fasync(int fd, struct file *file, int flag)
dece6358 16093+{
4a4d8108
AM
16094+ int err;
16095+ struct file *h_file;
4a4d8108 16096+ struct super_block *sb;
1308ab2a 16097+
b912730e 16098+ sb = file->f_path.dentry->d_sb;
e49829fe 16099+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
b912730e 16100+
ae9dfd79 16101+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
b912730e
AM
16102+ err = PTR_ERR(h_file);
16103+ if (IS_ERR(h_file))
4a4d8108
AM
16104+ goto out;
16105+
523b37e3 16106+ if (h_file->f_op->fasync)
4a4d8108 16107+ err = h_file->f_op->fasync(fd, h_file, flag);
b912730e 16108+ fput(h_file); /* instead of au_read_post() */
1308ab2a 16109+
4f0767ce 16110+out:
4a4d8108 16111+ si_read_unlock(sb);
1308ab2a 16112+ return err;
dece6358 16113+}
4a4d8108 16114+
febd17d6
JR
16115+static int aufs_setfl(struct file *file, unsigned long arg)
16116+{
16117+ int err;
16118+ struct file *h_file;
16119+ struct super_block *sb;
16120+
16121+ sb = file->f_path.dentry->d_sb;
16122+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
16123+
ae9dfd79 16124+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
febd17d6
JR
16125+ err = PTR_ERR(h_file);
16126+ if (IS_ERR(h_file))
16127+ goto out;
16128+
ae9dfd79
AM
16129+ /* stop calling h_file->fasync */
16130+ arg |= vfsub_file_flags(file) & FASYNC;
febd17d6
JR
16131+ err = setfl(/*unused fd*/-1, h_file, arg);
16132+ fput(h_file); /* instead of au_read_post() */
16133+
16134+out:
16135+ si_read_unlock(sb);
16136+ return err;
16137+}
16138+
4a4d8108
AM
16139+/* ---------------------------------------------------------------------- */
16140+
16141+/* no one supports this operation, currently */
16142+#if 0
16143+static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
2000de60 16144+ size_t len, loff_t *pos, int more)
4a4d8108
AM
16145+{
16146+}
16147+#endif
16148+
16149+/* ---------------------------------------------------------------------- */
16150+
16151+const struct file_operations aufs_file_fop = {
16152+ .owner = THIS_MODULE,
2cbb1c4b 16153+
027c5e7a 16154+ .llseek = default_llseek,
4a4d8108
AM
16155+
16156+ .read = aufs_read,
16157+ .write = aufs_write,
076b876e
AM
16158+ .read_iter = aufs_read_iter,
16159+ .write_iter = aufs_write_iter,
16160+
4a4d8108
AM
16161+#ifdef CONFIG_AUFS_POLL
16162+ .poll = aufs_poll,
16163+#endif
16164+ .unlocked_ioctl = aufs_ioctl_nondir,
b752ccd1 16165+#ifdef CONFIG_COMPAT
c2b27bf2 16166+ .compat_ioctl = aufs_compat_ioctl_nondir,
b752ccd1 16167+#endif
4a4d8108
AM
16168+ .mmap = aufs_mmap,
16169+ .open = aufs_open_nondir,
16170+ .flush = aufs_flush_nondir,
16171+ .release = aufs_release_nondir,
16172+ .fsync = aufs_fsync_nondir,
4a4d8108
AM
16173+ .fasync = aufs_fasync,
16174+ /* .sendpage = aufs_sendpage, */
febd17d6 16175+ .setfl = aufs_setfl,
4a4d8108
AM
16176+ .splice_write = aufs_splice_write,
16177+ .splice_read = aufs_splice_read,
16178+#if 0
16179+ .aio_splice_write = aufs_aio_splice_write,
38d290e6 16180+ .aio_splice_read = aufs_aio_splice_read,
4a4d8108 16181+#endif
ae9dfd79
AM
16182+ .fallocate = aufs_fallocate,
16183+ .copy_file_range = aufs_copy_file_range
4a4d8108 16184+};
7f207e10
AM
16185diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
16186--- /usr/share/empty/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 16187+++ linux/fs/aufs/fstype.h 2018-04-15 08:49:13.397817296 +0200
b912730e 16188@@ -0,0 +1,400 @@
4a4d8108 16189+/*
ae9dfd79 16190+ * Copyright (C) 2005-2018 Junjiro R. Okajima
4a4d8108
AM
16191+ *
16192+ * This program, aufs is free software; you can redistribute it and/or modify
16193+ * it under the terms of the GNU General Public License as published by
16194+ * the Free Software Foundation; either version 2 of the License, or
16195+ * (at your option) any later version.
16196+ *
16197+ * This program is distributed in the hope that it will be useful,
16198+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16199+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16200+ * GNU General Public License for more details.
16201+ *
16202+ * You should have received a copy of the GNU General Public License
523b37e3 16203+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
16204+ */
16205+
16206+/*
16207+ * judging filesystem type
16208+ */
16209+
16210+#ifndef __AUFS_FSTYPE_H__
16211+#define __AUFS_FSTYPE_H__
16212+
16213+#ifdef __KERNEL__
16214+
16215+#include <linux/fs.h>
16216+#include <linux/magic.h>
b912730e 16217+#include <linux/nfs_fs.h>
b95c5147 16218+#include <linux/romfs_fs.h>
4a4d8108
AM
16219+
16220+static inline int au_test_aufs(struct super_block *sb)
16221+{
16222+ return sb->s_magic == AUFS_SUPER_MAGIC;
16223+}
16224+
16225+static inline const char *au_sbtype(struct super_block *sb)
16226+{
16227+ return sb->s_type->name;
16228+}
1308ab2a 16229+
16230+static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
16231+{
f0c0a007 16232+#if IS_ENABLED(CONFIG_ISO9660_FS)
2000de60 16233+ return sb->s_magic == ISOFS_SUPER_MAGIC;
dece6358
AM
16234+#else
16235+ return 0;
16236+#endif
16237+}
16238+
1308ab2a 16239+static inline int au_test_romfs(struct super_block *sb __maybe_unused)
dece6358 16240+{
f0c0a007 16241+#if IS_ENABLED(CONFIG_ROMFS_FS)
2000de60 16242+ return sb->s_magic == ROMFS_MAGIC;
dece6358
AM
16243+#else
16244+ return 0;
16245+#endif
16246+}
16247+
1308ab2a 16248+static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
dece6358 16249+{
f0c0a007 16250+#if IS_ENABLED(CONFIG_CRAMFS)
1308ab2a 16251+ return sb->s_magic == CRAMFS_MAGIC;
16252+#endif
16253+ return 0;
16254+}
16255+
16256+static inline int au_test_nfs(struct super_block *sb __maybe_unused)
16257+{
f0c0a007 16258+#if IS_ENABLED(CONFIG_NFS_FS)
1308ab2a 16259+ return sb->s_magic == NFS_SUPER_MAGIC;
dece6358
AM
16260+#else
16261+ return 0;
16262+#endif
16263+}
16264+
1308ab2a 16265+static inline int au_test_fuse(struct super_block *sb __maybe_unused)
dece6358 16266+{
f0c0a007 16267+#if IS_ENABLED(CONFIG_FUSE_FS)
1308ab2a 16268+ return sb->s_magic == FUSE_SUPER_MAGIC;
dece6358
AM
16269+#else
16270+ return 0;
16271+#endif
16272+}
16273+
1308ab2a 16274+static inline int au_test_xfs(struct super_block *sb __maybe_unused)
dece6358 16275+{
f0c0a007 16276+#if IS_ENABLED(CONFIG_XFS_FS)
1308ab2a 16277+ return sb->s_magic == XFS_SB_MAGIC;
dece6358
AM
16278+#else
16279+ return 0;
16280+#endif
16281+}
16282+
1308ab2a 16283+static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
dece6358 16284+{
1308ab2a 16285+#ifdef CONFIG_TMPFS
16286+ return sb->s_magic == TMPFS_MAGIC;
16287+#else
16288+ return 0;
dece6358 16289+#endif
dece6358
AM
16290+}
16291+
1308ab2a 16292+static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
1facf9fc 16293+{
f0c0a007 16294+#if IS_ENABLED(CONFIG_ECRYPT_FS)
1308ab2a 16295+ return !strcmp(au_sbtype(sb), "ecryptfs");
16296+#else
16297+ return 0;
16298+#endif
1facf9fc 16299+}
16300+
1308ab2a 16301+static inline int au_test_ramfs(struct super_block *sb)
16302+{
16303+ return sb->s_magic == RAMFS_MAGIC;
16304+}
16305+
16306+static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
16307+{
f0c0a007 16308+#if IS_ENABLED(CONFIG_UBIFS_FS)
1308ab2a 16309+ return sb->s_magic == UBIFS_SUPER_MAGIC;
16310+#else
16311+ return 0;
16312+#endif
16313+}
16314+
16315+static inline int au_test_procfs(struct super_block *sb __maybe_unused)
16316+{
16317+#ifdef CONFIG_PROC_FS
16318+ return sb->s_magic == PROC_SUPER_MAGIC;
16319+#else
16320+ return 0;
16321+#endif
16322+}
16323+
16324+static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
16325+{
16326+#ifdef CONFIG_SYSFS
16327+ return sb->s_magic == SYSFS_MAGIC;
16328+#else
16329+ return 0;
16330+#endif
16331+}
16332+
16333+static inline int au_test_configfs(struct super_block *sb __maybe_unused)
16334+{
f0c0a007 16335+#if IS_ENABLED(CONFIG_CONFIGFS_FS)
1308ab2a 16336+ return sb->s_magic == CONFIGFS_MAGIC;
16337+#else
16338+ return 0;
16339+#endif
16340+}
16341+
16342+static inline int au_test_minix(struct super_block *sb __maybe_unused)
16343+{
f0c0a007 16344+#if IS_ENABLED(CONFIG_MINIX_FS)
1308ab2a 16345+ return sb->s_magic == MINIX3_SUPER_MAGIC
16346+ || sb->s_magic == MINIX2_SUPER_MAGIC
16347+ || sb->s_magic == MINIX2_SUPER_MAGIC2
16348+ || sb->s_magic == MINIX_SUPER_MAGIC
16349+ || sb->s_magic == MINIX_SUPER_MAGIC2;
16350+#else
16351+ return 0;
16352+#endif
16353+}
16354+
1308ab2a 16355+static inline int au_test_fat(struct super_block *sb __maybe_unused)
16356+{
f0c0a007 16357+#if IS_ENABLED(CONFIG_FAT_FS)
1308ab2a 16358+ return sb->s_magic == MSDOS_SUPER_MAGIC;
16359+#else
16360+ return 0;
16361+#endif
16362+}
16363+
16364+static inline int au_test_msdos(struct super_block *sb)
16365+{
16366+ return au_test_fat(sb);
16367+}
16368+
16369+static inline int au_test_vfat(struct super_block *sb)
16370+{
16371+ return au_test_fat(sb);
16372+}
16373+
16374+static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
16375+{
16376+#ifdef CONFIG_SECURITYFS
16377+ return sb->s_magic == SECURITYFS_MAGIC;
16378+#else
16379+ return 0;
16380+#endif
16381+}
16382+
16383+static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
16384+{
f0c0a007 16385+#if IS_ENABLED(CONFIG_SQUASHFS)
1308ab2a 16386+ return sb->s_magic == SQUASHFS_MAGIC;
16387+#else
16388+ return 0;
16389+#endif
16390+}
16391+
16392+static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
16393+{
f0c0a007 16394+#if IS_ENABLED(CONFIG_BTRFS_FS)
1308ab2a 16395+ return sb->s_magic == BTRFS_SUPER_MAGIC;
16396+#else
16397+ return 0;
16398+#endif
16399+}
16400+
16401+static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
16402+{
f0c0a007 16403+#if IS_ENABLED(CONFIG_XENFS)
1308ab2a 16404+ return sb->s_magic == XENFS_SUPER_MAGIC;
16405+#else
16406+ return 0;
16407+#endif
16408+}
16409+
16410+static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
16411+{
16412+#ifdef CONFIG_DEBUG_FS
16413+ return sb->s_magic == DEBUGFS_MAGIC;
16414+#else
16415+ return 0;
16416+#endif
16417+}
16418+
16419+static inline int au_test_nilfs(struct super_block *sb __maybe_unused)
16420+{
f0c0a007 16421+#if IS_ENABLED(CONFIG_NILFS)
1308ab2a 16422+ return sb->s_magic == NILFS_SUPER_MAGIC;
16423+#else
16424+ return 0;
16425+#endif
16426+}
16427+
4a4d8108
AM
16428+static inline int au_test_hfsplus(struct super_block *sb __maybe_unused)
16429+{
f0c0a007 16430+#if IS_ENABLED(CONFIG_HFSPLUS_FS)
4a4d8108
AM
16431+ return sb->s_magic == HFSPLUS_SUPER_MAGIC;
16432+#else
16433+ return 0;
16434+#endif
16435+}
16436+
1308ab2a 16437+/* ---------------------------------------------------------------------- */
16438+/*
16439+ * they can't be an aufs branch.
16440+ */
16441+static inline int au_test_fs_unsuppoted(struct super_block *sb)
16442+{
16443+ return
16444+#ifndef CONFIG_AUFS_BR_RAMFS
16445+ au_test_ramfs(sb) ||
16446+#endif
16447+ au_test_procfs(sb)
16448+ || au_test_sysfs(sb)
16449+ || au_test_configfs(sb)
16450+ || au_test_debugfs(sb)
16451+ || au_test_securityfs(sb)
16452+ || au_test_xenfs(sb)
16453+ || au_test_ecryptfs(sb)
16454+ /* || !strcmp(au_sbtype(sb), "unionfs") */
16455+ || au_test_aufs(sb); /* will be supported in next version */
16456+}
16457+
1308ab2a 16458+static inline int au_test_fs_remote(struct super_block *sb)
16459+{
16460+ return !au_test_tmpfs(sb)
16461+#ifdef CONFIG_AUFS_BR_RAMFS
16462+ && !au_test_ramfs(sb)
16463+#endif
16464+ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
16465+}
16466+
16467+/* ---------------------------------------------------------------------- */
16468+
16469+/*
16470+ * Note: these functions (below) are created after reading ->getattr() in all
16471+ * filesystems under linux/fs. it means we have to do so in every update...
16472+ */
16473+
16474+/*
16475+ * some filesystems require getattr to refresh the inode attributes before
16476+ * referencing.
16477+ * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
16478+ * and leave the work for d_revalidate()
16479+ */
16480+static inline int au_test_fs_refresh_iattr(struct super_block *sb)
16481+{
16482+ return au_test_nfs(sb)
16483+ || au_test_fuse(sb)
1308ab2a 16484+ /* || au_test_btrfs(sb) */ /* untested */
1308ab2a 16485+ ;
16486+}
16487+
16488+/*
16489+ * filesystems which don't maintain i_size or i_blocks.
16490+ */
16491+static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
16492+{
16493+ return au_test_xfs(sb)
4a4d8108
AM
16494+ || au_test_btrfs(sb)
16495+ || au_test_ubifs(sb)
16496+ || au_test_hfsplus(sb) /* maintained, but incorrect */
1308ab2a 16497+ /* || au_test_minix(sb) */ /* untested */
16498+ ;
16499+}
16500+
16501+/*
16502+ * filesystems which don't store the correct value in some of their inode
16503+ * attributes.
16504+ */
16505+static inline int au_test_fs_bad_iattr(struct super_block *sb)
16506+{
16507+ return au_test_fs_bad_iattr_size(sb)
1308ab2a 16508+ || au_test_fat(sb)
16509+ || au_test_msdos(sb)
16510+ || au_test_vfat(sb);
1facf9fc 16511+}
16512+
16513+/* they don't check i_nlink in link(2) */
16514+static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
16515+{
16516+ return au_test_tmpfs(sb)
16517+#ifdef CONFIG_AUFS_BR_RAMFS
16518+ || au_test_ramfs(sb)
16519+#endif
4a4d8108 16520+ || au_test_ubifs(sb)
4a4d8108 16521+ || au_test_hfsplus(sb);
1facf9fc 16522+}
16523+
16524+/*
16525+ * filesystems which sets S_NOATIME and S_NOCMTIME.
16526+ */
16527+static inline int au_test_fs_notime(struct super_block *sb)
16528+{
16529+ return au_test_nfs(sb)
16530+ || au_test_fuse(sb)
dece6358 16531+ || au_test_ubifs(sb)
1facf9fc 16532+ ;
16533+}
16534+
1facf9fc 16535+/* temporary support for i#1 in cramfs */
16536+static inline int au_test_fs_unique_ino(struct inode *inode)
16537+{
16538+ if (au_test_cramfs(inode->i_sb))
16539+ return inode->i_ino != 1;
16540+ return 1;
16541+}
16542+
16543+/* ---------------------------------------------------------------------- */
16544+
16545+/*
16546+ * the filesystem where the xino files placed must support i/o after unlink and
16547+ * maintain i_size and i_blocks.
16548+ */
16549+static inline int au_test_fs_bad_xino(struct super_block *sb)
16550+{
16551+ return au_test_fs_remote(sb)
16552+ || au_test_fs_bad_iattr_size(sb)
1facf9fc 16553+ /* don't want unnecessary work for xino */
16554+ || au_test_aufs(sb)
1308ab2a 16555+ || au_test_ecryptfs(sb)
16556+ || au_test_nilfs(sb);
1facf9fc 16557+}
16558+
16559+static inline int au_test_fs_trunc_xino(struct super_block *sb)
16560+{
16561+ return au_test_tmpfs(sb)
16562+ || au_test_ramfs(sb);
16563+}
16564+
16565+/*
16566+ * test if the @sb is real-readonly.
16567+ */
16568+static inline int au_test_fs_rr(struct super_block *sb)
16569+{
16570+ return au_test_squashfs(sb)
16571+ || au_test_iso9660(sb)
16572+ || au_test_cramfs(sb)
16573+ || au_test_romfs(sb);
16574+}
16575+
b912730e
AM
16576+/*
16577+ * test if the @inode is nfs with 'noacl' option
16578+ * NFS always sets MS_POSIXACL regardless its mount option 'noacl.'
16579+ */
16580+static inline int au_test_nfs_noacl(struct inode *inode)
16581+{
16582+ return au_test_nfs(inode->i_sb)
16583+ /* && IS_POSIXACL(inode) */
16584+ && !nfs_server_capable(inode, NFS_CAP_ACLS);
16585+}
16586+
1facf9fc 16587+#endif /* __KERNEL__ */
16588+#endif /* __AUFS_FSTYPE_H__ */
ae9dfd79
AM
16589diff -urN /usr/share/empty/fs/aufs/hbl.h linux/fs/aufs/hbl.h
16590--- /usr/share/empty/fs/aufs/hbl.h 1970-01-01 01:00:00.000000000 +0100
16591+++ linux/fs/aufs/hbl.h 2018-04-15 08:49:13.401150731 +0200
16592@@ -0,0 +1,64 @@
16593+/*
16594+ * Copyright (C) 2017-2018 Junjiro R. Okajima
16595+ *
16596+ * This program, aufs is free software; you can redistribute it and/or modify
16597+ * it under the terms of the GNU General Public License as published by
16598+ * the Free Software Foundation; either version 2 of the License, or
16599+ * (at your option) any later version.
16600+ *
16601+ * This program is distributed in the hope that it will be useful,
16602+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16603+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16604+ * GNU General Public License for more details.
16605+ *
16606+ * You should have received a copy of the GNU General Public License
16607+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16608+ */
16609+
16610+/*
16611+ * helpers for hlist_bl.h
16612+ */
16613+
16614+#ifndef __AUFS_HBL_H__
16615+#define __AUFS_HBL_H__
16616+
16617+#ifdef __KERNEL__
16618+
16619+#include <linux/list_bl.h>
16620+
16621+static inline void au_hbl_add(struct hlist_bl_node *node,
16622+ struct hlist_bl_head *hbl)
16623+{
16624+ hlist_bl_lock(hbl);
16625+ hlist_bl_add_head(node, hbl);
16626+ hlist_bl_unlock(hbl);
16627+}
16628+
16629+static inline void au_hbl_del(struct hlist_bl_node *node,
16630+ struct hlist_bl_head *hbl)
16631+{
16632+ hlist_bl_lock(hbl);
16633+ hlist_bl_del(node);
16634+ hlist_bl_unlock(hbl);
16635+}
16636+
16637+#define au_hbl_for_each(pos, head) \
16638+ for (pos = hlist_bl_first(head); \
16639+ pos; \
16640+ pos = pos->next)
16641+
16642+static inline unsigned long au_hbl_count(struct hlist_bl_head *hbl)
16643+{
16644+ unsigned long cnt;
16645+ struct hlist_bl_node *pos;
16646+
16647+ cnt = 0;
16648+ hlist_bl_lock(hbl);
16649+ au_hbl_for_each(pos, hbl)
16650+ cnt++;
16651+ hlist_bl_unlock(hbl);
16652+ return cnt;
16653+}
16654+
16655+#endif /* __KERNEL__ */
16656+#endif /* __AUFS_HBL_H__ */
7f207e10
AM
16657diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
16658--- /usr/share/empty/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 16659+++ linux/fs/aufs/hfsnotify.c 2018-04-15 08:49:13.401150731 +0200
5afbbe0d 16660@@ -0,0 +1,287 @@
1facf9fc 16661+/*
ae9dfd79 16662+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 16663+ *
16664+ * This program, aufs is free software; you can redistribute it and/or modify
16665+ * it under the terms of the GNU General Public License as published by
16666+ * the Free Software Foundation; either version 2 of the License, or
16667+ * (at your option) any later version.
dece6358
AM
16668+ *
16669+ * This program is distributed in the hope that it will be useful,
16670+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16671+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16672+ * GNU General Public License for more details.
16673+ *
16674+ * You should have received a copy of the GNU General Public License
523b37e3 16675+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 16676+ */
16677+
16678+/*
4a4d8108 16679+ * fsnotify for the lower directories
1facf9fc 16680+ */
16681+
16682+#include "aufs.h"
16683+
4a4d8108
AM
16684+/* FS_IN_IGNORED is unnecessary */
16685+static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE
16686+ | FS_CREATE | FS_EVENT_ON_CHILD);
7f207e10 16687+static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
7eafdf33 16688+static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0);
1facf9fc 16689+
0c5527e5 16690+static void au_hfsn_free_mark(struct fsnotify_mark *mark)
1facf9fc 16691+{
0c5527e5
AM
16692+ struct au_hnotify *hn = container_of(mark, struct au_hnotify,
16693+ hn_mark);
5afbbe0d 16694+ /* AuDbg("here\n"); */
ae9dfd79
AM
16695+ au_cache_free_hnotify(hn);
16696+ smp_mb__before_atomic(); /* for atomic64_dec */
1716fcea
AM
16697+ if (atomic64_dec_and_test(&au_hfsn_ifree))
16698+ wake_up(&au_hfsn_wq);
4a4d8108 16699+}
1facf9fc 16700+
027c5e7a 16701+static int au_hfsn_alloc(struct au_hinode *hinode)
4a4d8108 16702+{
1716fcea 16703+ int err;
027c5e7a
AM
16704+ struct au_hnotify *hn;
16705+ struct super_block *sb;
16706+ struct au_branch *br;
0c5527e5 16707+ struct fsnotify_mark *mark;
027c5e7a 16708+ aufs_bindex_t bindex;
1facf9fc 16709+
027c5e7a
AM
16710+ hn = hinode->hi_notify;
16711+ sb = hn->hn_aufs_inode->i_sb;
16712+ bindex = au_br_index(sb, hinode->hi_id);
16713+ br = au_sbr(sb, bindex);
1716fcea
AM
16714+ AuDebugOn(!br->br_hfsn);
16715+
0c5527e5
AM
16716+ mark = &hn->hn_mark;
16717+ fsnotify_init_mark(mark, au_hfsn_free_mark);
16718+ mark->mask = AuHfsnMask;
7f207e10
AM
16719+ /*
16720+ * by udba rename or rmdir, aufs assign a new inode to the known
16721+ * h_inode, so specify 1 to allow dups.
16722+ */
c1595e42 16723+ lockdep_off();
1716fcea 16724+ err = fsnotify_add_mark(mark, br->br_hfsn->hfsn_group, hinode->hi_inode,
027c5e7a 16725+ /*mnt*/NULL, /*allow_dups*/1);
c1595e42 16726+ lockdep_on();
1716fcea
AM
16727+
16728+ return err;
1facf9fc 16729+}
16730+
7eafdf33 16731+static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn)
1facf9fc 16732+{
0c5527e5 16733+ struct fsnotify_mark *mark;
7eafdf33 16734+ unsigned long long ull;
1716fcea 16735+ struct fsnotify_group *group;
7eafdf33
AM
16736+
16737+ ull = atomic64_inc_return(&au_hfsn_ifree);
16738+ BUG_ON(!ull);
953406b4 16739+
0c5527e5 16740+ mark = &hn->hn_mark;
1716fcea
AM
16741+ spin_lock(&mark->lock);
16742+ group = mark->group;
16743+ fsnotify_get_group(group);
16744+ spin_unlock(&mark->lock);
c1595e42 16745+ lockdep_off();
1716fcea 16746+ fsnotify_destroy_mark(mark, group);
5afbbe0d 16747+ fsnotify_put_mark(mark);
1716fcea 16748+ fsnotify_put_group(group);
c1595e42 16749+ lockdep_on();
7f207e10 16750+
7eafdf33
AM
16751+ /* free hn by myself */
16752+ return 0;
1facf9fc 16753+}
16754+
16755+/* ---------------------------------------------------------------------- */
16756+
4a4d8108 16757+static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
1facf9fc 16758+{
0c5527e5 16759+ struct fsnotify_mark *mark;
1facf9fc 16760+
0c5527e5
AM
16761+ mark = &hinode->hi_notify->hn_mark;
16762+ spin_lock(&mark->lock);
1facf9fc 16763+ if (do_set) {
0c5527e5
AM
16764+ AuDebugOn(mark->mask & AuHfsnMask);
16765+ mark->mask |= AuHfsnMask;
1facf9fc 16766+ } else {
0c5527e5
AM
16767+ AuDebugOn(!(mark->mask & AuHfsnMask));
16768+ mark->mask &= ~AuHfsnMask;
1facf9fc 16769+ }
0c5527e5 16770+ spin_unlock(&mark->lock);
4a4d8108 16771+ /* fsnotify_recalc_inode_mask(hinode->hi_inode); */
1facf9fc 16772+}
16773+
4a4d8108 16774+/* ---------------------------------------------------------------------- */
1facf9fc 16775+
4a4d8108
AM
16776+/* #define AuDbgHnotify */
16777+#ifdef AuDbgHnotify
16778+static char *au_hfsn_name(u32 mask)
16779+{
16780+#ifdef CONFIG_AUFS_DEBUG
c06a8ce3
AM
16781+#define test_ret(flag) \
16782+ do { \
16783+ if (mask & flag) \
16784+ return #flag; \
16785+ } while (0)
4a4d8108
AM
16786+ test_ret(FS_ACCESS);
16787+ test_ret(FS_MODIFY);
16788+ test_ret(FS_ATTRIB);
16789+ test_ret(FS_CLOSE_WRITE);
16790+ test_ret(FS_CLOSE_NOWRITE);
16791+ test_ret(FS_OPEN);
16792+ test_ret(FS_MOVED_FROM);
16793+ test_ret(FS_MOVED_TO);
16794+ test_ret(FS_CREATE);
16795+ test_ret(FS_DELETE);
16796+ test_ret(FS_DELETE_SELF);
16797+ test_ret(FS_MOVE_SELF);
16798+ test_ret(FS_UNMOUNT);
16799+ test_ret(FS_Q_OVERFLOW);
16800+ test_ret(FS_IN_IGNORED);
b912730e 16801+ test_ret(FS_ISDIR);
4a4d8108
AM
16802+ test_ret(FS_IN_ONESHOT);
16803+ test_ret(FS_EVENT_ON_CHILD);
16804+ return "";
16805+#undef test_ret
16806+#else
16807+ return "??";
16808+#endif
1facf9fc 16809+}
4a4d8108 16810+#endif
1facf9fc 16811+
16812+/* ---------------------------------------------------------------------- */
16813+
1716fcea
AM
16814+static void au_hfsn_free_group(struct fsnotify_group *group)
16815+{
16816+ struct au_br_hfsnotify *hfsn = group->private;
16817+
5afbbe0d 16818+ /* AuDbg("here\n"); */
ae9dfd79 16819+ kfree(hfsn);
1716fcea
AM
16820+}
16821+
4a4d8108 16822+static int au_hfsn_handle_event(struct fsnotify_group *group,
fb47a38f 16823+ struct inode *inode,
0c5527e5
AM
16824+ struct fsnotify_mark *inode_mark,
16825+ struct fsnotify_mark *vfsmount_mark,
fb47a38f
JR
16826+ u32 mask, void *data, int data_type,
16827+ const unsigned char *file_name, u32 cookie)
1facf9fc 16828+{
16829+ int err;
4a4d8108
AM
16830+ struct au_hnotify *hnotify;
16831+ struct inode *h_dir, *h_inode;
fb47a38f 16832+ struct qstr h_child_qstr = QSTR_INIT(file_name, strlen(file_name));
4a4d8108 16833+
fb47a38f 16834+ AuDebugOn(data_type != FSNOTIFY_EVENT_INODE);
1facf9fc 16835+
16836+ err = 0;
0c5527e5 16837+ /* if FS_UNMOUNT happens, there must be another bug */
4a4d8108 16838+ AuDebugOn(mask & FS_UNMOUNT);
0c5527e5 16839+ if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
1facf9fc 16840+ goto out;
1facf9fc 16841+
fb47a38f
JR
16842+ h_dir = inode;
16843+ h_inode = NULL;
4a4d8108 16844+#ifdef AuDbgHnotify
392086de 16845+ au_debug_on();
4a4d8108
AM
16846+ if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
16847+ || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
16848+ AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
16849+ h_dir->i_ino, mask, au_hfsn_name(mask),
16850+ AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
16851+ /* WARN_ON(1); */
1facf9fc 16852+ }
392086de 16853+ au_debug_off();
1facf9fc 16854+#endif
4a4d8108 16855+
0c5527e5
AM
16856+ AuDebugOn(!inode_mark);
16857+ hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
16858+ err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode);
1facf9fc 16859+
4a4d8108
AM
16860+out:
16861+ return err;
16862+}
1facf9fc 16863+
4a4d8108 16864+static struct fsnotify_ops au_hfsn_ops = {
1716fcea
AM
16865+ .handle_event = au_hfsn_handle_event,
16866+ .free_group_priv = au_hfsn_free_group
4a4d8108
AM
16867+};
16868+
16869+/* ---------------------------------------------------------------------- */
16870+
027c5e7a
AM
16871+static void au_hfsn_fin_br(struct au_branch *br)
16872+{
1716fcea 16873+ struct au_br_hfsnotify *hfsn;
027c5e7a 16874+
1716fcea 16875+ hfsn = br->br_hfsn;
c1595e42
JR
16876+ if (hfsn) {
16877+ lockdep_off();
1716fcea 16878+ fsnotify_put_group(hfsn->hfsn_group);
c1595e42
JR
16879+ lockdep_on();
16880+ }
027c5e7a
AM
16881+}
16882+
1716fcea 16883+static int au_hfsn_init_br(struct au_branch *br, int perm)
4a4d8108
AM
16884+{
16885+ int err;
1716fcea
AM
16886+ struct fsnotify_group *group;
16887+ struct au_br_hfsnotify *hfsn;
1facf9fc 16888+
4a4d8108 16889+ err = 0;
1716fcea
AM
16890+ br->br_hfsn = NULL;
16891+ if (!au_br_hnotifyable(perm))
027c5e7a 16892+ goto out;
027c5e7a 16893+
1716fcea
AM
16894+ err = -ENOMEM;
16895+ hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS);
16896+ if (unlikely(!hfsn))
027c5e7a
AM
16897+ goto out;
16898+
1716fcea
AM
16899+ err = 0;
16900+ group = fsnotify_alloc_group(&au_hfsn_ops);
16901+ if (IS_ERR(group)) {
16902+ err = PTR_ERR(group);
0c5527e5 16903+ pr_err("fsnotify_alloc_group() failed, %d\n", err);
1716fcea 16904+ goto out_hfsn;
4a4d8108 16905+ }
1facf9fc 16906+
1716fcea
AM
16907+ group->private = hfsn;
16908+ hfsn->hfsn_group = group;
16909+ br->br_hfsn = hfsn;
16910+ goto out; /* success */
16911+
16912+out_hfsn:
ae9dfd79 16913+ kfree(hfsn);
027c5e7a 16914+out:
1716fcea
AM
16915+ return err;
16916+}
16917+
16918+static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm)
16919+{
16920+ int err;
16921+
16922+ err = 0;
16923+ if (!br->br_hfsn)
16924+ err = au_hfsn_init_br(br, perm);
16925+
1facf9fc 16926+ return err;
16927+}
16928+
7eafdf33
AM
16929+/* ---------------------------------------------------------------------- */
16930+
16931+static void au_hfsn_fin(void)
16932+{
16933+ AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree));
16934+ wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree));
16935+}
16936+
4a4d8108
AM
16937+const struct au_hnotify_op au_hnotify_op = {
16938+ .ctl = au_hfsn_ctl,
16939+ .alloc = au_hfsn_alloc,
16940+ .free = au_hfsn_free,
1facf9fc 16941+
7eafdf33
AM
16942+ .fin = au_hfsn_fin,
16943+
027c5e7a
AM
16944+ .reset_br = au_hfsn_reset_br,
16945+ .fin_br = au_hfsn_fin_br,
16946+ .init_br = au_hfsn_init_br
4a4d8108 16947+};
7f207e10
AM
16948diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c
16949--- /usr/share/empty/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 16950+++ linux/fs/aufs/hfsplus.c 2018-04-15 08:49:13.401150731 +0200
523b37e3 16951@@ -0,0 +1,56 @@
4a4d8108 16952+/*
ae9dfd79 16953+ * Copyright (C) 2010-2018 Junjiro R. Okajima
4a4d8108
AM
16954+ *
16955+ * This program, aufs is free software; you can redistribute it and/or modify
16956+ * it under the terms of the GNU General Public License as published by
16957+ * the Free Software Foundation; either version 2 of the License, or
16958+ * (at your option) any later version.
16959+ *
16960+ * This program is distributed in the hope that it will be useful,
16961+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16962+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16963+ * GNU General Public License for more details.
16964+ *
16965+ * You should have received a copy of the GNU General Public License
523b37e3 16966+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 16967+ */
1facf9fc 16968+
4a4d8108
AM
16969+/*
16970+ * special support for filesystems which aqucires an inode mutex
16971+ * at final closing a file, eg, hfsplus.
16972+ *
16973+ * This trick is very simple and stupid, just to open the file before really
16974+ * neceeary open to tell hfsplus that this is not the final closing.
16975+ * The caller should call au_h_open_pre() after acquiring the inode mutex,
16976+ * and au_h_open_post() after releasing it.
16977+ */
1facf9fc 16978+
4a4d8108 16979+#include "aufs.h"
1facf9fc 16980+
392086de
AM
16981+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
16982+ int force_wr)
4a4d8108
AM
16983+{
16984+ struct file *h_file;
16985+ struct dentry *h_dentry;
1facf9fc 16986+
4a4d8108
AM
16987+ h_dentry = au_h_dptr(dentry, bindex);
16988+ AuDebugOn(!h_dentry);
5527c038 16989+ AuDebugOn(d_is_negative(h_dentry));
4a4d8108
AM
16990+
16991+ h_file = NULL;
16992+ if (au_test_hfsplus(h_dentry->d_sb)
7e9cd9fe 16993+ && d_is_reg(h_dentry))
4a4d8108
AM
16994+ h_file = au_h_open(dentry, bindex,
16995+ O_RDONLY | O_NOATIME | O_LARGEFILE,
392086de 16996+ /*file*/NULL, force_wr);
4a4d8108 16997+ return h_file;
1facf9fc 16998+}
16999+
4a4d8108
AM
17000+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
17001+ struct file *h_file)
17002+{
17003+ if (h_file) {
17004+ fput(h_file);
17005+ au_sbr_put(dentry->d_sb, bindex);
17006+ }
17007+}
7f207e10
AM
17008diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
17009--- /usr/share/empty/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
17010+++ linux/fs/aufs/hnotify.c 2018-04-15 08:49:13.401150731 +0200
17011@@ -0,0 +1,719 @@
e49829fe 17012+/*
ae9dfd79 17013+ * Copyright (C) 2005-2018 Junjiro R. Okajima
e49829fe
JR
17014+ *
17015+ * This program, aufs is free software; you can redistribute it and/or modify
17016+ * it under the terms of the GNU General Public License as published by
17017+ * the Free Software Foundation; either version 2 of the License, or
17018+ * (at your option) any later version.
17019+ *
17020+ * This program is distributed in the hope that it will be useful,
17021+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17022+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17023+ * GNU General Public License for more details.
17024+ *
17025+ * You should have received a copy of the GNU General Public License
523b37e3 17026+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
17027+ */
17028+
17029+/*
7f207e10 17030+ * abstraction to notify the direct changes on lower directories
e49829fe
JR
17031+ */
17032+
17033+#include "aufs.h"
17034+
027c5e7a 17035+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
e49829fe
JR
17036+{
17037+ int err;
7f207e10 17038+ struct au_hnotify *hn;
1facf9fc 17039+
4a4d8108
AM
17040+ err = -ENOMEM;
17041+ hn = au_cache_alloc_hnotify();
17042+ if (hn) {
17043+ hn->hn_aufs_inode = inode;
027c5e7a
AM
17044+ hinode->hi_notify = hn;
17045+ err = au_hnotify_op.alloc(hinode);
17046+ AuTraceErr(err);
17047+ if (unlikely(err)) {
17048+ hinode->hi_notify = NULL;
ae9dfd79 17049+ au_cache_free_hnotify(hn);
4a4d8108
AM
17050+ /*
17051+ * The upper dir was removed by udba, but the same named
17052+ * dir left. In this case, aufs assignes a new inode
17053+ * number and set the monitor again.
17054+ * For the lower dir, the old monitnor is still left.
17055+ */
17056+ if (err == -EEXIST)
17057+ err = 0;
17058+ }
1308ab2a 17059+ }
1308ab2a 17060+
027c5e7a 17061+ AuTraceErr(err);
1308ab2a 17062+ return err;
dece6358 17063+}
1facf9fc 17064+
4a4d8108 17065+void au_hn_free(struct au_hinode *hinode)
dece6358 17066+{
4a4d8108 17067+ struct au_hnotify *hn;
1facf9fc 17068+
4a4d8108
AM
17069+ hn = hinode->hi_notify;
17070+ if (hn) {
4a4d8108 17071+ hinode->hi_notify = NULL;
7eafdf33 17072+ if (au_hnotify_op.free(hinode, hn))
ae9dfd79 17073+ au_cache_free_hnotify(hn);
4a4d8108
AM
17074+ }
17075+}
dece6358 17076+
4a4d8108 17077+/* ---------------------------------------------------------------------- */
dece6358 17078+
4a4d8108
AM
17079+void au_hn_ctl(struct au_hinode *hinode, int do_set)
17080+{
17081+ if (hinode->hi_notify)
17082+ au_hnotify_op.ctl(hinode, do_set);
17083+}
17084+
17085+void au_hn_reset(struct inode *inode, unsigned int flags)
17086+{
5afbbe0d 17087+ aufs_bindex_t bindex, bbot;
4a4d8108
AM
17088+ struct inode *hi;
17089+ struct dentry *iwhdentry;
1facf9fc 17090+
5afbbe0d
AM
17091+ bbot = au_ibbot(inode);
17092+ for (bindex = au_ibtop(inode); bindex <= bbot; bindex++) {
4a4d8108
AM
17093+ hi = au_h_iptr(inode, bindex);
17094+ if (!hi)
17095+ continue;
1308ab2a 17096+
febd17d6 17097+ /* inode_lock_nested(hi, AuLsc_I_CHILD); */
4a4d8108
AM
17098+ iwhdentry = au_hi_wh(inode, bindex);
17099+ if (iwhdentry)
17100+ dget(iwhdentry);
17101+ au_igrab(hi);
17102+ au_set_h_iptr(inode, bindex, NULL, 0);
17103+ au_set_h_iptr(inode, bindex, au_igrab(hi),
17104+ flags & ~AuHi_XINO);
17105+ iput(hi);
17106+ dput(iwhdentry);
febd17d6 17107+ /* inode_unlock(hi); */
1facf9fc 17108+ }
1facf9fc 17109+}
17110+
1308ab2a 17111+/* ---------------------------------------------------------------------- */
1facf9fc 17112+
4a4d8108 17113+static int hn_xino(struct inode *inode, struct inode *h_inode)
1facf9fc 17114+{
4a4d8108 17115+ int err;
5afbbe0d 17116+ aufs_bindex_t bindex, bbot, bfound, btop;
4a4d8108 17117+ struct inode *h_i;
1facf9fc 17118+
4a4d8108
AM
17119+ err = 0;
17120+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 17121+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
17122+ goto out;
17123+ }
1facf9fc 17124+
4a4d8108 17125+ bfound = -1;
5afbbe0d
AM
17126+ bbot = au_ibbot(inode);
17127+ btop = au_ibtop(inode);
4a4d8108 17128+#if 0 /* reserved for future use */
5afbbe0d 17129+ if (bindex == bbot) {
4a4d8108
AM
17130+ /* keep this ino in rename case */
17131+ goto out;
17132+ }
17133+#endif
5afbbe0d 17134+ for (bindex = btop; bindex <= bbot; bindex++)
4a4d8108
AM
17135+ if (au_h_iptr(inode, bindex) == h_inode) {
17136+ bfound = bindex;
17137+ break;
17138+ }
17139+ if (bfound < 0)
1308ab2a 17140+ goto out;
1facf9fc 17141+
5afbbe0d 17142+ for (bindex = btop; bindex <= bbot; bindex++) {
4a4d8108
AM
17143+ h_i = au_h_iptr(inode, bindex);
17144+ if (!h_i)
17145+ continue;
1facf9fc 17146+
4a4d8108
AM
17147+ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
17148+ /* ignore this error */
17149+ /* bad action? */
1facf9fc 17150+ }
1facf9fc 17151+
4a4d8108 17152+ /* children inode number will be broken */
1facf9fc 17153+
4f0767ce 17154+out:
4a4d8108
AM
17155+ AuTraceErr(err);
17156+ return err;
1facf9fc 17157+}
17158+
4a4d8108 17159+static int hn_gen_tree(struct dentry *dentry)
1facf9fc 17160+{
4a4d8108
AM
17161+ int err, i, j, ndentry;
17162+ struct au_dcsub_pages dpages;
17163+ struct au_dpage *dpage;
17164+ struct dentry **dentries;
1facf9fc 17165+
4a4d8108
AM
17166+ err = au_dpages_init(&dpages, GFP_NOFS);
17167+ if (unlikely(err))
17168+ goto out;
17169+ err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
17170+ if (unlikely(err))
17171+ goto out_dpages;
1facf9fc 17172+
4a4d8108
AM
17173+ for (i = 0; i < dpages.ndpage; i++) {
17174+ dpage = dpages.dpages + i;
17175+ dentries = dpage->dentries;
17176+ ndentry = dpage->ndentry;
17177+ for (j = 0; j < ndentry; j++) {
17178+ struct dentry *d;
17179+
17180+ d = dentries[j];
17181+ if (IS_ROOT(d))
17182+ continue;
17183+
4a4d8108 17184+ au_digen_dec(d);
5527c038 17185+ if (d_really_is_positive(d))
4a4d8108
AM
17186+ /* todo: reset children xino?
17187+ cached children only? */
5527c038 17188+ au_iigen_dec(d_inode(d));
1308ab2a 17189+ }
dece6358 17190+ }
1facf9fc 17191+
4f0767ce 17192+out_dpages:
4a4d8108 17193+ au_dpages_free(&dpages);
dece6358 17194+
027c5e7a 17195+#if 0
4a4d8108
AM
17196+ /* discard children */
17197+ dentry_unhash(dentry);
17198+ dput(dentry);
027c5e7a 17199+#endif
4f0767ce 17200+out:
dece6358
AM
17201+ return err;
17202+}
17203+
1308ab2a 17204+/*
4a4d8108 17205+ * return 0 if processed.
1308ab2a 17206+ */
4a4d8108
AM
17207+static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
17208+ const unsigned int isdir)
dece6358 17209+{
1308ab2a 17210+ int err;
4a4d8108
AM
17211+ struct dentry *d;
17212+ struct qstr *dname;
1facf9fc 17213+
4a4d8108
AM
17214+ err = 1;
17215+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 17216+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
17217+ err = 0;
17218+ goto out;
17219+ }
dece6358 17220+
4a4d8108
AM
17221+ if (!isdir) {
17222+ AuDebugOn(!name);
17223+ au_iigen_dec(inode);
027c5e7a 17224+ spin_lock(&inode->i_lock);
c1595e42 17225+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
027c5e7a 17226+ spin_lock(&d->d_lock);
4a4d8108
AM
17227+ dname = &d->d_name;
17228+ if (dname->len != nlen
027c5e7a
AM
17229+ && memcmp(dname->name, name, nlen)) {
17230+ spin_unlock(&d->d_lock);
4a4d8108 17231+ continue;
027c5e7a 17232+ }
4a4d8108 17233+ err = 0;
4a4d8108
AM
17234+ au_digen_dec(d);
17235+ spin_unlock(&d->d_lock);
17236+ break;
1facf9fc 17237+ }
027c5e7a 17238+ spin_unlock(&inode->i_lock);
1308ab2a 17239+ } else {
027c5e7a 17240+ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
c1595e42 17241+ d = d_find_any_alias(inode);
4a4d8108
AM
17242+ if (!d) {
17243+ au_iigen_dec(inode);
17244+ goto out;
17245+ }
1facf9fc 17246+
027c5e7a 17247+ spin_lock(&d->d_lock);
4a4d8108 17248+ dname = &d->d_name;
027c5e7a
AM
17249+ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
17250+ spin_unlock(&d->d_lock);
4a4d8108 17251+ err = hn_gen_tree(d);
027c5e7a
AM
17252+ spin_lock(&d->d_lock);
17253+ }
17254+ spin_unlock(&d->d_lock);
4a4d8108
AM
17255+ dput(d);
17256+ }
1facf9fc 17257+
4f0767ce 17258+out:
4a4d8108 17259+ AuTraceErr(err);
1308ab2a 17260+ return err;
17261+}
dece6358 17262+
4a4d8108 17263+static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
1facf9fc 17264+{
4a4d8108 17265+ int err;
1facf9fc 17266+
5527c038 17267+ if (IS_ROOT(dentry)) {
0c3ec466 17268+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
17269+ return 0;
17270+ }
1308ab2a 17271+
4a4d8108
AM
17272+ err = 0;
17273+ if (!isdir) {
4a4d8108 17274+ au_digen_dec(dentry);
5527c038
JR
17275+ if (d_really_is_positive(dentry))
17276+ au_iigen_dec(d_inode(dentry));
4a4d8108 17277+ } else {
027c5e7a 17278+ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
5527c038 17279+ if (d_really_is_positive(dentry))
4a4d8108
AM
17280+ err = hn_gen_tree(dentry);
17281+ }
17282+
17283+ AuTraceErr(err);
17284+ return err;
1facf9fc 17285+}
17286+
4a4d8108 17287+/* ---------------------------------------------------------------------- */
1facf9fc 17288+
4a4d8108
AM
17289+/* hnotify job flags */
17290+#define AuHnJob_XINO0 1
17291+#define AuHnJob_GEN (1 << 1)
17292+#define AuHnJob_DIRENT (1 << 2)
17293+#define AuHnJob_ISDIR (1 << 3)
17294+#define AuHnJob_TRYXINO0 (1 << 4)
17295+#define AuHnJob_MNTPNT (1 << 5)
17296+#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name)
7f207e10
AM
17297+#define au_fset_hnjob(flags, name) \
17298+ do { (flags) |= AuHnJob_##name; } while (0)
17299+#define au_fclr_hnjob(flags, name) \
17300+ do { (flags) &= ~AuHnJob_##name; } while (0)
1facf9fc 17301+
4a4d8108
AM
17302+enum {
17303+ AuHn_CHILD,
17304+ AuHn_PARENT,
17305+ AuHnLast
17306+};
1facf9fc 17307+
4a4d8108
AM
17308+struct au_hnotify_args {
17309+ struct inode *h_dir, *dir, *h_child_inode;
17310+ u32 mask;
17311+ unsigned int flags[AuHnLast];
17312+ unsigned int h_child_nlen;
17313+ char h_child_name[];
17314+};
1facf9fc 17315+
4a4d8108
AM
17316+struct hn_job_args {
17317+ unsigned int flags;
17318+ struct inode *inode, *h_inode, *dir, *h_dir;
17319+ struct dentry *dentry;
17320+ char *h_name;
17321+ int h_nlen;
17322+};
1308ab2a 17323+
4a4d8108
AM
17324+static int hn_job(struct hn_job_args *a)
17325+{
17326+ const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
076b876e 17327+ int e;
1308ab2a 17328+
4a4d8108
AM
17329+ /* reset xino */
17330+ if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
17331+ hn_xino(a->inode, a->h_inode); /* ignore this error */
1308ab2a 17332+
4a4d8108
AM
17333+ if (au_ftest_hnjob(a->flags, TRYXINO0)
17334+ && a->inode
17335+ && a->h_inode) {
ae9dfd79 17336+ vfsub_inode_lock_shared_nested(a->h_inode, AuLsc_I_CHILD);
38d290e6
JR
17337+ if (!a->h_inode->i_nlink
17338+ && !(a->h_inode->i_state & I_LINKABLE))
4a4d8108 17339+ hn_xino(a->inode, a->h_inode); /* ignore this error */
ae9dfd79 17340+ inode_unlock_shared(a->h_inode);
1308ab2a 17341+ }
1facf9fc 17342+
4a4d8108
AM
17343+ /* make the generation obsolete */
17344+ if (au_ftest_hnjob(a->flags, GEN)) {
076b876e 17345+ e = -1;
4a4d8108 17346+ if (a->inode)
076b876e 17347+ e = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
4a4d8108 17348+ isdir);
076b876e 17349+ if (e && a->dentry)
4a4d8108
AM
17350+ hn_gen_by_name(a->dentry, isdir);
17351+ /* ignore this error */
1facf9fc 17352+ }
1facf9fc 17353+
4a4d8108
AM
17354+ /* make dir entries obsolete */
17355+ if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
17356+ struct au_vdir *vdir;
1facf9fc 17357+
4a4d8108
AM
17358+ vdir = au_ivdir(a->inode);
17359+ if (vdir)
17360+ vdir->vd_jiffy = 0;
17361+ /* IMustLock(a->inode); */
17362+ /* a->inode->i_version++; */
17363+ }
1facf9fc 17364+
4a4d8108
AM
17365+ /* can do nothing but warn */
17366+ if (au_ftest_hnjob(a->flags, MNTPNT)
17367+ && a->dentry
17368+ && d_mountpoint(a->dentry))
523b37e3 17369+ pr_warn("mount-point %pd is removed or renamed\n", a->dentry);
1facf9fc 17370+
4a4d8108 17371+ return 0;
1308ab2a 17372+}
1facf9fc 17373+
1308ab2a 17374+/* ---------------------------------------------------------------------- */
1facf9fc 17375+
4a4d8108
AM
17376+static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
17377+ struct inode *dir)
1308ab2a 17378+{
4a4d8108
AM
17379+ struct dentry *dentry, *d, *parent;
17380+ struct qstr *dname;
1308ab2a 17381+
c1595e42 17382+ parent = d_find_any_alias(dir);
4a4d8108
AM
17383+ if (!parent)
17384+ return NULL;
1308ab2a 17385+
4a4d8108 17386+ dentry = NULL;
027c5e7a 17387+ spin_lock(&parent->d_lock);
c1595e42 17388+ list_for_each_entry(d, &parent->d_subdirs, d_child) {
523b37e3 17389+ /* AuDbg("%pd\n", d); */
027c5e7a 17390+ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
4a4d8108
AM
17391+ dname = &d->d_name;
17392+ if (dname->len != nlen || memcmp(dname->name, name, nlen))
027c5e7a
AM
17393+ goto cont_unlock;
17394+ if (au_di(d))
17395+ au_digen_dec(d);
17396+ else
17397+ goto cont_unlock;
c1595e42 17398+ if (au_dcount(d) > 0) {
027c5e7a 17399+ dentry = dget_dlock(d);
4a4d8108 17400+ spin_unlock(&d->d_lock);
027c5e7a 17401+ break;
dece6358 17402+ }
1facf9fc 17403+
f6b6e03d 17404+cont_unlock:
027c5e7a 17405+ spin_unlock(&d->d_lock);
1308ab2a 17406+ }
027c5e7a 17407+ spin_unlock(&parent->d_lock);
4a4d8108 17408+ dput(parent);
1facf9fc 17409+
4a4d8108
AM
17410+ if (dentry)
17411+ di_write_lock_child(dentry);
1308ab2a 17412+
4a4d8108
AM
17413+ return dentry;
17414+}
dece6358 17415+
4a4d8108
AM
17416+static struct inode *lookup_wlock_by_ino(struct super_block *sb,
17417+ aufs_bindex_t bindex, ino_t h_ino)
17418+{
17419+ struct inode *inode;
17420+ ino_t ino;
17421+ int err;
17422+
17423+ inode = NULL;
17424+ err = au_xino_read(sb, bindex, h_ino, &ino);
17425+ if (!err && ino)
17426+ inode = ilookup(sb, ino);
17427+ if (!inode)
17428+ goto out;
17429+
17430+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 17431+ pr_warn("wrong root branch\n");
4a4d8108
AM
17432+ iput(inode);
17433+ inode = NULL;
17434+ goto out;
1308ab2a 17435+ }
17436+
4a4d8108 17437+ ii_write_lock_child(inode);
1308ab2a 17438+
4f0767ce 17439+out:
4a4d8108 17440+ return inode;
dece6358
AM
17441+}
17442+
4a4d8108 17443+static void au_hn_bh(void *_args)
1facf9fc 17444+{
4a4d8108
AM
17445+ struct au_hnotify_args *a = _args;
17446+ struct super_block *sb;
5afbbe0d 17447+ aufs_bindex_t bindex, bbot, bfound;
4a4d8108 17448+ unsigned char xino, try_iput;
1facf9fc 17449+ int err;
1308ab2a 17450+ struct inode *inode;
4a4d8108
AM
17451+ ino_t h_ino;
17452+ struct hn_job_args args;
17453+ struct dentry *dentry;
17454+ struct au_sbinfo *sbinfo;
1facf9fc 17455+
4a4d8108
AM
17456+ AuDebugOn(!_args);
17457+ AuDebugOn(!a->h_dir);
17458+ AuDebugOn(!a->dir);
17459+ AuDebugOn(!a->mask);
17460+ AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
17461+ a->mask, a->dir->i_ino, a->h_dir->i_ino,
17462+ a->h_child_inode ? a->h_child_inode->i_ino : 0);
1facf9fc 17463+
4a4d8108
AM
17464+ inode = NULL;
17465+ dentry = NULL;
17466+ /*
17467+ * do not lock a->dir->i_mutex here
17468+ * because of d_revalidate() may cause a deadlock.
17469+ */
17470+ sb = a->dir->i_sb;
17471+ AuDebugOn(!sb);
17472+ sbinfo = au_sbi(sb);
17473+ AuDebugOn(!sbinfo);
7f207e10 17474+ si_write_lock(sb, AuLock_NOPLMW);
1facf9fc 17475+
ae9dfd79
AM
17476+ if (au_opt_test(sbinfo->si_mntflags, DIRREN))
17477+ switch (a->mask & FS_EVENTS_POSS_ON_CHILD) {
17478+ case FS_MOVED_FROM:
17479+ case FS_MOVED_TO:
17480+ AuWarn1("DIRREN with UDBA may not work correctly "
17481+ "for the direct rename(2)\n");
17482+ }
17483+
4a4d8108
AM
17484+ ii_read_lock_parent(a->dir);
17485+ bfound = -1;
5afbbe0d
AM
17486+ bbot = au_ibbot(a->dir);
17487+ for (bindex = au_ibtop(a->dir); bindex <= bbot; bindex++)
4a4d8108
AM
17488+ if (au_h_iptr(a->dir, bindex) == a->h_dir) {
17489+ bfound = bindex;
17490+ break;
17491+ }
17492+ ii_read_unlock(a->dir);
17493+ if (unlikely(bfound < 0))
17494+ goto out;
1facf9fc 17495+
4a4d8108
AM
17496+ xino = !!au_opt_test(au_mntflags(sb), XINO);
17497+ h_ino = 0;
17498+ if (a->h_child_inode)
17499+ h_ino = a->h_child_inode->i_ino;
1facf9fc 17500+
4a4d8108
AM
17501+ if (a->h_child_nlen
17502+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
17503+ || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
17504+ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
17505+ a->dir);
17506+ try_iput = 0;
5527c038
JR
17507+ if (dentry && d_really_is_positive(dentry))
17508+ inode = d_inode(dentry);
4a4d8108
AM
17509+ if (xino && !inode && h_ino
17510+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
17511+ || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
17512+ || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
17513+ inode = lookup_wlock_by_ino(sb, bfound, h_ino);
17514+ try_iput = 1;
f0c0a007 17515+ }
1facf9fc 17516+
4a4d8108
AM
17517+ args.flags = a->flags[AuHn_CHILD];
17518+ args.dentry = dentry;
17519+ args.inode = inode;
17520+ args.h_inode = a->h_child_inode;
17521+ args.dir = a->dir;
17522+ args.h_dir = a->h_dir;
17523+ args.h_name = a->h_child_name;
17524+ args.h_nlen = a->h_child_nlen;
17525+ err = hn_job(&args);
17526+ if (dentry) {
027c5e7a 17527+ if (au_di(dentry))
4a4d8108
AM
17528+ di_write_unlock(dentry);
17529+ dput(dentry);
17530+ }
17531+ if (inode && try_iput) {
17532+ ii_write_unlock(inode);
17533+ iput(inode);
17534+ }
1facf9fc 17535+
4a4d8108
AM
17536+ ii_write_lock_parent(a->dir);
17537+ args.flags = a->flags[AuHn_PARENT];
17538+ args.dentry = NULL;
17539+ args.inode = a->dir;
17540+ args.h_inode = a->h_dir;
17541+ args.dir = NULL;
17542+ args.h_dir = NULL;
17543+ args.h_name = NULL;
17544+ args.h_nlen = 0;
17545+ err = hn_job(&args);
17546+ ii_write_unlock(a->dir);
1facf9fc 17547+
4f0767ce 17548+out:
4a4d8108
AM
17549+ iput(a->h_child_inode);
17550+ iput(a->h_dir);
17551+ iput(a->dir);
027c5e7a
AM
17552+ si_write_unlock(sb);
17553+ au_nwt_done(&sbinfo->si_nowait);
ae9dfd79 17554+ kfree(a);
dece6358 17555+}
1facf9fc 17556+
4a4d8108
AM
17557+/* ---------------------------------------------------------------------- */
17558+
17559+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
17560+ struct qstr *h_child_qstr, struct inode *h_child_inode)
dece6358 17561+{
4a4d8108 17562+ int err, len;
53392da6 17563+ unsigned int flags[AuHnLast], f;
4a4d8108
AM
17564+ unsigned char isdir, isroot, wh;
17565+ struct inode *dir;
17566+ struct au_hnotify_args *args;
17567+ char *p, *h_child_name;
dece6358 17568+
1308ab2a 17569+ err = 0;
4a4d8108
AM
17570+ AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
17571+ dir = igrab(hnotify->hn_aufs_inode);
17572+ if (!dir)
17573+ goto out;
1facf9fc 17574+
4a4d8108
AM
17575+ isroot = (dir->i_ino == AUFS_ROOT_INO);
17576+ wh = 0;
17577+ h_child_name = (void *)h_child_qstr->name;
17578+ len = h_child_qstr->len;
17579+ if (h_child_name) {
17580+ if (len > AUFS_WH_PFX_LEN
17581+ && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
17582+ h_child_name += AUFS_WH_PFX_LEN;
17583+ len -= AUFS_WH_PFX_LEN;
17584+ wh = 1;
17585+ }
1facf9fc 17586+ }
dece6358 17587+
4a4d8108
AM
17588+ isdir = 0;
17589+ if (h_child_inode)
17590+ isdir = !!S_ISDIR(h_child_inode->i_mode);
17591+ flags[AuHn_PARENT] = AuHnJob_ISDIR;
17592+ flags[AuHn_CHILD] = 0;
17593+ if (isdir)
17594+ flags[AuHn_CHILD] = AuHnJob_ISDIR;
17595+ au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
17596+ au_fset_hnjob(flags[AuHn_CHILD], GEN);
17597+ switch (mask & FS_EVENTS_POSS_ON_CHILD) {
17598+ case FS_MOVED_FROM:
17599+ case FS_MOVED_TO:
17600+ au_fset_hnjob(flags[AuHn_CHILD], XINO0);
17601+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
17602+ /*FALLTHROUGH*/
17603+ case FS_CREATE:
fb47a38f 17604+ AuDebugOn(!h_child_name);
4a4d8108 17605+ break;
1facf9fc 17606+
4a4d8108
AM
17607+ case FS_DELETE:
17608+ /*
17609+ * aufs never be able to get this child inode.
17610+ * revalidation should be in d_revalidate()
17611+ * by checking i_nlink, i_generation or d_unhashed().
17612+ */
17613+ AuDebugOn(!h_child_name);
17614+ au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
17615+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
17616+ break;
dece6358 17617+
4a4d8108
AM
17618+ default:
17619+ AuDebugOn(1);
17620+ }
1308ab2a 17621+
4a4d8108
AM
17622+ if (wh)
17623+ h_child_inode = NULL;
1308ab2a 17624+
4a4d8108
AM
17625+ err = -ENOMEM;
17626+ /* iput() and kfree() will be called in au_hnotify() */
4a4d8108 17627+ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
4a4d8108
AM
17628+ if (unlikely(!args)) {
17629+ AuErr1("no memory\n");
17630+ iput(dir);
17631+ goto out;
17632+ }
17633+ args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
17634+ args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
17635+ args->mask = mask;
17636+ args->dir = dir;
17637+ args->h_dir = igrab(h_dir);
17638+ if (h_child_inode)
17639+ h_child_inode = igrab(h_child_inode); /* can be NULL */
17640+ args->h_child_inode = h_child_inode;
17641+ args->h_child_nlen = len;
17642+ if (len) {
17643+ p = (void *)args;
17644+ p += sizeof(*args);
17645+ memcpy(p, h_child_name, len);
17646+ p[len] = 0;
1308ab2a 17647+ }
1308ab2a 17648+
38d290e6 17649+ /* NFS fires the event for silly-renamed one from kworker */
53392da6 17650+ f = 0;
38d290e6
JR
17651+ if (!dir->i_nlink
17652+ || (au_test_nfs(h_dir->i_sb) && (mask & FS_DELETE)))
53392da6
AM
17653+ f = AuWkq_NEST;
17654+ err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
4a4d8108
AM
17655+ if (unlikely(err)) {
17656+ pr_err("wkq %d\n", err);
17657+ iput(args->h_child_inode);
17658+ iput(args->h_dir);
17659+ iput(args->dir);
ae9dfd79 17660+ kfree(args);
1facf9fc 17661+ }
1facf9fc 17662+
4a4d8108 17663+out:
1facf9fc 17664+ return err;
17665+}
17666+
027c5e7a
AM
17667+/* ---------------------------------------------------------------------- */
17668+
17669+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
17670+{
17671+ int err;
17672+
17673+ AuDebugOn(!(udba & AuOptMask_UDBA));
17674+
17675+ err = 0;
17676+ if (au_hnotify_op.reset_br)
17677+ err = au_hnotify_op.reset_br(udba, br, perm);
17678+
17679+ return err;
17680+}
17681+
17682+int au_hnotify_init_br(struct au_branch *br, int perm)
17683+{
17684+ int err;
17685+
17686+ err = 0;
17687+ if (au_hnotify_op.init_br)
17688+ err = au_hnotify_op.init_br(br, perm);
17689+
17690+ return err;
17691+}
17692+
17693+void au_hnotify_fin_br(struct au_branch *br)
17694+{
17695+ if (au_hnotify_op.fin_br)
17696+ au_hnotify_op.fin_br(br);
17697+}
17698+
4a4d8108
AM
17699+static void au_hn_destroy_cache(void)
17700+{
ae9dfd79
AM
17701+ kmem_cache_destroy(au_cache[AuCache_HNOTIFY]);
17702+ au_cache[AuCache_HNOTIFY] = NULL;
4a4d8108 17703+}
1308ab2a 17704+
4a4d8108 17705+int __init au_hnotify_init(void)
1facf9fc 17706+{
1308ab2a 17707+ int err;
1308ab2a 17708+
4a4d8108 17709+ err = -ENOMEM;
ae9dfd79
AM
17710+ au_cache[AuCache_HNOTIFY] = AuCache(au_hnotify);
17711+ if (au_cache[AuCache_HNOTIFY]) {
027c5e7a
AM
17712+ err = 0;
17713+ if (au_hnotify_op.init)
17714+ err = au_hnotify_op.init();
4a4d8108
AM
17715+ if (unlikely(err))
17716+ au_hn_destroy_cache();
1308ab2a 17717+ }
1308ab2a 17718+ AuTraceErr(err);
4a4d8108 17719+ return err;
1308ab2a 17720+}
17721+
4a4d8108 17722+void au_hnotify_fin(void)
1308ab2a 17723+{
027c5e7a
AM
17724+ if (au_hnotify_op.fin)
17725+ au_hnotify_op.fin();
f0c0a007 17726+
4a4d8108 17727+ /* cf. au_cache_fin() */
ae9dfd79 17728+ if (au_cache[AuCache_HNOTIFY])
4a4d8108 17729+ au_hn_destroy_cache();
dece6358 17730+}
7f207e10
AM
17731diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
17732--- /usr/share/empty/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 17733+++ linux/fs/aufs/iinfo.c 2018-04-15 08:49:13.401150731 +0200
e2f27e51 17734@@ -0,0 +1,285 @@
dece6358 17735+/*
ae9dfd79 17736+ * Copyright (C) 2005-2018 Junjiro R. Okajima
dece6358
AM
17737+ *
17738+ * This program, aufs is free software; you can redistribute it and/or modify
17739+ * it under the terms of the GNU General Public License as published by
17740+ * the Free Software Foundation; either version 2 of the License, or
17741+ * (at your option) any later version.
17742+ *
17743+ * This program is distributed in the hope that it will be useful,
17744+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17745+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17746+ * GNU General Public License for more details.
17747+ *
17748+ * You should have received a copy of the GNU General Public License
523b37e3 17749+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 17750+ */
1facf9fc 17751+
dece6358 17752+/*
4a4d8108 17753+ * inode private data
dece6358 17754+ */
1facf9fc 17755+
1308ab2a 17756+#include "aufs.h"
1facf9fc 17757+
4a4d8108 17758+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 17759+{
4a4d8108 17760+ struct inode *h_inode;
5afbbe0d 17761+ struct au_hinode *hinode;
1facf9fc 17762+
4a4d8108 17763+ IiMustAnyLock(inode);
1facf9fc 17764+
5afbbe0d
AM
17765+ hinode = au_hinode(au_ii(inode), bindex);
17766+ h_inode = hinode->hi_inode;
4a4d8108
AM
17767+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
17768+ return h_inode;
17769+}
1facf9fc 17770+
4a4d8108
AM
17771+/* todo: hard/soft set? */
17772+void au_hiput(struct au_hinode *hinode)
17773+{
17774+ au_hn_free(hinode);
17775+ dput(hinode->hi_whdentry);
17776+ iput(hinode->hi_inode);
17777+}
1facf9fc 17778+
4a4d8108
AM
17779+unsigned int au_hi_flags(struct inode *inode, int isdir)
17780+{
17781+ unsigned int flags;
17782+ const unsigned int mnt_flags = au_mntflags(inode->i_sb);
1facf9fc 17783+
4a4d8108
AM
17784+ flags = 0;
17785+ if (au_opt_test(mnt_flags, XINO))
17786+ au_fset_hi(flags, XINO);
17787+ if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY))
17788+ au_fset_hi(flags, HNOTIFY);
17789+ return flags;
1facf9fc 17790+}
17791+
4a4d8108
AM
17792+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
17793+ struct inode *h_inode, unsigned int flags)
1308ab2a 17794+{
4a4d8108
AM
17795+ struct au_hinode *hinode;
17796+ struct inode *hi;
17797+ struct au_iinfo *iinfo = au_ii(inode);
1facf9fc 17798+
4a4d8108 17799+ IiMustWriteLock(inode);
dece6358 17800+
5afbbe0d 17801+ hinode = au_hinode(iinfo, bindex);
4a4d8108
AM
17802+ hi = hinode->hi_inode;
17803+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
17804+
17805+ if (hi)
17806+ au_hiput(hinode);
17807+ hinode->hi_inode = h_inode;
17808+ if (h_inode) {
17809+ int err;
17810+ struct super_block *sb = inode->i_sb;
17811+ struct au_branch *br;
17812+
027c5e7a
AM
17813+ AuDebugOn(inode->i_mode
17814+ && (h_inode->i_mode & S_IFMT)
17815+ != (inode->i_mode & S_IFMT));
5afbbe0d 17816+ if (bindex == iinfo->ii_btop)
4a4d8108
AM
17817+ au_cpup_igen(inode, h_inode);
17818+ br = au_sbr(sb, bindex);
17819+ hinode->hi_id = br->br_id;
17820+ if (au_ftest_hi(flags, XINO)) {
17821+ err = au_xino_write(sb, bindex, h_inode->i_ino,
17822+ inode->i_ino);
17823+ if (unlikely(err))
17824+ AuIOErr1("failed au_xino_write() %d\n", err);
17825+ }
17826+
17827+ if (au_ftest_hi(flags, HNOTIFY)
17828+ && au_br_hnotifyable(br->br_perm)) {
027c5e7a 17829+ err = au_hn_alloc(hinode, inode);
4a4d8108
AM
17830+ if (unlikely(err))
17831+ AuIOErr1("au_hn_alloc() %d\n", err);
1308ab2a 17832+ }
17833+ }
4a4d8108 17834+}
dece6358 17835+
4a4d8108
AM
17836+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
17837+ struct dentry *h_wh)
17838+{
17839+ struct au_hinode *hinode;
dece6358 17840+
4a4d8108
AM
17841+ IiMustWriteLock(inode);
17842+
5afbbe0d 17843+ hinode = au_hinode(au_ii(inode), bindex);
4a4d8108
AM
17844+ AuDebugOn(hinode->hi_whdentry);
17845+ hinode->hi_whdentry = h_wh;
1facf9fc 17846+}
17847+
537831f9 17848+void au_update_iigen(struct inode *inode, int half)
1308ab2a 17849+{
537831f9
AM
17850+ struct au_iinfo *iinfo;
17851+ struct au_iigen *iigen;
17852+ unsigned int sigen;
17853+
17854+ sigen = au_sigen(inode->i_sb);
17855+ iinfo = au_ii(inode);
17856+ iigen = &iinfo->ii_generation;
be52b249 17857+ spin_lock(&iigen->ig_spin);
537831f9
AM
17858+ iigen->ig_generation = sigen;
17859+ if (half)
17860+ au_ig_fset(iigen->ig_flags, HALF_REFRESHED);
17861+ else
17862+ au_ig_fclr(iigen->ig_flags, HALF_REFRESHED);
be52b249 17863+ spin_unlock(&iigen->ig_spin);
4a4d8108 17864+}
1facf9fc 17865+
4a4d8108
AM
17866+/* it may be called at remount time, too */
17867+void au_update_ibrange(struct inode *inode, int do_put_zero)
17868+{
17869+ struct au_iinfo *iinfo;
5afbbe0d 17870+ aufs_bindex_t bindex, bbot;
1facf9fc 17871+
5afbbe0d 17872+ AuDebugOn(au_is_bad_inode(inode));
4a4d8108 17873+ IiMustWriteLock(inode);
1facf9fc 17874+
5afbbe0d
AM
17875+ iinfo = au_ii(inode);
17876+ if (do_put_zero && iinfo->ii_btop >= 0) {
17877+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot;
4a4d8108
AM
17878+ bindex++) {
17879+ struct inode *h_i;
1facf9fc 17880+
5afbbe0d 17881+ h_i = au_hinode(iinfo, bindex)->hi_inode;
38d290e6
JR
17882+ if (h_i
17883+ && !h_i->i_nlink
17884+ && !(h_i->i_state & I_LINKABLE))
027c5e7a
AM
17885+ au_set_h_iptr(inode, bindex, NULL, 0);
17886+ }
4a4d8108
AM
17887+ }
17888+
5afbbe0d
AM
17889+ iinfo->ii_btop = -1;
17890+ iinfo->ii_bbot = -1;
17891+ bbot = au_sbbot(inode->i_sb);
17892+ for (bindex = 0; bindex <= bbot; bindex++)
17893+ if (au_hinode(iinfo, bindex)->hi_inode) {
17894+ iinfo->ii_btop = bindex;
4a4d8108 17895+ break;
027c5e7a 17896+ }
5afbbe0d
AM
17897+ if (iinfo->ii_btop >= 0)
17898+ for (bindex = bbot; bindex >= iinfo->ii_btop; bindex--)
17899+ if (au_hinode(iinfo, bindex)->hi_inode) {
17900+ iinfo->ii_bbot = bindex;
027c5e7a
AM
17901+ break;
17902+ }
5afbbe0d 17903+ AuDebugOn(iinfo->ii_btop > iinfo->ii_bbot);
1308ab2a 17904+}
1facf9fc 17905+
dece6358 17906+/* ---------------------------------------------------------------------- */
1facf9fc 17907+
4a4d8108 17908+void au_icntnr_init_once(void *_c)
dece6358 17909+{
4a4d8108
AM
17910+ struct au_icntnr *c = _c;
17911+ struct au_iinfo *iinfo = &c->iinfo;
1facf9fc 17912+
be52b249 17913+ spin_lock_init(&iinfo->ii_generation.ig_spin);
4a4d8108
AM
17914+ au_rw_init(&iinfo->ii_rwsem);
17915+ inode_init_once(&c->vfs_inode);
17916+}
1facf9fc 17917+
5afbbe0d
AM
17918+void au_hinode_init(struct au_hinode *hinode)
17919+{
17920+ hinode->hi_inode = NULL;
17921+ hinode->hi_id = -1;
17922+ au_hn_init(hinode);
17923+ hinode->hi_whdentry = NULL;
17924+}
17925+
4a4d8108
AM
17926+int au_iinfo_init(struct inode *inode)
17927+{
17928+ struct au_iinfo *iinfo;
17929+ struct super_block *sb;
5afbbe0d 17930+ struct au_hinode *hi;
4a4d8108 17931+ int nbr, i;
1facf9fc 17932+
4a4d8108
AM
17933+ sb = inode->i_sb;
17934+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
5afbbe0d 17935+ nbr = au_sbbot(sb) + 1;
4a4d8108
AM
17936+ if (unlikely(nbr <= 0))
17937+ nbr = 1;
5afbbe0d
AM
17938+ hi = kmalloc_array(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
17939+ if (hi) {
7f207e10 17940+ au_ninodes_inc(sb);
5afbbe0d
AM
17941+
17942+ iinfo->ii_hinode = hi;
17943+ for (i = 0; i < nbr; i++, hi++)
17944+ au_hinode_init(hi);
1facf9fc 17945+
537831f9 17946+ iinfo->ii_generation.ig_generation = au_sigen(sb);
5afbbe0d
AM
17947+ iinfo->ii_btop = -1;
17948+ iinfo->ii_bbot = -1;
4a4d8108
AM
17949+ iinfo->ii_vdir = NULL;
17950+ return 0;
1308ab2a 17951+ }
4a4d8108
AM
17952+ return -ENOMEM;
17953+}
1facf9fc 17954+
e2f27e51 17955+int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink)
4a4d8108 17956+{
5afbbe0d 17957+ int err, i;
4a4d8108 17958+ struct au_hinode *hip;
1facf9fc 17959+
4a4d8108
AM
17960+ AuRwMustWriteLock(&iinfo->ii_rwsem);
17961+
17962+ err = -ENOMEM;
e2f27e51
AM
17963+ hip = au_krealloc(iinfo->ii_hinode, sizeof(*hip) * nbr, GFP_NOFS,
17964+ may_shrink);
4a4d8108
AM
17965+ if (hip) {
17966+ iinfo->ii_hinode = hip;
5afbbe0d
AM
17967+ i = iinfo->ii_bbot + 1;
17968+ hip += i;
17969+ for (; i < nbr; i++, hip++)
17970+ au_hinode_init(hip);
4a4d8108 17971+ err = 0;
1308ab2a 17972+ }
4a4d8108 17973+
1308ab2a 17974+ return err;
1facf9fc 17975+}
17976+
4a4d8108 17977+void au_iinfo_fin(struct inode *inode)
1facf9fc 17978+{
4a4d8108
AM
17979+ struct au_iinfo *iinfo;
17980+ struct au_hinode *hi;
17981+ struct super_block *sb;
5afbbe0d 17982+ aufs_bindex_t bindex, bbot;
b752ccd1 17983+ const unsigned char unlinked = !inode->i_nlink;
1308ab2a 17984+
5afbbe0d 17985+ AuDebugOn(au_is_bad_inode(inode));
1308ab2a 17986+
b752ccd1 17987+ sb = inode->i_sb;
7f207e10 17988+ au_ninodes_dec(sb);
b752ccd1
AM
17989+ if (si_pid_test(sb))
17990+ au_xino_delete_inode(inode, unlinked);
17991+ else {
17992+ /*
17993+ * it is safe to hide the dependency between sbinfo and
17994+ * sb->s_umount.
17995+ */
17996+ lockdep_off();
17997+ si_noflush_read_lock(sb);
17998+ au_xino_delete_inode(inode, unlinked);
17999+ si_read_unlock(sb);
18000+ lockdep_on();
18001+ }
18002+
5afbbe0d 18003+ iinfo = au_ii(inode);
4a4d8108 18004+ if (iinfo->ii_vdir)
ae9dfd79 18005+ au_vdir_free(iinfo->ii_vdir);
1308ab2a 18006+
5afbbe0d 18007+ bindex = iinfo->ii_btop;
b752ccd1 18008+ if (bindex >= 0) {
5afbbe0d
AM
18009+ hi = au_hinode(iinfo, bindex);
18010+ bbot = iinfo->ii_bbot;
18011+ while (bindex++ <= bbot) {
b752ccd1 18012+ if (hi->hi_inode)
4a4d8108 18013+ au_hiput(hi);
4a4d8108
AM
18014+ hi++;
18015+ }
18016+ }
ae9dfd79 18017+ kfree(iinfo->ii_hinode);
4a4d8108 18018+ AuRwDestroy(&iinfo->ii_rwsem);
dece6358 18019+}
7f207e10
AM
18020diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
18021--- /usr/share/empty/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
18022+++ linux/fs/aufs/inode.c 2018-04-15 08:49:13.401150731 +0200
18023@@ -0,0 +1,527 @@
4a4d8108 18024+/*
ae9dfd79 18025+ * Copyright (C) 2005-2018 Junjiro R. Okajima
4a4d8108
AM
18026+ *
18027+ * This program, aufs is free software; you can redistribute it and/or modify
18028+ * it under the terms of the GNU General Public License as published by
18029+ * the Free Software Foundation; either version 2 of the License, or
18030+ * (at your option) any later version.
18031+ *
18032+ * This program is distributed in the hope that it will be useful,
18033+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18034+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18035+ * GNU General Public License for more details.
18036+ *
18037+ * You should have received a copy of the GNU General Public License
523b37e3 18038+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 18039+ */
1facf9fc 18040+
4a4d8108
AM
18041+/*
18042+ * inode functions
18043+ */
1facf9fc 18044+
4a4d8108 18045+#include "aufs.h"
1308ab2a 18046+
4a4d8108
AM
18047+struct inode *au_igrab(struct inode *inode)
18048+{
18049+ if (inode) {
18050+ AuDebugOn(!atomic_read(&inode->i_count));
027c5e7a 18051+ ihold(inode);
1facf9fc 18052+ }
4a4d8108
AM
18053+ return inode;
18054+}
1facf9fc 18055+
4a4d8108
AM
18056+static void au_refresh_hinode_attr(struct inode *inode, int do_version)
18057+{
18058+ au_cpup_attr_all(inode, /*force*/0);
537831f9 18059+ au_update_iigen(inode, /*half*/1);
4a4d8108
AM
18060+ if (do_version)
18061+ inode->i_version++;
dece6358 18062+}
1facf9fc 18063+
027c5e7a 18064+static int au_ii_refresh(struct inode *inode, int *update)
dece6358 18065+{
e2f27e51 18066+ int err, e, nbr;
027c5e7a 18067+ umode_t type;
4a4d8108 18068+ aufs_bindex_t bindex, new_bindex;
1308ab2a 18069+ struct super_block *sb;
4a4d8108 18070+ struct au_iinfo *iinfo;
027c5e7a 18071+ struct au_hinode *p, *q, tmp;
1facf9fc 18072+
5afbbe0d 18073+ AuDebugOn(au_is_bad_inode(inode));
4a4d8108 18074+ IiMustWriteLock(inode);
1facf9fc 18075+
027c5e7a 18076+ *update = 0;
4a4d8108 18077+ sb = inode->i_sb;
e2f27e51 18078+ nbr = au_sbbot(sb) + 1;
027c5e7a 18079+ type = inode->i_mode & S_IFMT;
4a4d8108 18080+ iinfo = au_ii(inode);
e2f27e51 18081+ err = au_hinode_realloc(iinfo, nbr, /*may_shrink*/0);
4a4d8108 18082+ if (unlikely(err))
1308ab2a 18083+ goto out;
1facf9fc 18084+
5afbbe0d
AM
18085+ AuDebugOn(iinfo->ii_btop < 0);
18086+ p = au_hinode(iinfo, iinfo->ii_btop);
18087+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot;
4a4d8108
AM
18088+ bindex++, p++) {
18089+ if (!p->hi_inode)
18090+ continue;
1facf9fc 18091+
027c5e7a 18092+ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT));
4a4d8108
AM
18093+ new_bindex = au_br_index(sb, p->hi_id);
18094+ if (new_bindex == bindex)
18095+ continue;
1facf9fc 18096+
4a4d8108 18097+ if (new_bindex < 0) {
027c5e7a 18098+ *update = 1;
4a4d8108
AM
18099+ au_hiput(p);
18100+ p->hi_inode = NULL;
18101+ continue;
1308ab2a 18102+ }
4a4d8108 18103+
5afbbe0d
AM
18104+ if (new_bindex < iinfo->ii_btop)
18105+ iinfo->ii_btop = new_bindex;
18106+ if (iinfo->ii_bbot < new_bindex)
18107+ iinfo->ii_bbot = new_bindex;
4a4d8108 18108+ /* swap two lower inode, and loop again */
5afbbe0d 18109+ q = au_hinode(iinfo, new_bindex);
4a4d8108
AM
18110+ tmp = *q;
18111+ *q = *p;
18112+ *p = tmp;
18113+ if (tmp.hi_inode) {
18114+ bindex--;
18115+ p--;
1308ab2a 18116+ }
18117+ }
4a4d8108 18118+ au_update_ibrange(inode, /*do_put_zero*/0);
e2f27e51 18119+ au_hinode_realloc(iinfo, nbr, /*may_shrink*/1); /* harmless if err */
4a4d8108
AM
18120+ e = au_dy_irefresh(inode);
18121+ if (unlikely(e && !err))
18122+ err = e;
1facf9fc 18123+
4f0767ce 18124+out:
027c5e7a
AM
18125+ AuTraceErr(err);
18126+ return err;
18127+}
18128+
b95c5147
AM
18129+void au_refresh_iop(struct inode *inode, int force_getattr)
18130+{
18131+ int type;
18132+ struct au_sbinfo *sbi = au_sbi(inode->i_sb);
18133+ const struct inode_operations *iop
18134+ = force_getattr ? aufs_iop : sbi->si_iop_array;
18135+
18136+ if (inode->i_op == iop)
18137+ return;
18138+
18139+ switch (inode->i_mode & S_IFMT) {
18140+ case S_IFDIR:
18141+ type = AuIop_DIR;
18142+ break;
18143+ case S_IFLNK:
18144+ type = AuIop_SYMLINK;
18145+ break;
18146+ default:
18147+ type = AuIop_OTHER;
18148+ break;
18149+ }
18150+
18151+ inode->i_op = iop + type;
18152+ /* unnecessary smp_wmb() */
18153+}
18154+
027c5e7a
AM
18155+int au_refresh_hinode_self(struct inode *inode)
18156+{
18157+ int err, update;
18158+
18159+ err = au_ii_refresh(inode, &update);
18160+ if (!err)
18161+ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
18162+
18163+ AuTraceErr(err);
4a4d8108
AM
18164+ return err;
18165+}
1facf9fc 18166+
4a4d8108
AM
18167+int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
18168+{
027c5e7a 18169+ int err, e, update;
4a4d8108 18170+ unsigned int flags;
027c5e7a 18171+ umode_t mode;
5afbbe0d 18172+ aufs_bindex_t bindex, bbot;
027c5e7a 18173+ unsigned char isdir;
4a4d8108
AM
18174+ struct au_hinode *p;
18175+ struct au_iinfo *iinfo;
1facf9fc 18176+
027c5e7a 18177+ err = au_ii_refresh(inode, &update);
4a4d8108
AM
18178+ if (unlikely(err))
18179+ goto out;
18180+
18181+ update = 0;
18182+ iinfo = au_ii(inode);
5afbbe0d 18183+ p = au_hinode(iinfo, iinfo->ii_btop);
027c5e7a
AM
18184+ mode = (inode->i_mode & S_IFMT);
18185+ isdir = S_ISDIR(mode);
4a4d8108 18186+ flags = au_hi_flags(inode, isdir);
5afbbe0d
AM
18187+ bbot = au_dbbot(dentry);
18188+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++) {
5527c038 18189+ struct inode *h_i, *h_inode;
4a4d8108
AM
18190+ struct dentry *h_d;
18191+
18192+ h_d = au_h_dptr(dentry, bindex);
5527c038 18193+ if (!h_d || d_is_negative(h_d))
4a4d8108
AM
18194+ continue;
18195+
5527c038
JR
18196+ h_inode = d_inode(h_d);
18197+ AuDebugOn(mode != (h_inode->i_mode & S_IFMT));
5afbbe0d 18198+ if (iinfo->ii_btop <= bindex && bindex <= iinfo->ii_bbot) {
4a4d8108
AM
18199+ h_i = au_h_iptr(inode, bindex);
18200+ if (h_i) {
5527c038 18201+ if (h_i == h_inode)
4a4d8108
AM
18202+ continue;
18203+ err = -EIO;
18204+ break;
18205+ }
18206+ }
5afbbe0d
AM
18207+ if (bindex < iinfo->ii_btop)
18208+ iinfo->ii_btop = bindex;
18209+ if (iinfo->ii_bbot < bindex)
18210+ iinfo->ii_bbot = bindex;
5527c038 18211+ au_set_h_iptr(inode, bindex, au_igrab(h_inode), flags);
4a4d8108 18212+ update = 1;
1308ab2a 18213+ }
4a4d8108
AM
18214+ au_update_ibrange(inode, /*do_put_zero*/0);
18215+ e = au_dy_irefresh(inode);
18216+ if (unlikely(e && !err))
18217+ err = e;
027c5e7a
AM
18218+ if (!err)
18219+ au_refresh_hinode_attr(inode, update && isdir);
4a4d8108 18220+
4f0767ce 18221+out:
4a4d8108 18222+ AuTraceErr(err);
1308ab2a 18223+ return err;
dece6358
AM
18224+}
18225+
4a4d8108 18226+static int set_inode(struct inode *inode, struct dentry *dentry)
dece6358 18227+{
4a4d8108
AM
18228+ int err;
18229+ unsigned int flags;
18230+ umode_t mode;
5afbbe0d 18231+ aufs_bindex_t bindex, btop, btail;
4a4d8108
AM
18232+ unsigned char isdir;
18233+ struct dentry *h_dentry;
18234+ struct inode *h_inode;
18235+ struct au_iinfo *iinfo;
b95c5147 18236+ struct inode_operations *iop;
dece6358 18237+
4a4d8108 18238+ IiMustWriteLock(inode);
dece6358 18239+
4a4d8108
AM
18240+ err = 0;
18241+ isdir = 0;
b95c5147 18242+ iop = au_sbi(inode->i_sb)->si_iop_array;
5afbbe0d
AM
18243+ btop = au_dbtop(dentry);
18244+ h_dentry = au_h_dptr(dentry, btop);
5527c038 18245+ h_inode = d_inode(h_dentry);
4a4d8108
AM
18246+ mode = h_inode->i_mode;
18247+ switch (mode & S_IFMT) {
18248+ case S_IFREG:
18249+ btail = au_dbtail(dentry);
b95c5147 18250+ inode->i_op = iop + AuIop_OTHER;
4a4d8108 18251+ inode->i_fop = &aufs_file_fop;
5afbbe0d 18252+ err = au_dy_iaop(inode, btop, h_inode);
4a4d8108
AM
18253+ if (unlikely(err))
18254+ goto out;
18255+ break;
18256+ case S_IFDIR:
18257+ isdir = 1;
18258+ btail = au_dbtaildir(dentry);
b95c5147 18259+ inode->i_op = iop + AuIop_DIR;
4a4d8108
AM
18260+ inode->i_fop = &aufs_dir_fop;
18261+ break;
18262+ case S_IFLNK:
18263+ btail = au_dbtail(dentry);
b95c5147 18264+ inode->i_op = iop + AuIop_SYMLINK;
4a4d8108
AM
18265+ break;
18266+ case S_IFBLK:
18267+ case S_IFCHR:
18268+ case S_IFIFO:
18269+ case S_IFSOCK:
18270+ btail = au_dbtail(dentry);
b95c5147 18271+ inode->i_op = iop + AuIop_OTHER;
38d290e6 18272+ init_special_inode(inode, mode, h_inode->i_rdev);
4a4d8108
AM
18273+ break;
18274+ default:
18275+ AuIOErr("Unknown file type 0%o\n", mode);
18276+ err = -EIO;
1308ab2a 18277+ goto out;
4a4d8108 18278+ }
dece6358 18279+
4a4d8108
AM
18280+ /* do not set hnotify for whiteouted dirs (SHWH mode) */
18281+ flags = au_hi_flags(inode, isdir);
18282+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
18283+ && au_ftest_hi(flags, HNOTIFY)
18284+ && dentry->d_name.len > AUFS_WH_PFX_LEN
18285+ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
18286+ au_fclr_hi(flags, HNOTIFY);
18287+ iinfo = au_ii(inode);
5afbbe0d
AM
18288+ iinfo->ii_btop = btop;
18289+ iinfo->ii_bbot = btail;
18290+ for (bindex = btop; bindex <= btail; bindex++) {
4a4d8108
AM
18291+ h_dentry = au_h_dptr(dentry, bindex);
18292+ if (h_dentry)
18293+ au_set_h_iptr(inode, bindex,
5527c038 18294+ au_igrab(d_inode(h_dentry)), flags);
4a4d8108
AM
18295+ }
18296+ au_cpup_attr_all(inode, /*force*/1);
c1595e42
JR
18297+ /*
18298+ * to force calling aufs_get_acl() every time,
18299+ * do not call cache_no_acl() for aufs inode.
18300+ */
dece6358 18301+
4f0767ce 18302+out:
4a4d8108
AM
18303+ return err;
18304+}
dece6358 18305+
027c5e7a
AM
18306+/*
18307+ * successful returns with iinfo write_locked
18308+ * minus: errno
18309+ * zero: success, matched
18310+ * plus: no error, but unmatched
18311+ */
18312+static int reval_inode(struct inode *inode, struct dentry *dentry)
4a4d8108
AM
18313+{
18314+ int err;
cfc41e69 18315+ unsigned int gen, igflags;
5afbbe0d 18316+ aufs_bindex_t bindex, bbot;
4a4d8108 18317+ struct inode *h_inode, *h_dinode;
5527c038 18318+ struct dentry *h_dentry;
dece6358 18319+
4a4d8108
AM
18320+ /*
18321+ * before this function, if aufs got any iinfo lock, it must be only
18322+ * one, the parent dir.
18323+ * it can happen by UDBA and the obsoleted inode number.
18324+ */
18325+ err = -EIO;
18326+ if (unlikely(inode->i_ino == parent_ino(dentry)))
18327+ goto out;
18328+
027c5e7a 18329+ err = 1;
4a4d8108 18330+ ii_write_lock_new_child(inode);
5afbbe0d 18331+ h_dentry = au_h_dptr(dentry, au_dbtop(dentry));
5527c038 18332+ h_dinode = d_inode(h_dentry);
5afbbe0d
AM
18333+ bbot = au_ibbot(inode);
18334+ for (bindex = au_ibtop(inode); bindex <= bbot; bindex++) {
4a4d8108 18335+ h_inode = au_h_iptr(inode, bindex);
537831f9
AM
18336+ if (!h_inode || h_inode != h_dinode)
18337+ continue;
18338+
18339+ err = 0;
cfc41e69 18340+ gen = au_iigen(inode, &igflags);
537831f9 18341+ if (gen == au_digen(dentry)
cfc41e69 18342+ && !au_ig_ftest(igflags, HALF_REFRESHED))
4a4d8108 18343+ break;
537831f9
AM
18344+
18345+ /* fully refresh inode using dentry */
18346+ err = au_refresh_hinode(inode, dentry);
18347+ if (!err)
18348+ au_update_iigen(inode, /*half*/0);
18349+ break;
1facf9fc 18350+ }
dece6358 18351+
4a4d8108
AM
18352+ if (unlikely(err))
18353+ ii_write_unlock(inode);
4f0767ce 18354+out:
1facf9fc 18355+ return err;
18356+}
1facf9fc 18357+
4a4d8108
AM
18358+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
18359+ unsigned int d_type, ino_t *ino)
1facf9fc 18360+{
ae9dfd79
AM
18361+ int err, idx;
18362+ const int isnondir = d_type != DT_DIR;
1facf9fc 18363+
b752ccd1 18364+ /* prevent hardlinked inode number from race condition */
ae9dfd79
AM
18365+ if (isnondir) {
18366+ err = au_xinondir_enter(sb, bindex, h_ino, &idx);
18367+ if (unlikely(err))
18368+ goto out;
4a4d8108 18369+ }
ae9dfd79 18370+
4a4d8108
AM
18371+ err = au_xino_read(sb, bindex, h_ino, ino);
18372+ if (unlikely(err))
ae9dfd79 18373+ goto out_xinondir;
1308ab2a 18374+
4a4d8108
AM
18375+ if (!*ino) {
18376+ err = -EIO;
18377+ *ino = au_xino_new_ino(sb);
18378+ if (unlikely(!*ino))
ae9dfd79 18379+ goto out_xinondir;
4a4d8108
AM
18380+ err = au_xino_write(sb, bindex, h_ino, *ino);
18381+ if (unlikely(err))
ae9dfd79 18382+ goto out_xinondir;
1308ab2a 18383+ }
1facf9fc 18384+
ae9dfd79
AM
18385+out_xinondir:
18386+ if (isnondir && idx >= 0)
18387+ au_xinondir_leave(sb, bindex, h_ino, idx);
4f0767ce 18388+out:
1facf9fc 18389+ return err;
18390+}
18391+
4a4d8108
AM
18392+/* successful returns with iinfo write_locked */
18393+/* todo: return with unlocked? */
18394+struct inode *au_new_inode(struct dentry *dentry, int must_new)
1facf9fc 18395+{
5527c038 18396+ struct inode *inode, *h_inode;
4a4d8108
AM
18397+ struct dentry *h_dentry;
18398+ struct super_block *sb;
18399+ ino_t h_ino, ino;
ae9dfd79 18400+ int err, idx, hlinked;
5afbbe0d 18401+ aufs_bindex_t btop;
1facf9fc 18402+
4a4d8108 18403+ sb = dentry->d_sb;
5afbbe0d
AM
18404+ btop = au_dbtop(dentry);
18405+ h_dentry = au_h_dptr(dentry, btop);
5527c038
JR
18406+ h_inode = d_inode(h_dentry);
18407+ h_ino = h_inode->i_ino;
ae9dfd79 18408+ hlinked = !d_is_dir(h_dentry) && h_inode->i_nlink > 1;
b752ccd1 18409+
ae9dfd79 18410+new_ino:
b752ccd1
AM
18411+ /*
18412+ * stop 'race'-ing between hardlinks under different
18413+ * parents.
18414+ */
ae9dfd79
AM
18415+ if (hlinked) {
18416+ err = au_xinondir_enter(sb, btop, h_ino, &idx);
18417+ inode = ERR_PTR(err);
18418+ if (unlikely(err))
18419+ goto out;
18420+ }
b752ccd1 18421+
5afbbe0d 18422+ err = au_xino_read(sb, btop, h_ino, &ino);
4a4d8108
AM
18423+ inode = ERR_PTR(err);
18424+ if (unlikely(err))
ae9dfd79 18425+ goto out_xinondir;
b752ccd1 18426+
4a4d8108
AM
18427+ if (!ino) {
18428+ ino = au_xino_new_ino(sb);
18429+ if (unlikely(!ino)) {
18430+ inode = ERR_PTR(-EIO);
ae9dfd79 18431+ goto out_xinondir;
dece6358
AM
18432+ }
18433+ }
1facf9fc 18434+
4a4d8108
AM
18435+ AuDbg("i%lu\n", (unsigned long)ino);
18436+ inode = au_iget_locked(sb, ino);
18437+ err = PTR_ERR(inode);
18438+ if (IS_ERR(inode))
ae9dfd79 18439+ goto out_xinondir;
1facf9fc 18440+
4a4d8108
AM
18441+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
18442+ if (inode->i_state & I_NEW) {
18443+ ii_write_lock_new_child(inode);
18444+ err = set_inode(inode, dentry);
18445+ if (!err) {
18446+ unlock_new_inode(inode);
ae9dfd79 18447+ goto out_xinondir; /* success */
4a4d8108 18448+ }
1308ab2a 18449+
027c5e7a
AM
18450+ /*
18451+ * iget_failed() calls iput(), but we need to call
18452+ * ii_write_unlock() after iget_failed(). so dirty hack for
18453+ * i_count.
18454+ */
18455+ atomic_inc(&inode->i_count);
4a4d8108 18456+ iget_failed(inode);
027c5e7a 18457+ ii_write_unlock(inode);
5afbbe0d 18458+ au_xino_write(sb, btop, h_ino, /*ino*/0);
027c5e7a
AM
18459+ /* ignore this error */
18460+ goto out_iput;
18461+ } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) {
b752ccd1
AM
18462+ /*
18463+ * horrible race condition between lookup, readdir and copyup
18464+ * (or something).
18465+ */
ae9dfd79
AM
18466+ if (hlinked && idx >= 0)
18467+ au_xinondir_leave(sb, btop, h_ino, idx);
027c5e7a
AM
18468+ err = reval_inode(inode, dentry);
18469+ if (unlikely(err < 0)) {
ae9dfd79 18470+ hlinked = 0;
027c5e7a
AM
18471+ goto out_iput;
18472+ }
ae9dfd79 18473+ if (!err)
4a4d8108 18474+ goto out; /* success */
ae9dfd79
AM
18475+ else if (hlinked && idx >= 0) {
18476+ err = au_xinondir_enter(sb, btop, h_ino, &idx);
18477+ if (unlikely(err)) {
18478+ iput(inode);
18479+ inode = ERR_PTR(err);
18480+ goto out;
18481+ }
18482+ }
4a4d8108
AM
18483+ }
18484+
5527c038 18485+ if (unlikely(au_test_fs_unique_ino(h_inode)))
4a4d8108 18486+ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
523b37e3 18487+ " b%d, %s, %pd, hi%lu, i%lu.\n",
5afbbe0d 18488+ btop, au_sbtype(h_dentry->d_sb), dentry,
4a4d8108
AM
18489+ (unsigned long)h_ino, (unsigned long)ino);
18490+ ino = 0;
5afbbe0d 18491+ err = au_xino_write(sb, btop, h_ino, /*ino*/0);
4a4d8108
AM
18492+ if (!err) {
18493+ iput(inode);
ae9dfd79
AM
18494+ if (hlinked && idx >= 0)
18495+ au_xinondir_leave(sb, btop, h_ino, idx);
4a4d8108
AM
18496+ goto new_ino;
18497+ }
1308ab2a 18498+
4f0767ce 18499+out_iput:
4a4d8108 18500+ iput(inode);
4a4d8108 18501+ inode = ERR_PTR(err);
ae9dfd79
AM
18502+out_xinondir:
18503+ if (hlinked && idx >= 0)
18504+ au_xinondir_leave(sb, btop, h_ino, idx);
4f0767ce 18505+out:
4a4d8108 18506+ return inode;
1facf9fc 18507+}
18508+
4a4d8108 18509+/* ---------------------------------------------------------------------- */
1facf9fc 18510+
4a4d8108
AM
18511+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
18512+ struct inode *inode)
18513+{
18514+ int err;
076b876e 18515+ struct inode *hi;
1facf9fc 18516+
4a4d8108 18517+ err = au_br_rdonly(au_sbr(sb, bindex));
1facf9fc 18518+
4a4d8108
AM
18519+ /* pseudo-link after flushed may happen out of bounds */
18520+ if (!err
18521+ && inode
5afbbe0d
AM
18522+ && au_ibtop(inode) <= bindex
18523+ && bindex <= au_ibbot(inode)) {
4a4d8108
AM
18524+ /*
18525+ * permission check is unnecessary since vfsub routine
18526+ * will be called later
18527+ */
076b876e 18528+ hi = au_h_iptr(inode, bindex);
4a4d8108
AM
18529+ if (hi)
18530+ err = IS_IMMUTABLE(hi) ? -EROFS : 0;
1facf9fc 18531+ }
18532+
4a4d8108
AM
18533+ return err;
18534+}
dece6358 18535+
4a4d8108
AM
18536+int au_test_h_perm(struct inode *h_inode, int mask)
18537+{
2dfbb274 18538+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
4a4d8108
AM
18539+ return 0;
18540+ return inode_permission(h_inode, mask);
18541+}
1facf9fc 18542+
4a4d8108
AM
18543+int au_test_h_perm_sio(struct inode *h_inode, int mask)
18544+{
18545+ if (au_test_nfs(h_inode->i_sb)
18546+ && (mask & MAY_WRITE)
18547+ && S_ISDIR(h_inode->i_mode))
18548+ mask |= MAY_READ; /* force permission check */
18549+ return au_test_h_perm(h_inode, mask);
1facf9fc 18550+}
7f207e10
AM
18551diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
18552--- /usr/share/empty/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
18553+++ linux/fs/aufs/inode.h 2018-04-15 08:49:13.401150731 +0200
18554@@ -0,0 +1,696 @@
4a4d8108 18555+/*
ae9dfd79 18556+ * Copyright (C) 2005-2018 Junjiro R. Okajima
4a4d8108
AM
18557+ *
18558+ * This program, aufs is free software; you can redistribute it and/or modify
18559+ * it under the terms of the GNU General Public License as published by
18560+ * the Free Software Foundation; either version 2 of the License, or
18561+ * (at your option) any later version.
18562+ *
18563+ * This program is distributed in the hope that it will be useful,
18564+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18565+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18566+ * GNU General Public License for more details.
18567+ *
18568+ * You should have received a copy of the GNU General Public License
523b37e3 18569+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 18570+ */
1facf9fc 18571+
1308ab2a 18572+/*
4a4d8108 18573+ * inode operations
1308ab2a 18574+ */
dece6358 18575+
4a4d8108
AM
18576+#ifndef __AUFS_INODE_H__
18577+#define __AUFS_INODE_H__
dece6358 18578+
4a4d8108 18579+#ifdef __KERNEL__
1308ab2a 18580+
4a4d8108 18581+#include <linux/fsnotify.h>
4a4d8108 18582+#include "rwsem.h"
1308ab2a 18583+
4a4d8108 18584+struct vfsmount;
1facf9fc 18585+
4a4d8108
AM
18586+struct au_hnotify {
18587+#ifdef CONFIG_AUFS_HNOTIFY
18588+#ifdef CONFIG_AUFS_HFSNOTIFY
7f207e10 18589+ /* never use fsnotify_add_vfsmount_mark() */
0c5527e5 18590+ struct fsnotify_mark hn_mark;
4a4d8108 18591+#endif
ae9dfd79 18592+ struct inode *hn_aufs_inode; /* no get/put */
4a4d8108
AM
18593+#endif
18594+} ____cacheline_aligned_in_smp;
1facf9fc 18595+
4a4d8108
AM
18596+struct au_hinode {
18597+ struct inode *hi_inode;
18598+ aufs_bindex_t hi_id;
18599+#ifdef CONFIG_AUFS_HNOTIFY
18600+ struct au_hnotify *hi_notify;
18601+#endif
dece6358 18602+
4a4d8108
AM
18603+ /* reference to the copied-up whiteout with get/put */
18604+ struct dentry *hi_whdentry;
18605+};
dece6358 18606+
537831f9
AM
18607+/* ig_flags */
18608+#define AuIG_HALF_REFRESHED 1
18609+#define au_ig_ftest(flags, name) ((flags) & AuIG_##name)
18610+#define au_ig_fset(flags, name) \
18611+ do { (flags) |= AuIG_##name; } while (0)
18612+#define au_ig_fclr(flags, name) \
18613+ do { (flags) &= ~AuIG_##name; } while (0)
18614+
18615+struct au_iigen {
be52b249 18616+ spinlock_t ig_spin;
537831f9
AM
18617+ __u32 ig_generation, ig_flags;
18618+};
18619+
4a4d8108
AM
18620+struct au_vdir;
18621+struct au_iinfo {
7a9e40b8 18622+ struct au_iigen ii_generation;
4a4d8108 18623+ struct super_block *ii_hsb1; /* no get/put */
1facf9fc 18624+
4a4d8108 18625+ struct au_rwsem ii_rwsem;
5afbbe0d 18626+ aufs_bindex_t ii_btop, ii_bbot;
4a4d8108
AM
18627+ __u32 ii_higen;
18628+ struct au_hinode *ii_hinode;
18629+ struct au_vdir *ii_vdir;
18630+};
1facf9fc 18631+
4a4d8108
AM
18632+struct au_icntnr {
18633+ struct au_iinfo iinfo;
18634+ struct inode vfs_inode;
ae9dfd79 18635+ struct hlist_bl_node plink;
4a4d8108 18636+} ____cacheline_aligned_in_smp;
1308ab2a 18637+
4a4d8108
AM
18638+/* au_pin flags */
18639+#define AuPin_DI_LOCKED 1
18640+#define AuPin_MNT_WRITE (1 << 1)
18641+#define au_ftest_pin(flags, name) ((flags) & AuPin_##name)
7f207e10
AM
18642+#define au_fset_pin(flags, name) \
18643+ do { (flags) |= AuPin_##name; } while (0)
18644+#define au_fclr_pin(flags, name) \
18645+ do { (flags) &= ~AuPin_##name; } while (0)
4a4d8108
AM
18646+
18647+struct au_pin {
18648+ /* input */
18649+ struct dentry *dentry;
18650+ unsigned int udba;
18651+ unsigned char lsc_di, lsc_hi, flags;
18652+ aufs_bindex_t bindex;
18653+
18654+ /* output */
18655+ struct dentry *parent;
18656+ struct au_hinode *hdir;
18657+ struct vfsmount *h_mnt;
86dc4139
AM
18658+
18659+ /* temporary unlock/relock for copyup */
18660+ struct dentry *h_dentry, *h_parent;
18661+ struct au_branch *br;
18662+ struct task_struct *task;
4a4d8108 18663+};
1facf9fc 18664+
86dc4139 18665+void au_pin_hdir_unlock(struct au_pin *p);
c1595e42 18666+int au_pin_hdir_lock(struct au_pin *p);
86dc4139 18667+int au_pin_hdir_relock(struct au_pin *p);
86dc4139
AM
18668+void au_pin_hdir_acquire_nest(struct au_pin *p);
18669+void au_pin_hdir_release(struct au_pin *p);
18670+
1308ab2a 18671+/* ---------------------------------------------------------------------- */
18672+
4a4d8108 18673+static inline struct au_iinfo *au_ii(struct inode *inode)
1facf9fc 18674+{
5afbbe0d
AM
18675+ BUG_ON(is_bad_inode(inode));
18676+ return &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
4a4d8108 18677+}
1facf9fc 18678+
4a4d8108 18679+/* ---------------------------------------------------------------------- */
1facf9fc 18680+
4a4d8108
AM
18681+/* inode.c */
18682+struct inode *au_igrab(struct inode *inode);
b95c5147 18683+void au_refresh_iop(struct inode *inode, int force_getattr);
027c5e7a 18684+int au_refresh_hinode_self(struct inode *inode);
4a4d8108
AM
18685+int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
18686+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
18687+ unsigned int d_type, ino_t *ino);
18688+struct inode *au_new_inode(struct dentry *dentry, int must_new);
18689+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
18690+ struct inode *inode);
18691+int au_test_h_perm(struct inode *h_inode, int mask);
18692+int au_test_h_perm_sio(struct inode *h_inode, int mask);
1facf9fc 18693+
4a4d8108
AM
18694+static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex,
18695+ ino_t h_ino, unsigned int d_type, ino_t *ino)
18696+{
18697+#ifdef CONFIG_AUFS_SHWH
18698+ return au_ino(sb, bindex, h_ino, d_type, ino);
18699+#else
18700+ return 0;
18701+#endif
18702+}
1facf9fc 18703+
4a4d8108 18704+/* i_op.c */
b95c5147
AM
18705+enum {
18706+ AuIop_SYMLINK,
18707+ AuIop_DIR,
18708+ AuIop_OTHER,
18709+ AuIop_Last
18710+};
18711+extern struct inode_operations aufs_iop[AuIop_Last],
18712+ aufs_iop_nogetattr[AuIop_Last];
1308ab2a 18713+
4a4d8108
AM
18714+/* au_wr_dir flags */
18715+#define AuWrDir_ADD_ENTRY 1
7e9cd9fe
AM
18716+#define AuWrDir_ISDIR (1 << 1)
18717+#define AuWrDir_TMPFILE (1 << 2)
4a4d8108 18718+#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
7f207e10
AM
18719+#define au_fset_wrdir(flags, name) \
18720+ do { (flags) |= AuWrDir_##name; } while (0)
18721+#define au_fclr_wrdir(flags, name) \
18722+ do { (flags) &= ~AuWrDir_##name; } while (0)
1facf9fc 18723+
4a4d8108
AM
18724+struct au_wr_dir_args {
18725+ aufs_bindex_t force_btgt;
18726+ unsigned char flags;
18727+};
18728+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
18729+ struct au_wr_dir_args *args);
dece6358 18730+
4a4d8108
AM
18731+struct dentry *au_pinned_h_parent(struct au_pin *pin);
18732+void au_pin_init(struct au_pin *pin, struct dentry *dentry,
18733+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
18734+ unsigned int udba, unsigned char flags);
18735+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
18736+ unsigned int udba, unsigned char flags) __must_check;
18737+int au_do_pin(struct au_pin *pin) __must_check;
18738+void au_unpin(struct au_pin *pin);
c1595e42
JR
18739+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen);
18740+
18741+#define AuIcpup_DID_CPUP 1
18742+#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
18743+#define au_fset_icpup(flags, name) \
18744+ do { (flags) |= AuIcpup_##name; } while (0)
18745+#define au_fclr_icpup(flags, name) \
18746+ do { (flags) &= ~AuIcpup_##name; } while (0)
18747+
18748+struct au_icpup_args {
18749+ unsigned char flags;
18750+ unsigned char pin_flags;
18751+ aufs_bindex_t btgt;
18752+ unsigned int udba;
18753+ struct au_pin pin;
18754+ struct path h_path;
18755+ struct inode *h_inode;
18756+};
18757+
18758+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
18759+ struct au_icpup_args *a);
18760+
ae9dfd79
AM
18761+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path,
18762+ int locked);
1facf9fc 18763+
4a4d8108
AM
18764+/* i_op_add.c */
18765+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
18766+ struct dentry *h_parent, int isdir);
7eafdf33
AM
18767+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
18768+ dev_t dev);
4a4d8108 18769+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
7eafdf33 18770+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 18771+ bool want_excl);
b912730e
AM
18772+struct vfsub_aopen_args;
18773+int au_aopen_or_create(struct inode *dir, struct dentry *dentry,
18774+ struct vfsub_aopen_args *args);
38d290e6 18775+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode);
4a4d8108
AM
18776+int aufs_link(struct dentry *src_dentry, struct inode *dir,
18777+ struct dentry *dentry);
7eafdf33 18778+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
1facf9fc 18779+
4a4d8108
AM
18780+/* i_op_del.c */
18781+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
18782+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
18783+ struct dentry *h_parent, int isdir);
18784+int aufs_unlink(struct inode *dir, struct dentry *dentry);
18785+int aufs_rmdir(struct inode *dir, struct dentry *dentry);
1308ab2a 18786+
4a4d8108
AM
18787+/* i_op_ren.c */
18788+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
18789+int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
f2c43d5f
AM
18790+ struct inode *dir, struct dentry *dentry,
18791+ unsigned int flags);
1facf9fc 18792+
4a4d8108
AM
18793+/* iinfo.c */
18794+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
18795+void au_hiput(struct au_hinode *hinode);
18796+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
18797+ struct dentry *h_wh);
18798+unsigned int au_hi_flags(struct inode *inode, int isdir);
1308ab2a 18799+
4a4d8108
AM
18800+/* hinode flags */
18801+#define AuHi_XINO 1
18802+#define AuHi_HNOTIFY (1 << 1)
18803+#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
7f207e10
AM
18804+#define au_fset_hi(flags, name) \
18805+ do { (flags) |= AuHi_##name; } while (0)
18806+#define au_fclr_hi(flags, name) \
18807+ do { (flags) &= ~AuHi_##name; } while (0)
1facf9fc 18808+
4a4d8108
AM
18809+#ifndef CONFIG_AUFS_HNOTIFY
18810+#undef AuHi_HNOTIFY
18811+#define AuHi_HNOTIFY 0
18812+#endif
1facf9fc 18813+
4a4d8108
AM
18814+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
18815+ struct inode *h_inode, unsigned int flags);
1facf9fc 18816+
537831f9 18817+void au_update_iigen(struct inode *inode, int half);
4a4d8108 18818+void au_update_ibrange(struct inode *inode, int do_put_zero);
1facf9fc 18819+
4a4d8108 18820+void au_icntnr_init_once(void *_c);
5afbbe0d 18821+void au_hinode_init(struct au_hinode *hinode);
4a4d8108
AM
18822+int au_iinfo_init(struct inode *inode);
18823+void au_iinfo_fin(struct inode *inode);
e2f27e51 18824+int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink);
1308ab2a 18825+
e49829fe 18826+#ifdef CONFIG_PROC_FS
4a4d8108 18827+/* plink.c */
e49829fe 18828+int au_plink_maint(struct super_block *sb, int flags);
7e9cd9fe 18829+struct au_sbinfo;
e49829fe
JR
18830+void au_plink_maint_leave(struct au_sbinfo *sbinfo);
18831+int au_plink_maint_enter(struct super_block *sb);
4a4d8108
AM
18832+#ifdef CONFIG_AUFS_DEBUG
18833+void au_plink_list(struct super_block *sb);
18834+#else
18835+AuStubVoid(au_plink_list, struct super_block *sb)
18836+#endif
18837+int au_plink_test(struct inode *inode);
18838+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
18839+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
18840+ struct dentry *h_dentry);
e49829fe
JR
18841+void au_plink_put(struct super_block *sb, int verbose);
18842+void au_plink_clean(struct super_block *sb, int verbose);
4a4d8108 18843+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
e49829fe
JR
18844+#else
18845+AuStubInt0(au_plink_maint, struct super_block *sb, int flags);
18846+AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo);
18847+AuStubInt0(au_plink_maint_enter, struct super_block *sb);
18848+AuStubVoid(au_plink_list, struct super_block *sb);
18849+AuStubInt0(au_plink_test, struct inode *inode);
18850+AuStub(struct dentry *, au_plink_lkup, return NULL,
18851+ struct inode *inode, aufs_bindex_t bindex);
18852+AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex,
18853+ struct dentry *h_dentry);
18854+AuStubVoid(au_plink_put, struct super_block *sb, int verbose);
18855+AuStubVoid(au_plink_clean, struct super_block *sb, int verbose);
18856+AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id);
18857+#endif /* CONFIG_PROC_FS */
1facf9fc 18858+
c1595e42
JR
18859+#ifdef CONFIG_AUFS_XATTR
18860+/* xattr.c */
7e9cd9fe
AM
18861+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags,
18862+ unsigned int verbose);
c1595e42 18863+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size);
f2c43d5f 18864+void au_xattr_init(struct super_block *sb);
c1595e42
JR
18865+#else
18866+AuStubInt0(au_cpup_xattr, struct dentry *h_dst, struct dentry *h_src,
7e9cd9fe 18867+ int ignore_flags, unsigned int verbose);
f2c43d5f 18868+AuStubVoid(au_xattr_init, struct super_block *sb);
c1595e42
JR
18869+#endif
18870+
18871+#ifdef CONFIG_FS_POSIX_ACL
18872+struct posix_acl *aufs_get_acl(struct inode *inode, int type);
18873+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
18874+#endif
18875+
18876+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
18877+enum {
18878+ AU_XATTR_SET,
c1595e42
JR
18879+ AU_ACL_SET
18880+};
18881+
f2c43d5f 18882+struct au_sxattr {
c1595e42
JR
18883+ int type;
18884+ union {
18885+ struct {
18886+ const char *name;
18887+ const void *value;
18888+ size_t size;
18889+ int flags;
18890+ } set;
18891+ struct {
c1595e42
JR
18892+ struct posix_acl *acl;
18893+ int type;
18894+ } acl_set;
18895+ } u;
18896+};
f2c43d5f
AM
18897+ssize_t au_sxattr(struct dentry *dentry, struct inode *inode,
18898+ struct au_sxattr *arg);
c1595e42
JR
18899+#endif
18900+
4a4d8108 18901+/* ---------------------------------------------------------------------- */
1308ab2a 18902+
4a4d8108
AM
18903+/* lock subclass for iinfo */
18904+enum {
18905+ AuLsc_II_CHILD, /* child first */
18906+ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */
18907+ AuLsc_II_CHILD3, /* copyup dirs */
18908+ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
18909+ AuLsc_II_PARENT2,
18910+ AuLsc_II_PARENT3, /* copyup dirs */
18911+ AuLsc_II_NEW_CHILD
18912+};
1308ab2a 18913+
1facf9fc 18914+/*
4a4d8108
AM
18915+ * ii_read_lock_child, ii_write_lock_child,
18916+ * ii_read_lock_child2, ii_write_lock_child2,
18917+ * ii_read_lock_child3, ii_write_lock_child3,
18918+ * ii_read_lock_parent, ii_write_lock_parent,
18919+ * ii_read_lock_parent2, ii_write_lock_parent2,
18920+ * ii_read_lock_parent3, ii_write_lock_parent3,
18921+ * ii_read_lock_new_child, ii_write_lock_new_child,
1facf9fc 18922+ */
4a4d8108
AM
18923+#define AuReadLockFunc(name, lsc) \
18924+static inline void ii_read_lock_##name(struct inode *i) \
18925+{ \
18926+ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
18927+}
18928+
18929+#define AuWriteLockFunc(name, lsc) \
18930+static inline void ii_write_lock_##name(struct inode *i) \
18931+{ \
18932+ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
18933+}
18934+
18935+#define AuRWLockFuncs(name, lsc) \
18936+ AuReadLockFunc(name, lsc) \
18937+ AuWriteLockFunc(name, lsc)
18938+
18939+AuRWLockFuncs(child, CHILD);
18940+AuRWLockFuncs(child2, CHILD2);
18941+AuRWLockFuncs(child3, CHILD3);
18942+AuRWLockFuncs(parent, PARENT);
18943+AuRWLockFuncs(parent2, PARENT2);
18944+AuRWLockFuncs(parent3, PARENT3);
18945+AuRWLockFuncs(new_child, NEW_CHILD);
18946+
18947+#undef AuReadLockFunc
18948+#undef AuWriteLockFunc
18949+#undef AuRWLockFuncs
1facf9fc 18950+
18951+/*
4a4d8108 18952+ * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
1facf9fc 18953+ */
4a4d8108 18954+AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
1facf9fc 18955+
4a4d8108
AM
18956+#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
18957+#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
18958+#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
1facf9fc 18959+
4a4d8108 18960+/* ---------------------------------------------------------------------- */
1308ab2a 18961+
027c5e7a
AM
18962+static inline void au_icntnr_init(struct au_icntnr *c)
18963+{
18964+#ifdef CONFIG_AUFS_DEBUG
18965+ c->vfs_inode.i_mode = 0;
18966+#endif
18967+}
18968+
cfc41e69 18969+static inline unsigned int au_iigen(struct inode *inode, unsigned int *igflags)
4a4d8108 18970+{
537831f9
AM
18971+ unsigned int gen;
18972+ struct au_iinfo *iinfo;
be52b249 18973+ struct au_iigen *iigen;
537831f9
AM
18974+
18975+ iinfo = au_ii(inode);
be52b249
AM
18976+ iigen = &iinfo->ii_generation;
18977+ spin_lock(&iigen->ig_spin);
cfc41e69
AM
18978+ if (igflags)
18979+ *igflags = iigen->ig_flags;
be52b249
AM
18980+ gen = iigen->ig_generation;
18981+ spin_unlock(&iigen->ig_spin);
537831f9
AM
18982+
18983+ return gen;
4a4d8108 18984+}
1308ab2a 18985+
4a4d8108
AM
18986+/* tiny test for inode number */
18987+/* tmpfs generation is too rough */
18988+static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
18989+{
18990+ struct au_iinfo *iinfo;
1308ab2a 18991+
4a4d8108
AM
18992+ iinfo = au_ii(inode);
18993+ AuRwMustAnyLock(&iinfo->ii_rwsem);
18994+ return !(iinfo->ii_hsb1 == h_inode->i_sb
18995+ && iinfo->ii_higen == h_inode->i_generation);
18996+}
1308ab2a 18997+
4a4d8108
AM
18998+static inline void au_iigen_dec(struct inode *inode)
18999+{
537831f9 19000+ struct au_iinfo *iinfo;
be52b249 19001+ struct au_iigen *iigen;
537831f9
AM
19002+
19003+ iinfo = au_ii(inode);
be52b249
AM
19004+ iigen = &iinfo->ii_generation;
19005+ spin_lock(&iigen->ig_spin);
19006+ iigen->ig_generation--;
19007+ spin_unlock(&iigen->ig_spin);
027c5e7a
AM
19008+}
19009+
19010+static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
19011+{
19012+ int err;
19013+
19014+ err = 0;
537831f9 19015+ if (unlikely(inode && au_iigen(inode, NULL) != sigen))
027c5e7a
AM
19016+ err = -EIO;
19017+
19018+ return err;
4a4d8108 19019+}
1308ab2a 19020+
4a4d8108 19021+/* ---------------------------------------------------------------------- */
1308ab2a 19022+
5afbbe0d
AM
19023+static inline struct au_hinode *au_hinode(struct au_iinfo *iinfo,
19024+ aufs_bindex_t bindex)
19025+{
19026+ return iinfo->ii_hinode + bindex;
19027+}
19028+
19029+static inline int au_is_bad_inode(struct inode *inode)
19030+{
19031+ return !!(is_bad_inode(inode) || !au_hinode(au_ii(inode), 0));
19032+}
19033+
4a4d8108
AM
19034+static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
19035+ aufs_bindex_t bindex)
19036+{
19037+ IiMustAnyLock(inode);
5afbbe0d 19038+ return au_hinode(au_ii(inode), bindex)->hi_id;
4a4d8108 19039+}
1308ab2a 19040+
5afbbe0d 19041+static inline aufs_bindex_t au_ibtop(struct inode *inode)
4a4d8108
AM
19042+{
19043+ IiMustAnyLock(inode);
5afbbe0d 19044+ return au_ii(inode)->ii_btop;
4a4d8108 19045+}
1308ab2a 19046+
5afbbe0d 19047+static inline aufs_bindex_t au_ibbot(struct inode *inode)
4a4d8108
AM
19048+{
19049+ IiMustAnyLock(inode);
5afbbe0d 19050+ return au_ii(inode)->ii_bbot;
4a4d8108 19051+}
1308ab2a 19052+
4a4d8108
AM
19053+static inline struct au_vdir *au_ivdir(struct inode *inode)
19054+{
19055+ IiMustAnyLock(inode);
19056+ return au_ii(inode)->ii_vdir;
19057+}
1308ab2a 19058+
4a4d8108
AM
19059+static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
19060+{
19061+ IiMustAnyLock(inode);
5afbbe0d 19062+ return au_hinode(au_ii(inode), bindex)->hi_whdentry;
4a4d8108 19063+}
1308ab2a 19064+
5afbbe0d 19065+static inline void au_set_ibtop(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 19066+{
4a4d8108 19067+ IiMustWriteLock(inode);
5afbbe0d 19068+ au_ii(inode)->ii_btop = bindex;
4a4d8108 19069+}
1308ab2a 19070+
5afbbe0d 19071+static inline void au_set_ibbot(struct inode *inode, aufs_bindex_t bindex)
4a4d8108
AM
19072+{
19073+ IiMustWriteLock(inode);
5afbbe0d 19074+ au_ii(inode)->ii_bbot = bindex;
1308ab2a 19075+}
19076+
4a4d8108
AM
19077+static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
19078+{
19079+ IiMustWriteLock(inode);
19080+ au_ii(inode)->ii_vdir = vdir;
19081+}
1facf9fc 19082+
4a4d8108 19083+static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 19084+{
4a4d8108 19085+ IiMustAnyLock(inode);
5afbbe0d 19086+ return au_hinode(au_ii(inode), bindex);
4a4d8108 19087+}
dece6358 19088+
4a4d8108 19089+/* ---------------------------------------------------------------------- */
1facf9fc 19090+
4a4d8108
AM
19091+static inline struct dentry *au_pinned_parent(struct au_pin *pin)
19092+{
19093+ if (pin)
19094+ return pin->parent;
19095+ return NULL;
1facf9fc 19096+}
19097+
4a4d8108 19098+static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
1facf9fc 19099+{
4a4d8108
AM
19100+ if (pin && pin->hdir)
19101+ return pin->hdir->hi_inode;
19102+ return NULL;
1308ab2a 19103+}
1facf9fc 19104+
4a4d8108
AM
19105+static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
19106+{
19107+ if (pin)
19108+ return pin->hdir;
19109+ return NULL;
19110+}
1facf9fc 19111+
4a4d8108 19112+static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
1308ab2a 19113+{
4a4d8108
AM
19114+ if (pin)
19115+ pin->dentry = dentry;
19116+}
1308ab2a 19117+
4a4d8108
AM
19118+static inline void au_pin_set_parent_lflag(struct au_pin *pin,
19119+ unsigned char lflag)
19120+{
19121+ if (pin) {
7f207e10 19122+ if (lflag)
4a4d8108 19123+ au_fset_pin(pin->flags, DI_LOCKED);
7f207e10 19124+ else
4a4d8108 19125+ au_fclr_pin(pin->flags, DI_LOCKED);
1308ab2a 19126+ }
4a4d8108
AM
19127+}
19128+
7e9cd9fe 19129+#if 0 /* reserved */
4a4d8108
AM
19130+static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
19131+{
19132+ if (pin) {
19133+ dput(pin->parent);
19134+ pin->parent = dget(parent);
1facf9fc 19135+ }
4a4d8108 19136+}
7e9cd9fe 19137+#endif
1facf9fc 19138+
4a4d8108
AM
19139+/* ---------------------------------------------------------------------- */
19140+
027c5e7a 19141+struct au_branch;
4a4d8108
AM
19142+#ifdef CONFIG_AUFS_HNOTIFY
19143+struct au_hnotify_op {
19144+ void (*ctl)(struct au_hinode *hinode, int do_set);
027c5e7a 19145+ int (*alloc)(struct au_hinode *hinode);
7eafdf33
AM
19146+
19147+ /*
19148+ * if it returns true, the the caller should free hinode->hi_notify,
19149+ * otherwise ->free() frees it.
19150+ */
19151+ int (*free)(struct au_hinode *hinode,
19152+ struct au_hnotify *hn) __must_check;
4a4d8108
AM
19153+
19154+ void (*fin)(void);
19155+ int (*init)(void);
027c5e7a
AM
19156+
19157+ int (*reset_br)(unsigned int udba, struct au_branch *br, int perm);
19158+ void (*fin_br)(struct au_branch *br);
19159+ int (*init_br)(struct au_branch *br, int perm);
4a4d8108
AM
19160+};
19161+
19162+/* hnotify.c */
027c5e7a 19163+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
4a4d8108
AM
19164+void au_hn_free(struct au_hinode *hinode);
19165+void au_hn_ctl(struct au_hinode *hinode, int do_set);
19166+void au_hn_reset(struct inode *inode, unsigned int flags);
19167+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
19168+ struct qstr *h_child_qstr, struct inode *h_child_inode);
027c5e7a
AM
19169+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm);
19170+int au_hnotify_init_br(struct au_branch *br, int perm);
19171+void au_hnotify_fin_br(struct au_branch *br);
4a4d8108
AM
19172+int __init au_hnotify_init(void);
19173+void au_hnotify_fin(void);
19174+
7f207e10 19175+/* hfsnotify.c */
4a4d8108
AM
19176+extern const struct au_hnotify_op au_hnotify_op;
19177+
19178+static inline
19179+void au_hn_init(struct au_hinode *hinode)
19180+{
19181+ hinode->hi_notify = NULL;
1308ab2a 19182+}
19183+
53392da6
AM
19184+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
19185+{
19186+ return hinode->hi_notify;
19187+}
19188+
4a4d8108 19189+#else
c1595e42
JR
19190+AuStub(int, au_hn_alloc, return -EOPNOTSUPP,
19191+ struct au_hinode *hinode __maybe_unused,
19192+ struct inode *inode __maybe_unused)
19193+AuStub(struct au_hnotify *, au_hn, return NULL, struct au_hinode *hinode)
4a4d8108
AM
19194+AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused)
19195+AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused,
19196+ int do_set __maybe_unused)
19197+AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused,
19198+ unsigned int flags __maybe_unused)
027c5e7a
AM
19199+AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused,
19200+ struct au_branch *br __maybe_unused,
19201+ int perm __maybe_unused)
19202+AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused,
19203+ int perm __maybe_unused)
19204+AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused)
4a4d8108
AM
19205+AuStubInt0(__init au_hnotify_init, void)
19206+AuStubVoid(au_hnotify_fin, void)
19207+AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused)
19208+#endif /* CONFIG_AUFS_HNOTIFY */
19209+
19210+static inline void au_hn_suspend(struct au_hinode *hdir)
19211+{
19212+ au_hn_ctl(hdir, /*do_set*/0);
1308ab2a 19213+}
19214+
4a4d8108 19215+static inline void au_hn_resume(struct au_hinode *hdir)
1308ab2a 19216+{
4a4d8108
AM
19217+ au_hn_ctl(hdir, /*do_set*/1);
19218+}
1308ab2a 19219+
5afbbe0d 19220+static inline void au_hn_inode_lock(struct au_hinode *hdir)
4a4d8108 19221+{
febd17d6 19222+ inode_lock(hdir->hi_inode);
4a4d8108
AM
19223+ au_hn_suspend(hdir);
19224+}
dece6358 19225+
5afbbe0d 19226+static inline void au_hn_inode_lock_nested(struct au_hinode *hdir,
4a4d8108
AM
19227+ unsigned int sc __maybe_unused)
19228+{
febd17d6 19229+ inode_lock_nested(hdir->hi_inode, sc);
4a4d8108 19230+ au_hn_suspend(hdir);
1facf9fc 19231+}
1facf9fc 19232+
ae9dfd79
AM
19233+#if 0 /* unused */
19234+#include "vfsub.h"
19235+static inline void au_hn_inode_lock_shared_nested(struct au_hinode *hdir,
19236+ unsigned int sc)
19237+{
19238+ vfsub_inode_lock_shared_nested(hdir->hi_inode, sc);
19239+ au_hn_suspend(hdir);
19240+}
19241+#endif
19242+
5afbbe0d 19243+static inline void au_hn_inode_unlock(struct au_hinode *hdir)
4a4d8108
AM
19244+{
19245+ au_hn_resume(hdir);
febd17d6 19246+ inode_unlock(hdir->hi_inode);
4a4d8108
AM
19247+}
19248+
19249+#endif /* __KERNEL__ */
19250+#endif /* __AUFS_INODE_H__ */
7f207e10
AM
19251diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c
19252--- /usr/share/empty/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 19253+++ linux/fs/aufs/ioctl.c 2018-04-15 08:49:13.401150731 +0200
c1595e42 19254@@ -0,0 +1,219 @@
4a4d8108 19255+/*
ae9dfd79 19256+ * Copyright (C) 2005-2018 Junjiro R. Okajima
4a4d8108
AM
19257+ *
19258+ * This program, aufs is free software; you can redistribute it and/or modify
19259+ * it under the terms of the GNU General Public License as published by
19260+ * the Free Software Foundation; either version 2 of the License, or
19261+ * (at your option) any later version.
19262+ *
19263+ * This program is distributed in the hope that it will be useful,
19264+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19265+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19266+ * GNU General Public License for more details.
19267+ *
19268+ * You should have received a copy of the GNU General Public License
523b37e3 19269+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
19270+ */
19271+
19272+/*
19273+ * ioctl
19274+ * plink-management and readdir in userspace.
19275+ * assist the pathconf(3) wrapper library.
c2b27bf2 19276+ * move-down
076b876e 19277+ * File-based Hierarchical Storage Management.
4a4d8108
AM
19278+ */
19279+
c2b27bf2
AM
19280+#include <linux/compat.h>
19281+#include <linux/file.h>
4a4d8108
AM
19282+#include "aufs.h"
19283+
1e00d052 19284+static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
4a4d8108
AM
19285+{
19286+ int err, fd;
5afbbe0d 19287+ aufs_bindex_t wbi, bindex, bbot;
4a4d8108
AM
19288+ struct file *h_file;
19289+ struct super_block *sb;
19290+ struct dentry *root;
1e00d052
AM
19291+ struct au_branch *br;
19292+ struct aufs_wbr_fd wbrfd = {
19293+ .oflags = au_dir_roflags,
19294+ .brid = -1
19295+ };
19296+ const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY
19297+ | O_NOATIME | O_CLOEXEC;
4a4d8108 19298+
1e00d052
AM
19299+ AuDebugOn(wbrfd.oflags & ~valid);
19300+
19301+ if (arg) {
19302+ err = copy_from_user(&wbrfd, arg, sizeof(wbrfd));
19303+ if (unlikely(err)) {
19304+ err = -EFAULT;
19305+ goto out;
19306+ }
19307+
19308+ err = -EINVAL;
19309+ AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid);
19310+ wbrfd.oflags |= au_dir_roflags;
19311+ AuDbg("0%o\n", wbrfd.oflags);
19312+ if (unlikely(wbrfd.oflags & ~valid))
19313+ goto out;
19314+ }
19315+
2000de60 19316+ fd = get_unused_fd_flags(0);
1e00d052
AM
19317+ err = fd;
19318+ if (unlikely(fd < 0))
4a4d8108 19319+ goto out;
4a4d8108 19320+
1e00d052 19321+ h_file = ERR_PTR(-EINVAL);
4a4d8108 19322+ wbi = 0;
1e00d052 19323+ br = NULL;
4a4d8108
AM
19324+ sb = path->dentry->d_sb;
19325+ root = sb->s_root;
19326+ aufs_read_lock(root, AuLock_IR);
5afbbe0d 19327+ bbot = au_sbbot(sb);
1e00d052
AM
19328+ if (wbrfd.brid >= 0) {
19329+ wbi = au_br_index(sb, wbrfd.brid);
5afbbe0d 19330+ if (unlikely(wbi < 0 || wbi > bbot))
1e00d052
AM
19331+ goto out_unlock;
19332+ }
19333+
19334+ h_file = ERR_PTR(-ENOENT);
19335+ br = au_sbr(sb, wbi);
19336+ if (!au_br_writable(br->br_perm)) {
19337+ if (arg)
19338+ goto out_unlock;
19339+
19340+ bindex = wbi + 1;
19341+ wbi = -1;
5afbbe0d 19342+ for (; bindex <= bbot; bindex++) {
1e00d052
AM
19343+ br = au_sbr(sb, bindex);
19344+ if (au_br_writable(br->br_perm)) {
4a4d8108 19345+ wbi = bindex;
1e00d052 19346+ br = au_sbr(sb, wbi);
4a4d8108
AM
19347+ break;
19348+ }
19349+ }
4a4d8108
AM
19350+ }
19351+ AuDbg("wbi %d\n", wbi);
1e00d052 19352+ if (wbi >= 0)
392086de
AM
19353+ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL,
19354+ /*force_wr*/0);
1e00d052
AM
19355+
19356+out_unlock:
4a4d8108
AM
19357+ aufs_read_unlock(root, AuLock_IR);
19358+ err = PTR_ERR(h_file);
19359+ if (IS_ERR(h_file))
19360+ goto out_fd;
19361+
5afbbe0d 19362+ au_br_put(br); /* cf. au_h_open() */
4a4d8108
AM
19363+ fd_install(fd, h_file);
19364+ err = fd;
19365+ goto out; /* success */
19366+
4f0767ce 19367+out_fd:
4a4d8108 19368+ put_unused_fd(fd);
4f0767ce 19369+out:
1e00d052 19370+ AuTraceErr(err);
4a4d8108
AM
19371+ return err;
19372+}
19373+
19374+/* ---------------------------------------------------------------------- */
19375+
19376+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
19377+{
19378+ long err;
c1595e42 19379+ struct dentry *dentry;
4a4d8108
AM
19380+
19381+ switch (cmd) {
4a4d8108
AM
19382+ case AUFS_CTL_RDU:
19383+ case AUFS_CTL_RDU_INO:
19384+ err = au_rdu_ioctl(file, cmd, arg);
19385+ break;
19386+
19387+ case AUFS_CTL_WBR_FD:
1e00d052 19388+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
19389+ break;
19390+
027c5e7a
AM
19391+ case AUFS_CTL_IBUSY:
19392+ err = au_ibusy_ioctl(file, arg);
19393+ break;
19394+
076b876e
AM
19395+ case AUFS_CTL_BRINFO:
19396+ err = au_brinfo_ioctl(file, arg);
19397+ break;
19398+
19399+ case AUFS_CTL_FHSM_FD:
2000de60 19400+ dentry = file->f_path.dentry;
c1595e42
JR
19401+ if (IS_ROOT(dentry))
19402+ err = au_fhsm_fd(dentry->d_sb, arg);
19403+ else
19404+ err = -ENOTTY;
076b876e
AM
19405+ break;
19406+
4a4d8108
AM
19407+ default:
19408+ /* do not call the lower */
19409+ AuDbg("0x%x\n", cmd);
19410+ err = -ENOTTY;
19411+ }
19412+
19413+ AuTraceErr(err);
19414+ return err;
19415+}
19416+
19417+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
19418+{
19419+ long err;
19420+
19421+ switch (cmd) {
c2b27bf2 19422+ case AUFS_CTL_MVDOWN:
2000de60 19423+ err = au_mvdown(file->f_path.dentry, (void __user *)arg);
c2b27bf2
AM
19424+ break;
19425+
4a4d8108 19426+ case AUFS_CTL_WBR_FD:
1e00d052 19427+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
19428+ break;
19429+
19430+ default:
19431+ /* do not call the lower */
19432+ AuDbg("0x%x\n", cmd);
19433+ err = -ENOTTY;
19434+ }
19435+
19436+ AuTraceErr(err);
19437+ return err;
19438+}
b752ccd1
AM
19439+
19440+#ifdef CONFIG_COMPAT
19441+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
19442+ unsigned long arg)
19443+{
19444+ long err;
19445+
19446+ switch (cmd) {
19447+ case AUFS_CTL_RDU:
19448+ case AUFS_CTL_RDU_INO:
19449+ err = au_rdu_compat_ioctl(file, cmd, arg);
19450+ break;
19451+
027c5e7a
AM
19452+ case AUFS_CTL_IBUSY:
19453+ err = au_ibusy_compat_ioctl(file, arg);
19454+ break;
19455+
076b876e
AM
19456+ case AUFS_CTL_BRINFO:
19457+ err = au_brinfo_compat_ioctl(file, arg);
19458+ break;
19459+
b752ccd1
AM
19460+ default:
19461+ err = aufs_ioctl_dir(file, cmd, arg);
19462+ }
19463+
19464+ AuTraceErr(err);
19465+ return err;
19466+}
19467+
b752ccd1
AM
19468+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
19469+ unsigned long arg)
19470+{
19471+ return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg));
19472+}
19473+#endif
7f207e10
AM
19474diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
19475--- /usr/share/empty/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 19476+++ linux/fs/aufs/i_op_add.c 2018-04-15 08:49:13.401150731 +0200
f2c43d5f 19477@@ -0,0 +1,928 @@
4a4d8108 19478+/*
ae9dfd79 19479+ * Copyright (C) 2005-2018 Junjiro R. Okajima
4a4d8108
AM
19480+ *
19481+ * This program, aufs is free software; you can redistribute it and/or modify
19482+ * it under the terms of the GNU General Public License as published by
19483+ * the Free Software Foundation; either version 2 of the License, or
19484+ * (at your option) any later version.
19485+ *
19486+ * This program is distributed in the hope that it will be useful,
19487+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19488+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19489+ * GNU General Public License for more details.
19490+ *
19491+ * You should have received a copy of the GNU General Public License
523b37e3 19492+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
19493+ */
19494+
19495+/*
19496+ * inode operations (add entry)
19497+ */
19498+
19499+#include "aufs.h"
19500+
19501+/*
19502+ * final procedure of adding a new entry, except link(2).
19503+ * remove whiteout, instantiate, copyup the parent dir's times and size
19504+ * and update version.
19505+ * if it failed, re-create the removed whiteout.
19506+ */
19507+static int epilog(struct inode *dir, aufs_bindex_t bindex,
19508+ struct dentry *wh_dentry, struct dentry *dentry)
19509+{
19510+ int err, rerr;
19511+ aufs_bindex_t bwh;
19512+ struct path h_path;
076b876e 19513+ struct super_block *sb;
4a4d8108
AM
19514+ struct inode *inode, *h_dir;
19515+ struct dentry *wh;
19516+
19517+ bwh = -1;
076b876e 19518+ sb = dir->i_sb;
4a4d8108 19519+ if (wh_dentry) {
5527c038 19520+ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */
4a4d8108
AM
19521+ IMustLock(h_dir);
19522+ AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
19523+ bwh = au_dbwh(dentry);
19524+ h_path.dentry = wh_dentry;
076b876e 19525+ h_path.mnt = au_sbr_mnt(sb, bindex);
4a4d8108
AM
19526+ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
19527+ dentry);
19528+ if (unlikely(err))
19529+ goto out;
19530+ }
19531+
19532+ inode = au_new_inode(dentry, /*must_new*/1);
19533+ if (!IS_ERR(inode)) {
19534+ d_instantiate(dentry, inode);
5527c038 19535+ dir = d_inode(dentry->d_parent); /* dir inode is locked */
4a4d8108 19536+ IMustLock(dir);
b912730e 19537+ au_dir_ts(dir, bindex);
4a4d8108 19538+ dir->i_version++;
076b876e 19539+ au_fhsm_wrote(sb, bindex, /*force*/0);
4a4d8108
AM
19540+ return 0; /* success */
19541+ }
19542+
19543+ err = PTR_ERR(inode);
19544+ if (!wh_dentry)
19545+ goto out;
19546+
19547+ /* revert */
19548+ /* dir inode is locked */
19549+ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
19550+ rerr = PTR_ERR(wh);
19551+ if (IS_ERR(wh)) {
523b37e3
AM
19552+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n",
19553+ dentry, err, rerr);
4a4d8108
AM
19554+ err = -EIO;
19555+ } else
19556+ dput(wh);
19557+
4f0767ce 19558+out:
4a4d8108
AM
19559+ return err;
19560+}
19561+
027c5e7a
AM
19562+static int au_d_may_add(struct dentry *dentry)
19563+{
19564+ int err;
19565+
19566+ err = 0;
19567+ if (unlikely(d_unhashed(dentry)))
19568+ err = -ENOENT;
5527c038 19569+ if (unlikely(d_really_is_positive(dentry)))
027c5e7a
AM
19570+ err = -EEXIST;
19571+ return err;
19572+}
19573+
4a4d8108
AM
19574+/*
19575+ * simple tests for the adding inode operations.
19576+ * following the checks in vfs, plus the parent-child relationship.
19577+ */
19578+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
19579+ struct dentry *h_parent, int isdir)
19580+{
19581+ int err;
19582+ umode_t h_mode;
19583+ struct dentry *h_dentry;
19584+ struct inode *h_inode;
19585+
19586+ err = -ENAMETOOLONG;
19587+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
19588+ goto out;
19589+
19590+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 19591+ if (d_really_is_negative(dentry)) {
4a4d8108 19592+ err = -EEXIST;
5527c038 19593+ if (unlikely(d_is_positive(h_dentry)))
4a4d8108
AM
19594+ goto out;
19595+ } else {
19596+ /* rename(2) case */
19597+ err = -EIO;
5527c038
JR
19598+ if (unlikely(d_is_negative(h_dentry)))
19599+ goto out;
19600+ h_inode = d_inode(h_dentry);
19601+ if (unlikely(!h_inode->i_nlink))
4a4d8108
AM
19602+ goto out;
19603+
19604+ h_mode = h_inode->i_mode;
19605+ if (!isdir) {
19606+ err = -EISDIR;
19607+ if (unlikely(S_ISDIR(h_mode)))
19608+ goto out;
19609+ } else if (unlikely(!S_ISDIR(h_mode))) {
19610+ err = -ENOTDIR;
19611+ goto out;
19612+ }
19613+ }
19614+
19615+ err = 0;
19616+ /* expected parent dir is locked */
19617+ if (unlikely(h_parent != h_dentry->d_parent))
19618+ err = -EIO;
19619+
4f0767ce 19620+out:
4a4d8108
AM
19621+ AuTraceErr(err);
19622+ return err;
19623+}
19624+
19625+/*
19626+ * initial procedure of adding a new entry.
19627+ * prepare writable branch and the parent dir, lock it,
19628+ * and lookup whiteout for the new entry.
19629+ */
19630+static struct dentry*
19631+lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
19632+ struct dentry *src_dentry, struct au_pin *pin,
19633+ struct au_wr_dir_args *wr_dir_args)
19634+{
19635+ struct dentry *wh_dentry, *h_parent;
19636+ struct super_block *sb;
19637+ struct au_branch *br;
19638+ int err;
19639+ unsigned int udba;
19640+ aufs_bindex_t bcpup;
19641+
523b37e3 19642+ AuDbg("%pd\n", dentry);
4a4d8108
AM
19643+
19644+ err = au_wr_dir(dentry, src_dentry, wr_dir_args);
19645+ bcpup = err;
19646+ wh_dentry = ERR_PTR(err);
19647+ if (unlikely(err < 0))
19648+ goto out;
19649+
19650+ sb = dentry->d_sb;
19651+ udba = au_opt_udba(sb);
19652+ err = au_pin(pin, dentry, bcpup, udba,
19653+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
19654+ wh_dentry = ERR_PTR(err);
19655+ if (unlikely(err))
19656+ goto out;
19657+
19658+ h_parent = au_pinned_h_parent(pin);
19659+ if (udba != AuOpt_UDBA_NONE
5afbbe0d 19660+ && au_dbtop(dentry) == bcpup)
4a4d8108
AM
19661+ err = au_may_add(dentry, bcpup, h_parent,
19662+ au_ftest_wrdir(wr_dir_args->flags, ISDIR));
19663+ else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
19664+ err = -ENAMETOOLONG;
19665+ wh_dentry = ERR_PTR(err);
19666+ if (unlikely(err))
19667+ goto out_unpin;
19668+
19669+ br = au_sbr(sb, bcpup);
19670+ if (dt) {
19671+ struct path tmp = {
19672+ .dentry = h_parent,
86dc4139 19673+ .mnt = au_br_mnt(br)
4a4d8108
AM
19674+ };
19675+ au_dtime_store(dt, au_pinned_parent(pin), &tmp);
19676+ }
19677+
19678+ wh_dentry = NULL;
19679+ if (bcpup != au_dbwh(dentry))
19680+ goto out; /* success */
19681+
2000de60
JR
19682+ /*
19683+ * ENAMETOOLONG here means that if we allowed create such name, then it
19684+ * would not be able to removed in the future. So we don't allow such
19685+ * name here and we don't handle ENAMETOOLONG differently here.
19686+ */
4a4d8108
AM
19687+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
19688+
4f0767ce 19689+out_unpin:
4a4d8108
AM
19690+ if (IS_ERR(wh_dentry))
19691+ au_unpin(pin);
4f0767ce 19692+out:
4a4d8108
AM
19693+ return wh_dentry;
19694+}
19695+
19696+/* ---------------------------------------------------------------------- */
19697+
19698+enum { Mknod, Symlink, Creat };
19699+struct simple_arg {
19700+ int type;
19701+ union {
19702+ struct {
b912730e
AM
19703+ umode_t mode;
19704+ bool want_excl;
19705+ bool try_aopen;
19706+ struct vfsub_aopen_args *aopen;
4a4d8108
AM
19707+ } c;
19708+ struct {
19709+ const char *symname;
19710+ } s;
19711+ struct {
7eafdf33 19712+ umode_t mode;
4a4d8108
AM
19713+ dev_t dev;
19714+ } m;
19715+ } u;
19716+};
19717+
19718+static int add_simple(struct inode *dir, struct dentry *dentry,
19719+ struct simple_arg *arg)
19720+{
076b876e 19721+ int err, rerr;
5afbbe0d 19722+ aufs_bindex_t btop;
4a4d8108 19723+ unsigned char created;
b912730e
AM
19724+ const unsigned char try_aopen
19725+ = (arg->type == Creat && arg->u.c.try_aopen);
4a4d8108
AM
19726+ struct dentry *wh_dentry, *parent;
19727+ struct inode *h_dir;
b912730e
AM
19728+ struct super_block *sb;
19729+ struct au_branch *br;
c2b27bf2
AM
19730+ /* to reuduce stack size */
19731+ struct {
19732+ struct au_dtime dt;
19733+ struct au_pin pin;
19734+ struct path h_path;
19735+ struct au_wr_dir_args wr_dir_args;
19736+ } *a;
4a4d8108 19737+
523b37e3 19738+ AuDbg("%pd\n", dentry);
4a4d8108
AM
19739+ IMustLock(dir);
19740+
c2b27bf2
AM
19741+ err = -ENOMEM;
19742+ a = kmalloc(sizeof(*a), GFP_NOFS);
19743+ if (unlikely(!a))
19744+ goto out;
19745+ a->wr_dir_args.force_btgt = -1;
19746+ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY;
19747+
4a4d8108 19748+ parent = dentry->d_parent; /* dir inode is locked */
b912730e
AM
19749+ if (!try_aopen) {
19750+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
19751+ if (unlikely(err))
19752+ goto out_free;
19753+ }
027c5e7a
AM
19754+ err = au_d_may_add(dentry);
19755+ if (unlikely(err))
19756+ goto out_unlock;
b912730e
AM
19757+ if (!try_aopen)
19758+ di_write_lock_parent(parent);
c2b27bf2
AM
19759+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
19760+ &a->pin, &a->wr_dir_args);
4a4d8108
AM
19761+ err = PTR_ERR(wh_dentry);
19762+ if (IS_ERR(wh_dentry))
027c5e7a 19763+ goto out_parent;
4a4d8108 19764+
5afbbe0d 19765+ btop = au_dbtop(dentry);
b912730e 19766+ sb = dentry->d_sb;
5afbbe0d
AM
19767+ br = au_sbr(sb, btop);
19768+ a->h_path.dentry = au_h_dptr(dentry, btop);
b912730e 19769+ a->h_path.mnt = au_br_mnt(br);
c2b27bf2 19770+ h_dir = au_pinned_h_dir(&a->pin);
4a4d8108
AM
19771+ switch (arg->type) {
19772+ case Creat:
b912730e
AM
19773+ err = 0;
19774+ if (!try_aopen || !h_dir->i_op->atomic_open)
19775+ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode,
19776+ arg->u.c.want_excl);
19777+ else
19778+ err = vfsub_atomic_open(h_dir, a->h_path.dentry,
19779+ arg->u.c.aopen, br);
4a4d8108
AM
19780+ break;
19781+ case Symlink:
c2b27bf2 19782+ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname);
4a4d8108
AM
19783+ break;
19784+ case Mknod:
c2b27bf2
AM
19785+ err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode,
19786+ arg->u.m.dev);
4a4d8108
AM
19787+ break;
19788+ default:
19789+ BUG();
19790+ }
19791+ created = !err;
19792+ if (!err)
5afbbe0d 19793+ err = epilog(dir, btop, wh_dentry, dentry);
4a4d8108
AM
19794+
19795+ /* revert */
5527c038 19796+ if (unlikely(created && err && d_is_positive(a->h_path.dentry))) {
523b37e3
AM
19797+ /* no delegation since it is just created */
19798+ rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL,
19799+ /*force*/0);
4a4d8108 19800+ if (rerr) {
523b37e3
AM
19801+ AuIOErr("%pd revert failure(%d, %d)\n",
19802+ dentry, err, rerr);
4a4d8108
AM
19803+ err = -EIO;
19804+ }
c2b27bf2 19805+ au_dtime_revert(&a->dt);
4a4d8108
AM
19806+ }
19807+
b912730e
AM
19808+ if (!err && try_aopen && !h_dir->i_op->atomic_open)
19809+ *arg->u.c.aopen->opened |= FILE_CREATED;
19810+
c2b27bf2 19811+ au_unpin(&a->pin);
4a4d8108
AM
19812+ dput(wh_dentry);
19813+
027c5e7a 19814+out_parent:
b912730e
AM
19815+ if (!try_aopen)
19816+ di_write_unlock(parent);
027c5e7a 19817+out_unlock:
4a4d8108 19818+ if (unlikely(err)) {
5afbbe0d 19819+ au_update_dbtop(dentry);
4a4d8108
AM
19820+ d_drop(dentry);
19821+ }
b912730e
AM
19822+ if (!try_aopen)
19823+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2 19824+out_free:
ae9dfd79 19825+ kfree(a);
027c5e7a 19826+out:
4a4d8108
AM
19827+ return err;
19828+}
19829+
7eafdf33
AM
19830+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
19831+ dev_t dev)
4a4d8108
AM
19832+{
19833+ struct simple_arg arg = {
19834+ .type = Mknod,
19835+ .u.m = {
19836+ .mode = mode,
19837+ .dev = dev
19838+ }
19839+ };
19840+ return add_simple(dir, dentry, &arg);
19841+}
19842+
19843+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
19844+{
19845+ struct simple_arg arg = {
19846+ .type = Symlink,
19847+ .u.s.symname = symname
19848+ };
19849+ return add_simple(dir, dentry, &arg);
19850+}
19851+
7eafdf33 19852+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 19853+ bool want_excl)
4a4d8108
AM
19854+{
19855+ struct simple_arg arg = {
19856+ .type = Creat,
19857+ .u.c = {
b4510431
AM
19858+ .mode = mode,
19859+ .want_excl = want_excl
4a4d8108
AM
19860+ }
19861+ };
19862+ return add_simple(dir, dentry, &arg);
19863+}
19864+
b912730e
AM
19865+int au_aopen_or_create(struct inode *dir, struct dentry *dentry,
19866+ struct vfsub_aopen_args *aopen_args)
19867+{
19868+ struct simple_arg arg = {
19869+ .type = Creat,
19870+ .u.c = {
19871+ .mode = aopen_args->create_mode,
19872+ .want_excl = aopen_args->open_flag & O_EXCL,
19873+ .try_aopen = true,
19874+ .aopen = aopen_args
19875+ }
19876+ };
19877+ return add_simple(dir, dentry, &arg);
19878+}
19879+
38d290e6
JR
19880+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
19881+{
19882+ int err;
19883+ aufs_bindex_t bindex;
19884+ struct super_block *sb;
19885+ struct dentry *parent, *h_parent, *h_dentry;
19886+ struct inode *h_dir, *inode;
19887+ struct vfsmount *h_mnt;
19888+ struct au_wr_dir_args wr_dir_args = {
19889+ .force_btgt = -1,
19890+ .flags = AuWrDir_TMPFILE
19891+ };
19892+
19893+ /* copy-up may happen */
febd17d6 19894+ inode_lock(dir);
38d290e6
JR
19895+
19896+ sb = dir->i_sb;
19897+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
19898+ if (unlikely(err))
19899+ goto out;
19900+
19901+ err = au_di_init(dentry);
19902+ if (unlikely(err))
19903+ goto out_si;
19904+
19905+ err = -EBUSY;
19906+ parent = d_find_any_alias(dir);
19907+ AuDebugOn(!parent);
19908+ di_write_lock_parent(parent);
5527c038 19909+ if (unlikely(d_inode(parent) != dir))
38d290e6
JR
19910+ goto out_parent;
19911+
19912+ err = au_digen_test(parent, au_sigen(sb));
19913+ if (unlikely(err))
19914+ goto out_parent;
19915+
5afbbe0d
AM
19916+ bindex = au_dbtop(parent);
19917+ au_set_dbtop(dentry, bindex);
19918+ au_set_dbbot(dentry, bindex);
38d290e6
JR
19919+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
19920+ bindex = err;
19921+ if (unlikely(err < 0))
19922+ goto out_parent;
19923+
19924+ err = -EOPNOTSUPP;
19925+ h_dir = au_h_iptr(dir, bindex);
19926+ if (unlikely(!h_dir->i_op->tmpfile))
19927+ goto out_parent;
19928+
19929+ h_mnt = au_sbr_mnt(sb, bindex);
19930+ err = vfsub_mnt_want_write(h_mnt);
19931+ if (unlikely(err))
19932+ goto out_parent;
19933+
19934+ h_parent = au_h_dptr(parent, bindex);
5527c038 19935+ err = inode_permission(d_inode(h_parent), MAY_WRITE | MAY_EXEC);
38d290e6
JR
19936+ if (unlikely(err))
19937+ goto out_mnt;
19938+
19939+ err = -ENOMEM;
19940+ h_dentry = d_alloc(h_parent, &dentry->d_name);
19941+ if (unlikely(!h_dentry))
19942+ goto out_mnt;
19943+
19944+ err = h_dir->i_op->tmpfile(h_dir, h_dentry, mode);
19945+ if (unlikely(err))
19946+ goto out_dentry;
19947+
5afbbe0d
AM
19948+ au_set_dbtop(dentry, bindex);
19949+ au_set_dbbot(dentry, bindex);
38d290e6
JR
19950+ au_set_h_dptr(dentry, bindex, dget(h_dentry));
19951+ inode = au_new_inode(dentry, /*must_new*/1);
19952+ if (IS_ERR(inode)) {
19953+ err = PTR_ERR(inode);
19954+ au_set_h_dptr(dentry, bindex, NULL);
5afbbe0d
AM
19955+ au_set_dbtop(dentry, -1);
19956+ au_set_dbbot(dentry, -1);
38d290e6
JR
19957+ } else {
19958+ if (!inode->i_nlink)
19959+ set_nlink(inode, 1);
19960+ d_tmpfile(dentry, inode);
19961+ au_di(dentry)->di_tmpfile = 1;
19962+
19963+ /* update without i_mutex */
5afbbe0d 19964+ if (au_ibtop(dir) == au_dbtop(dentry))
38d290e6
JR
19965+ au_cpup_attr_timesizes(dir);
19966+ }
19967+
19968+out_dentry:
19969+ dput(h_dentry);
19970+out_mnt:
19971+ vfsub_mnt_drop_write(h_mnt);
19972+out_parent:
19973+ di_write_unlock(parent);
19974+ dput(parent);
19975+ di_write_unlock(dentry);
5afbbe0d 19976+ if (unlikely(err)) {
38d290e6
JR
19977+ au_di_fin(dentry);
19978+ dentry->d_fsdata = NULL;
19979+ }
19980+out_si:
19981+ si_read_unlock(sb);
19982+out:
febd17d6 19983+ inode_unlock(dir);
38d290e6
JR
19984+ return err;
19985+}
19986+
4a4d8108
AM
19987+/* ---------------------------------------------------------------------- */
19988+
19989+struct au_link_args {
19990+ aufs_bindex_t bdst, bsrc;
19991+ struct au_pin pin;
19992+ struct path h_path;
19993+ struct dentry *src_parent, *parent;
19994+};
19995+
19996+static int au_cpup_before_link(struct dentry *src_dentry,
19997+ struct au_link_args *a)
19998+{
19999+ int err;
20000+ struct dentry *h_src_dentry;
c2b27bf2
AM
20001+ struct au_cp_generic cpg = {
20002+ .dentry = src_dentry,
20003+ .bdst = a->bdst,
20004+ .bsrc = a->bsrc,
20005+ .len = -1,
20006+ .pin = &a->pin,
20007+ .flags = AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */
20008+ };
4a4d8108
AM
20009+
20010+ di_read_lock_parent(a->src_parent, AuLock_IR);
20011+ err = au_test_and_cpup_dirs(src_dentry, a->bdst);
20012+ if (unlikely(err))
20013+ goto out;
20014+
20015+ h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
4a4d8108
AM
20016+ err = au_pin(&a->pin, src_dentry, a->bdst,
20017+ au_opt_udba(src_dentry->d_sb),
20018+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
20019+ if (unlikely(err))
20020+ goto out;
367653fa 20021+
c2b27bf2 20022+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
20023+ au_unpin(&a->pin);
20024+
4f0767ce 20025+out:
4a4d8108
AM
20026+ di_read_unlock(a->src_parent, AuLock_IR);
20027+ return err;
20028+}
20029+
86dc4139
AM
20030+static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry,
20031+ struct au_link_args *a)
4a4d8108
AM
20032+{
20033+ int err;
20034+ unsigned char plink;
5afbbe0d 20035+ aufs_bindex_t bbot;
4a4d8108 20036+ struct dentry *h_src_dentry;
523b37e3 20037+ struct inode *h_inode, *inode, *delegated;
4a4d8108
AM
20038+ struct super_block *sb;
20039+ struct file *h_file;
20040+
20041+ plink = 0;
20042+ h_inode = NULL;
20043+ sb = src_dentry->d_sb;
5527c038 20044+ inode = d_inode(src_dentry);
5afbbe0d 20045+ if (au_ibtop(inode) <= a->bdst)
4a4d8108
AM
20046+ h_inode = au_h_iptr(inode, a->bdst);
20047+ if (!h_inode || !h_inode->i_nlink) {
20048+ /* copyup src_dentry as the name of dentry. */
5afbbe0d
AM
20049+ bbot = au_dbbot(dentry);
20050+ if (bbot < a->bsrc)
20051+ au_set_dbbot(dentry, a->bsrc);
86dc4139
AM
20052+ au_set_h_dptr(dentry, a->bsrc,
20053+ dget(au_h_dptr(src_dentry, a->bsrc)));
20054+ dget(a->h_path.dentry);
20055+ au_set_h_dptr(dentry, a->bdst, NULL);
c1595e42
JR
20056+ AuDbg("temporary d_inode...\n");
20057+ spin_lock(&dentry->d_lock);
5527c038 20058+ dentry->d_inode = d_inode(src_dentry); /* tmp */
c1595e42 20059+ spin_unlock(&dentry->d_lock);
392086de 20060+ h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0);
86dc4139 20061+ if (IS_ERR(h_file))
4a4d8108 20062+ err = PTR_ERR(h_file);
86dc4139 20063+ else {
c2b27bf2
AM
20064+ struct au_cp_generic cpg = {
20065+ .dentry = dentry,
20066+ .bdst = a->bdst,
20067+ .bsrc = -1,
20068+ .len = -1,
20069+ .pin = &a->pin,
20070+ .flags = AuCpup_KEEPLINO
20071+ };
20072+ err = au_sio_cpup_simple(&cpg);
86dc4139
AM
20073+ au_h_open_post(dentry, a->bsrc, h_file);
20074+ if (!err) {
20075+ dput(a->h_path.dentry);
20076+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
20077+ } else
20078+ au_set_h_dptr(dentry, a->bdst,
20079+ a->h_path.dentry);
20080+ }
c1595e42 20081+ spin_lock(&dentry->d_lock);
86dc4139 20082+ dentry->d_inode = NULL; /* restore */
c1595e42
JR
20083+ spin_unlock(&dentry->d_lock);
20084+ AuDbg("temporary d_inode...done\n");
86dc4139 20085+ au_set_h_dptr(dentry, a->bsrc, NULL);
5afbbe0d 20086+ au_set_dbbot(dentry, bbot);
4a4d8108
AM
20087+ } else {
20088+ /* the inode of src_dentry already exists on a.bdst branch */
20089+ h_src_dentry = d_find_alias(h_inode);
20090+ if (!h_src_dentry && au_plink_test(inode)) {
20091+ plink = 1;
20092+ h_src_dentry = au_plink_lkup(inode, a->bdst);
20093+ err = PTR_ERR(h_src_dentry);
20094+ if (IS_ERR(h_src_dentry))
20095+ goto out;
20096+
5527c038 20097+ if (unlikely(d_is_negative(h_src_dentry))) {
4a4d8108
AM
20098+ dput(h_src_dentry);
20099+ h_src_dentry = NULL;
20100+ }
20101+
20102+ }
20103+ if (h_src_dentry) {
523b37e3 20104+ delegated = NULL;
4a4d8108 20105+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
20106+ &a->h_path, &delegated);
20107+ if (unlikely(err == -EWOULDBLOCK)) {
20108+ pr_warn("cannot retry for NFSv4 delegation"
20109+ " for an internal link\n");
20110+ iput(delegated);
20111+ }
4a4d8108
AM
20112+ dput(h_src_dentry);
20113+ } else {
20114+ AuIOErr("no dentry found for hi%lu on b%d\n",
20115+ h_inode->i_ino, a->bdst);
20116+ err = -EIO;
20117+ }
20118+ }
20119+
20120+ if (!err && !plink)
20121+ au_plink_append(inode, a->bdst, a->h_path.dentry);
20122+
20123+out:
2cbb1c4b 20124+ AuTraceErr(err);
4a4d8108
AM
20125+ return err;
20126+}
20127+
20128+int aufs_link(struct dentry *src_dentry, struct inode *dir,
20129+ struct dentry *dentry)
20130+{
20131+ int err, rerr;
20132+ struct au_dtime dt;
20133+ struct au_link_args *a;
20134+ struct dentry *wh_dentry, *h_src_dentry;
523b37e3 20135+ struct inode *inode, *delegated;
4a4d8108
AM
20136+ struct super_block *sb;
20137+ struct au_wr_dir_args wr_dir_args = {
20138+ /* .force_btgt = -1, */
20139+ .flags = AuWrDir_ADD_ENTRY
20140+ };
20141+
20142+ IMustLock(dir);
5527c038 20143+ inode = d_inode(src_dentry);
4a4d8108
AM
20144+ IMustLock(inode);
20145+
4a4d8108
AM
20146+ err = -ENOMEM;
20147+ a = kzalloc(sizeof(*a), GFP_NOFS);
20148+ if (unlikely(!a))
20149+ goto out;
20150+
20151+ a->parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
20152+ err = aufs_read_and_write_lock2(dentry, src_dentry,
20153+ AuLock_NOPLM | AuLock_GEN);
e49829fe
JR
20154+ if (unlikely(err))
20155+ goto out_kfree;
38d290e6 20156+ err = au_d_linkable(src_dentry);
027c5e7a
AM
20157+ if (unlikely(err))
20158+ goto out_unlock;
20159+ err = au_d_may_add(dentry);
20160+ if (unlikely(err))
20161+ goto out_unlock;
e49829fe 20162+
4a4d8108 20163+ a->src_parent = dget_parent(src_dentry);
5afbbe0d 20164+ wr_dir_args.force_btgt = au_ibtop(inode);
4a4d8108
AM
20165+
20166+ di_write_lock_parent(a->parent);
20167+ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
20168+ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
20169+ &wr_dir_args);
20170+ err = PTR_ERR(wh_dentry);
20171+ if (IS_ERR(wh_dentry))
027c5e7a 20172+ goto out_parent;
4a4d8108
AM
20173+
20174+ err = 0;
20175+ sb = dentry->d_sb;
5afbbe0d 20176+ a->bdst = au_dbtop(dentry);
4a4d8108
AM
20177+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
20178+ a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
5afbbe0d 20179+ a->bsrc = au_ibtop(inode);
2cbb1c4b 20180+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
38d290e6
JR
20181+ if (!h_src_dentry && au_di(src_dentry)->di_tmpfile)
20182+ h_src_dentry = dget(au_hi_wh(inode, a->bsrc));
2cbb1c4b 20183+ if (!h_src_dentry) {
5afbbe0d 20184+ a->bsrc = au_dbtop(src_dentry);
2cbb1c4b
JR
20185+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
20186+ AuDebugOn(!h_src_dentry);
38d290e6
JR
20187+ } else if (IS_ERR(h_src_dentry)) {
20188+ err = PTR_ERR(h_src_dentry);
2cbb1c4b 20189+ goto out_parent;
38d290e6 20190+ }
2cbb1c4b 20191+
f2c43d5f
AM
20192+ /*
20193+ * aufs doesn't touch the credential so
20194+ * security_dentry_create_files_as() is unnecrssary.
20195+ */
4a4d8108
AM
20196+ if (au_opt_test(au_mntflags(sb), PLINK)) {
20197+ if (a->bdst < a->bsrc
20198+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
86dc4139 20199+ err = au_cpup_or_link(src_dentry, dentry, a);
523b37e3
AM
20200+ else {
20201+ delegated = NULL;
4a4d8108 20202+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
20203+ &a->h_path, &delegated);
20204+ if (unlikely(err == -EWOULDBLOCK)) {
20205+ pr_warn("cannot retry for NFSv4 delegation"
20206+ " for an internal link\n");
20207+ iput(delegated);
20208+ }
20209+ }
2cbb1c4b 20210+ dput(h_src_dentry);
4a4d8108
AM
20211+ } else {
20212+ /*
20213+ * copyup src_dentry to the branch we process,
20214+ * and then link(2) to it.
20215+ */
2cbb1c4b 20216+ dput(h_src_dentry);
4a4d8108
AM
20217+ if (a->bdst < a->bsrc
20218+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
20219+ au_unpin(&a->pin);
20220+ di_write_unlock(a->parent);
20221+ err = au_cpup_before_link(src_dentry, a);
20222+ di_write_lock_parent(a->parent);
20223+ if (!err)
20224+ err = au_pin(&a->pin, dentry, a->bdst,
20225+ au_opt_udba(sb),
20226+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
20227+ if (unlikely(err))
20228+ goto out_wh;
20229+ }
20230+ if (!err) {
20231+ h_src_dentry = au_h_dptr(src_dentry, a->bdst);
20232+ err = -ENOENT;
5527c038 20233+ if (h_src_dentry && d_is_positive(h_src_dentry)) {
523b37e3 20234+ delegated = NULL;
4a4d8108
AM
20235+ err = vfsub_link(h_src_dentry,
20236+ au_pinned_h_dir(&a->pin),
523b37e3
AM
20237+ &a->h_path, &delegated);
20238+ if (unlikely(err == -EWOULDBLOCK)) {
20239+ pr_warn("cannot retry"
20240+ " for NFSv4 delegation"
20241+ " for an internal link\n");
20242+ iput(delegated);
20243+ }
20244+ }
4a4d8108
AM
20245+ }
20246+ }
20247+ if (unlikely(err))
20248+ goto out_unpin;
20249+
20250+ if (wh_dentry) {
20251+ a->h_path.dentry = wh_dentry;
20252+ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
20253+ dentry);
20254+ if (unlikely(err))
20255+ goto out_revert;
20256+ }
20257+
b912730e 20258+ au_dir_ts(dir, a->bdst);
4a4d8108 20259+ dir->i_version++;
4a4d8108
AM
20260+ inc_nlink(inode);
20261+ inode->i_ctime = dir->i_ctime;
027c5e7a
AM
20262+ d_instantiate(dentry, au_igrab(inode));
20263+ if (d_unhashed(a->h_path.dentry))
4a4d8108
AM
20264+ /* some filesystem calls d_drop() */
20265+ d_drop(dentry);
076b876e
AM
20266+ /* some filesystems consume an inode even hardlink */
20267+ au_fhsm_wrote(sb, a->bdst, /*force*/0);
4a4d8108
AM
20268+ goto out_unpin; /* success */
20269+
4f0767ce 20270+out_revert:
523b37e3
AM
20271+ /* no delegation since it is just created */
20272+ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path,
20273+ /*delegated*/NULL, /*force*/0);
027c5e7a 20274+ if (unlikely(rerr)) {
523b37e3 20275+ AuIOErr("%pd reverting failed(%d, %d)\n", dentry, err, rerr);
027c5e7a
AM
20276+ err = -EIO;
20277+ }
4a4d8108 20278+ au_dtime_revert(&dt);
4f0767ce 20279+out_unpin:
4a4d8108 20280+ au_unpin(&a->pin);
4f0767ce 20281+out_wh:
4a4d8108 20282+ dput(wh_dentry);
027c5e7a
AM
20283+out_parent:
20284+ di_write_unlock(a->parent);
20285+ dput(a->src_parent);
4f0767ce 20286+out_unlock:
4a4d8108 20287+ if (unlikely(err)) {
5afbbe0d 20288+ au_update_dbtop(dentry);
4a4d8108
AM
20289+ d_drop(dentry);
20290+ }
4a4d8108 20291+ aufs_read_and_write_unlock2(dentry, src_dentry);
e49829fe 20292+out_kfree:
ae9dfd79 20293+ kfree(a);
4f0767ce 20294+out:
86dc4139 20295+ AuTraceErr(err);
4a4d8108
AM
20296+ return err;
20297+}
20298+
7eafdf33 20299+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
4a4d8108
AM
20300+{
20301+ int err, rerr;
20302+ aufs_bindex_t bindex;
20303+ unsigned char diropq;
20304+ struct path h_path;
20305+ struct dentry *wh_dentry, *parent, *opq_dentry;
febd17d6 20306+ struct inode *h_inode;
4a4d8108
AM
20307+ struct super_block *sb;
20308+ struct {
20309+ struct au_pin pin;
20310+ struct au_dtime dt;
20311+ } *a; /* reduce the stack usage */
20312+ struct au_wr_dir_args wr_dir_args = {
20313+ .force_btgt = -1,
20314+ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
20315+ };
20316+
20317+ IMustLock(dir);
20318+
20319+ err = -ENOMEM;
20320+ a = kmalloc(sizeof(*a), GFP_NOFS);
20321+ if (unlikely(!a))
20322+ goto out;
20323+
027c5e7a
AM
20324+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
20325+ if (unlikely(err))
20326+ goto out_free;
20327+ err = au_d_may_add(dentry);
20328+ if (unlikely(err))
20329+ goto out_unlock;
20330+
4a4d8108
AM
20331+ parent = dentry->d_parent; /* dir inode is locked */
20332+ di_write_lock_parent(parent);
20333+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
20334+ &a->pin, &wr_dir_args);
20335+ err = PTR_ERR(wh_dentry);
20336+ if (IS_ERR(wh_dentry))
027c5e7a 20337+ goto out_parent;
4a4d8108
AM
20338+
20339+ sb = dentry->d_sb;
5afbbe0d 20340+ bindex = au_dbtop(dentry);
4a4d8108
AM
20341+ h_path.dentry = au_h_dptr(dentry, bindex);
20342+ h_path.mnt = au_sbr_mnt(sb, bindex);
20343+ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
20344+ if (unlikely(err))
027c5e7a 20345+ goto out_unpin;
4a4d8108
AM
20346+
20347+ /* make the dir opaque */
20348+ diropq = 0;
febd17d6 20349+ h_inode = d_inode(h_path.dentry);
4a4d8108
AM
20350+ if (wh_dentry
20351+ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
febd17d6 20352+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
4a4d8108 20353+ opq_dentry = au_diropq_create(dentry, bindex);
febd17d6 20354+ inode_unlock(h_inode);
4a4d8108
AM
20355+ err = PTR_ERR(opq_dentry);
20356+ if (IS_ERR(opq_dentry))
20357+ goto out_dir;
20358+ dput(opq_dentry);
20359+ diropq = 1;
20360+ }
20361+
20362+ err = epilog(dir, bindex, wh_dentry, dentry);
20363+ if (!err) {
20364+ inc_nlink(dir);
027c5e7a 20365+ goto out_unpin; /* success */
4a4d8108
AM
20366+ }
20367+
20368+ /* revert */
20369+ if (diropq) {
20370+ AuLabel(revert opq);
febd17d6 20371+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
4a4d8108 20372+ rerr = au_diropq_remove(dentry, bindex);
febd17d6 20373+ inode_unlock(h_inode);
4a4d8108 20374+ if (rerr) {
523b37e3
AM
20375+ AuIOErr("%pd reverting diropq failed(%d, %d)\n",
20376+ dentry, err, rerr);
4a4d8108
AM
20377+ err = -EIO;
20378+ }
20379+ }
20380+
4f0767ce 20381+out_dir:
4a4d8108
AM
20382+ AuLabel(revert dir);
20383+ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
20384+ if (rerr) {
523b37e3
AM
20385+ AuIOErr("%pd reverting dir failed(%d, %d)\n",
20386+ dentry, err, rerr);
4a4d8108
AM
20387+ err = -EIO;
20388+ }
4a4d8108 20389+ au_dtime_revert(&a->dt);
027c5e7a 20390+out_unpin:
4a4d8108
AM
20391+ au_unpin(&a->pin);
20392+ dput(wh_dentry);
027c5e7a
AM
20393+out_parent:
20394+ di_write_unlock(parent);
20395+out_unlock:
4a4d8108 20396+ if (unlikely(err)) {
5afbbe0d 20397+ au_update_dbtop(dentry);
4a4d8108
AM
20398+ d_drop(dentry);
20399+ }
4a4d8108 20400+ aufs_read_unlock(dentry, AuLock_DW);
027c5e7a 20401+out_free:
ae9dfd79 20402+ kfree(a);
4f0767ce 20403+out:
4a4d8108
AM
20404+ return err;
20405+}
7f207e10
AM
20406diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
20407--- /usr/share/empty/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
20408+++ linux/fs/aufs/i_op.c 2018-04-15 08:49:13.401150731 +0200
20409@@ -0,0 +1,1459 @@
4a4d8108 20410+/*
ae9dfd79 20411+ * Copyright (C) 2005-2018 Junjiro R. Okajima
4a4d8108
AM
20412+ *
20413+ * This program, aufs is free software; you can redistribute it and/or modify
20414+ * it under the terms of the GNU General Public License as published by
20415+ * the Free Software Foundation; either version 2 of the License, or
20416+ * (at your option) any later version.
20417+ *
20418+ * This program is distributed in the hope that it will be useful,
20419+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20420+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20421+ * GNU General Public License for more details.
20422+ *
20423+ * You should have received a copy of the GNU General Public License
523b37e3 20424+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 20425+ */
1facf9fc 20426+
1308ab2a 20427+/*
4a4d8108 20428+ * inode operations (except add/del/rename)
1308ab2a 20429+ */
4a4d8108
AM
20430+
20431+#include <linux/device_cgroup.h>
20432+#include <linux/fs_stack.h>
4a4d8108
AM
20433+#include <linux/namei.h>
20434+#include <linux/security.h>
4a4d8108
AM
20435+#include "aufs.h"
20436+
1e00d052 20437+static int h_permission(struct inode *h_inode, int mask,
79b8bda9 20438+ struct path *h_path, int brperm)
1facf9fc 20439+{
1308ab2a 20440+ int err;
4a4d8108 20441+ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
1facf9fc 20442+
e2f27e51
AM
20443+ err = -EPERM;
20444+ if (write_mask && IS_IMMUTABLE(h_inode))
20445+ goto out;
20446+
4a4d8108 20447+ err = -EACCES;
e2f27e51
AM
20448+ if (((mask & MAY_EXEC)
20449+ && S_ISREG(h_inode->i_mode)
20450+ && (path_noexec(h_path)
20451+ || !(h_inode->i_mode & S_IXUGO))))
4a4d8108
AM
20452+ goto out;
20453+
20454+ /*
20455+ * - skip the lower fs test in the case of write to ro branch.
20456+ * - nfs dir permission write check is optimized, but a policy for
20457+ * link/rename requires a real check.
b912730e
AM
20458+ * - nfs always sets MS_POSIXACL regardless its mount option 'noacl.'
20459+ * in this case, generic_permission() returns -EOPNOTSUPP.
4a4d8108
AM
20460+ */
20461+ if ((write_mask && !au_br_writable(brperm))
20462+ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
20463+ && write_mask && !(mask & MAY_READ))
20464+ || !h_inode->i_op->permission) {
20465+ /* AuLabel(generic_permission); */
b912730e 20466+ /* AuDbg("get_acl %pf\n", h_inode->i_op->get_acl); */
1e00d052 20467+ err = generic_permission(h_inode, mask);
b912730e
AM
20468+ if (err == -EOPNOTSUPP && au_test_nfs_noacl(h_inode))
20469+ err = h_inode->i_op->permission(h_inode, mask);
20470+ AuTraceErr(err);
1308ab2a 20471+ } else {
4a4d8108 20472+ /* AuLabel(h_inode->permission); */
1e00d052 20473+ err = h_inode->i_op->permission(h_inode, mask);
4a4d8108
AM
20474+ AuTraceErr(err);
20475+ }
1facf9fc 20476+
4a4d8108
AM
20477+ if (!err)
20478+ err = devcgroup_inode_permission(h_inode, mask);
7f207e10 20479+ if (!err)
4a4d8108 20480+ err = security_inode_permission(h_inode, mask);
4a4d8108
AM
20481+
20482+#if 0
20483+ if (!err) {
20484+ /* todo: do we need to call ima_path_check()? */
20485+ struct path h_path = {
20486+ .dentry =
20487+ .mnt = h_mnt
20488+ };
20489+ err = ima_path_check(&h_path,
20490+ mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
20491+ IMA_COUNT_LEAVE);
1308ab2a 20492+ }
4a4d8108 20493+#endif
dece6358 20494+
4f0767ce 20495+out:
1308ab2a 20496+ return err;
20497+}
dece6358 20498+
1e00d052 20499+static int aufs_permission(struct inode *inode, int mask)
1308ab2a 20500+{
20501+ int err;
5afbbe0d 20502+ aufs_bindex_t bindex, bbot;
4a4d8108
AM
20503+ const unsigned char isdir = !!S_ISDIR(inode->i_mode),
20504+ write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
20505+ struct inode *h_inode;
20506+ struct super_block *sb;
20507+ struct au_branch *br;
1facf9fc 20508+
027c5e7a 20509+ /* todo: support rcu-walk? */
1e00d052 20510+ if (mask & MAY_NOT_BLOCK)
027c5e7a
AM
20511+ return -ECHILD;
20512+
4a4d8108
AM
20513+ sb = inode->i_sb;
20514+ si_read_lock(sb, AuLock_FLUSH);
20515+ ii_read_lock_child(inode);
027c5e7a
AM
20516+#if 0
20517+ err = au_iigen_test(inode, au_sigen(sb));
20518+ if (unlikely(err))
20519+ goto out;
20520+#endif
dece6358 20521+
076b876e
AM
20522+ if (!isdir
20523+ || write_mask
20524+ || au_opt_test(au_mntflags(sb), DIRPERM1)) {
4a4d8108 20525+ err = au_busy_or_stale();
5afbbe0d 20526+ h_inode = au_h_iptr(inode, au_ibtop(inode));
4a4d8108
AM
20527+ if (unlikely(!h_inode
20528+ || (h_inode->i_mode & S_IFMT)
20529+ != (inode->i_mode & S_IFMT)))
20530+ goto out;
1facf9fc 20531+
4a4d8108 20532+ err = 0;
5afbbe0d 20533+ bindex = au_ibtop(inode);
4a4d8108 20534+ br = au_sbr(sb, bindex);
79b8bda9 20535+ err = h_permission(h_inode, mask, &br->br_path, br->br_perm);
4a4d8108
AM
20536+ if (write_mask
20537+ && !err
20538+ && !special_file(h_inode->i_mode)) {
20539+ /* test whether the upper writable branch exists */
20540+ err = -EROFS;
20541+ for (; bindex >= 0; bindex--)
20542+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
20543+ err = 0;
20544+ break;
20545+ }
20546+ }
20547+ goto out;
20548+ }
dece6358 20549+
4a4d8108 20550+ /* non-write to dir */
1308ab2a 20551+ err = 0;
5afbbe0d
AM
20552+ bbot = au_ibbot(inode);
20553+ for (bindex = au_ibtop(inode); !err && bindex <= bbot; bindex++) {
4a4d8108
AM
20554+ h_inode = au_h_iptr(inode, bindex);
20555+ if (h_inode) {
20556+ err = au_busy_or_stale();
20557+ if (unlikely(!S_ISDIR(h_inode->i_mode)))
20558+ break;
20559+
20560+ br = au_sbr(sb, bindex);
79b8bda9 20561+ err = h_permission(h_inode, mask, &br->br_path,
4a4d8108
AM
20562+ br->br_perm);
20563+ }
20564+ }
1308ab2a 20565+
4f0767ce 20566+out:
4a4d8108
AM
20567+ ii_read_unlock(inode);
20568+ si_read_unlock(sb);
1308ab2a 20569+ return err;
20570+}
20571+
4a4d8108 20572+/* ---------------------------------------------------------------------- */
1facf9fc 20573+
4a4d8108 20574+static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
b4510431 20575+ unsigned int flags)
4a4d8108
AM
20576+{
20577+ struct dentry *ret, *parent;
b752ccd1 20578+ struct inode *inode;
4a4d8108 20579+ struct super_block *sb;
1716fcea 20580+ int err, npositive;
dece6358 20581+
4a4d8108 20582+ IMustLock(dir);
1308ab2a 20583+
537831f9
AM
20584+ /* todo: support rcu-walk? */
20585+ ret = ERR_PTR(-ECHILD);
20586+ if (flags & LOOKUP_RCU)
20587+ goto out;
20588+
20589+ ret = ERR_PTR(-ENAMETOOLONG);
20590+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
20591+ goto out;
20592+
4a4d8108 20593+ sb = dir->i_sb;
7f207e10
AM
20594+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
20595+ ret = ERR_PTR(err);
20596+ if (unlikely(err))
20597+ goto out;
20598+
4a4d8108
AM
20599+ err = au_di_init(dentry);
20600+ ret = ERR_PTR(err);
20601+ if (unlikely(err))
7f207e10 20602+ goto out_si;
1308ab2a 20603+
9dbd164d 20604+ inode = NULL;
027c5e7a 20605+ npositive = 0; /* suppress a warning */
4a4d8108
AM
20606+ parent = dentry->d_parent; /* dir inode is locked */
20607+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
20608+ err = au_alive_dir(parent);
20609+ if (!err)
20610+ err = au_digen_test(parent, au_sigen(sb));
20611+ if (!err) {
5afbbe0d
AM
20612+ /* regardless LOOKUP_CREATE, always ALLOW_NEG */
20613+ npositive = au_lkup_dentry(dentry, au_dbtop(parent),
20614+ AuLkup_ALLOW_NEG);
027c5e7a
AM
20615+ err = npositive;
20616+ }
4a4d8108 20617+ di_read_unlock(parent, AuLock_IR);
4a4d8108
AM
20618+ ret = ERR_PTR(err);
20619+ if (unlikely(err < 0))
20620+ goto out_unlock;
1308ab2a 20621+
4a4d8108 20622+ if (npositive) {
b752ccd1 20623+ inode = au_new_inode(dentry, /*must_new*/0);
c1595e42
JR
20624+ if (IS_ERR(inode)) {
20625+ ret = (void *)inode;
20626+ inode = NULL;
20627+ goto out_unlock;
20628+ }
9dbd164d 20629+ }
4a4d8108 20630+
c1595e42
JR
20631+ if (inode)
20632+ atomic_inc(&inode->i_count);
4a4d8108 20633+ ret = d_splice_alias(inode, dentry);
537831f9
AM
20634+#if 0
20635+ if (unlikely(d_need_lookup(dentry))) {
20636+ spin_lock(&dentry->d_lock);
20637+ dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
20638+ spin_unlock(&dentry->d_lock);
20639+ } else
20640+#endif
c1595e42 20641+ if (inode) {
2000de60 20642+ if (!IS_ERR(ret)) {
c1595e42 20643+ iput(inode);
2000de60
JR
20644+ if (ret && ret != dentry)
20645+ ii_write_unlock(inode);
20646+ } else {
c1595e42
JR
20647+ ii_write_unlock(inode);
20648+ iput(inode);
20649+ inode = NULL;
20650+ }
7f207e10 20651+ }
1facf9fc 20652+
4f0767ce 20653+out_unlock:
4a4d8108 20654+ di_write_unlock(dentry);
7f207e10 20655+out_si:
4a4d8108 20656+ si_read_unlock(sb);
7f207e10 20657+out:
4a4d8108
AM
20658+ return ret;
20659+}
1facf9fc 20660+
4a4d8108 20661+/* ---------------------------------------------------------------------- */
1facf9fc 20662+
b912730e 20663+struct aopen_node {
ae9dfd79 20664+ struct hlist_bl_node hblist;
b912730e
AM
20665+ struct file *file, *h_file;
20666+};
20667+
20668+static int au_do_aopen(struct inode *inode, struct file *file)
20669+{
ae9dfd79
AM
20670+ struct hlist_bl_head *aopen;
20671+ struct hlist_bl_node *pos;
b912730e
AM
20672+ struct aopen_node *node;
20673+ struct au_do_open_args args = {
ae9dfd79
AM
20674+ .aopen = 1,
20675+ .open = au_do_open_nondir
b912730e
AM
20676+ };
20677+
20678+ aopen = &au_sbi(inode->i_sb)->si_aopen;
ae9dfd79
AM
20679+ hlist_bl_lock(aopen);
20680+ hlist_bl_for_each_entry(node, pos, aopen, hblist)
b912730e
AM
20681+ if (node->file == file) {
20682+ args.h_file = node->h_file;
20683+ break;
20684+ }
ae9dfd79 20685+ hlist_bl_unlock(aopen);
b912730e
AM
20686+ /* AuDebugOn(!args.h_file); */
20687+
20688+ return au_do_open(file, &args);
20689+}
20690+
20691+static int aufs_atomic_open(struct inode *dir, struct dentry *dentry,
20692+ struct file *file, unsigned int open_flag,
20693+ umode_t create_mode, int *opened)
20694+{
ae9dfd79 20695+ int err, unlocked, h_opened = *opened;
5afbbe0d 20696+ unsigned int lkup_flags;
f0c0a007 20697+ struct dentry *parent, *d;
ae9dfd79 20698+ struct hlist_bl_head *aopen;
b912730e
AM
20699+ struct vfsub_aopen_args args = {
20700+ .open_flag = open_flag,
20701+ .create_mode = create_mode,
20702+ .opened = &h_opened
20703+ };
20704+ struct aopen_node aopen_node = {
20705+ .file = file
20706+ };
20707+
20708+ IMustLock(dir);
5afbbe0d 20709+ AuDbg("open_flag 0%o\n", open_flag);
b912730e
AM
20710+ AuDbgDentry(dentry);
20711+
20712+ err = 0;
20713+ if (!au_di(dentry)) {
5afbbe0d
AM
20714+ lkup_flags = LOOKUP_OPEN;
20715+ if (open_flag & O_CREAT)
20716+ lkup_flags |= LOOKUP_CREATE;
20717+ d = aufs_lookup(dir, dentry, lkup_flags);
b912730e
AM
20718+ if (IS_ERR(d)) {
20719+ err = PTR_ERR(d);
5afbbe0d 20720+ AuTraceErr(err);
b912730e
AM
20721+ goto out;
20722+ } else if (d) {
20723+ /*
20724+ * obsoleted dentry found.
20725+ * another error will be returned later.
20726+ */
20727+ d_drop(d);
b912730e 20728+ AuDbgDentry(d);
5afbbe0d 20729+ dput(d);
b912730e
AM
20730+ }
20731+ AuDbgDentry(dentry);
20732+ }
20733+
20734+ if (d_is_positive(dentry)
20735+ || d_unhashed(dentry)
20736+ || d_unlinked(dentry)
20737+ || !(open_flag & O_CREAT))
20738+ goto out_no_open;
20739+
ae9dfd79 20740+ unlocked = 0;
b912730e
AM
20741+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
20742+ if (unlikely(err))
20743+ goto out;
20744+
20745+ parent = dentry->d_parent; /* dir is locked */
20746+ di_write_lock_parent(parent);
5afbbe0d 20747+ err = au_lkup_dentry(dentry, /*btop*/0, AuLkup_ALLOW_NEG);
b912730e
AM
20748+ if (unlikely(err))
20749+ goto out_unlock;
20750+
20751+ AuDbgDentry(dentry);
20752+ if (d_is_positive(dentry))
20753+ goto out_unlock;
20754+
20755+ args.file = get_empty_filp();
20756+ err = PTR_ERR(args.file);
20757+ if (IS_ERR(args.file))
20758+ goto out_unlock;
20759+
20760+ args.file->f_flags = file->f_flags;
20761+ err = au_aopen_or_create(dir, dentry, &args);
20762+ AuTraceErr(err);
20763+ AuDbgFile(args.file);
20764+ if (unlikely(err < 0)) {
20765+ if (h_opened & FILE_OPENED)
20766+ fput(args.file);
20767+ else
20768+ put_filp(args.file);
20769+ goto out_unlock;
20770+ }
ae9dfd79
AM
20771+ di_write_unlock(parent);
20772+ di_write_unlock(dentry);
20773+ unlocked = 1;
b912730e
AM
20774+
20775+ /* some filesystems don't set FILE_CREATED while succeeded? */
20776+ *opened |= FILE_CREATED;
20777+ if (h_opened & FILE_OPENED)
20778+ aopen_node.h_file = args.file;
20779+ else {
20780+ put_filp(args.file);
20781+ args.file = NULL;
20782+ }
20783+ aopen = &au_sbi(dir->i_sb)->si_aopen;
ae9dfd79 20784+ au_hbl_add(&aopen_node.hblist, aopen);
b912730e 20785+ err = finish_open(file, dentry, au_do_aopen, opened);
ae9dfd79 20786+ au_hbl_del(&aopen_node.hblist, aopen);
b912730e
AM
20787+ AuTraceErr(err);
20788+ AuDbgFile(file);
20789+ if (aopen_node.h_file)
20790+ fput(aopen_node.h_file);
20791+
20792+out_unlock:
ae9dfd79
AM
20793+ if (unlocked)
20794+ si_read_unlock(dentry->d_sb);
20795+ else {
20796+ di_write_unlock(parent);
20797+ aufs_read_unlock(dentry, AuLock_DW);
20798+ }
b912730e 20799+ AuDbgDentry(dentry);
f0c0a007 20800+ if (unlikely(err < 0))
b912730e
AM
20801+ goto out;
20802+out_no_open:
f0c0a007 20803+ if (err >= 0 && !(*opened & FILE_CREATED)) {
b912730e
AM
20804+ AuLabel(out_no_open);
20805+ dget(dentry);
20806+ err = finish_no_open(file, dentry);
20807+ }
20808+out:
20809+ AuDbg("%pd%s%s\n", dentry,
20810+ (*opened & FILE_CREATED) ? " created" : "",
20811+ (*opened & FILE_OPENED) ? " opened" : "");
20812+ AuTraceErr(err);
20813+ return err;
20814+}
20815+
20816+
20817+/* ---------------------------------------------------------------------- */
20818+
4a4d8108
AM
20819+static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
20820+ const unsigned char add_entry, aufs_bindex_t bcpup,
5afbbe0d 20821+ aufs_bindex_t btop)
4a4d8108
AM
20822+{
20823+ int err;
20824+ struct dentry *h_parent;
20825+ struct inode *h_dir;
1facf9fc 20826+
027c5e7a 20827+ if (add_entry)
5527c038 20828+ IMustLock(d_inode(parent));
027c5e7a 20829+ else
4a4d8108
AM
20830+ di_write_lock_parent(parent);
20831+
20832+ err = 0;
20833+ if (!au_h_dptr(parent, bcpup)) {
5afbbe0d 20834+ if (btop > bcpup)
c2b27bf2 20835+ err = au_cpup_dirs(dentry, bcpup);
5afbbe0d 20836+ else if (btop < bcpup)
4a4d8108
AM
20837+ err = au_cpdown_dirs(dentry, bcpup);
20838+ else
c2b27bf2 20839+ BUG();
4a4d8108 20840+ }
38d290e6 20841+ if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) {
4a4d8108 20842+ h_parent = au_h_dptr(parent, bcpup);
5527c038 20843+ h_dir = d_inode(h_parent);
ae9dfd79 20844+ vfsub_inode_lock_shared_nested(h_dir, AuLsc_I_PARENT);
7e9cd9fe 20845+ err = au_lkup_neg(dentry, bcpup, /*wh*/0);
4a4d8108 20846+ /* todo: no unlock here */
ae9dfd79 20847+ inode_unlock_shared(h_dir);
027c5e7a
AM
20848+
20849+ AuDbg("bcpup %d\n", bcpup);
20850+ if (!err) {
5527c038 20851+ if (d_really_is_negative(dentry))
5afbbe0d 20852+ au_set_h_dptr(dentry, btop, NULL);
4a4d8108
AM
20853+ au_update_dbrange(dentry, /*do_put_zero*/0);
20854+ }
1308ab2a 20855+ }
1facf9fc 20856+
4a4d8108
AM
20857+ if (!add_entry)
20858+ di_write_unlock(parent);
20859+ if (!err)
20860+ err = bcpup; /* success */
1308ab2a 20861+
027c5e7a 20862+ AuTraceErr(err);
4a4d8108
AM
20863+ return err;
20864+}
1facf9fc 20865+
4a4d8108
AM
20866+/*
20867+ * decide the branch and the parent dir where we will create a new entry.
20868+ * returns new bindex or an error.
20869+ * copyup the parent dir if needed.
20870+ */
20871+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
20872+ struct au_wr_dir_args *args)
20873+{
20874+ int err;
392086de 20875+ unsigned int flags;
5afbbe0d 20876+ aufs_bindex_t bcpup, btop, src_btop;
86dc4139
AM
20877+ const unsigned char add_entry
20878+ = au_ftest_wrdir(args->flags, ADD_ENTRY)
38d290e6 20879+ | au_ftest_wrdir(args->flags, TMPFILE);
4a4d8108
AM
20880+ struct super_block *sb;
20881+ struct dentry *parent;
20882+ struct au_sbinfo *sbinfo;
1facf9fc 20883+
4a4d8108
AM
20884+ sb = dentry->d_sb;
20885+ sbinfo = au_sbi(sb);
20886+ parent = dget_parent(dentry);
5afbbe0d
AM
20887+ btop = au_dbtop(dentry);
20888+ bcpup = btop;
4a4d8108
AM
20889+ if (args->force_btgt < 0) {
20890+ if (src_dentry) {
5afbbe0d
AM
20891+ src_btop = au_dbtop(src_dentry);
20892+ if (src_btop < btop)
20893+ bcpup = src_btop;
4a4d8108 20894+ } else if (add_entry) {
392086de
AM
20895+ flags = 0;
20896+ if (au_ftest_wrdir(args->flags, ISDIR))
20897+ au_fset_wbr(flags, DIR);
20898+ err = AuWbrCreate(sbinfo, dentry, flags);
4a4d8108
AM
20899+ bcpup = err;
20900+ }
1facf9fc 20901+
5527c038 20902+ if (bcpup < 0 || au_test_ro(sb, bcpup, d_inode(dentry))) {
4a4d8108
AM
20903+ if (add_entry)
20904+ err = AuWbrCopyup(sbinfo, dentry);
20905+ else {
20906+ if (!IS_ROOT(dentry)) {
20907+ di_read_lock_parent(parent, !AuLock_IR);
20908+ err = AuWbrCopyup(sbinfo, dentry);
20909+ di_read_unlock(parent, !AuLock_IR);
20910+ } else
20911+ err = AuWbrCopyup(sbinfo, dentry);
20912+ }
20913+ bcpup = err;
20914+ if (unlikely(err < 0))
20915+ goto out;
20916+ }
20917+ } else {
20918+ bcpup = args->force_btgt;
5527c038 20919+ AuDebugOn(au_test_ro(sb, bcpup, d_inode(dentry)));
1308ab2a 20920+ }
027c5e7a 20921+
5afbbe0d 20922+ AuDbg("btop %d, bcpup %d\n", btop, bcpup);
4a4d8108 20923+ err = bcpup;
5afbbe0d 20924+ if (bcpup == btop)
4a4d8108 20925+ goto out; /* success */
4a4d8108
AM
20926+
20927+ /* copyup the new parent into the branch we process */
5afbbe0d 20928+ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, btop);
027c5e7a 20929+ if (err >= 0) {
5527c038 20930+ if (d_really_is_negative(dentry)) {
5afbbe0d
AM
20931+ au_set_h_dptr(dentry, btop, NULL);
20932+ au_set_dbtop(dentry, bcpup);
20933+ au_set_dbbot(dentry, bcpup);
027c5e7a 20934+ }
38d290e6
JR
20935+ AuDebugOn(add_entry
20936+ && !au_ftest_wrdir(args->flags, TMPFILE)
20937+ && !au_h_dptr(dentry, bcpup));
027c5e7a 20938+ }
86dc4139
AM
20939+
20940+out:
20941+ dput(parent);
20942+ return err;
20943+}
20944+
20945+/* ---------------------------------------------------------------------- */
20946+
20947+void au_pin_hdir_unlock(struct au_pin *p)
20948+{
20949+ if (p->hdir)
5afbbe0d 20950+ au_hn_inode_unlock(p->hdir);
86dc4139
AM
20951+}
20952+
c1595e42 20953+int au_pin_hdir_lock(struct au_pin *p)
86dc4139
AM
20954+{
20955+ int err;
20956+
20957+ err = 0;
20958+ if (!p->hdir)
20959+ goto out;
20960+
20961+ /* even if an error happens later, keep this lock */
5afbbe0d 20962+ au_hn_inode_lock_nested(p->hdir, p->lsc_hi);
86dc4139
AM
20963+
20964+ err = -EBUSY;
5527c038 20965+ if (unlikely(p->hdir->hi_inode != d_inode(p->h_parent)))
86dc4139
AM
20966+ goto out;
20967+
20968+ err = 0;
20969+ if (p->h_dentry)
20970+ err = au_h_verify(p->h_dentry, p->udba, p->hdir->hi_inode,
20971+ p->h_parent, p->br);
20972+
20973+out:
20974+ return err;
20975+}
20976+
20977+int au_pin_hdir_relock(struct au_pin *p)
20978+{
20979+ int err, i;
20980+ struct inode *h_i;
20981+ struct dentry *h_d[] = {
20982+ p->h_dentry,
20983+ p->h_parent
20984+ };
20985+
20986+ err = au_pin_hdir_lock(p);
20987+ if (unlikely(err))
20988+ goto out;
20989+
20990+ for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) {
20991+ if (!h_d[i])
20992+ continue;
5527c038
JR
20993+ if (d_is_positive(h_d[i])) {
20994+ h_i = d_inode(h_d[i]);
86dc4139 20995+ err = !h_i->i_nlink;
5527c038 20996+ }
86dc4139
AM
20997+ }
20998+
20999+out:
21000+ return err;
21001+}
21002+
5afbbe0d 21003+static void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task)
86dc4139 21004+{
5afbbe0d
AM
21005+#if !defined(CONFIG_RWSEM_GENERIC_SPINLOCK) && defined(CONFIG_RWSEM_SPIN_ON_OWNER)
21006+ p->hdir->hi_inode->i_rwsem.owner = task;
86dc4139
AM
21007+#endif
21008+}
21009+
21010+void au_pin_hdir_acquire_nest(struct au_pin *p)
21011+{
21012+ if (p->hdir) {
5afbbe0d 21013+ rwsem_acquire_nest(&p->hdir->hi_inode->i_rwsem.dep_map,
86dc4139
AM
21014+ p->lsc_hi, 0, NULL, _RET_IP_);
21015+ au_pin_hdir_set_owner(p, current);
21016+ }
dece6358 21017+}
1facf9fc 21018+
86dc4139
AM
21019+void au_pin_hdir_release(struct au_pin *p)
21020+{
21021+ if (p->hdir) {
21022+ au_pin_hdir_set_owner(p, p->task);
5afbbe0d 21023+ rwsem_release(&p->hdir->hi_inode->i_rwsem.dep_map, 1, _RET_IP_);
86dc4139
AM
21024+ }
21025+}
1308ab2a 21026+
4a4d8108 21027+struct dentry *au_pinned_h_parent(struct au_pin *pin)
1308ab2a 21028+{
4a4d8108
AM
21029+ if (pin && pin->parent)
21030+ return au_h_dptr(pin->parent, pin->bindex);
21031+ return NULL;
dece6358 21032+}
1facf9fc 21033+
4a4d8108 21034+void au_unpin(struct au_pin *p)
dece6358 21035+{
86dc4139
AM
21036+ if (p->hdir)
21037+ au_pin_hdir_unlock(p);
e49829fe 21038+ if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE))
b4510431 21039+ vfsub_mnt_drop_write(p->h_mnt);
4a4d8108
AM
21040+ if (!p->hdir)
21041+ return;
1facf9fc 21042+
4a4d8108
AM
21043+ if (!au_ftest_pin(p->flags, DI_LOCKED))
21044+ di_read_unlock(p->parent, AuLock_IR);
21045+ iput(p->hdir->hi_inode);
21046+ dput(p->parent);
21047+ p->parent = NULL;
21048+ p->hdir = NULL;
21049+ p->h_mnt = NULL;
86dc4139 21050+ /* do not clear p->task */
4a4d8108 21051+}
1308ab2a 21052+
4a4d8108
AM
21053+int au_do_pin(struct au_pin *p)
21054+{
21055+ int err;
21056+ struct super_block *sb;
4a4d8108
AM
21057+ struct inode *h_dir;
21058+
21059+ err = 0;
21060+ sb = p->dentry->d_sb;
86dc4139 21061+ p->br = au_sbr(sb, p->bindex);
4a4d8108
AM
21062+ if (IS_ROOT(p->dentry)) {
21063+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 21064+ p->h_mnt = au_br_mnt(p->br);
b4510431 21065+ err = vfsub_mnt_want_write(p->h_mnt);
4a4d8108
AM
21066+ if (unlikely(err)) {
21067+ au_fclr_pin(p->flags, MNT_WRITE);
21068+ goto out_err;
21069+ }
21070+ }
dece6358 21071+ goto out;
1facf9fc 21072+ }
21073+
86dc4139 21074+ p->h_dentry = NULL;
5afbbe0d 21075+ if (p->bindex <= au_dbbot(p->dentry))
86dc4139 21076+ p->h_dentry = au_h_dptr(p->dentry, p->bindex);
dece6358 21077+
4a4d8108
AM
21078+ p->parent = dget_parent(p->dentry);
21079+ if (!au_ftest_pin(p->flags, DI_LOCKED))
21080+ di_read_lock(p->parent, AuLock_IR, p->lsc_di);
dece6358 21081+
4a4d8108 21082+ h_dir = NULL;
86dc4139 21083+ p->h_parent = au_h_dptr(p->parent, p->bindex);
5527c038 21084+ p->hdir = au_hi(d_inode(p->parent), p->bindex);
4a4d8108
AM
21085+ if (p->hdir)
21086+ h_dir = p->hdir->hi_inode;
dece6358 21087+
b752ccd1
AM
21088+ /*
21089+ * udba case, or
21090+ * if DI_LOCKED is not set, then p->parent may be different
21091+ * and h_parent can be NULL.
21092+ */
86dc4139 21093+ if (unlikely(!p->hdir || !h_dir || !p->h_parent)) {
e49829fe 21094+ err = -EBUSY;
4a4d8108
AM
21095+ if (!au_ftest_pin(p->flags, DI_LOCKED))
21096+ di_read_unlock(p->parent, AuLock_IR);
21097+ dput(p->parent);
21098+ p->parent = NULL;
21099+ goto out_err;
21100+ }
1308ab2a 21101+
4a4d8108 21102+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 21103+ p->h_mnt = au_br_mnt(p->br);
b4510431 21104+ err = vfsub_mnt_want_write(p->h_mnt);
dece6358 21105+ if (unlikely(err)) {
4a4d8108 21106+ au_fclr_pin(p->flags, MNT_WRITE);
86dc4139
AM
21107+ if (!au_ftest_pin(p->flags, DI_LOCKED))
21108+ di_read_unlock(p->parent, AuLock_IR);
21109+ dput(p->parent);
21110+ p->parent = NULL;
21111+ goto out_err;
dece6358
AM
21112+ }
21113+ }
4a4d8108 21114+
86dc4139
AM
21115+ au_igrab(h_dir);
21116+ err = au_pin_hdir_lock(p);
21117+ if (!err)
21118+ goto out; /* success */
21119+
076b876e
AM
21120+ au_unpin(p);
21121+
4f0767ce 21122+out_err:
4a4d8108
AM
21123+ pr_err("err %d\n", err);
21124+ err = au_busy_or_stale();
4f0767ce 21125+out:
1facf9fc 21126+ return err;
21127+}
21128+
4a4d8108
AM
21129+void au_pin_init(struct au_pin *p, struct dentry *dentry,
21130+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
21131+ unsigned int udba, unsigned char flags)
21132+{
21133+ p->dentry = dentry;
21134+ p->udba = udba;
21135+ p->lsc_di = lsc_di;
21136+ p->lsc_hi = lsc_hi;
21137+ p->flags = flags;
21138+ p->bindex = bindex;
21139+
21140+ p->parent = NULL;
21141+ p->hdir = NULL;
21142+ p->h_mnt = NULL;
86dc4139
AM
21143+
21144+ p->h_dentry = NULL;
21145+ p->h_parent = NULL;
21146+ p->br = NULL;
21147+ p->task = current;
4a4d8108
AM
21148+}
21149+
21150+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
21151+ unsigned int udba, unsigned char flags)
21152+{
21153+ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
21154+ udba, flags);
21155+ return au_do_pin(pin);
21156+}
21157+
dece6358
AM
21158+/* ---------------------------------------------------------------------- */
21159+
1308ab2a 21160+/*
4a4d8108
AM
21161+ * ->setattr() and ->getattr() are called in various cases.
21162+ * chmod, stat: dentry is revalidated.
21163+ * fchmod, fstat: file and dentry are not revalidated, additionally they may be
21164+ * unhashed.
21165+ * for ->setattr(), ia->ia_file is passed from ftruncate only.
1308ab2a 21166+ */
027c5e7a 21167+/* todo: consolidate with do_refresh() and simple_reval_dpath() */
c1595e42 21168+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
1facf9fc 21169+{
4a4d8108 21170+ int err;
4a4d8108 21171+ struct dentry *parent;
1facf9fc 21172+
1308ab2a 21173+ err = 0;
027c5e7a 21174+ if (au_digen_test(dentry, sigen)) {
4a4d8108
AM
21175+ parent = dget_parent(dentry);
21176+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 21177+ err = au_refresh_dentry(dentry, parent);
4a4d8108
AM
21178+ di_read_unlock(parent, AuLock_IR);
21179+ dput(parent);
dece6358 21180+ }
1facf9fc 21181+
4a4d8108 21182+ AuTraceErr(err);
1308ab2a 21183+ return err;
21184+}
dece6358 21185+
c1595e42
JR
21186+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
21187+ struct au_icpup_args *a)
1308ab2a 21188+{
21189+ int err;
4a4d8108 21190+ loff_t sz;
5afbbe0d 21191+ aufs_bindex_t btop, ibtop;
4a4d8108
AM
21192+ struct dentry *hi_wh, *parent;
21193+ struct inode *inode;
4a4d8108
AM
21194+ struct au_wr_dir_args wr_dir_args = {
21195+ .force_btgt = -1,
21196+ .flags = 0
21197+ };
21198+
2000de60 21199+ if (d_is_dir(dentry))
4a4d8108
AM
21200+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
21201+ /* plink or hi_wh() case */
5afbbe0d 21202+ btop = au_dbtop(dentry);
5527c038 21203+ inode = d_inode(dentry);
5afbbe0d
AM
21204+ ibtop = au_ibtop(inode);
21205+ if (btop != ibtop && !au_test_ro(inode->i_sb, ibtop, inode))
21206+ wr_dir_args.force_btgt = ibtop;
4a4d8108
AM
21207+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
21208+ if (unlikely(err < 0))
21209+ goto out;
21210+ a->btgt = err;
5afbbe0d 21211+ if (err != btop)
4a4d8108
AM
21212+ au_fset_icpup(a->flags, DID_CPUP);
21213+
21214+ err = 0;
21215+ a->pin_flags = AuPin_MNT_WRITE;
21216+ parent = NULL;
21217+ if (!IS_ROOT(dentry)) {
21218+ au_fset_pin(a->pin_flags, DI_LOCKED);
21219+ parent = dget_parent(dentry);
21220+ di_write_lock_parent(parent);
21221+ }
21222+
21223+ err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags);
21224+ if (unlikely(err))
21225+ goto out_parent;
21226+
4a4d8108 21227+ sz = -1;
5afbbe0d 21228+ a->h_path.dentry = au_h_dptr(dentry, btop);
5527c038 21229+ a->h_inode = d_inode(a->h_path.dentry);
c1595e42 21230+ if (ia && (ia->ia_valid & ATTR_SIZE)) {
ae9dfd79 21231+ vfsub_inode_lock_shared_nested(a->h_inode, AuLsc_I_CHILD);
c1595e42
JR
21232+ if (ia->ia_size < i_size_read(a->h_inode))
21233+ sz = ia->ia_size;
ae9dfd79 21234+ inode_unlock_shared(a->h_inode);
c1595e42 21235+ }
4a4d8108 21236+
4a4d8108 21237+ hi_wh = NULL;
027c5e7a 21238+ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) {
4a4d8108
AM
21239+ hi_wh = au_hi_wh(inode, a->btgt);
21240+ if (!hi_wh) {
c2b27bf2
AM
21241+ struct au_cp_generic cpg = {
21242+ .dentry = dentry,
21243+ .bdst = a->btgt,
21244+ .bsrc = -1,
21245+ .len = sz,
21246+ .pin = &a->pin
21247+ };
21248+ err = au_sio_cpup_wh(&cpg, /*file*/NULL);
4a4d8108
AM
21249+ if (unlikely(err))
21250+ goto out_unlock;
21251+ hi_wh = au_hi_wh(inode, a->btgt);
21252+ /* todo: revalidate hi_wh? */
21253+ }
21254+ }
21255+
21256+ if (parent) {
21257+ au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
21258+ di_downgrade_lock(parent, AuLock_IR);
21259+ dput(parent);
21260+ parent = NULL;
21261+ }
21262+ if (!au_ftest_icpup(a->flags, DID_CPUP))
21263+ goto out; /* success */
21264+
21265+ if (!d_unhashed(dentry)) {
c2b27bf2
AM
21266+ struct au_cp_generic cpg = {
21267+ .dentry = dentry,
21268+ .bdst = a->btgt,
5afbbe0d 21269+ .bsrc = btop,
c2b27bf2
AM
21270+ .len = sz,
21271+ .pin = &a->pin,
21272+ .flags = AuCpup_DTIME | AuCpup_HOPEN
21273+ };
21274+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
21275+ if (!err)
21276+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
21277+ } else if (!hi_wh)
21278+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
21279+ else
21280+ a->h_path.dentry = hi_wh; /* do not dget here */
1308ab2a 21281+
4f0767ce 21282+out_unlock:
5527c038 21283+ a->h_inode = d_inode(a->h_path.dentry);
86dc4139 21284+ if (!err)
dece6358 21285+ goto out; /* success */
4a4d8108 21286+ au_unpin(&a->pin);
4f0767ce 21287+out_parent:
4a4d8108
AM
21288+ if (parent) {
21289+ di_write_unlock(parent);
21290+ dput(parent);
21291+ }
4f0767ce 21292+out:
86dc4139 21293+ if (!err)
febd17d6 21294+ inode_lock_nested(a->h_inode, AuLsc_I_CHILD);
1facf9fc 21295+ return err;
21296+}
21297+
4a4d8108 21298+static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
1facf9fc 21299+{
4a4d8108 21300+ int err;
523b37e3 21301+ struct inode *inode, *delegated;
4a4d8108
AM
21302+ struct super_block *sb;
21303+ struct file *file;
21304+ struct au_icpup_args *a;
1facf9fc 21305+
5527c038 21306+ inode = d_inode(dentry);
4a4d8108 21307+ IMustLock(inode);
dece6358 21308+
f2c43d5f
AM
21309+ err = setattr_prepare(dentry, ia);
21310+ if (unlikely(err))
21311+ goto out;
21312+
4a4d8108
AM
21313+ err = -ENOMEM;
21314+ a = kzalloc(sizeof(*a), GFP_NOFS);
21315+ if (unlikely(!a))
21316+ goto out;
1facf9fc 21317+
4a4d8108
AM
21318+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
21319+ ia->ia_valid &= ~ATTR_MODE;
dece6358 21320+
4a4d8108
AM
21321+ file = NULL;
21322+ sb = dentry->d_sb;
e49829fe
JR
21323+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
21324+ if (unlikely(err))
21325+ goto out_kfree;
21326+
4a4d8108
AM
21327+ if (ia->ia_valid & ATTR_FILE) {
21328+ /* currently ftruncate(2) only */
7e9cd9fe 21329+ AuDebugOn(!d_is_reg(dentry));
4a4d8108 21330+ file = ia->ia_file;
ae9dfd79
AM
21331+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1,
21332+ /*fi_lsc*/0);
4a4d8108
AM
21333+ if (unlikely(err))
21334+ goto out_si;
21335+ ia->ia_file = au_hf_top(file);
21336+ a->udba = AuOpt_UDBA_NONE;
21337+ } else {
21338+ /* fchmod() doesn't pass ia_file */
21339+ a->udba = au_opt_udba(sb);
027c5e7a
AM
21340+ di_write_lock_child(dentry);
21341+ /* no d_unlinked(), to set UDBA_NONE for root */
4a4d8108
AM
21342+ if (d_unhashed(dentry))
21343+ a->udba = AuOpt_UDBA_NONE;
4a4d8108
AM
21344+ if (a->udba != AuOpt_UDBA_NONE) {
21345+ AuDebugOn(IS_ROOT(dentry));
21346+ err = au_reval_for_attr(dentry, au_sigen(sb));
21347+ if (unlikely(err))
21348+ goto out_dentry;
21349+ }
dece6358 21350+ }
dece6358 21351+
4a4d8108
AM
21352+ err = au_pin_and_icpup(dentry, ia, a);
21353+ if (unlikely(err < 0))
21354+ goto out_dentry;
21355+ if (au_ftest_icpup(a->flags, DID_CPUP)) {
21356+ ia->ia_file = NULL;
21357+ ia->ia_valid &= ~ATTR_FILE;
1308ab2a 21358+ }
dece6358 21359+
4a4d8108
AM
21360+ a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
21361+ if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME))
21362+ == (ATTR_MODE | ATTR_CTIME)) {
7eafdf33 21363+ err = security_path_chmod(&a->h_path, ia->ia_mode);
4a4d8108
AM
21364+ if (unlikely(err))
21365+ goto out_unlock;
21366+ } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
21367+ && (ia->ia_valid & ATTR_CTIME)) {
86dc4139 21368+ err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid);
4a4d8108
AM
21369+ if (unlikely(err))
21370+ goto out_unlock;
21371+ }
dece6358 21372+
4a4d8108
AM
21373+ if (ia->ia_valid & ATTR_SIZE) {
21374+ struct file *f;
1308ab2a 21375+
953406b4 21376+ if (ia->ia_size < i_size_read(inode))
4a4d8108 21377+ /* unmap only */
953406b4 21378+ truncate_setsize(inode, ia->ia_size);
1308ab2a 21379+
4a4d8108
AM
21380+ f = NULL;
21381+ if (ia->ia_valid & ATTR_FILE)
21382+ f = ia->ia_file;
febd17d6 21383+ inode_unlock(a->h_inode);
4a4d8108 21384+ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
febd17d6 21385+ inode_lock_nested(a->h_inode, AuLsc_I_CHILD);
523b37e3
AM
21386+ } else {
21387+ delegated = NULL;
21388+ while (1) {
21389+ err = vfsub_notify_change(&a->h_path, ia, &delegated);
21390+ if (delegated) {
21391+ err = break_deleg_wait(&delegated);
21392+ if (!err)
21393+ continue;
21394+ }
21395+ break;
21396+ }
21397+ }
8cdd5066
JR
21398+ /*
21399+ * regardless aufs 'acl' option setting.
21400+ * why don't all acl-aware fs call this func from their ->setattr()?
21401+ */
21402+ if (!err && (ia->ia_valid & ATTR_MODE))
21403+ err = vfsub_acl_chmod(a->h_inode, ia->ia_mode);
4a4d8108
AM
21404+ if (!err)
21405+ au_cpup_attr_changeable(inode);
1308ab2a 21406+
4f0767ce 21407+out_unlock:
febd17d6 21408+ inode_unlock(a->h_inode);
4a4d8108 21409+ au_unpin(&a->pin);
027c5e7a 21410+ if (unlikely(err))
5afbbe0d 21411+ au_update_dbtop(dentry);
4f0767ce 21412+out_dentry:
4a4d8108
AM
21413+ di_write_unlock(dentry);
21414+ if (file) {
21415+ fi_write_unlock(file);
21416+ ia->ia_file = file;
21417+ ia->ia_valid |= ATTR_FILE;
21418+ }
4f0767ce 21419+out_si:
4a4d8108 21420+ si_read_unlock(sb);
e49829fe 21421+out_kfree:
ae9dfd79 21422+ kfree(a);
4f0767ce 21423+out:
4a4d8108
AM
21424+ AuTraceErr(err);
21425+ return err;
1facf9fc 21426+}
21427+
c1595e42
JR
21428+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
21429+static int au_h_path_to_set_attr(struct dentry *dentry,
21430+ struct au_icpup_args *a, struct path *h_path)
21431+{
21432+ int err;
21433+ struct super_block *sb;
21434+
21435+ sb = dentry->d_sb;
21436+ a->udba = au_opt_udba(sb);
21437+ /* no d_unlinked(), to set UDBA_NONE for root */
21438+ if (d_unhashed(dentry))
21439+ a->udba = AuOpt_UDBA_NONE;
21440+ if (a->udba != AuOpt_UDBA_NONE) {
21441+ AuDebugOn(IS_ROOT(dentry));
21442+ err = au_reval_for_attr(dentry, au_sigen(sb));
21443+ if (unlikely(err))
21444+ goto out;
21445+ }
21446+ err = au_pin_and_icpup(dentry, /*ia*/NULL, a);
21447+ if (unlikely(err < 0))
21448+ goto out;
21449+
21450+ h_path->dentry = a->h_path.dentry;
21451+ h_path->mnt = au_sbr_mnt(sb, a->btgt);
21452+
21453+out:
21454+ return err;
21455+}
21456+
f2c43d5f
AM
21457+ssize_t au_sxattr(struct dentry *dentry, struct inode *inode,
21458+ struct au_sxattr *arg)
c1595e42
JR
21459+{
21460+ int err;
21461+ struct path h_path;
21462+ struct super_block *sb;
21463+ struct au_icpup_args *a;
5afbbe0d 21464+ struct inode *h_inode;
c1595e42 21465+
c1595e42
JR
21466+ IMustLock(inode);
21467+
21468+ err = -ENOMEM;
21469+ a = kzalloc(sizeof(*a), GFP_NOFS);
21470+ if (unlikely(!a))
21471+ goto out;
21472+
21473+ sb = dentry->d_sb;
21474+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
21475+ if (unlikely(err))
21476+ goto out_kfree;
21477+
21478+ h_path.dentry = NULL; /* silence gcc */
21479+ di_write_lock_child(dentry);
21480+ err = au_h_path_to_set_attr(dentry, a, &h_path);
21481+ if (unlikely(err))
21482+ goto out_di;
21483+
febd17d6 21484+ inode_unlock(a->h_inode);
c1595e42
JR
21485+ switch (arg->type) {
21486+ case AU_XATTR_SET:
5afbbe0d 21487+ AuDebugOn(d_is_negative(h_path.dentry));
c1595e42
JR
21488+ err = vfsub_setxattr(h_path.dentry,
21489+ arg->u.set.name, arg->u.set.value,
21490+ arg->u.set.size, arg->u.set.flags);
21491+ break;
c1595e42
JR
21492+ case AU_ACL_SET:
21493+ err = -EOPNOTSUPP;
5527c038 21494+ h_inode = d_inode(h_path.dentry);
c1595e42 21495+ if (h_inode->i_op->set_acl)
f2c43d5f 21496+ /* this will call posix_acl_update_mode */
c1595e42
JR
21497+ err = h_inode->i_op->set_acl(h_inode,
21498+ arg->u.acl_set.acl,
21499+ arg->u.acl_set.type);
21500+ break;
21501+ }
21502+ if (!err)
21503+ au_cpup_attr_timesizes(inode);
21504+
21505+ au_unpin(&a->pin);
21506+ if (unlikely(err))
5afbbe0d 21507+ au_update_dbtop(dentry);
c1595e42
JR
21508+
21509+out_di:
21510+ di_write_unlock(dentry);
21511+ si_read_unlock(sb);
21512+out_kfree:
ae9dfd79 21513+ kfree(a);
c1595e42
JR
21514+out:
21515+ AuTraceErr(err);
21516+ return err;
21517+}
21518+#endif
21519+
4a4d8108
AM
21520+static void au_refresh_iattr(struct inode *inode, struct kstat *st,
21521+ unsigned int nlink)
1facf9fc 21522+{
9dbd164d
AM
21523+ unsigned int n;
21524+
4a4d8108 21525+ inode->i_mode = st->mode;
86dc4139
AM
21526+ /* don't i_[ug]id_write() here */
21527+ inode->i_uid = st->uid;
21528+ inode->i_gid = st->gid;
4a4d8108
AM
21529+ inode->i_atime = st->atime;
21530+ inode->i_mtime = st->mtime;
21531+ inode->i_ctime = st->ctime;
1facf9fc 21532+
4a4d8108
AM
21533+ au_cpup_attr_nlink(inode, /*force*/0);
21534+ if (S_ISDIR(inode->i_mode)) {
9dbd164d
AM
21535+ n = inode->i_nlink;
21536+ n -= nlink;
21537+ n += st->nlink;
f6b6e03d 21538+ smp_mb(); /* for i_nlink */
7eafdf33 21539+ /* 0 can happen */
92d182d2 21540+ set_nlink(inode, n);
4a4d8108 21541+ }
1facf9fc 21542+
4a4d8108
AM
21543+ spin_lock(&inode->i_lock);
21544+ inode->i_blocks = st->blocks;
21545+ i_size_write(inode, st->size);
21546+ spin_unlock(&inode->i_lock);
1facf9fc 21547+}
21548+
c1595e42 21549+/*
f2c43d5f 21550+ * common routine for aufs_getattr() and au_getxattr().
c1595e42
JR
21551+ * returns zero or negative (an error).
21552+ * @dentry will be read-locked in success.
21553+ */
ae9dfd79
AM
21554+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path,
21555+ int locked)
1facf9fc 21556+{
4a4d8108 21557+ int err;
076b876e 21558+ unsigned int mnt_flags, sigen;
c1595e42 21559+ unsigned char udba_none;
4a4d8108 21560+ aufs_bindex_t bindex;
4a4d8108
AM
21561+ struct super_block *sb, *h_sb;
21562+ struct inode *inode;
1facf9fc 21563+
c1595e42
JR
21564+ h_path->mnt = NULL;
21565+ h_path->dentry = NULL;
21566+
21567+ err = 0;
4a4d8108 21568+ sb = dentry->d_sb;
4a4d8108
AM
21569+ mnt_flags = au_mntflags(sb);
21570+ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
1facf9fc 21571+
ae9dfd79
AM
21572+ if (unlikely(locked))
21573+ goto body; /* skip locking dinfo */
21574+
4a4d8108 21575+ /* support fstat(2) */
027c5e7a 21576+ if (!d_unlinked(dentry) && !udba_none) {
076b876e 21577+ sigen = au_sigen(sb);
027c5e7a
AM
21578+ err = au_digen_test(dentry, sigen);
21579+ if (!err) {
4a4d8108 21580+ di_read_lock_child(dentry, AuLock_IR);
027c5e7a 21581+ err = au_dbrange_test(dentry);
c1595e42
JR
21582+ if (unlikely(err)) {
21583+ di_read_unlock(dentry, AuLock_IR);
21584+ goto out;
21585+ }
027c5e7a 21586+ } else {
4a4d8108
AM
21587+ AuDebugOn(IS_ROOT(dentry));
21588+ di_write_lock_child(dentry);
027c5e7a
AM
21589+ err = au_dbrange_test(dentry);
21590+ if (!err)
21591+ err = au_reval_for_attr(dentry, sigen);
c1595e42
JR
21592+ if (!err)
21593+ di_downgrade_lock(dentry, AuLock_IR);
21594+ else {
21595+ di_write_unlock(dentry);
21596+ goto out;
21597+ }
4a4d8108
AM
21598+ }
21599+ } else
21600+ di_read_lock_child(dentry, AuLock_IR);
1facf9fc 21601+
ae9dfd79 21602+body:
5527c038 21603+ inode = d_inode(dentry);
5afbbe0d 21604+ bindex = au_ibtop(inode);
c1595e42
JR
21605+ h_path->mnt = au_sbr_mnt(sb, bindex);
21606+ h_sb = h_path->mnt->mnt_sb;
21607+ if (!force
21608+ && !au_test_fs_bad_iattr(h_sb)
21609+ && udba_none)
21610+ goto out; /* success */
1facf9fc 21611+
5afbbe0d 21612+ if (au_dbtop(dentry) == bindex)
c1595e42 21613+ h_path->dentry = au_h_dptr(dentry, bindex);
4a4d8108 21614+ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
c1595e42
JR
21615+ h_path->dentry = au_plink_lkup(inode, bindex);
21616+ if (IS_ERR(h_path->dentry))
21617+ /* pretending success */
21618+ h_path->dentry = NULL;
21619+ else
21620+ dput(h_path->dentry);
4a4d8108 21621+ }
c1595e42
JR
21622+
21623+out:
21624+ return err;
21625+}
21626+
21627+static int aufs_getattr(struct vfsmount *mnt __maybe_unused,
21628+ struct dentry *dentry, struct kstat *st)
21629+{
21630+ int err;
21631+ unsigned char positive;
21632+ struct path h_path;
21633+ struct inode *inode;
21634+ struct super_block *sb;
21635+
5527c038 21636+ inode = d_inode(dentry);
c1595e42
JR
21637+ sb = dentry->d_sb;
21638+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
21639+ if (unlikely(err))
21640+ goto out;
ae9dfd79 21641+ err = au_h_path_getattr(dentry, /*force*/0, &h_path, /*locked*/0);
c1595e42
JR
21642+ if (unlikely(err))
21643+ goto out_si;
c06a8ce3 21644+ if (unlikely(!h_path.dentry))
c1595e42 21645+ /* illegally overlapped or something */
4a4d8108
AM
21646+ goto out_fill; /* pretending success */
21647+
5527c038 21648+ positive = d_is_positive(h_path.dentry);
4a4d8108 21649+ if (positive)
c06a8ce3 21650+ err = vfs_getattr(&h_path, st);
4a4d8108
AM
21651+ if (!err) {
21652+ if (positive)
c06a8ce3 21653+ au_refresh_iattr(inode, st,
5527c038 21654+ d_inode(h_path.dentry)->i_nlink);
4a4d8108 21655+ goto out_fill; /* success */
1facf9fc 21656+ }
7f207e10 21657+ AuTraceErr(err);
c1595e42 21658+ goto out_di;
4a4d8108 21659+
4f0767ce 21660+out_fill:
4a4d8108 21661+ generic_fillattr(inode, st);
c1595e42 21662+out_di:
4a4d8108 21663+ di_read_unlock(dentry, AuLock_IR);
c1595e42 21664+out_si:
4a4d8108 21665+ si_read_unlock(sb);
7f207e10
AM
21666+out:
21667+ AuTraceErr(err);
4a4d8108 21668+ return err;
1facf9fc 21669+}
21670+
21671+/* ---------------------------------------------------------------------- */
21672+
febd17d6
JR
21673+static const char *aufs_get_link(struct dentry *dentry, struct inode *inode,
21674+ struct delayed_call *done)
4a4d8108 21675+{
c2c0f25c 21676+ const char *ret;
c2c0f25c 21677+ struct dentry *h_dentry;
febd17d6 21678+ struct inode *h_inode;
4a4d8108 21679+ int err;
c2c0f25c 21680+ aufs_bindex_t bindex;
1facf9fc 21681+
79b8bda9 21682+ ret = NULL; /* suppress a warning */
febd17d6
JR
21683+ err = -ECHILD;
21684+ if (!dentry)
21685+ goto out;
21686+
027c5e7a
AM
21687+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
21688+ if (unlikely(err))
c2c0f25c 21689+ goto out;
027c5e7a
AM
21690+
21691+ err = au_d_hashed_positive(dentry);
c2c0f25c
AM
21692+ if (unlikely(err))
21693+ goto out_unlock;
21694+
21695+ err = -EINVAL;
21696+ inode = d_inode(dentry);
5afbbe0d 21697+ bindex = au_ibtop(inode);
c2c0f25c 21698+ h_inode = au_h_iptr(inode, bindex);
febd17d6 21699+ if (unlikely(!h_inode->i_op->get_link))
c2c0f25c
AM
21700+ goto out_unlock;
21701+
21702+ err = -EBUSY;
21703+ h_dentry = NULL;
5afbbe0d 21704+ if (au_dbtop(dentry) <= bindex) {
c2c0f25c
AM
21705+ h_dentry = au_h_dptr(dentry, bindex);
21706+ if (h_dentry)
21707+ dget(h_dentry);
027c5e7a 21708+ }
c2c0f25c
AM
21709+ if (!h_dentry) {
21710+ h_dentry = d_find_any_alias(h_inode);
21711+ if (IS_ERR(h_dentry)) {
21712+ err = PTR_ERR(h_dentry);
febd17d6 21713+ goto out_unlock;
c2c0f25c
AM
21714+ }
21715+ }
21716+ if (unlikely(!h_dentry))
febd17d6 21717+ goto out_unlock;
1facf9fc 21718+
c2c0f25c 21719+ err = 0;
febd17d6 21720+ AuDbg("%pf\n", h_inode->i_op->get_link);
c2c0f25c 21721+ AuDbgDentry(h_dentry);
f2c43d5f 21722+ ret = vfs_get_link(h_dentry, done);
c2c0f25c 21723+ dput(h_dentry);
febd17d6
JR
21724+ if (IS_ERR(ret))
21725+ err = PTR_ERR(ret);
c2c0f25c 21726+
c2c0f25c
AM
21727+out_unlock:
21728+ aufs_read_unlock(dentry, AuLock_IR);
4f0767ce 21729+out:
c2c0f25c
AM
21730+ if (unlikely(err))
21731+ ret = ERR_PTR(err);
21732+ AuTraceErrPtr(ret);
21733+ return ret;
4a4d8108 21734+}
1facf9fc 21735+
4a4d8108 21736+/* ---------------------------------------------------------------------- */
1facf9fc 21737+
e2f27e51
AM
21738+static int au_is_special(struct inode *inode)
21739+{
21740+ return (inode->i_mode & (S_IFBLK | S_IFCHR | S_IFIFO | S_IFSOCK));
21741+}
21742+
0c3ec466 21743+static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags)
4a4d8108 21744+{
0c3ec466 21745+ int err;
e2f27e51 21746+ aufs_bindex_t bindex;
0c3ec466
AM
21747+ struct super_block *sb;
21748+ struct inode *h_inode;
e2f27e51 21749+ struct vfsmount *h_mnt;
0c3ec466
AM
21750+
21751+ sb = inode->i_sb;
e2f27e51
AM
21752+ WARN_ONCE((flags & S_ATIME) && !IS_NOATIME(inode),
21753+ "unexpected s_flags 0x%lx", sb->s_flags);
21754+
0c3ec466
AM
21755+ /* mmap_sem might be acquired already, cf. aufs_mmap() */
21756+ lockdep_off();
21757+ si_read_lock(sb, AuLock_FLUSH);
21758+ ii_write_lock_child(inode);
21759+ lockdep_on();
e2f27e51
AM
21760+
21761+ err = 0;
21762+ bindex = au_ibtop(inode);
21763+ h_inode = au_h_iptr(inode, bindex);
21764+ if (!au_test_ro(sb, bindex, inode)) {
21765+ h_mnt = au_sbr_mnt(sb, bindex);
21766+ err = vfsub_mnt_want_write(h_mnt);
21767+ if (!err) {
21768+ err = vfsub_update_time(h_inode, ts, flags);
21769+ vfsub_mnt_drop_write(h_mnt);
21770+ }
21771+ } else if (au_is_special(h_inode)) {
21772+ /*
21773+ * Never copy-up here.
21774+ * These special files may already be opened and used for
21775+ * communicating. If we copied it up, then the communication
21776+ * would be corrupted.
21777+ */
21778+ AuWarn1("timestamps for i%lu are ignored "
21779+ "since it is on readonly branch (hi%lu).\n",
21780+ inode->i_ino, h_inode->i_ino);
21781+ } else if (flags & ~S_ATIME) {
21782+ err = -EIO;
21783+ AuIOErr1("unexpected flags 0x%x\n", flags);
21784+ AuDebugOn(1);
21785+ }
21786+
0c3ec466 21787+ lockdep_off();
38d290e6
JR
21788+ if (!err)
21789+ au_cpup_attr_timesizes(inode);
0c3ec466
AM
21790+ ii_write_unlock(inode);
21791+ si_read_unlock(sb);
21792+ lockdep_on();
38d290e6
JR
21793+
21794+ if (!err && (flags & S_VERSION))
21795+ inode_inc_iversion(inode);
21796+
0c3ec466 21797+ return err;
4a4d8108 21798+}
1facf9fc 21799+
4a4d8108 21800+/* ---------------------------------------------------------------------- */
1308ab2a 21801+
b95c5147
AM
21802+/* no getattr version will be set by module.c:aufs_init() */
21803+struct inode_operations aufs_iop_nogetattr[AuIop_Last],
21804+ aufs_iop[] = {
21805+ [AuIop_SYMLINK] = {
21806+ .permission = aufs_permission,
c1595e42 21807+#ifdef CONFIG_FS_POSIX_ACL
b95c5147
AM
21808+ .get_acl = aufs_get_acl,
21809+ .set_acl = aufs_set_acl, /* unsupport for symlink? */
c1595e42
JR
21810+#endif
21811+
b95c5147
AM
21812+ .setattr = aufs_setattr,
21813+ .getattr = aufs_getattr,
0c3ec466 21814+
c1595e42 21815+#ifdef CONFIG_AUFS_XATTR
b95c5147 21816+ .listxattr = aufs_listxattr,
c1595e42
JR
21817+#endif
21818+
b95c5147 21819+ .readlink = generic_readlink,
febd17d6 21820+ .get_link = aufs_get_link,
0c3ec466 21821+
b95c5147
AM
21822+ /* .update_time = aufs_update_time */
21823+ },
21824+ [AuIop_DIR] = {
21825+ .create = aufs_create,
21826+ .lookup = aufs_lookup,
21827+ .link = aufs_link,
21828+ .unlink = aufs_unlink,
21829+ .symlink = aufs_symlink,
21830+ .mkdir = aufs_mkdir,
21831+ .rmdir = aufs_rmdir,
21832+ .mknod = aufs_mknod,
21833+ .rename = aufs_rename,
21834+
21835+ .permission = aufs_permission,
c1595e42 21836+#ifdef CONFIG_FS_POSIX_ACL
b95c5147
AM
21837+ .get_acl = aufs_get_acl,
21838+ .set_acl = aufs_set_acl,
c1595e42
JR
21839+#endif
21840+
b95c5147
AM
21841+ .setattr = aufs_setattr,
21842+ .getattr = aufs_getattr,
0c3ec466 21843+
c1595e42 21844+#ifdef CONFIG_AUFS_XATTR
b95c5147 21845+ .listxattr = aufs_listxattr,
c1595e42
JR
21846+#endif
21847+
b95c5147
AM
21848+ .update_time = aufs_update_time,
21849+ .atomic_open = aufs_atomic_open,
21850+ .tmpfile = aufs_tmpfile
21851+ },
21852+ [AuIop_OTHER] = {
21853+ .permission = aufs_permission,
c1595e42 21854+#ifdef CONFIG_FS_POSIX_ACL
b95c5147
AM
21855+ .get_acl = aufs_get_acl,
21856+ .set_acl = aufs_set_acl,
c1595e42
JR
21857+#endif
21858+
b95c5147
AM
21859+ .setattr = aufs_setattr,
21860+ .getattr = aufs_getattr,
0c3ec466 21861+
c1595e42 21862+#ifdef CONFIG_AUFS_XATTR
b95c5147 21863+ .listxattr = aufs_listxattr,
c1595e42
JR
21864+#endif
21865+
b95c5147
AM
21866+ .update_time = aufs_update_time
21867+ }
4a4d8108 21868+};
7f207e10
AM
21869diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
21870--- /usr/share/empty/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 21871+++ linux/fs/aufs/i_op_del.c 2018-04-15 08:49:13.401150731 +0200
5afbbe0d 21872@@ -0,0 +1,511 @@
1facf9fc 21873+/*
ae9dfd79 21874+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 21875+ *
21876+ * This program, aufs is free software; you can redistribute it and/or modify
21877+ * it under the terms of the GNU General Public License as published by
21878+ * the Free Software Foundation; either version 2 of the License, or
21879+ * (at your option) any later version.
dece6358
AM
21880+ *
21881+ * This program is distributed in the hope that it will be useful,
21882+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21883+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21884+ * GNU General Public License for more details.
21885+ *
21886+ * You should have received a copy of the GNU General Public License
523b37e3 21887+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 21888+ */
21889+
21890+/*
4a4d8108 21891+ * inode operations (del entry)
1308ab2a 21892+ */
dece6358 21893+
1308ab2a 21894+#include "aufs.h"
dece6358 21895+
4a4d8108
AM
21896+/*
21897+ * decide if a new whiteout for @dentry is necessary or not.
21898+ * when it is necessary, prepare the parent dir for the upper branch whose
21899+ * branch index is @bcpup for creation. the actual creation of the whiteout will
21900+ * be done by caller.
21901+ * return value:
21902+ * 0: wh is unnecessary
21903+ * plus: wh is necessary
21904+ * minus: error
21905+ */
21906+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
1308ab2a 21907+{
4a4d8108 21908+ int need_wh, err;
5afbbe0d 21909+ aufs_bindex_t btop;
4a4d8108 21910+ struct super_block *sb;
dece6358 21911+
4a4d8108 21912+ sb = dentry->d_sb;
5afbbe0d 21913+ btop = au_dbtop(dentry);
4a4d8108 21914+ if (*bcpup < 0) {
5afbbe0d
AM
21915+ *bcpup = btop;
21916+ if (au_test_ro(sb, btop, d_inode(dentry))) {
4a4d8108
AM
21917+ err = AuWbrCopyup(au_sbi(sb), dentry);
21918+ *bcpup = err;
21919+ if (unlikely(err < 0))
21920+ goto out;
21921+ }
21922+ } else
5afbbe0d 21923+ AuDebugOn(btop < *bcpup
5527c038 21924+ || au_test_ro(sb, *bcpup, d_inode(dentry)));
5afbbe0d 21925+ AuDbg("bcpup %d, btop %d\n", *bcpup, btop);
1308ab2a 21926+
5afbbe0d 21927+ if (*bcpup != btop) {
4a4d8108
AM
21928+ err = au_cpup_dirs(dentry, *bcpup);
21929+ if (unlikely(err))
21930+ goto out;
21931+ need_wh = 1;
21932+ } else {
027c5e7a 21933+ struct au_dinfo *dinfo, *tmp;
4a4d8108 21934+
027c5e7a
AM
21935+ need_wh = -ENOMEM;
21936+ dinfo = au_di(dentry);
21937+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
21938+ if (tmp) {
21939+ au_di_cp(tmp, dinfo);
21940+ au_di_swap(tmp, dinfo);
21941+ /* returns the number of positive dentries */
5afbbe0d
AM
21942+ need_wh = au_lkup_dentry(dentry, btop + 1,
21943+ /* AuLkup_IGNORE_PERM */ 0);
027c5e7a
AM
21944+ au_di_swap(tmp, dinfo);
21945+ au_rw_write_unlock(&tmp->di_rwsem);
21946+ au_di_free(tmp);
4a4d8108
AM
21947+ }
21948+ }
21949+ AuDbg("need_wh %d\n", need_wh);
21950+ err = need_wh;
21951+
4f0767ce 21952+out:
4a4d8108 21953+ return err;
1facf9fc 21954+}
21955+
4a4d8108
AM
21956+/*
21957+ * simple tests for the del-entry operations.
21958+ * following the checks in vfs, plus the parent-child relationship.
21959+ */
21960+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
21961+ struct dentry *h_parent, int isdir)
1facf9fc 21962+{
4a4d8108
AM
21963+ int err;
21964+ umode_t h_mode;
21965+ struct dentry *h_dentry, *h_latest;
1308ab2a 21966+ struct inode *h_inode;
1facf9fc 21967+
4a4d8108 21968+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 21969+ if (d_really_is_positive(dentry)) {
4a4d8108 21970+ err = -ENOENT;
5527c038
JR
21971+ if (unlikely(d_is_negative(h_dentry)))
21972+ goto out;
21973+ h_inode = d_inode(h_dentry);
21974+ if (unlikely(!h_inode->i_nlink))
4a4d8108 21975+ goto out;
1facf9fc 21976+
4a4d8108
AM
21977+ h_mode = h_inode->i_mode;
21978+ if (!isdir) {
21979+ err = -EISDIR;
21980+ if (unlikely(S_ISDIR(h_mode)))
21981+ goto out;
21982+ } else if (unlikely(!S_ISDIR(h_mode))) {
21983+ err = -ENOTDIR;
21984+ goto out;
21985+ }
21986+ } else {
21987+ /* rename(2) case */
21988+ err = -EIO;
5527c038 21989+ if (unlikely(d_is_positive(h_dentry)))
4a4d8108
AM
21990+ goto out;
21991+ }
1facf9fc 21992+
4a4d8108
AM
21993+ err = -ENOENT;
21994+ /* expected parent dir is locked */
21995+ if (unlikely(h_parent != h_dentry->d_parent))
21996+ goto out;
21997+ err = 0;
21998+
21999+ /*
22000+ * rmdir a dir may break the consistency on some filesystem.
22001+ * let's try heavy test.
22002+ */
22003+ err = -EACCES;
076b876e 22004+ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1)
5527c038 22005+ && au_test_h_perm(d_inode(h_parent),
076b876e 22006+ MAY_EXEC | MAY_WRITE)))
4a4d8108
AM
22007+ goto out;
22008+
076b876e 22009+ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent);
4a4d8108
AM
22010+ err = -EIO;
22011+ if (IS_ERR(h_latest))
22012+ goto out;
22013+ if (h_latest == h_dentry)
22014+ err = 0;
22015+ dput(h_latest);
22016+
4f0767ce 22017+out:
4a4d8108 22018+ return err;
1308ab2a 22019+}
1facf9fc 22020+
4a4d8108
AM
22021+/*
22022+ * decide the branch where we operate for @dentry. the branch index will be set
22023+ * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
22024+ * dir for reverting.
22025+ * when a new whiteout is necessary, create it.
22026+ */
22027+static struct dentry*
22028+lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
22029+ struct au_dtime *dt, struct au_pin *pin)
1308ab2a 22030+{
4a4d8108
AM
22031+ struct dentry *wh_dentry;
22032+ struct super_block *sb;
22033+ struct path h_path;
22034+ int err, need_wh;
22035+ unsigned int udba;
22036+ aufs_bindex_t bcpup;
dece6358 22037+
4a4d8108
AM
22038+ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
22039+ wh_dentry = ERR_PTR(need_wh);
22040+ if (unlikely(need_wh < 0))
22041+ goto out;
22042+
22043+ sb = dentry->d_sb;
22044+ udba = au_opt_udba(sb);
22045+ bcpup = *rbcpup;
22046+ err = au_pin(pin, dentry, bcpup, udba,
22047+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
22048+ wh_dentry = ERR_PTR(err);
22049+ if (unlikely(err))
22050+ goto out;
22051+
22052+ h_path.dentry = au_pinned_h_parent(pin);
22053+ if (udba != AuOpt_UDBA_NONE
5afbbe0d 22054+ && au_dbtop(dentry) == bcpup) {
4a4d8108
AM
22055+ err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
22056+ wh_dentry = ERR_PTR(err);
22057+ if (unlikely(err))
22058+ goto out_unpin;
22059+ }
22060+
22061+ h_path.mnt = au_sbr_mnt(sb, bcpup);
22062+ au_dtime_store(dt, au_pinned_parent(pin), &h_path);
22063+ wh_dentry = NULL;
22064+ if (!need_wh)
22065+ goto out; /* success, no need to create whiteout */
22066+
22067+ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
22068+ if (IS_ERR(wh_dentry))
22069+ goto out_unpin;
22070+
22071+ /* returns with the parent is locked and wh_dentry is dget-ed */
22072+ goto out; /* success */
22073+
4f0767ce 22074+out_unpin:
4a4d8108 22075+ au_unpin(pin);
4f0767ce 22076+out:
4a4d8108 22077+ return wh_dentry;
1facf9fc 22078+}
22079+
4a4d8108
AM
22080+/*
22081+ * when removing a dir, rename it to a unique temporary whiteout-ed name first
22082+ * in order to be revertible and save time for removing many child whiteouts
22083+ * under the dir.
22084+ * returns 1 when there are too many child whiteout and caller should remove
22085+ * them asynchronously. returns 0 when the number of children is enough small to
22086+ * remove now or the branch fs is a remote fs.
22087+ * otherwise return an error.
22088+ */
22089+static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
22090+ struct au_nhash *whlist, struct inode *dir)
1facf9fc 22091+{
4a4d8108
AM
22092+ int rmdir_later, err, dirwh;
22093+ struct dentry *h_dentry;
22094+ struct super_block *sb;
5527c038 22095+ struct inode *inode;
4a4d8108
AM
22096+
22097+ sb = dentry->d_sb;
22098+ SiMustAnyLock(sb);
22099+ h_dentry = au_h_dptr(dentry, bindex);
22100+ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
22101+ if (unlikely(err))
22102+ goto out;
22103+
22104+ /* stop monitoring */
5527c038
JR
22105+ inode = d_inode(dentry);
22106+ au_hn_free(au_hi(inode, bindex));
4a4d8108
AM
22107+
22108+ if (!au_test_fs_remote(h_dentry->d_sb)) {
22109+ dirwh = au_sbi(sb)->si_dirwh;
22110+ rmdir_later = (dirwh <= 1);
22111+ if (!rmdir_later)
22112+ rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
22113+ dirwh);
22114+ if (rmdir_later)
22115+ return rmdir_later;
22116+ }
1facf9fc 22117+
4a4d8108
AM
22118+ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
22119+ if (unlikely(err)) {
523b37e3
AM
22120+ AuIOErr("rmdir %pd, b%d failed, %d. ignored\n",
22121+ h_dentry, bindex, err);
4a4d8108
AM
22122+ err = 0;
22123+ }
dece6358 22124+
4f0767ce 22125+out:
4a4d8108
AM
22126+ AuTraceErr(err);
22127+ return err;
22128+}
1308ab2a 22129+
4a4d8108
AM
22130+/*
22131+ * final procedure for deleting a entry.
22132+ * maintain dentry and iattr.
22133+ */
22134+static void epilog(struct inode *dir, struct dentry *dentry,
22135+ aufs_bindex_t bindex)
22136+{
22137+ struct inode *inode;
1308ab2a 22138+
5527c038 22139+ inode = d_inode(dentry);
4a4d8108
AM
22140+ d_drop(dentry);
22141+ inode->i_ctime = dir->i_ctime;
1308ab2a 22142+
b912730e 22143+ au_dir_ts(dir, bindex);
4a4d8108 22144+ dir->i_version++;
1facf9fc 22145+}
22146+
4a4d8108
AM
22147+/*
22148+ * when an error happened, remove the created whiteout and revert everything.
22149+ */
7f207e10
AM
22150+static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex,
22151+ aufs_bindex_t bwh, struct dentry *wh_dentry,
22152+ struct dentry *dentry, struct au_dtime *dt)
1facf9fc 22153+{
4a4d8108
AM
22154+ int rerr;
22155+ struct path h_path = {
22156+ .dentry = wh_dentry,
7f207e10 22157+ .mnt = au_sbr_mnt(dir->i_sb, bindex)
4a4d8108 22158+ };
dece6358 22159+
7f207e10 22160+ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
4a4d8108
AM
22161+ if (!rerr) {
22162+ au_set_dbwh(dentry, bwh);
22163+ au_dtime_revert(dt);
22164+ return 0;
22165+ }
dece6358 22166+
523b37e3 22167+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", dentry, err, rerr);
4a4d8108 22168+ return -EIO;
1facf9fc 22169+}
22170+
4a4d8108 22171+/* ---------------------------------------------------------------------- */
1facf9fc 22172+
4a4d8108 22173+int aufs_unlink(struct inode *dir, struct dentry *dentry)
1308ab2a 22174+{
4a4d8108 22175+ int err;
5afbbe0d 22176+ aufs_bindex_t bwh, bindex, btop;
523b37e3 22177+ struct inode *inode, *h_dir, *delegated;
4a4d8108 22178+ struct dentry *parent, *wh_dentry;
c2b27bf2
AM
22179+ /* to reuduce stack size */
22180+ struct {
22181+ struct au_dtime dt;
22182+ struct au_pin pin;
22183+ struct path h_path;
22184+ } *a;
1facf9fc 22185+
4a4d8108 22186+ IMustLock(dir);
027c5e7a 22187+
c2b27bf2
AM
22188+ err = -ENOMEM;
22189+ a = kmalloc(sizeof(*a), GFP_NOFS);
22190+ if (unlikely(!a))
22191+ goto out;
22192+
027c5e7a
AM
22193+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
22194+ if (unlikely(err))
c2b27bf2 22195+ goto out_free;
027c5e7a
AM
22196+ err = au_d_hashed_positive(dentry);
22197+ if (unlikely(err))
22198+ goto out_unlock;
5527c038 22199+ inode = d_inode(dentry);
4a4d8108 22200+ IMustLock(inode);
027c5e7a 22201+ err = -EISDIR;
2000de60 22202+ if (unlikely(d_is_dir(dentry)))
027c5e7a 22203+ goto out_unlock; /* possible? */
1facf9fc 22204+
5afbbe0d 22205+ btop = au_dbtop(dentry);
4a4d8108
AM
22206+ bwh = au_dbwh(dentry);
22207+ bindex = -1;
027c5e7a
AM
22208+ parent = dentry->d_parent; /* dir inode is locked */
22209+ di_write_lock_parent(parent);
c2b27bf2
AM
22210+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &a->dt,
22211+ &a->pin);
4a4d8108
AM
22212+ err = PTR_ERR(wh_dentry);
22213+ if (IS_ERR(wh_dentry))
027c5e7a 22214+ goto out_parent;
1facf9fc 22215+
5afbbe0d
AM
22216+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, btop);
22217+ a->h_path.dentry = au_h_dptr(dentry, btop);
c2b27bf2 22218+ dget(a->h_path.dentry);
5afbbe0d 22219+ if (bindex == btop) {
c2b27bf2 22220+ h_dir = au_pinned_h_dir(&a->pin);
523b37e3
AM
22221+ delegated = NULL;
22222+ err = vfsub_unlink(h_dir, &a->h_path, &delegated, /*force*/0);
22223+ if (unlikely(err == -EWOULDBLOCK)) {
22224+ pr_warn("cannot retry for NFSv4 delegation"
22225+ " for an internal unlink\n");
22226+ iput(delegated);
22227+ }
4a4d8108
AM
22228+ } else {
22229+ /* dir inode is locked */
5527c038 22230+ h_dir = d_inode(wh_dentry->d_parent);
4a4d8108
AM
22231+ IMustLock(h_dir);
22232+ err = 0;
22233+ }
dece6358 22234+
4a4d8108 22235+ if (!err) {
7f207e10 22236+ vfsub_drop_nlink(inode);
4a4d8108
AM
22237+ epilog(dir, dentry, bindex);
22238+
22239+ /* update target timestamps */
5afbbe0d 22240+ if (bindex == btop) {
c2b27bf2
AM
22241+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL);
22242+ /*ignore*/
5527c038 22243+ inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
4a4d8108
AM
22244+ } else
22245+ /* todo: this timestamp may be reverted later */
22246+ inode->i_ctime = h_dir->i_ctime;
027c5e7a 22247+ goto out_unpin; /* success */
1facf9fc 22248+ }
22249+
4a4d8108
AM
22250+ /* revert */
22251+ if (wh_dentry) {
22252+ int rerr;
22253+
c2b27bf2
AM
22254+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
22255+ &a->dt);
4a4d8108
AM
22256+ if (rerr)
22257+ err = rerr;
dece6358 22258+ }
1facf9fc 22259+
027c5e7a 22260+out_unpin:
c2b27bf2 22261+ au_unpin(&a->pin);
4a4d8108 22262+ dput(wh_dentry);
c2b27bf2 22263+ dput(a->h_path.dentry);
027c5e7a 22264+out_parent:
4a4d8108 22265+ di_write_unlock(parent);
027c5e7a 22266+out_unlock:
4a4d8108 22267+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2 22268+out_free:
ae9dfd79 22269+ kfree(a);
027c5e7a 22270+out:
4a4d8108 22271+ return err;
dece6358
AM
22272+}
22273+
4a4d8108 22274+int aufs_rmdir(struct inode *dir, struct dentry *dentry)
1308ab2a 22275+{
4a4d8108 22276+ int err, rmdir_later;
5afbbe0d 22277+ aufs_bindex_t bwh, bindex, btop;
4a4d8108
AM
22278+ struct inode *inode;
22279+ struct dentry *parent, *wh_dentry, *h_dentry;
22280+ struct au_whtmp_rmdir *args;
c2b27bf2
AM
22281+ /* to reuduce stack size */
22282+ struct {
22283+ struct au_dtime dt;
22284+ struct au_pin pin;
22285+ } *a;
1facf9fc 22286+
4a4d8108 22287+ IMustLock(dir);
027c5e7a 22288+
c2b27bf2
AM
22289+ err = -ENOMEM;
22290+ a = kmalloc(sizeof(*a), GFP_NOFS);
22291+ if (unlikely(!a))
22292+ goto out;
22293+
027c5e7a
AM
22294+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
22295+ if (unlikely(err))
c2b27bf2 22296+ goto out_free;
53392da6
AM
22297+ err = au_alive_dir(dentry);
22298+ if (unlikely(err))
027c5e7a 22299+ goto out_unlock;
5527c038 22300+ inode = d_inode(dentry);
4a4d8108 22301+ IMustLock(inode);
027c5e7a 22302+ err = -ENOTDIR;
2000de60 22303+ if (unlikely(!d_is_dir(dentry)))
027c5e7a 22304+ goto out_unlock; /* possible? */
dece6358 22305+
4a4d8108
AM
22306+ err = -ENOMEM;
22307+ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
22308+ if (unlikely(!args))
22309+ goto out_unlock;
dece6358 22310+
4a4d8108
AM
22311+ parent = dentry->d_parent; /* dir inode is locked */
22312+ di_write_lock_parent(parent);
22313+ err = au_test_empty(dentry, &args->whlist);
22314+ if (unlikely(err))
027c5e7a 22315+ goto out_parent;
1facf9fc 22316+
5afbbe0d 22317+ btop = au_dbtop(dentry);
4a4d8108
AM
22318+ bwh = au_dbwh(dentry);
22319+ bindex = -1;
c2b27bf2
AM
22320+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &a->dt,
22321+ &a->pin);
4a4d8108
AM
22322+ err = PTR_ERR(wh_dentry);
22323+ if (IS_ERR(wh_dentry))
027c5e7a 22324+ goto out_parent;
1facf9fc 22325+
5afbbe0d 22326+ h_dentry = au_h_dptr(dentry, btop);
4a4d8108
AM
22327+ dget(h_dentry);
22328+ rmdir_later = 0;
5afbbe0d
AM
22329+ if (bindex == btop) {
22330+ err = renwh_and_rmdir(dentry, btop, &args->whlist, dir);
4a4d8108
AM
22331+ if (err > 0) {
22332+ rmdir_later = err;
22333+ err = 0;
22334+ }
22335+ } else {
22336+ /* stop monitoring */
5afbbe0d 22337+ au_hn_free(au_hi(inode, btop));
4a4d8108
AM
22338+
22339+ /* dir inode is locked */
5527c038 22340+ IMustLock(d_inode(wh_dentry->d_parent));
1facf9fc 22341+ err = 0;
22342+ }
22343+
4a4d8108 22344+ if (!err) {
027c5e7a 22345+ vfsub_dead_dir(inode);
4a4d8108
AM
22346+ au_set_dbdiropq(dentry, -1);
22347+ epilog(dir, dentry, bindex);
1308ab2a 22348+
4a4d8108 22349+ if (rmdir_later) {
5afbbe0d 22350+ au_whtmp_kick_rmdir(dir, btop, h_dentry, args);
4a4d8108
AM
22351+ args = NULL;
22352+ }
1308ab2a 22353+
4a4d8108 22354+ goto out_unpin; /* success */
1facf9fc 22355+ }
22356+
4a4d8108
AM
22357+ /* revert */
22358+ AuLabel(revert);
22359+ if (wh_dentry) {
22360+ int rerr;
1308ab2a 22361+
c2b27bf2
AM
22362+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
22363+ &a->dt);
4a4d8108
AM
22364+ if (rerr)
22365+ err = rerr;
1facf9fc 22366+ }
22367+
4f0767ce 22368+out_unpin:
c2b27bf2 22369+ au_unpin(&a->pin);
4a4d8108
AM
22370+ dput(wh_dentry);
22371+ dput(h_dentry);
027c5e7a 22372+out_parent:
4a4d8108
AM
22373+ di_write_unlock(parent);
22374+ if (args)
22375+ au_whtmp_rmdir_free(args);
4f0767ce 22376+out_unlock:
4a4d8108 22377+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2 22378+out_free:
ae9dfd79 22379+ kfree(a);
4f0767ce 22380+out:
4a4d8108
AM
22381+ AuTraceErr(err);
22382+ return err;
dece6358 22383+}
7f207e10
AM
22384diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
22385--- /usr/share/empty/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
22386+++ linux/fs/aufs/i_op_ren.c 2018-04-15 08:49:13.401150731 +0200
22387@@ -0,0 +1,1246 @@
1facf9fc 22388+/*
ae9dfd79 22389+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 22390+ *
22391+ * This program, aufs is free software; you can redistribute it and/or modify
22392+ * it under the terms of the GNU General Public License as published by
22393+ * the Free Software Foundation; either version 2 of the License, or
22394+ * (at your option) any later version.
dece6358
AM
22395+ *
22396+ * This program is distributed in the hope that it will be useful,
22397+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22398+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22399+ * GNU General Public License for more details.
22400+ *
22401+ * You should have received a copy of the GNU General Public License
523b37e3 22402+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 22403+ */
22404+
22405+/*
4a4d8108
AM
22406+ * inode operation (rename entry)
22407+ * todo: this is crazy monster
1facf9fc 22408+ */
22409+
22410+#include "aufs.h"
22411+
4a4d8108
AM
22412+enum { AuSRC, AuDST, AuSrcDst };
22413+enum { AuPARENT, AuCHILD, AuParentChild };
1facf9fc 22414+
f2c43d5f
AM
22415+#define AuRen_ISDIR_SRC 1
22416+#define AuRen_ISDIR_DST (1 << 1)
22417+#define AuRen_ISSAMEDIR (1 << 2)
22418+#define AuRen_WHSRC (1 << 3)
22419+#define AuRen_WHDST (1 << 4)
22420+#define AuRen_MNT_WRITE (1 << 5)
22421+#define AuRen_DT_DSTDIR (1 << 6)
22422+#define AuRen_DIROPQ_SRC (1 << 7)
22423+#define AuRen_DIROPQ_DST (1 << 8)
ae9dfd79
AM
22424+#define AuRen_DIRREN (1 << 9)
22425+#define AuRen_DROPPED_SRC (1 << 10)
22426+#define AuRen_DROPPED_DST (1 << 11)
4a4d8108 22427+#define au_ftest_ren(flags, name) ((flags) & AuRen_##name)
7f207e10
AM
22428+#define au_fset_ren(flags, name) \
22429+ do { (flags) |= AuRen_##name; } while (0)
22430+#define au_fclr_ren(flags, name) \
22431+ do { (flags) &= ~AuRen_##name; } while (0)
1facf9fc 22432+
ae9dfd79
AM
22433+#ifndef CONFIG_AUFS_DIRREN
22434+#undef AuRen_DIRREN
22435+#define AuRen_DIRREN 0
22436+#endif
22437+
4a4d8108
AM
22438+struct au_ren_args {
22439+ struct {
22440+ struct dentry *dentry, *h_dentry, *parent, *h_parent,
22441+ *wh_dentry;
22442+ struct inode *dir, *inode;
f2c43d5f 22443+ struct au_hinode *hdir, *hinode;
4a4d8108 22444+ struct au_dtime dt[AuParentChild];
f2c43d5f 22445+ aufs_bindex_t btop, bdiropq;
4a4d8108 22446+ } sd[AuSrcDst];
1facf9fc 22447+
4a4d8108
AM
22448+#define src_dentry sd[AuSRC].dentry
22449+#define src_dir sd[AuSRC].dir
22450+#define src_inode sd[AuSRC].inode
22451+#define src_h_dentry sd[AuSRC].h_dentry
22452+#define src_parent sd[AuSRC].parent
22453+#define src_h_parent sd[AuSRC].h_parent
22454+#define src_wh_dentry sd[AuSRC].wh_dentry
22455+#define src_hdir sd[AuSRC].hdir
f2c43d5f 22456+#define src_hinode sd[AuSRC].hinode
4a4d8108
AM
22457+#define src_h_dir sd[AuSRC].hdir->hi_inode
22458+#define src_dt sd[AuSRC].dt
5afbbe0d 22459+#define src_btop sd[AuSRC].btop
f2c43d5f 22460+#define src_bdiropq sd[AuSRC].bdiropq
1facf9fc 22461+
4a4d8108
AM
22462+#define dst_dentry sd[AuDST].dentry
22463+#define dst_dir sd[AuDST].dir
22464+#define dst_inode sd[AuDST].inode
22465+#define dst_h_dentry sd[AuDST].h_dentry
22466+#define dst_parent sd[AuDST].parent
22467+#define dst_h_parent sd[AuDST].h_parent
22468+#define dst_wh_dentry sd[AuDST].wh_dentry
22469+#define dst_hdir sd[AuDST].hdir
f2c43d5f 22470+#define dst_hinode sd[AuDST].hinode
4a4d8108
AM
22471+#define dst_h_dir sd[AuDST].hdir->hi_inode
22472+#define dst_dt sd[AuDST].dt
5afbbe0d 22473+#define dst_btop sd[AuDST].btop
f2c43d5f 22474+#define dst_bdiropq sd[AuDST].bdiropq
4a4d8108
AM
22475+
22476+ struct dentry *h_trap;
22477+ struct au_branch *br;
4a4d8108
AM
22478+ struct path h_path;
22479+ struct au_nhash whlist;
f2c43d5f 22480+ aufs_bindex_t btgt, src_bwh;
1facf9fc 22481+
f2c43d5f
AM
22482+ struct {
22483+ unsigned short auren_flags;
22484+ unsigned char flags; /* syscall parameter */
22485+ unsigned char exchange;
22486+ } __packed;
1facf9fc 22487+
4a4d8108
AM
22488+ struct au_whtmp_rmdir *thargs;
22489+ struct dentry *h_dst;
ae9dfd79 22490+ struct au_hinode *h_root;
4a4d8108 22491+};
1308ab2a 22492+
4a4d8108 22493+/* ---------------------------------------------------------------------- */
1308ab2a 22494+
4a4d8108
AM
22495+/*
22496+ * functions for reverting.
22497+ * when an error happened in a single rename systemcall, we should revert
79b8bda9 22498+ * everything as if nothing happened.
4a4d8108
AM
22499+ * we don't need to revert the copied-up/down the parent dir since they are
22500+ * harmless.
22501+ */
1facf9fc 22502+
4a4d8108
AM
22503+#define RevertFailure(fmt, ...) do { \
22504+ AuIOErr("revert failure: " fmt " (%d, %d)\n", \
22505+ ##__VA_ARGS__, err, rerr); \
22506+ err = -EIO; \
22507+} while (0)
1facf9fc 22508+
f2c43d5f 22509+static void au_ren_do_rev_diropq(int err, struct au_ren_args *a, int idx)
1facf9fc 22510+{
4a4d8108 22511+ int rerr;
f2c43d5f
AM
22512+ struct dentry *d;
22513+#define src_or_dst(member) a->sd[idx].member
1facf9fc 22514+
f2c43d5f
AM
22515+ d = src_or_dst(dentry); /* {src,dst}_dentry */
22516+ au_hn_inode_lock_nested(src_or_dst(hinode), AuLsc_I_CHILD);
22517+ rerr = au_diropq_remove(d, a->btgt);
22518+ au_hn_inode_unlock(src_or_dst(hinode));
22519+ au_set_dbdiropq(d, src_or_dst(bdiropq));
4a4d8108 22520+ if (rerr)
f2c43d5f
AM
22521+ RevertFailure("remove diropq %pd", d);
22522+
22523+#undef src_or_dst_
22524+}
22525+
22526+static void au_ren_rev_diropq(int err, struct au_ren_args *a)
22527+{
22528+ if (au_ftest_ren(a->auren_flags, DIROPQ_SRC))
22529+ au_ren_do_rev_diropq(err, a, AuSRC);
22530+ if (au_ftest_ren(a->auren_flags, DIROPQ_DST))
22531+ au_ren_do_rev_diropq(err, a, AuDST);
4a4d8108 22532+}
1facf9fc 22533+
4a4d8108
AM
22534+static void au_ren_rev_rename(int err, struct au_ren_args *a)
22535+{
22536+ int rerr;
523b37e3 22537+ struct inode *delegated;
1facf9fc 22538+
b4510431
AM
22539+ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name,
22540+ a->src_h_parent);
4a4d8108
AM
22541+ rerr = PTR_ERR(a->h_path.dentry);
22542+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 22543+ RevertFailure("lkup one %pd", a->src_dentry);
4a4d8108 22544+ return;
1facf9fc 22545+ }
22546+
523b37e3 22547+ delegated = NULL;
4a4d8108
AM
22548+ rerr = vfsub_rename(a->dst_h_dir,
22549+ au_h_dptr(a->src_dentry, a->btgt),
f2c43d5f 22550+ a->src_h_dir, &a->h_path, &delegated, a->flags);
523b37e3
AM
22551+ if (unlikely(rerr == -EWOULDBLOCK)) {
22552+ pr_warn("cannot retry for NFSv4 delegation"
22553+ " for an internal rename\n");
22554+ iput(delegated);
22555+ }
4a4d8108
AM
22556+ d_drop(a->h_path.dentry);
22557+ dput(a->h_path.dentry);
22558+ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
22559+ if (rerr)
523b37e3 22560+ RevertFailure("rename %pd", a->src_dentry);
1facf9fc 22561+}
22562+
4a4d8108 22563+static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
1facf9fc 22564+{
4a4d8108 22565+ int rerr;
523b37e3 22566+ struct inode *delegated;
dece6358 22567+
b4510431
AM
22568+ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name,
22569+ a->dst_h_parent);
4a4d8108
AM
22570+ rerr = PTR_ERR(a->h_path.dentry);
22571+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 22572+ RevertFailure("lkup one %pd", a->dst_dentry);
4a4d8108
AM
22573+ return;
22574+ }
5527c038 22575+ if (d_is_positive(a->h_path.dentry)) {
4a4d8108
AM
22576+ d_drop(a->h_path.dentry);
22577+ dput(a->h_path.dentry);
22578+ return;
dece6358
AM
22579+ }
22580+
523b37e3
AM
22581+ delegated = NULL;
22582+ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path,
f2c43d5f 22583+ &delegated, a->flags);
523b37e3
AM
22584+ if (unlikely(rerr == -EWOULDBLOCK)) {
22585+ pr_warn("cannot retry for NFSv4 delegation"
22586+ " for an internal rename\n");
22587+ iput(delegated);
22588+ }
4a4d8108
AM
22589+ d_drop(a->h_path.dentry);
22590+ dput(a->h_path.dentry);
22591+ if (!rerr)
22592+ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
22593+ else
523b37e3 22594+ RevertFailure("rename %pd", a->h_dst);
4a4d8108 22595+}
1308ab2a 22596+
4a4d8108
AM
22597+static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
22598+{
22599+ int rerr;
1308ab2a 22600+
4a4d8108
AM
22601+ a->h_path.dentry = a->src_wh_dentry;
22602+ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
027c5e7a 22603+ au_set_dbwh(a->src_dentry, a->src_bwh);
4a4d8108 22604+ if (rerr)
523b37e3 22605+ RevertFailure("unlink %pd", a->src_wh_dentry);
4a4d8108 22606+}
4a4d8108 22607+#undef RevertFailure
1facf9fc 22608+
1308ab2a 22609+/* ---------------------------------------------------------------------- */
22610+
4a4d8108
AM
22611+/*
22612+ * when we have to copyup the renaming entry, do it with the rename-target name
22613+ * in order to minimize the cost (the later actual rename is unnecessary).
22614+ * otherwise rename it on the target branch.
22615+ */
22616+static int au_ren_or_cpup(struct au_ren_args *a)
1facf9fc 22617+{
dece6358 22618+ int err;
4a4d8108 22619+ struct dentry *d;
523b37e3 22620+ struct inode *delegated;
1facf9fc 22621+
4a4d8108 22622+ d = a->src_dentry;
5afbbe0d 22623+ if (au_dbtop(d) == a->btgt) {
4a4d8108 22624+ a->h_path.dentry = a->dst_h_dentry;
5afbbe0d 22625+ AuDebugOn(au_dbtop(d) != a->btgt);
523b37e3 22626+ delegated = NULL;
4a4d8108 22627+ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
f2c43d5f
AM
22628+ a->dst_h_dir, &a->h_path, &delegated,
22629+ a->flags);
523b37e3
AM
22630+ if (unlikely(err == -EWOULDBLOCK)) {
22631+ pr_warn("cannot retry for NFSv4 delegation"
22632+ " for an internal rename\n");
22633+ iput(delegated);
22634+ }
c2b27bf2 22635+ } else
86dc4139 22636+ BUG();
1308ab2a 22637+
027c5e7a
AM
22638+ if (!err && a->h_dst)
22639+ /* it will be set to dinfo later */
22640+ dget(a->h_dst);
1facf9fc 22641+
dece6358
AM
22642+ return err;
22643+}
1facf9fc 22644+
4a4d8108
AM
22645+/* cf. aufs_rmdir() */
22646+static int au_ren_del_whtmp(struct au_ren_args *a)
dece6358 22647+{
4a4d8108
AM
22648+ int err;
22649+ struct inode *dir;
1facf9fc 22650+
4a4d8108
AM
22651+ dir = a->dst_dir;
22652+ SiMustAnyLock(dir->i_sb);
22653+ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
22654+ au_sbi(dir->i_sb)->si_dirwh)
22655+ || au_test_fs_remote(a->h_dst->d_sb)) {
22656+ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
22657+ if (unlikely(err))
523b37e3
AM
22658+ pr_warn("failed removing whtmp dir %pd (%d), "
22659+ "ignored.\n", a->h_dst, err);
4a4d8108
AM
22660+ } else {
22661+ au_nhash_wh_free(&a->thargs->whlist);
22662+ a->thargs->whlist = a->whlist;
22663+ a->whlist.nh_num = 0;
22664+ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
22665+ dput(a->h_dst);
22666+ a->thargs = NULL;
22667+ }
22668+
22669+ return 0;
1308ab2a 22670+}
1facf9fc 22671+
4a4d8108 22672+/* make it 'opaque' dir. */
f2c43d5f 22673+static int au_ren_do_diropq(struct au_ren_args *a, int idx)
4a4d8108
AM
22674+{
22675+ int err;
f2c43d5f
AM
22676+ struct dentry *d, *diropq;
22677+#define src_or_dst(member) a->sd[idx].member
1facf9fc 22678+
4a4d8108 22679+ err = 0;
f2c43d5f
AM
22680+ d = src_or_dst(dentry); /* {src,dst}_dentry */
22681+ src_or_dst(bdiropq) = au_dbdiropq(d);
22682+ src_or_dst(hinode) = au_hi(src_or_dst(inode), a->btgt);
22683+ au_hn_inode_lock_nested(src_or_dst(hinode), AuLsc_I_CHILD);
22684+ diropq = au_diropq_create(d, a->btgt);
22685+ au_hn_inode_unlock(src_or_dst(hinode));
4a4d8108
AM
22686+ if (IS_ERR(diropq))
22687+ err = PTR_ERR(diropq);
076b876e
AM
22688+ else
22689+ dput(diropq);
1facf9fc 22690+
f2c43d5f 22691+#undef src_or_dst_
4a4d8108
AM
22692+ return err;
22693+}
1facf9fc 22694+
f2c43d5f 22695+static int au_ren_diropq(struct au_ren_args *a)
4a4d8108
AM
22696+{
22697+ int err;
f2c43d5f
AM
22698+ unsigned char always;
22699+ struct dentry *d;
1facf9fc 22700+
f2c43d5f
AM
22701+ err = 0;
22702+ d = a->dst_dentry; /* already renamed on the branch */
22703+ always = !!au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ);
22704+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)
ae9dfd79 22705+ && !au_ftest_ren(a->auren_flags, DIRREN)
f2c43d5f
AM
22706+ && a->btgt != au_dbdiropq(a->src_dentry)
22707+ && (a->dst_wh_dentry
22708+ || a->btgt <= au_dbdiropq(d)
22709+ /* hide the lower to keep xino */
22710+ /* the lowers may not be a dir, but we hide them anyway */
22711+ || a->btgt < au_dbbot(d)
22712+ || always)) {
22713+ AuDbg("here\n");
22714+ err = au_ren_do_diropq(a, AuSRC);
22715+ if (unlikely(err))
4a4d8108 22716+ goto out;
f2c43d5f 22717+ au_fset_ren(a->auren_flags, DIROPQ_SRC);
4a4d8108 22718+ }
f2c43d5f
AM
22719+ if (!a->exchange)
22720+ goto out; /* success */
1facf9fc 22721+
f2c43d5f
AM
22722+ d = a->src_dentry; /* already renamed on the branch */
22723+ if (au_ftest_ren(a->auren_flags, ISDIR_DST)
22724+ && a->btgt != au_dbdiropq(a->dst_dentry)
22725+ && (a->btgt < au_dbdiropq(d)
22726+ || a->btgt < au_dbbot(d)
22727+ || always)) {
22728+ AuDbgDentry(a->src_dentry);
22729+ AuDbgDentry(a->dst_dentry);
22730+ err = au_ren_do_diropq(a, AuDST);
4a4d8108 22731+ if (unlikely(err))
f2c43d5f
AM
22732+ goto out_rev_src;
22733+ au_fset_ren(a->auren_flags, DIROPQ_DST);
22734+ }
22735+ goto out; /* success */
dece6358 22736+
f2c43d5f
AM
22737+out_rev_src:
22738+ AuDbg("err %d, reverting src\n", err);
22739+ au_ren_rev_diropq(err, a);
22740+out:
22741+ return err;
22742+}
22743+
22744+static int do_rename(struct au_ren_args *a)
22745+{
22746+ int err;
22747+ struct dentry *d, *h_d;
22748+
22749+ if (!a->exchange) {
22750+ /* prepare workqueue args for asynchronous rmdir */
22751+ h_d = a->dst_h_dentry;
22752+ if (au_ftest_ren(a->auren_flags, ISDIR_DST)
ae9dfd79 22753+ /* && !au_ftest_ren(a->auren_flags, DIRREN) */
f2c43d5f
AM
22754+ && d_is_positive(h_d)) {
22755+ err = -ENOMEM;
22756+ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb,
22757+ GFP_NOFS);
22758+ if (unlikely(!a->thargs))
22759+ goto out;
22760+ a->h_dst = dget(h_d);
22761+ }
22762+
22763+ /* create whiteout for src_dentry */
22764+ if (au_ftest_ren(a->auren_flags, WHSRC)) {
22765+ a->src_bwh = au_dbwh(a->src_dentry);
22766+ AuDebugOn(a->src_bwh >= 0);
22767+ a->src_wh_dentry = au_wh_create(a->src_dentry, a->btgt,
22768+ a->src_h_parent);
22769+ err = PTR_ERR(a->src_wh_dentry);
22770+ if (IS_ERR(a->src_wh_dentry))
22771+ goto out_thargs;
22772+ }
22773+
22774+ /* lookup whiteout for dentry */
22775+ if (au_ftest_ren(a->auren_flags, WHDST)) {
22776+ h_d = au_wh_lkup(a->dst_h_parent,
22777+ &a->dst_dentry->d_name, a->br);
22778+ err = PTR_ERR(h_d);
22779+ if (IS_ERR(h_d))
22780+ goto out_whsrc;
22781+ if (d_is_negative(h_d))
22782+ dput(h_d);
22783+ else
22784+ a->dst_wh_dentry = h_d;
22785+ }
22786+
22787+ /* rename dentry to tmpwh */
22788+ if (a->thargs) {
22789+ err = au_whtmp_ren(a->dst_h_dentry, a->br);
22790+ if (unlikely(err))
22791+ goto out_whdst;
22792+
22793+ d = a->dst_dentry;
22794+ au_set_h_dptr(d, a->btgt, NULL);
22795+ err = au_lkup_neg(d, a->btgt, /*wh*/0);
22796+ if (unlikely(err))
22797+ goto out_whtmp;
22798+ a->dst_h_dentry = au_h_dptr(d, a->btgt);
22799+ }
4a4d8108 22800+ }
1facf9fc 22801+
5afbbe0d 22802+ BUG_ON(d_is_positive(a->dst_h_dentry) && a->src_btop != a->btgt);
ae9dfd79
AM
22803+#if 0
22804+ BUG_ON(!au_ftest_ren(a->auren_flags, DIRREN)
22805+ && d_is_positive(a->dst_h_dentry)
22806+ && a->src_btop != a->btgt);
22807+#endif
1facf9fc 22808+
4a4d8108 22809+ /* rename by vfs_rename or cpup */
4a4d8108
AM
22810+ err = au_ren_or_cpup(a);
22811+ if (unlikely(err))
22812+ /* leave the copied-up one */
22813+ goto out_whtmp;
1308ab2a 22814+
4a4d8108 22815+ /* make dir opaque */
f2c43d5f
AM
22816+ err = au_ren_diropq(a);
22817+ if (unlikely(err))
22818+ goto out_rename;
1308ab2a 22819+
4a4d8108 22820+ /* update target timestamps */
f2c43d5f
AM
22821+ if (a->exchange) {
22822+ AuDebugOn(au_dbtop(a->dst_dentry) != a->btgt);
22823+ a->h_path.dentry = au_h_dptr(a->dst_dentry, a->btgt);
22824+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
22825+ a->dst_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
22826+ }
5afbbe0d 22827+ AuDebugOn(au_dbtop(a->src_dentry) != a->btgt);
4a4d8108
AM
22828+ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
22829+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
5527c038 22830+ a->src_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
1facf9fc 22831+
f2c43d5f
AM
22832+ if (!a->exchange) {
22833+ /* remove whiteout for dentry */
22834+ if (a->dst_wh_dentry) {
22835+ a->h_path.dentry = a->dst_wh_dentry;
22836+ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
22837+ a->dst_dentry);
22838+ if (unlikely(err))
22839+ goto out_diropq;
22840+ }
1facf9fc 22841+
f2c43d5f
AM
22842+ /* remove whtmp */
22843+ if (a->thargs)
22844+ au_ren_del_whtmp(a); /* ignore this error */
1308ab2a 22845+
f2c43d5f
AM
22846+ au_fhsm_wrote(a->src_dentry->d_sb, a->btgt, /*force*/0);
22847+ }
4a4d8108
AM
22848+ err = 0;
22849+ goto out_success;
22850+
4f0767ce 22851+out_diropq:
f2c43d5f 22852+ au_ren_rev_diropq(err, a);
4f0767ce 22853+out_rename:
7e9cd9fe 22854+ au_ren_rev_rename(err, a);
027c5e7a 22855+ dput(a->h_dst);
4f0767ce 22856+out_whtmp:
4a4d8108
AM
22857+ if (a->thargs)
22858+ au_ren_rev_whtmp(err, a);
4f0767ce 22859+out_whdst:
4a4d8108
AM
22860+ dput(a->dst_wh_dentry);
22861+ a->dst_wh_dentry = NULL;
4f0767ce 22862+out_whsrc:
4a4d8108
AM
22863+ if (a->src_wh_dentry)
22864+ au_ren_rev_whsrc(err, a);
4f0767ce 22865+out_success:
4a4d8108
AM
22866+ dput(a->src_wh_dentry);
22867+ dput(a->dst_wh_dentry);
4f0767ce 22868+out_thargs:
4a4d8108
AM
22869+ if (a->thargs) {
22870+ dput(a->h_dst);
22871+ au_whtmp_rmdir_free(a->thargs);
22872+ a->thargs = NULL;
22873+ }
4f0767ce 22874+out:
4a4d8108 22875+ return err;
dece6358 22876+}
1facf9fc 22877+
1308ab2a 22878+/* ---------------------------------------------------------------------- */
1facf9fc 22879+
4a4d8108
AM
22880+/*
22881+ * test if @dentry dir can be rename destination or not.
22882+ * success means, it is a logically empty dir.
22883+ */
22884+static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
1308ab2a 22885+{
4a4d8108 22886+ return au_test_empty(dentry, whlist);
1308ab2a 22887+}
1facf9fc 22888+
4a4d8108 22889+/*
ae9dfd79
AM
22890+ * test if @a->src_dentry dir can be rename source or not.
22891+ * if it can, return 0.
4a4d8108
AM
22892+ * success means,
22893+ * - it is a logically empty dir.
22894+ * - or, it exists on writable branch and has no children including whiteouts
ae9dfd79 22895+ * on the lower branch unless DIRREN is on.
4a4d8108 22896+ */
ae9dfd79 22897+static int may_rename_srcdir(struct au_ren_args *a)
4a4d8108
AM
22898+{
22899+ int err;
22900+ unsigned int rdhash;
ae9dfd79
AM
22901+ aufs_bindex_t btop, btgt;
22902+ struct dentry *dentry;
22903+ struct super_block *sb;
22904+ struct au_sbinfo *sbinfo;
22905+
22906+ dentry = a->src_dentry;
22907+ sb = dentry->d_sb;
22908+ sbinfo = au_sbi(sb);
22909+ if (au_opt_test(sbinfo->si_mntflags, DIRREN))
22910+ au_fset_ren(a->auren_flags, DIRREN);
1facf9fc 22911+
ae9dfd79 22912+ btgt = a->btgt;
5afbbe0d
AM
22913+ btop = au_dbtop(dentry);
22914+ if (btop != btgt) {
4a4d8108 22915+ struct au_nhash whlist;
dece6358 22916+
ae9dfd79
AM
22917+ SiMustAnyLock(sb);
22918+ rdhash = sbinfo->si_rdhash;
4a4d8108
AM
22919+ if (!rdhash)
22920+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL,
22921+ dentry));
22922+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
22923+ if (unlikely(err))
22924+ goto out;
22925+ err = au_test_empty(dentry, &whlist);
22926+ au_nhash_wh_free(&whlist);
22927+ goto out;
22928+ }
dece6358 22929+
5afbbe0d 22930+ if (btop == au_dbtaildir(dentry))
4a4d8108 22931+ return 0; /* success */
dece6358 22932+
4a4d8108 22933+ err = au_test_empty_lower(dentry);
1facf9fc 22934+
4f0767ce 22935+out:
4a4d8108 22936+ if (err == -ENOTEMPTY) {
ae9dfd79
AM
22937+ if (au_ftest_ren(a->auren_flags, DIRREN)) {
22938+ err = 0;
22939+ } else {
22940+ AuWarn1("renaming dir who has child(ren) on multiple "
22941+ "branches, is not supported\n");
22942+ err = -EXDEV;
22943+ }
4a4d8108
AM
22944+ }
22945+ return err;
22946+}
1308ab2a 22947+
4a4d8108
AM
22948+/* side effect: sets whlist and h_dentry */
22949+static int au_ren_may_dir(struct au_ren_args *a)
1308ab2a 22950+{
4a4d8108
AM
22951+ int err;
22952+ unsigned int rdhash;
22953+ struct dentry *d;
1facf9fc 22954+
4a4d8108
AM
22955+ d = a->dst_dentry;
22956+ SiMustAnyLock(d->d_sb);
1facf9fc 22957+
4a4d8108 22958+ err = 0;
f2c43d5f 22959+ if (au_ftest_ren(a->auren_flags, ISDIR_DST) && a->dst_inode) {
4a4d8108
AM
22960+ rdhash = au_sbi(d->d_sb)->si_rdhash;
22961+ if (!rdhash)
22962+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d));
22963+ err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS);
22964+ if (unlikely(err))
22965+ goto out;
1308ab2a 22966+
f2c43d5f
AM
22967+ if (!a->exchange) {
22968+ au_set_dbtop(d, a->dst_btop);
22969+ err = may_rename_dstdir(d, &a->whlist);
22970+ au_set_dbtop(d, a->btgt);
22971+ } else
ae9dfd79 22972+ err = may_rename_srcdir(a);
4a4d8108 22973+ }
5afbbe0d 22974+ a->dst_h_dentry = au_h_dptr(d, au_dbtop(d));
4a4d8108
AM
22975+ if (unlikely(err))
22976+ goto out;
22977+
22978+ d = a->src_dentry;
5afbbe0d 22979+ a->src_h_dentry = au_h_dptr(d, au_dbtop(d));
f2c43d5f 22980+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)) {
ae9dfd79 22981+ err = may_rename_srcdir(a);
4a4d8108
AM
22982+ if (unlikely(err)) {
22983+ au_nhash_wh_free(&a->whlist);
22984+ a->whlist.nh_num = 0;
22985+ }
22986+ }
4f0767ce 22987+out:
4a4d8108 22988+ return err;
1facf9fc 22989+}
22990+
4a4d8108 22991+/* ---------------------------------------------------------------------- */
1facf9fc 22992+
4a4d8108
AM
22993+/*
22994+ * simple tests for rename.
22995+ * following the checks in vfs, plus the parent-child relationship.
22996+ */
22997+static int au_may_ren(struct au_ren_args *a)
22998+{
22999+ int err, isdir;
23000+ struct inode *h_inode;
1facf9fc 23001+
5afbbe0d 23002+ if (a->src_btop == a->btgt) {
4a4d8108 23003+ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
f2c43d5f 23004+ au_ftest_ren(a->auren_flags, ISDIR_SRC));
4a4d8108
AM
23005+ if (unlikely(err))
23006+ goto out;
23007+ err = -EINVAL;
23008+ if (unlikely(a->src_h_dentry == a->h_trap))
23009+ goto out;
23010+ }
1facf9fc 23011+
4a4d8108 23012+ err = 0;
5afbbe0d 23013+ if (a->dst_btop != a->btgt)
4a4d8108 23014+ goto out;
1facf9fc 23015+
027c5e7a
AM
23016+ err = -ENOTEMPTY;
23017+ if (unlikely(a->dst_h_dentry == a->h_trap))
23018+ goto out;
23019+
4a4d8108 23020+ err = -EIO;
f2c43d5f 23021+ isdir = !!au_ftest_ren(a->auren_flags, ISDIR_DST);
5527c038
JR
23022+ if (d_really_is_negative(a->dst_dentry)) {
23023+ if (d_is_negative(a->dst_h_dentry))
23024+ err = au_may_add(a->dst_dentry, a->btgt,
23025+ a->dst_h_parent, isdir);
4a4d8108 23026+ } else {
5527c038 23027+ if (unlikely(d_is_negative(a->dst_h_dentry)))
4a4d8108 23028+ goto out;
5527c038
JR
23029+ h_inode = d_inode(a->dst_h_dentry);
23030+ if (h_inode->i_nlink)
23031+ err = au_may_del(a->dst_dentry, a->btgt,
23032+ a->dst_h_parent, isdir);
4a4d8108 23033+ }
1facf9fc 23034+
4f0767ce 23035+out:
4a4d8108
AM
23036+ if (unlikely(err == -ENOENT || err == -EEXIST))
23037+ err = -EIO;
23038+ AuTraceErr(err);
23039+ return err;
23040+}
1facf9fc 23041+
1308ab2a 23042+/* ---------------------------------------------------------------------- */
1facf9fc 23043+
4a4d8108
AM
23044+/*
23045+ * locking order
23046+ * (VFS)
23047+ * - src_dir and dir by lock_rename()
23048+ * - inode if exitsts
23049+ * (aufs)
23050+ * - lock all
23051+ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
23052+ * + si_read_lock
23053+ * + di_write_lock2_child()
23054+ * + di_write_lock_child()
23055+ * + ii_write_lock_child()
23056+ * + di_write_lock_child2()
23057+ * + ii_write_lock_child2()
23058+ * + src_parent and parent
23059+ * + di_write_lock_parent()
23060+ * + ii_write_lock_parent()
23061+ * + di_write_lock_parent2()
23062+ * + ii_write_lock_parent2()
23063+ * + lower src_dir and dir by vfsub_lock_rename()
23064+ * + verify the every relationships between child and parent. if any
23065+ * of them failed, unlock all and return -EBUSY.
23066+ */
23067+static void au_ren_unlock(struct au_ren_args *a)
1308ab2a 23068+{
4a4d8108
AM
23069+ vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
23070+ a->dst_h_parent, a->dst_hdir);
ae9dfd79
AM
23071+ if (au_ftest_ren(a->auren_flags, DIRREN)
23072+ && a->h_root)
23073+ au_hn_inode_unlock(a->h_root);
f2c43d5f 23074+ if (au_ftest_ren(a->auren_flags, MNT_WRITE))
86dc4139 23075+ vfsub_mnt_drop_write(au_br_mnt(a->br));
1308ab2a 23076+}
23077+
4a4d8108 23078+static int au_ren_lock(struct au_ren_args *a)
1308ab2a 23079+{
4a4d8108
AM
23080+ int err;
23081+ unsigned int udba;
1308ab2a 23082+
4a4d8108
AM
23083+ err = 0;
23084+ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
23085+ a->src_hdir = au_hi(a->src_dir, a->btgt);
23086+ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
23087+ a->dst_hdir = au_hi(a->dst_dir, a->btgt);
86dc4139
AM
23088+
23089+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
23090+ if (unlikely(err))
23091+ goto out;
f2c43d5f 23092+ au_fset_ren(a->auren_flags, MNT_WRITE);
ae9dfd79
AM
23093+ if (au_ftest_ren(a->auren_flags, DIRREN)) {
23094+ struct dentry *root;
23095+ struct inode *dir;
23096+
23097+ /*
23098+ * sbinfo is already locked, so this ii_read_lock is
23099+ * unnecessary. but our debugging feature checks it.
23100+ */
23101+ root = a->src_inode->i_sb->s_root;
23102+ if (root != a->src_parent && root != a->dst_parent) {
23103+ dir = d_inode(root);
23104+ ii_read_lock_parent3(dir);
23105+ a->h_root = au_hi(dir, a->btgt);
23106+ ii_read_unlock(dir);
23107+ au_hn_inode_lock_nested(a->h_root, AuLsc_I_PARENT3);
23108+ }
23109+ }
4a4d8108
AM
23110+ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
23111+ a->dst_h_parent, a->dst_hdir);
23112+ udba = au_opt_udba(a->src_dentry->d_sb);
5527c038
JR
23113+ if (unlikely(a->src_hdir->hi_inode != d_inode(a->src_h_parent)
23114+ || a->dst_hdir->hi_inode != d_inode(a->dst_h_parent)))
4a4d8108 23115+ err = au_busy_or_stale();
5afbbe0d 23116+ if (!err && au_dbtop(a->src_dentry) == a->btgt)
4a4d8108 23117+ err = au_h_verify(a->src_h_dentry, udba,
5527c038 23118+ d_inode(a->src_h_parent), a->src_h_parent,
4a4d8108 23119+ a->br);
5afbbe0d 23120+ if (!err && au_dbtop(a->dst_dentry) == a->btgt)
4a4d8108 23121+ err = au_h_verify(a->dst_h_dentry, udba,
5527c038 23122+ d_inode(a->dst_h_parent), a->dst_h_parent,
4a4d8108 23123+ a->br);
86dc4139 23124+ if (!err)
4a4d8108 23125+ goto out; /* success */
4a4d8108
AM
23126+
23127+ err = au_busy_or_stale();
4a4d8108 23128+ au_ren_unlock(a);
86dc4139 23129+
4f0767ce 23130+out:
4a4d8108 23131+ return err;
1facf9fc 23132+}
23133+
23134+/* ---------------------------------------------------------------------- */
23135+
4a4d8108 23136+static void au_ren_refresh_dir(struct au_ren_args *a)
1facf9fc 23137+{
4a4d8108 23138+ struct inode *dir;
dece6358 23139+
4a4d8108
AM
23140+ dir = a->dst_dir;
23141+ dir->i_version++;
f2c43d5f 23142+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)) {
4a4d8108
AM
23143+ /* is this updating defined in POSIX? */
23144+ au_cpup_attr_timesizes(a->src_inode);
23145+ au_cpup_attr_nlink(dir, /*force*/1);
4a4d8108 23146+ }
b912730e 23147+ au_dir_ts(dir, a->btgt);
dece6358 23148+
f2c43d5f
AM
23149+ if (a->exchange) {
23150+ dir = a->src_dir;
23151+ dir->i_version++;
23152+ if (au_ftest_ren(a->auren_flags, ISDIR_DST)) {
23153+ /* is this updating defined in POSIX? */
23154+ au_cpup_attr_timesizes(a->dst_inode);
23155+ au_cpup_attr_nlink(dir, /*force*/1);
23156+ }
23157+ au_dir_ts(dir, a->btgt);
23158+ }
23159+
23160+ if (au_ftest_ren(a->auren_flags, ISSAMEDIR))
4a4d8108 23161+ return;
dece6358 23162+
4a4d8108
AM
23163+ dir = a->src_dir;
23164+ dir->i_version++;
f2c43d5f 23165+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC))
4a4d8108 23166+ au_cpup_attr_nlink(dir, /*force*/1);
b912730e 23167+ au_dir_ts(dir, a->btgt);
1facf9fc 23168+}
23169+
4a4d8108 23170+static void au_ren_refresh(struct au_ren_args *a)
1facf9fc 23171+{
5afbbe0d 23172+ aufs_bindex_t bbot, bindex;
4a4d8108
AM
23173+ struct dentry *d, *h_d;
23174+ struct inode *i, *h_i;
23175+ struct super_block *sb;
dece6358 23176+
027c5e7a
AM
23177+ d = a->dst_dentry;
23178+ d_drop(d);
23179+ if (a->h_dst)
23180+ /* already dget-ed by au_ren_or_cpup() */
23181+ au_set_h_dptr(d, a->btgt, a->h_dst);
23182+
23183+ i = a->dst_inode;
23184+ if (i) {
f2c43d5f
AM
23185+ if (!a->exchange) {
23186+ if (!au_ftest_ren(a->auren_flags, ISDIR_DST))
23187+ vfsub_drop_nlink(i);
23188+ else {
23189+ vfsub_dead_dir(i);
23190+ au_cpup_attr_timesizes(i);
23191+ }
23192+ au_update_dbrange(d, /*do_put_zero*/1);
23193+ } else
23194+ au_cpup_attr_nlink(i, /*force*/1);
027c5e7a 23195+ } else {
5afbbe0d
AM
23196+ bbot = a->btgt;
23197+ for (bindex = au_dbtop(d); bindex < bbot; bindex++)
027c5e7a 23198+ au_set_h_dptr(d, bindex, NULL);
5afbbe0d
AM
23199+ bbot = au_dbbot(d);
23200+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++)
027c5e7a
AM
23201+ au_set_h_dptr(d, bindex, NULL);
23202+ au_update_dbrange(d, /*do_put_zero*/0);
23203+ }
23204+
ae9dfd79
AM
23205+ if (a->exchange
23206+ || au_ftest_ren(a->auren_flags, DIRREN)) {
23207+ d_drop(a->src_dentry);
23208+ if (au_ftest_ren(a->auren_flags, DIRREN))
23209+ au_set_dbwh(a->src_dentry, -1);
23210+ return;
23211+ }
23212+
4a4d8108 23213+ d = a->src_dentry;
ae9dfd79
AM
23214+ au_set_dbwh(d, -1);
23215+ bbot = au_dbbot(d);
23216+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++) {
23217+ h_d = au_h_dptr(d, bindex);
23218+ if (h_d)
23219+ au_set_h_dptr(d, bindex, NULL);
23220+ }
23221+ au_set_dbbot(d, a->btgt);
4a4d8108 23222+
ae9dfd79
AM
23223+ sb = d->d_sb;
23224+ i = a->src_inode;
23225+ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
23226+ return; /* success */
4a4d8108 23227+
ae9dfd79
AM
23228+ bbot = au_ibbot(i);
23229+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++) {
23230+ h_i = au_h_iptr(i, bindex);
23231+ if (h_i) {
23232+ au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
23233+ /* ignore this error */
23234+ au_set_h_iptr(i, bindex, NULL, 0);
4a4d8108
AM
23235+ }
23236+ }
ae9dfd79 23237+ au_set_ibbot(i, a->btgt);
1308ab2a 23238+}
dece6358 23239+
4a4d8108
AM
23240+/* ---------------------------------------------------------------------- */
23241+
23242+/* mainly for link(2) and rename(2) */
23243+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
1308ab2a 23244+{
4a4d8108
AM
23245+ aufs_bindex_t bdiropq, bwh;
23246+ struct dentry *parent;
23247+ struct au_branch *br;
23248+
23249+ parent = dentry->d_parent;
5527c038 23250+ IMustLock(d_inode(parent)); /* dir is locked */
4a4d8108
AM
23251+
23252+ bdiropq = au_dbdiropq(parent);
23253+ bwh = au_dbwh(dentry);
23254+ br = au_sbr(dentry->d_sb, btgt);
23255+ if (au_br_rdonly(br)
23256+ || (0 <= bdiropq && bdiropq < btgt)
23257+ || (0 <= bwh && bwh < btgt))
23258+ btgt = -1;
23259+
23260+ AuDbg("btgt %d\n", btgt);
23261+ return btgt;
1facf9fc 23262+}
23263+
5afbbe0d 23264+/* sets src_btop, dst_btop and btgt */
4a4d8108 23265+static int au_ren_wbr(struct au_ren_args *a)
1facf9fc 23266+{
4a4d8108
AM
23267+ int err;
23268+ struct au_wr_dir_args wr_dir_args = {
23269+ /* .force_btgt = -1, */
23270+ .flags = AuWrDir_ADD_ENTRY
23271+ };
dece6358 23272+
5afbbe0d
AM
23273+ a->src_btop = au_dbtop(a->src_dentry);
23274+ a->dst_btop = au_dbtop(a->dst_dentry);
f2c43d5f
AM
23275+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)
23276+ || au_ftest_ren(a->auren_flags, ISDIR_DST))
4a4d8108 23277+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
5afbbe0d
AM
23278+ wr_dir_args.force_btgt = a->src_btop;
23279+ if (a->dst_inode && a->dst_btop < a->src_btop)
23280+ wr_dir_args.force_btgt = a->dst_btop;
4a4d8108
AM
23281+ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
23282+ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
23283+ a->btgt = err;
f2c43d5f
AM
23284+ if (a->exchange)
23285+ au_update_dbtop(a->dst_dentry);
dece6358 23286+
4a4d8108 23287+ return err;
1facf9fc 23288+}
23289+
4a4d8108 23290+static void au_ren_dt(struct au_ren_args *a)
1facf9fc 23291+{
4a4d8108
AM
23292+ a->h_path.dentry = a->src_h_parent;
23293+ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
f2c43d5f 23294+ if (!au_ftest_ren(a->auren_flags, ISSAMEDIR)) {
4a4d8108
AM
23295+ a->h_path.dentry = a->dst_h_parent;
23296+ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
23297+ }
1facf9fc 23298+
f2c43d5f
AM
23299+ au_fclr_ren(a->auren_flags, DT_DSTDIR);
23300+ if (!au_ftest_ren(a->auren_flags, ISDIR_SRC)
23301+ && !a->exchange)
4a4d8108 23302+ return;
dece6358 23303+
4a4d8108
AM
23304+ a->h_path.dentry = a->src_h_dentry;
23305+ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
5527c038 23306+ if (d_is_positive(a->dst_h_dentry)) {
f2c43d5f 23307+ au_fset_ren(a->auren_flags, DT_DSTDIR);
4a4d8108
AM
23308+ a->h_path.dentry = a->dst_h_dentry;
23309+ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
23310+ }
1308ab2a 23311+}
dece6358 23312+
4a4d8108 23313+static void au_ren_rev_dt(int err, struct au_ren_args *a)
1308ab2a 23314+{
4a4d8108 23315+ struct dentry *h_d;
febd17d6 23316+ struct inode *h_inode;
4a4d8108
AM
23317+
23318+ au_dtime_revert(a->src_dt + AuPARENT);
f2c43d5f 23319+ if (!au_ftest_ren(a->auren_flags, ISSAMEDIR))
4a4d8108
AM
23320+ au_dtime_revert(a->dst_dt + AuPARENT);
23321+
f2c43d5f 23322+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC) && err != -EIO) {
4a4d8108 23323+ h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
febd17d6
JR
23324+ h_inode = d_inode(h_d);
23325+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
4a4d8108 23326+ au_dtime_revert(a->src_dt + AuCHILD);
febd17d6 23327+ inode_unlock(h_inode);
4a4d8108 23328+
f2c43d5f 23329+ if (au_ftest_ren(a->auren_flags, DT_DSTDIR)) {
4a4d8108 23330+ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
febd17d6
JR
23331+ h_inode = d_inode(h_d);
23332+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
4a4d8108 23333+ au_dtime_revert(a->dst_dt + AuCHILD);
febd17d6 23334+ inode_unlock(h_inode);
1facf9fc 23335+ }
23336+ }
23337+}
23338+
4a4d8108
AM
23339+/* ---------------------------------------------------------------------- */
23340+
23341+int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
f2c43d5f
AM
23342+ struct inode *_dst_dir, struct dentry *_dst_dentry,
23343+ unsigned int _flags)
1facf9fc 23344+{
f2c43d5f 23345+ int err, lock_flags;
ae9dfd79 23346+ void *rev;
4a4d8108
AM
23347+ /* reduce stack space */
23348+ struct au_ren_args *a;
f2c43d5f 23349+ struct au_pin pin;
4a4d8108 23350+
f2c43d5f 23351+ AuDbg("%pd, %pd, 0x%x\n", _src_dentry, _dst_dentry, _flags);
4a4d8108
AM
23352+ IMustLock(_src_dir);
23353+ IMustLock(_dst_dir);
23354+
f2c43d5f
AM
23355+ err = -EINVAL;
23356+ if (unlikely(_flags & RENAME_WHITEOUT))
23357+ goto out;
23358+
4a4d8108
AM
23359+ err = -ENOMEM;
23360+ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
23361+ a = kzalloc(sizeof(*a), GFP_NOFS);
23362+ if (unlikely(!a))
23363+ goto out;
23364+
f2c43d5f
AM
23365+ a->flags = _flags;
23366+ a->exchange = _flags & RENAME_EXCHANGE;
4a4d8108
AM
23367+ a->src_dir = _src_dir;
23368+ a->src_dentry = _src_dentry;
5527c038
JR
23369+ a->src_inode = NULL;
23370+ if (d_really_is_positive(a->src_dentry))
23371+ a->src_inode = d_inode(a->src_dentry);
4a4d8108
AM
23372+ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
23373+ a->dst_dir = _dst_dir;
23374+ a->dst_dentry = _dst_dentry;
5527c038
JR
23375+ a->dst_inode = NULL;
23376+ if (d_really_is_positive(a->dst_dentry))
23377+ a->dst_inode = d_inode(a->dst_dentry);
4a4d8108
AM
23378+ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
23379+ if (a->dst_inode) {
f2c43d5f
AM
23380+ /*
23381+ * if EXCHANGE && src is non-dir && dst is dir,
23382+ * dst is not locked.
23383+ */
23384+ /* IMustLock(a->dst_inode); */
4a4d8108 23385+ au_igrab(a->dst_inode);
1facf9fc 23386+ }
1facf9fc 23387+
4a4d8108 23388+ err = -ENOTDIR;
f2c43d5f 23389+ lock_flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
2000de60 23390+ if (d_is_dir(a->src_dentry)) {
f2c43d5f
AM
23391+ au_fset_ren(a->auren_flags, ISDIR_SRC);
23392+ if (unlikely(!a->exchange
23393+ && d_really_is_positive(a->dst_dentry)
2000de60 23394+ && !d_is_dir(a->dst_dentry)))
4a4d8108 23395+ goto out_free;
f2c43d5f
AM
23396+ lock_flags |= AuLock_DIRS;
23397+ }
23398+ if (a->dst_inode && d_is_dir(a->dst_dentry)) {
23399+ au_fset_ren(a->auren_flags, ISDIR_DST);
23400+ if (unlikely(!a->exchange
23401+ && d_really_is_positive(a->src_dentry)
23402+ && !d_is_dir(a->src_dentry)))
23403+ goto out_free;
23404+ lock_flags |= AuLock_DIRS;
b95c5147 23405+ }
ae9dfd79
AM
23406+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
23407+ lock_flags);
e49829fe
JR
23408+ if (unlikely(err))
23409+ goto out_free;
1facf9fc 23410+
027c5e7a
AM
23411+ err = au_d_hashed_positive(a->src_dentry);
23412+ if (unlikely(err))
23413+ goto out_unlock;
23414+ err = -ENOENT;
23415+ if (a->dst_inode) {
23416+ /*
f2c43d5f 23417+ * If it is a dir, VFS unhash it before this
027c5e7a
AM
23418+ * function. It means we cannot rely upon d_unhashed().
23419+ */
23420+ if (unlikely(!a->dst_inode->i_nlink))
23421+ goto out_unlock;
f2c43d5f 23422+ if (!au_ftest_ren(a->auren_flags, ISDIR_DST)) {
027c5e7a 23423+ err = au_d_hashed_positive(a->dst_dentry);
f2c43d5f 23424+ if (unlikely(err && !a->exchange))
027c5e7a
AM
23425+ goto out_unlock;
23426+ } else if (unlikely(IS_DEADDIR(a->dst_inode)))
23427+ goto out_unlock;
23428+ } else if (unlikely(d_unhashed(a->dst_dentry)))
23429+ goto out_unlock;
23430+
7eafdf33
AM
23431+ /*
23432+ * is it possible?
79b8bda9 23433+ * yes, it happened (in linux-3.3-rcN) but I don't know why.
7eafdf33
AM
23434+ * there may exist a problem somewhere else.
23435+ */
23436+ err = -EINVAL;
5527c038 23437+ if (unlikely(d_inode(a->dst_parent) == d_inode(a->src_dentry)))
7eafdf33
AM
23438+ goto out_unlock;
23439+
f2c43d5f 23440+ au_fset_ren(a->auren_flags, ISSAMEDIR); /* temporary */
4a4d8108 23441+ di_write_lock_parent(a->dst_parent);
1facf9fc 23442+
4a4d8108
AM
23443+ /* which branch we process */
23444+ err = au_ren_wbr(a);
23445+ if (unlikely(err < 0))
027c5e7a 23446+ goto out_parent;
4a4d8108 23447+ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
86dc4139 23448+ a->h_path.mnt = au_br_mnt(a->br);
1facf9fc 23449+
4a4d8108
AM
23450+ /* are they available to be renamed */
23451+ err = au_ren_may_dir(a);
23452+ if (unlikely(err))
23453+ goto out_children;
1facf9fc 23454+
4a4d8108 23455+ /* prepare the writable parent dir on the same branch */
5afbbe0d 23456+ if (a->dst_btop == a->btgt) {
f2c43d5f 23457+ au_fset_ren(a->auren_flags, WHDST);
4a4d8108
AM
23458+ } else {
23459+ err = au_cpup_dirs(a->dst_dentry, a->btgt);
23460+ if (unlikely(err))
23461+ goto out_children;
23462+ }
1facf9fc 23463+
f2c43d5f
AM
23464+ err = 0;
23465+ if (!a->exchange) {
23466+ if (a->src_dir != a->dst_dir) {
23467+ /*
23468+ * this temporary unlock is safe,
23469+ * because both dir->i_mutex are locked.
23470+ */
23471+ di_write_unlock(a->dst_parent);
23472+ di_write_lock_parent(a->src_parent);
23473+ err = au_wr_dir_need_wh(a->src_dentry,
23474+ au_ftest_ren(a->auren_flags,
23475+ ISDIR_SRC),
23476+ &a->btgt);
23477+ di_write_unlock(a->src_parent);
23478+ di_write_lock2_parent(a->src_parent, a->dst_parent,
23479+ /*isdir*/1);
23480+ au_fclr_ren(a->auren_flags, ISSAMEDIR);
23481+ } else
23482+ err = au_wr_dir_need_wh(a->src_dentry,
23483+ au_ftest_ren(a->auren_flags,
23484+ ISDIR_SRC),
23485+ &a->btgt);
23486+ }
4a4d8108
AM
23487+ if (unlikely(err < 0))
23488+ goto out_children;
23489+ if (err)
f2c43d5f 23490+ au_fset_ren(a->auren_flags, WHSRC);
1facf9fc 23491+
86dc4139 23492+ /* cpup src */
5afbbe0d 23493+ if (a->src_btop != a->btgt) {
86dc4139
AM
23494+ err = au_pin(&pin, a->src_dentry, a->btgt,
23495+ au_opt_udba(a->src_dentry->d_sb),
23496+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 23497+ if (!err) {
c2b27bf2
AM
23498+ struct au_cp_generic cpg = {
23499+ .dentry = a->src_dentry,
23500+ .bdst = a->btgt,
5afbbe0d 23501+ .bsrc = a->src_btop,
c2b27bf2
AM
23502+ .len = -1,
23503+ .pin = &pin,
23504+ .flags = AuCpup_DTIME | AuCpup_HOPEN
23505+ };
5afbbe0d 23506+ AuDebugOn(au_dbtop(a->src_dentry) != a->src_btop);
c2b27bf2 23507+ err = au_sio_cpup_simple(&cpg);
367653fa 23508+ au_unpin(&pin);
86dc4139 23509+ }
86dc4139
AM
23510+ if (unlikely(err))
23511+ goto out_children;
5afbbe0d 23512+ a->src_btop = a->btgt;
86dc4139 23513+ a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt);
f2c43d5f
AM
23514+ if (!a->exchange)
23515+ au_fset_ren(a->auren_flags, WHSRC);
23516+ }
23517+
23518+ /* cpup dst */
23519+ if (a->exchange && a->dst_inode
23520+ && a->dst_btop != a->btgt) {
23521+ err = au_pin(&pin, a->dst_dentry, a->btgt,
23522+ au_opt_udba(a->dst_dentry->d_sb),
23523+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
23524+ if (!err) {
23525+ struct au_cp_generic cpg = {
23526+ .dentry = a->dst_dentry,
23527+ .bdst = a->btgt,
23528+ .bsrc = a->dst_btop,
23529+ .len = -1,
23530+ .pin = &pin,
23531+ .flags = AuCpup_DTIME | AuCpup_HOPEN
23532+ };
23533+ err = au_sio_cpup_simple(&cpg);
23534+ au_unpin(&pin);
23535+ }
23536+ if (unlikely(err))
23537+ goto out_children;
23538+ a->dst_btop = a->btgt;
23539+ a->dst_h_dentry = au_h_dptr(a->dst_dentry, a->btgt);
86dc4139
AM
23540+ }
23541+
4a4d8108
AM
23542+ /* lock them all */
23543+ err = au_ren_lock(a);
23544+ if (unlikely(err))
86dc4139 23545+ /* leave the copied-up one */
4a4d8108 23546+ goto out_children;
1facf9fc 23547+
f2c43d5f
AM
23548+ if (!a->exchange) {
23549+ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE))
23550+ err = au_may_ren(a);
23551+ else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN))
23552+ err = -ENAMETOOLONG;
23553+ if (unlikely(err))
23554+ goto out_hdir;
23555+ }
1facf9fc 23556+
4a4d8108
AM
23557+ /* store timestamps to be revertible */
23558+ au_ren_dt(a);
1facf9fc 23559+
ae9dfd79
AM
23560+ /* store dirren info */
23561+ if (au_ftest_ren(a->auren_flags, DIRREN)) {
23562+ err = au_dr_rename(a->src_dentry, a->btgt,
23563+ &a->dst_dentry->d_name, &rev);
23564+ AuTraceErr(err);
23565+ if (unlikely(err))
23566+ goto out_dt;
23567+ }
23568+
4a4d8108
AM
23569+ /* here we go */
23570+ err = do_rename(a);
23571+ if (unlikely(err))
ae9dfd79
AM
23572+ goto out_dirren;
23573+
23574+ if (au_ftest_ren(a->auren_flags, DIRREN))
23575+ au_dr_rename_fin(a->src_dentry, a->btgt, rev);
4a4d8108
AM
23576+
23577+ /* update dir attributes */
23578+ au_ren_refresh_dir(a);
23579+
23580+ /* dput/iput all lower dentries */
23581+ au_ren_refresh(a);
23582+
23583+ goto out_hdir; /* success */
23584+
ae9dfd79
AM
23585+out_dirren:
23586+ if (au_ftest_ren(a->auren_flags, DIRREN))
23587+ au_dr_rename_rev(a->src_dentry, a->btgt, rev);
4f0767ce 23588+out_dt:
4a4d8108 23589+ au_ren_rev_dt(err, a);
4f0767ce 23590+out_hdir:
4a4d8108 23591+ au_ren_unlock(a);
4f0767ce 23592+out_children:
4a4d8108 23593+ au_nhash_wh_free(&a->whlist);
5afbbe0d
AM
23594+ if (err && a->dst_inode && a->dst_btop != a->btgt) {
23595+ AuDbg("btop %d, btgt %d\n", a->dst_btop, a->btgt);
027c5e7a 23596+ au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
5afbbe0d 23597+ au_set_dbtop(a->dst_dentry, a->dst_btop);
4a4d8108 23598+ }
027c5e7a 23599+out_parent:
f2c43d5f 23600+ if (!err) {
ae9dfd79
AM
23601+ if (d_unhashed(a->src_dentry))
23602+ au_fset_ren(a->auren_flags, DROPPED_SRC);
23603+ if (d_unhashed(a->dst_dentry))
23604+ au_fset_ren(a->auren_flags, DROPPED_DST);
f2c43d5f
AM
23605+ if (!a->exchange)
23606+ d_move(a->src_dentry, a->dst_dentry);
ae9dfd79 23607+ else {
f2c43d5f 23608+ d_exchange(a->src_dentry, a->dst_dentry);
ae9dfd79
AM
23609+ if (au_ftest_ren(a->auren_flags, DROPPED_DST))
23610+ d_drop(a->dst_dentry);
23611+ }
23612+ if (au_ftest_ren(a->auren_flags, DROPPED_SRC))
23613+ d_drop(a->src_dentry);
f2c43d5f 23614+ } else {
5afbbe0d 23615+ au_update_dbtop(a->dst_dentry);
027c5e7a
AM
23616+ if (!a->dst_inode)
23617+ d_drop(a->dst_dentry);
23618+ }
f2c43d5f 23619+ if (au_ftest_ren(a->auren_flags, ISSAMEDIR))
4a4d8108
AM
23620+ di_write_unlock(a->dst_parent);
23621+ else
23622+ di_write_unlock2(a->src_parent, a->dst_parent);
027c5e7a 23623+out_unlock:
4a4d8108 23624+ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
4f0767ce 23625+out_free:
4a4d8108
AM
23626+ iput(a->dst_inode);
23627+ if (a->thargs)
23628+ au_whtmp_rmdir_free(a->thargs);
ae9dfd79 23629+ kfree(a);
4f0767ce 23630+out:
4a4d8108
AM
23631+ AuTraceErr(err);
23632+ return err;
1308ab2a 23633+}
7f207e10
AM
23634diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
23635--- /usr/share/empty/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
23636+++ linux/fs/aufs/Kconfig 2018-04-15 08:49:13.394483860 +0200
23637@@ -0,0 +1,198 @@
4a4d8108
AM
23638+config AUFS_FS
23639+ tristate "Aufs (Advanced multi layered unification filesystem) support"
4a4d8108
AM
23640+ help
23641+ Aufs is a stackable unification filesystem such as Unionfs,
23642+ which unifies several directories and provides a merged single
23643+ directory.
23644+ In the early days, aufs was entirely re-designed and
23645+ re-implemented Unionfs Version 1.x series. Introducing many
23646+ original ideas, approaches and improvements, it becomes totally
23647+ different from Unionfs while keeping the basic features.
1facf9fc 23648+
4a4d8108
AM
23649+if AUFS_FS
23650+choice
23651+ prompt "Maximum number of branches"
23652+ default AUFS_BRANCH_MAX_127
23653+ help
23654+ Specifies the maximum number of branches (or member directories)
23655+ in a single aufs. The larger value consumes more system
23656+ resources and has a minor impact to performance.
23657+config AUFS_BRANCH_MAX_127
23658+ bool "127"
23659+ help
23660+ Specifies the maximum number of branches (or member directories)
23661+ in a single aufs. The larger value consumes more system
23662+ resources and has a minor impact to performance.
23663+config AUFS_BRANCH_MAX_511
23664+ bool "511"
23665+ help
23666+ Specifies the maximum number of branches (or member directories)
23667+ in a single aufs. The larger value consumes more system
23668+ resources and has a minor impact to performance.
23669+config AUFS_BRANCH_MAX_1023
23670+ bool "1023"
23671+ help
23672+ Specifies the maximum number of branches (or member directories)
23673+ in a single aufs. The larger value consumes more system
23674+ resources and has a minor impact to performance.
23675+config AUFS_BRANCH_MAX_32767
23676+ bool "32767"
23677+ help
23678+ Specifies the maximum number of branches (or member directories)
23679+ in a single aufs. The larger value consumes more system
23680+ resources and has a minor impact to performance.
23681+endchoice
1facf9fc 23682+
e49829fe
JR
23683+config AUFS_SBILIST
23684+ bool
23685+ depends on AUFS_MAGIC_SYSRQ || PROC_FS
23686+ default y
23687+ help
23688+ Automatic configuration for internal use.
23689+ When aufs supports Magic SysRq or /proc, enabled automatically.
23690+
4a4d8108
AM
23691+config AUFS_HNOTIFY
23692+ bool "Detect direct branch access (bypassing aufs)"
23693+ help
23694+ If you want to modify files on branches directly, eg. bypassing aufs,
23695+ and want aufs to detect the changes of them fully, then enable this
23696+ option and use 'udba=notify' mount option.
7f207e10 23697+ Currently there is only one available configuration, "fsnotify".
4a4d8108
AM
23698+ It will have a negative impact to the performance.
23699+ See detail in aufs.5.
dece6358 23700+
4a4d8108
AM
23701+choice
23702+ prompt "method" if AUFS_HNOTIFY
23703+ default AUFS_HFSNOTIFY
23704+config AUFS_HFSNOTIFY
23705+ bool "fsnotify"
23706+ select FSNOTIFY
4a4d8108 23707+endchoice
1facf9fc 23708+
4a4d8108
AM
23709+config AUFS_EXPORT
23710+ bool "NFS-exportable aufs"
2cbb1c4b 23711+ depends on EXPORTFS
4a4d8108
AM
23712+ help
23713+ If you want to export your mounted aufs via NFS, then enable this
23714+ option. There are several requirements for this configuration.
23715+ See detail in aufs.5.
1facf9fc 23716+
4a4d8108
AM
23717+config AUFS_INO_T_64
23718+ bool
23719+ depends on AUFS_EXPORT
23720+ depends on 64BIT && !(ALPHA || S390)
23721+ default y
23722+ help
23723+ Automatic configuration for internal use.
23724+ /* typedef unsigned long/int __kernel_ino_t */
23725+ /* alpha and s390x are int */
1facf9fc 23726+
c1595e42
JR
23727+config AUFS_XATTR
23728+ bool "support for XATTR/EA (including Security Labels)"
23729+ help
23730+ If your branch fs supports XATTR/EA and you want to make them
23731+ available in aufs too, then enable this opsion and specify the
23732+ branch attributes for EA.
23733+ See detail in aufs.5.
23734+
076b876e
AM
23735+config AUFS_FHSM
23736+ bool "File-based Hierarchical Storage Management"
23737+ help
23738+ Hierarchical Storage Management (or HSM) is a well-known feature
23739+ in the storage world. Aufs provides this feature as file-based.
23740+ with multiple branches.
23741+ These multiple branches are prioritized, ie. the topmost one
23742+ should be the fastest drive and be used heavily.
23743+
4a4d8108
AM
23744+config AUFS_RDU
23745+ bool "Readdir in userspace"
23746+ help
23747+ Aufs has two methods to provide a merged view for a directory,
23748+ by a user-space library and by kernel-space natively. The latter
23749+ is always enabled but sometimes large and slow.
23750+ If you enable this option, install the library in aufs2-util
23751+ package, and set some environment variables for your readdir(3),
23752+ then the work will be handled in user-space which generally
23753+ shows better performance in most cases.
23754+ See detail in aufs.5.
1facf9fc 23755+
ae9dfd79
AM
23756+config AUFS_DIRREN
23757+ bool "Workaround for rename(2)-ing a directory"
23758+ help
23759+ By default, aufs returns EXDEV error in renameing a dir who has
23760+ his child on the lower branch, since it is a bad idea to issue
23761+ rename(2) internally for every lower branch. But user may not
23762+ accept this behaviour. So here is a workaround to allow such
23763+ rename(2) and store some extra infromation on the writable
23764+ branch. Obviously this costs high (and I don't like it).
23765+ To use this feature, you need to enable this configuration AND
23766+ to specify the mount option `dirren.'
23767+ See details in aufs.5 and the design documents.
23768+
4a4d8108
AM
23769+config AUFS_SHWH
23770+ bool "Show whiteouts"
23771+ help
23772+ If you want to make the whiteouts in aufs visible, then enable
23773+ this option and specify 'shwh' mount option. Although it may
23774+ sounds like philosophy or something, but in technically it
23775+ simply shows the name of whiteout with keeping its behaviour.
1facf9fc 23776+
4a4d8108
AM
23777+config AUFS_BR_RAMFS
23778+ bool "Ramfs (initramfs/rootfs) as an aufs branch"
23779+ help
23780+ If you want to use ramfs as an aufs branch fs, then enable this
23781+ option. Generally tmpfs is recommended.
23782+ Aufs prohibited them to be a branch fs by default, because
23783+ initramfs becomes unusable after switch_root or something
23784+ generally. If you sets initramfs as an aufs branch and boot your
23785+ system by switch_root, you will meet a problem easily since the
23786+ files in initramfs may be inaccessible.
23787+ Unless you are going to use ramfs as an aufs branch fs without
23788+ switch_root or something, leave it N.
1facf9fc 23789+
4a4d8108
AM
23790+config AUFS_BR_FUSE
23791+ bool "Fuse fs as an aufs branch"
23792+ depends on FUSE_FS
23793+ select AUFS_POLL
23794+ help
23795+ If you want to use fuse-based userspace filesystem as an aufs
23796+ branch fs, then enable this option.
23797+ It implements the internal poll(2) operation which is
23798+ implemented by fuse only (curretnly).
1facf9fc 23799+
4a4d8108
AM
23800+config AUFS_POLL
23801+ bool
23802+ help
23803+ Automatic configuration for internal use.
1facf9fc 23804+
4a4d8108
AM
23805+config AUFS_BR_HFSPLUS
23806+ bool "Hfsplus as an aufs branch"
23807+ depends on HFSPLUS_FS
23808+ default y
23809+ help
23810+ If you want to use hfsplus fs as an aufs branch fs, then enable
23811+ this option. This option introduces a small overhead at
23812+ copying-up a file on hfsplus.
1facf9fc 23813+
4a4d8108
AM
23814+config AUFS_BDEV_LOOP
23815+ bool
23816+ depends on BLK_DEV_LOOP
23817+ default y
23818+ help
23819+ Automatic configuration for internal use.
23820+ Convert =[ym] into =y.
1308ab2a 23821+
4a4d8108
AM
23822+config AUFS_DEBUG
23823+ bool "Debug aufs"
23824+ help
23825+ Enable this to compile aufs internal debug code.
23826+ It will have a negative impact to the performance.
23827+
23828+config AUFS_MAGIC_SYSRQ
23829+ bool
23830+ depends on AUFS_DEBUG && MAGIC_SYSRQ
23831+ default y
23832+ help
23833+ Automatic configuration for internal use.
23834+ When aufs supports Magic SysRq, enabled automatically.
23835+endif
7f207e10
AM
23836diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
23837--- /usr/share/empty/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 23838+++ linux/fs/aufs/loop.c 2018-04-15 08:49:13.401150731 +0200
e2f27e51 23839@@ -0,0 +1,147 @@
1facf9fc 23840+/*
ae9dfd79 23841+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 23842+ *
23843+ * This program, aufs is free software; you can redistribute it and/or modify
23844+ * it under the terms of the GNU General Public License as published by
23845+ * the Free Software Foundation; either version 2 of the License, or
23846+ * (at your option) any later version.
dece6358
AM
23847+ *
23848+ * This program is distributed in the hope that it will be useful,
23849+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23850+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23851+ * GNU General Public License for more details.
23852+ *
23853+ * You should have received a copy of the GNU General Public License
523b37e3 23854+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 23855+ */
23856+
23857+/*
23858+ * support for loopback block device as a branch
23859+ */
23860+
1facf9fc 23861+#include "aufs.h"
23862+
392086de
AM
23863+/* added into drivers/block/loop.c */
23864+static struct file *(*backing_file_func)(struct super_block *sb);
23865+
1facf9fc 23866+/*
23867+ * test if two lower dentries have overlapping branches.
23868+ */
b752ccd1 23869+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
1facf9fc 23870+{
b752ccd1 23871+ struct super_block *h_sb;
392086de
AM
23872+ struct file *backing_file;
23873+
23874+ if (unlikely(!backing_file_func)) {
23875+ /* don't load "loop" module here */
23876+ backing_file_func = symbol_get(loop_backing_file);
23877+ if (unlikely(!backing_file_func))
23878+ /* "loop" module is not loaded */
23879+ return 0;
23880+ }
1facf9fc 23881+
b752ccd1 23882+ h_sb = h_adding->d_sb;
392086de
AM
23883+ backing_file = backing_file_func(h_sb);
23884+ if (!backing_file)
1facf9fc 23885+ return 0;
23886+
2000de60 23887+ h_adding = backing_file->f_path.dentry;
b752ccd1
AM
23888+ /*
23889+ * h_adding can be local NFS.
23890+ * in this case aufs cannot detect the loop.
23891+ */
23892+ if (unlikely(h_adding->d_sb == sb))
1facf9fc 23893+ return 1;
b752ccd1 23894+ return !!au_test_subdir(h_adding, sb->s_root);
1facf9fc 23895+}
23896+
23897+/* true if a kernel thread named 'loop[0-9].*' accesses a file */
23898+int au_test_loopback_kthread(void)
23899+{
b752ccd1
AM
23900+ int ret;
23901+ struct task_struct *tsk = current;
a2a7ad62 23902+ char c, comm[sizeof(tsk->comm)];
b752ccd1
AM
23903+
23904+ ret = 0;
23905+ if (tsk->flags & PF_KTHREAD) {
a2a7ad62
AM
23906+ get_task_comm(comm, tsk);
23907+ c = comm[4];
b752ccd1 23908+ ret = ('0' <= c && c <= '9'
a2a7ad62 23909+ && !strncmp(comm, "loop", 4));
b752ccd1 23910+ }
1facf9fc 23911+
b752ccd1 23912+ return ret;
1facf9fc 23913+}
87a755f4
AM
23914+
23915+/* ---------------------------------------------------------------------- */
23916+
23917+#define au_warn_loopback_step 16
23918+static int au_warn_loopback_nelem = au_warn_loopback_step;
23919+static unsigned long *au_warn_loopback_array;
23920+
23921+void au_warn_loopback(struct super_block *h_sb)
23922+{
23923+ int i, new_nelem;
23924+ unsigned long *a, magic;
23925+ static DEFINE_SPINLOCK(spin);
23926+
23927+ magic = h_sb->s_magic;
23928+ spin_lock(&spin);
23929+ a = au_warn_loopback_array;
23930+ for (i = 0; i < au_warn_loopback_nelem && *a; i++)
23931+ if (a[i] == magic) {
23932+ spin_unlock(&spin);
23933+ return;
23934+ }
23935+
23936+ /* h_sb is new to us, print it */
23937+ if (i < au_warn_loopback_nelem) {
23938+ a[i] = magic;
23939+ goto pr;
23940+ }
23941+
23942+ /* expand the array */
23943+ new_nelem = au_warn_loopback_nelem + au_warn_loopback_step;
23944+ a = au_kzrealloc(au_warn_loopback_array,
23945+ au_warn_loopback_nelem * sizeof(unsigned long),
e2f27e51
AM
23946+ new_nelem * sizeof(unsigned long), GFP_ATOMIC,
23947+ /*may_shrink*/0);
87a755f4
AM
23948+ if (a) {
23949+ au_warn_loopback_nelem = new_nelem;
23950+ au_warn_loopback_array = a;
23951+ a[i] = magic;
23952+ goto pr;
23953+ }
23954+
23955+ spin_unlock(&spin);
23956+ AuWarn1("realloc failed, ignored\n");
23957+ return;
23958+
23959+pr:
23960+ spin_unlock(&spin);
0c3ec466
AM
23961+ pr_warn("you may want to try another patch for loopback file "
23962+ "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic);
87a755f4
AM
23963+}
23964+
23965+int au_loopback_init(void)
23966+{
23967+ int err;
23968+ struct super_block *sb __maybe_unused;
23969+
79b8bda9 23970+ BUILD_BUG_ON(sizeof(sb->s_magic) != sizeof(unsigned long));
87a755f4
AM
23971+
23972+ err = 0;
23973+ au_warn_loopback_array = kcalloc(au_warn_loopback_step,
23974+ sizeof(unsigned long), GFP_NOFS);
23975+ if (unlikely(!au_warn_loopback_array))
23976+ err = -ENOMEM;
23977+
23978+ return err;
23979+}
23980+
23981+void au_loopback_fin(void)
23982+{
79b8bda9
AM
23983+ if (backing_file_func)
23984+ symbol_put(loop_backing_file);
ae9dfd79 23985+ kfree(au_warn_loopback_array);
87a755f4 23986+}
7f207e10
AM
23987diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
23988--- /usr/share/empty/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 23989+++ linux/fs/aufs/loop.h 2018-04-15 08:49:13.401150731 +0200
523b37e3 23990@@ -0,0 +1,52 @@
1facf9fc 23991+/*
ae9dfd79 23992+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 23993+ *
23994+ * This program, aufs is free software; you can redistribute it and/or modify
23995+ * it under the terms of the GNU General Public License as published by
23996+ * the Free Software Foundation; either version 2 of the License, or
23997+ * (at your option) any later version.
dece6358
AM
23998+ *
23999+ * This program is distributed in the hope that it will be useful,
24000+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24001+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24002+ * GNU General Public License for more details.
24003+ *
24004+ * You should have received a copy of the GNU General Public License
523b37e3 24005+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24006+ */
24007+
24008+/*
24009+ * support for loopback mount as a branch
24010+ */
24011+
24012+#ifndef __AUFS_LOOP_H__
24013+#define __AUFS_LOOP_H__
24014+
24015+#ifdef __KERNEL__
24016+
dece6358
AM
24017+struct dentry;
24018+struct super_block;
1facf9fc 24019+
24020+#ifdef CONFIG_AUFS_BDEV_LOOP
392086de
AM
24021+/* drivers/block/loop.c */
24022+struct file *loop_backing_file(struct super_block *sb);
24023+
1facf9fc 24024+/* loop.c */
b752ccd1 24025+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding);
1facf9fc 24026+int au_test_loopback_kthread(void);
87a755f4
AM
24027+void au_warn_loopback(struct super_block *h_sb);
24028+
24029+int au_loopback_init(void);
24030+void au_loopback_fin(void);
1facf9fc 24031+#else
4a4d8108 24032+AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
b752ccd1 24033+ struct dentry *h_adding)
4a4d8108 24034+AuStubInt0(au_test_loopback_kthread, void)
87a755f4
AM
24035+AuStubVoid(au_warn_loopback, struct super_block *h_sb)
24036+
24037+AuStubInt0(au_loopback_init, void)
24038+AuStubVoid(au_loopback_fin, void)
1facf9fc 24039+#endif /* BLK_DEV_LOOP */
24040+
24041+#endif /* __KERNEL__ */
24042+#endif /* __AUFS_LOOP_H__ */
7f207e10
AM
24043diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
24044--- /usr/share/empty/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 24045+++ linux/fs/aufs/magic.mk 2018-04-15 08:49:11.027744356 +0200
7e9cd9fe 24046@@ -0,0 +1,30 @@
1facf9fc 24047+
24048+# defined in ${srctree}/fs/fuse/inode.c
24049+# tristate
24050+ifdef CONFIG_FUSE_FS
24051+ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
24052+endif
24053+
1facf9fc 24054+# defined in ${srctree}/fs/xfs/xfs_sb.h
24055+# tristate
24056+ifdef CONFIG_XFS_FS
24057+ccflags-y += -DXFS_SB_MAGIC=0x58465342
24058+endif
24059+
24060+# defined in ${srctree}/fs/configfs/mount.c
24061+# tristate
24062+ifdef CONFIG_CONFIGFS_FS
24063+ccflags-y += -DCONFIGFS_MAGIC=0x62656570
24064+endif
24065+
1facf9fc 24066+# defined in ${srctree}/fs/ubifs/ubifs.h
24067+# tristate
24068+ifdef CONFIG_UBIFS_FS
24069+ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
24070+endif
4a4d8108
AM
24071+
24072+# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h
24073+# tristate
24074+ifdef CONFIG_HFSPLUS_FS
24075+ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b
24076+endif
7f207e10
AM
24077diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
24078--- /usr/share/empty/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
24079+++ linux/fs/aufs/Makefile 2018-04-15 08:49:13.394483860 +0200
24080@@ -0,0 +1,45 @@
4a4d8108
AM
24081+
24082+include ${src}/magic.mk
24083+ifeq (${CONFIG_AUFS_FS},m)
24084+include ${src}/conf.mk
24085+endif
24086+-include ${src}/priv_def.mk
24087+
24088+# cf. include/linux/kernel.h
24089+# enable pr_debug
24090+ccflags-y += -DDEBUG
f6c5ef8b
AM
24091+# sparse requires the full pathname
24092+ifdef M
523b37e3 24093+ccflags-y += -include ${M}/../../include/uapi/linux/aufs_type.h
f6c5ef8b 24094+else
523b37e3 24095+ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h
f6c5ef8b 24096+endif
4a4d8108
AM
24097+
24098+obj-$(CONFIG_AUFS_FS) += aufs.o
24099+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
24100+ wkq.o vfsub.o dcsub.o \
e49829fe 24101+ cpup.o whout.o wbr_policy.o \
4a4d8108
AM
24102+ dinfo.o dentry.o \
24103+ dynop.o \
24104+ finfo.o file.o f_op.o \
24105+ dir.o vdir.o \
24106+ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
c2b27bf2 24107+ mvdown.o ioctl.o
4a4d8108
AM
24108+
24109+# all are boolean
e49829fe 24110+aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
4a4d8108
AM
24111+aufs-$(CONFIG_SYSFS) += sysfs.o
24112+aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
24113+aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
24114+aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
24115+aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
4a4d8108 24116+aufs-$(CONFIG_AUFS_EXPORT) += export.o
c1595e42
JR
24117+aufs-$(CONFIG_AUFS_XATTR) += xattr.o
24118+aufs-$(CONFIG_FS_POSIX_ACL) += posix_acl.o
ae9dfd79 24119+aufs-$(CONFIG_AUFS_DIRREN) += dirren.o
076b876e 24120+aufs-$(CONFIG_AUFS_FHSM) += fhsm.o
4a4d8108
AM
24121+aufs-$(CONFIG_AUFS_POLL) += poll.o
24122+aufs-$(CONFIG_AUFS_RDU) += rdu.o
4a4d8108
AM
24123+aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
24124+aufs-$(CONFIG_AUFS_DEBUG) += debug.o
24125+aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
7f207e10
AM
24126diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
24127--- /usr/share/empty/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
24128+++ linux/fs/aufs/module.c 2018-04-15 08:49:13.401150731 +0200
24129@@ -0,0 +1,266 @@
1facf9fc 24130+/*
ae9dfd79 24131+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 24132+ *
24133+ * This program, aufs is free software; you can redistribute it and/or modify
24134+ * it under the terms of the GNU General Public License as published by
24135+ * the Free Software Foundation; either version 2 of the License, or
24136+ * (at your option) any later version.
dece6358
AM
24137+ *
24138+ * This program is distributed in the hope that it will be useful,
24139+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24140+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24141+ * GNU General Public License for more details.
24142+ *
24143+ * You should have received a copy of the GNU General Public License
523b37e3 24144+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24145+ */
24146+
24147+/*
24148+ * module global variables and operations
24149+ */
24150+
24151+#include <linux/module.h>
24152+#include <linux/seq_file.h>
24153+#include "aufs.h"
24154+
e2f27e51
AM
24155+/* shrinkable realloc */
24156+void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink)
1facf9fc 24157+{
e2f27e51
AM
24158+ size_t sz;
24159+ int diff;
1facf9fc 24160+
e2f27e51
AM
24161+ sz = 0;
24162+ diff = -1;
24163+ if (p) {
24164+#if 0 /* unused */
24165+ if (!new_sz) {
ae9dfd79 24166+ kfree(p);
e2f27e51
AM
24167+ p = NULL;
24168+ goto out;
24169+ }
24170+#else
24171+ AuDebugOn(!new_sz);
24172+#endif
24173+ sz = ksize(p);
24174+ diff = au_kmidx_sub(sz, new_sz);
24175+ }
24176+ if (sz && !diff)
24177+ goto out;
24178+
24179+ if (sz < new_sz)
24180+ /* expand or SLOB */
24181+ p = krealloc(p, new_sz, gfp);
24182+ else if (new_sz < sz && may_shrink) {
24183+ /* shrink */
24184+ void *q;
24185+
24186+ q = kmalloc(new_sz, gfp);
24187+ if (q) {
24188+ if (p) {
24189+ memcpy(q, p, new_sz);
ae9dfd79 24190+ kfree(p);
e2f27e51
AM
24191+ }
24192+ p = q;
24193+ } else
24194+ p = NULL;
24195+ }
24196+
24197+out:
24198+ return p;
24199+}
24200+
24201+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp,
24202+ int may_shrink)
24203+{
24204+ p = au_krealloc(p, new_sz, gfp, may_shrink);
24205+ if (p && new_sz > nused)
1facf9fc 24206+ memset(p + nused, 0, new_sz - nused);
24207+ return p;
24208+}
24209+
24210+/* ---------------------------------------------------------------------- */
1facf9fc 24211+/*
24212+ * aufs caches
24213+ */
ae9dfd79 24214+struct kmem_cache *au_cache[AuCache_Last];
5afbbe0d
AM
24215+
24216+static void au_cache_fin(void)
24217+{
24218+ int i;
24219+
24220+ /*
24221+ * Make sure all delayed rcu free inodes are flushed before we
24222+ * destroy cache.
24223+ */
24224+ rcu_barrier();
24225+
24226+ /* excluding AuCache_HNOTIFY */
24227+ BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
24228+ for (i = 0; i < AuCache_HNOTIFY; i++) {
ae9dfd79
AM
24229+ kmem_cache_destroy(au_cache[i]);
24230+ au_cache[i] = NULL;
5afbbe0d
AM
24231+ }
24232+}
24233+
1facf9fc 24234+static int __init au_cache_init(void)
24235+{
ae9dfd79
AM
24236+ au_cache[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
24237+ if (au_cache[AuCache_DINFO])
027c5e7a 24238+ /* SLAB_DESTROY_BY_RCU */
ae9dfd79 24239+ au_cache[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
f0c0a007 24240+ au_icntnr_init_once);
ae9dfd79
AM
24241+ if (au_cache[AuCache_ICNTNR])
24242+ au_cache[AuCache_FINFO] = AuCacheCtor(au_finfo,
f0c0a007 24243+ au_fi_init_once);
ae9dfd79
AM
24244+ if (au_cache[AuCache_FINFO])
24245+ au_cache[AuCache_VDIR] = AuCache(au_vdir);
24246+ if (au_cache[AuCache_VDIR])
24247+ au_cache[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
24248+ if (au_cache[AuCache_DEHSTR])
1facf9fc 24249+ return 0;
24250+
5afbbe0d 24251+ au_cache_fin();
1facf9fc 24252+ return -ENOMEM;
24253+}
24254+
1facf9fc 24255+/* ---------------------------------------------------------------------- */
24256+
24257+int au_dir_roflags;
24258+
e49829fe 24259+#ifdef CONFIG_AUFS_SBILIST
1e00d052
AM
24260+/*
24261+ * iterate_supers_type() doesn't protect us from
24262+ * remounting (branch management)
24263+ */
ae9dfd79 24264+struct hlist_bl_head au_sbilist;
e49829fe
JR
24265+#endif
24266+
1facf9fc 24267+/*
24268+ * functions for module interface.
24269+ */
24270+MODULE_LICENSE("GPL");
24271+/* MODULE_LICENSE("GPL v2"); */
dece6358 24272+MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
1facf9fc 24273+MODULE_DESCRIPTION(AUFS_NAME
24274+ " -- Advanced multi layered unification filesystem");
24275+MODULE_VERSION(AUFS_VERSION);
c06a8ce3 24276+MODULE_ALIAS_FS(AUFS_NAME);
1facf9fc 24277+
1facf9fc 24278+/* this module parameter has no meaning when SYSFS is disabled */
24279+int sysaufs_brs = 1;
24280+MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
24281+module_param_named(brs, sysaufs_brs, int, S_IRUGO);
24282+
076b876e 24283+/* this module parameter has no meaning when USER_NS is disabled */
8cdd5066 24284+bool au_userns;
076b876e
AM
24285+MODULE_PARM_DESC(allow_userns, "allow unprivileged to mount under userns");
24286+module_param_named(allow_userns, au_userns, bool, S_IRUGO);
24287+
1facf9fc 24288+/* ---------------------------------------------------------------------- */
24289+
24290+static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
24291+
24292+int au_seq_path(struct seq_file *seq, struct path *path)
24293+{
79b8bda9
AM
24294+ int err;
24295+
24296+ err = seq_path(seq, path, au_esc_chars);
ae9dfd79 24297+ if (err >= 0)
79b8bda9 24298+ err = 0;
ae9dfd79 24299+ else
79b8bda9
AM
24300+ err = -ENOMEM;
24301+
24302+ return err;
1facf9fc 24303+}
24304+
24305+/* ---------------------------------------------------------------------- */
24306+
24307+static int __init aufs_init(void)
24308+{
24309+ int err, i;
24310+ char *p;
24311+
24312+ p = au_esc_chars;
24313+ for (i = 1; i <= ' '; i++)
24314+ *p++ = i;
24315+ *p++ = '\\';
24316+ *p++ = '\x7f';
24317+ *p = 0;
24318+
24319+ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
24320+
b95c5147
AM
24321+ memcpy(aufs_iop_nogetattr, aufs_iop, sizeof(aufs_iop));
24322+ for (i = 0; i < AuIop_Last; i++)
24323+ aufs_iop_nogetattr[i].getattr = NULL;
24324+
ae9dfd79 24325+ memset(au_cache, 0, sizeof(au_cache)); /* including hnotify */
f0c0a007 24326+
e49829fe 24327+ au_sbilist_init();
1facf9fc 24328+ sysaufs_brs_init();
24329+ au_debug_init();
4a4d8108 24330+ au_dy_init();
1facf9fc 24331+ err = sysaufs_init();
24332+ if (unlikely(err))
24333+ goto out;
e49829fe 24334+ err = au_procfs_init();
4f0767ce 24335+ if (unlikely(err))
953406b4 24336+ goto out_sysaufs;
e49829fe
JR
24337+ err = au_wkq_init();
24338+ if (unlikely(err))
24339+ goto out_procfs;
87a755f4 24340+ err = au_loopback_init();
1facf9fc 24341+ if (unlikely(err))
24342+ goto out_wkq;
87a755f4
AM
24343+ err = au_hnotify_init();
24344+ if (unlikely(err))
24345+ goto out_loopback;
1facf9fc 24346+ err = au_sysrq_init();
24347+ if (unlikely(err))
24348+ goto out_hin;
24349+ err = au_cache_init();
24350+ if (unlikely(err))
24351+ goto out_sysrq;
076b876e
AM
24352+
24353+ aufs_fs_type.fs_flags |= au_userns ? FS_USERNS_MOUNT : 0;
1facf9fc 24354+ err = register_filesystem(&aufs_fs_type);
24355+ if (unlikely(err))
24356+ goto out_cache;
076b876e 24357+
4a4d8108
AM
24358+ /* since we define pr_fmt, call printk directly */
24359+ printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
1facf9fc 24360+ goto out; /* success */
24361+
4f0767ce 24362+out_cache:
1facf9fc 24363+ au_cache_fin();
4f0767ce 24364+out_sysrq:
1facf9fc 24365+ au_sysrq_fin();
4f0767ce 24366+out_hin:
4a4d8108 24367+ au_hnotify_fin();
87a755f4
AM
24368+out_loopback:
24369+ au_loopback_fin();
4f0767ce 24370+out_wkq:
1facf9fc 24371+ au_wkq_fin();
e49829fe
JR
24372+out_procfs:
24373+ au_procfs_fin();
4f0767ce 24374+out_sysaufs:
1facf9fc 24375+ sysaufs_fin();
4a4d8108 24376+ au_dy_fin();
4f0767ce 24377+out:
1facf9fc 24378+ return err;
24379+}
24380+
24381+static void __exit aufs_exit(void)
24382+{
24383+ unregister_filesystem(&aufs_fs_type);
24384+ au_cache_fin();
24385+ au_sysrq_fin();
4a4d8108 24386+ au_hnotify_fin();
87a755f4 24387+ au_loopback_fin();
1facf9fc 24388+ au_wkq_fin();
e49829fe 24389+ au_procfs_fin();
1facf9fc 24390+ sysaufs_fin();
4a4d8108 24391+ au_dy_fin();
1facf9fc 24392+}
24393+
24394+module_init(aufs_init);
24395+module_exit(aufs_exit);
7f207e10
AM
24396diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
24397--- /usr/share/empty/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
24398+++ linux/fs/aufs/module.h 2018-04-15 08:49:13.401150731 +0200
24399@@ -0,0 +1,101 @@
1facf9fc 24400+/*
ae9dfd79 24401+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 24402+ *
24403+ * This program, aufs is free software; you can redistribute it and/or modify
24404+ * it under the terms of the GNU General Public License as published by
24405+ * the Free Software Foundation; either version 2 of the License, or
24406+ * (at your option) any later version.
dece6358
AM
24407+ *
24408+ * This program is distributed in the hope that it will be useful,
24409+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24410+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24411+ * GNU General Public License for more details.
24412+ *
24413+ * You should have received a copy of the GNU General Public License
523b37e3 24414+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24415+ */
24416+
24417+/*
24418+ * module initialization and module-global
24419+ */
24420+
24421+#ifndef __AUFS_MODULE_H__
24422+#define __AUFS_MODULE_H__
24423+
24424+#ifdef __KERNEL__
24425+
24426+#include <linux/slab.h>
24427+
dece6358
AM
24428+struct path;
24429+struct seq_file;
24430+
1facf9fc 24431+/* module parameters */
1facf9fc 24432+extern int sysaufs_brs;
8cdd5066 24433+extern bool au_userns;
1facf9fc 24434+
24435+/* ---------------------------------------------------------------------- */
24436+
24437+extern int au_dir_roflags;
24438+
e2f27e51
AM
24439+void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink);
24440+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp,
24441+ int may_shrink);
24442+
24443+static inline int au_kmidx_sub(size_t sz, size_t new_sz)
24444+{
24445+#ifndef CONFIG_SLOB
24446+ return kmalloc_index(sz) - kmalloc_index(new_sz);
24447+#else
24448+ return -1; /* SLOB is untested */
24449+#endif
24450+}
24451+
1facf9fc 24452+int au_seq_path(struct seq_file *seq, struct path *path);
24453+
e49829fe
JR
24454+#ifdef CONFIG_PROC_FS
24455+/* procfs.c */
24456+int __init au_procfs_init(void);
24457+void au_procfs_fin(void);
24458+#else
24459+AuStubInt0(au_procfs_init, void);
24460+AuStubVoid(au_procfs_fin, void);
24461+#endif
24462+
4f0767ce
JR
24463+/* ---------------------------------------------------------------------- */
24464+
ae9dfd79 24465+/* kmem cache */
1facf9fc 24466+enum {
24467+ AuCache_DINFO,
24468+ AuCache_ICNTNR,
24469+ AuCache_FINFO,
24470+ AuCache_VDIR,
24471+ AuCache_DEHSTR,
7eafdf33 24472+ AuCache_HNOTIFY, /* must be last */
1facf9fc 24473+ AuCache_Last
24474+};
24475+
ae9dfd79 24476+extern struct kmem_cache *au_cache[AuCache_Last];
f0c0a007 24477+
4a4d8108
AM
24478+#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
24479+#define AuCache(type) KMEM_CACHE(type, AuCacheFlags)
24480+#define AuCacheCtor(type, ctor) \
24481+ kmem_cache_create(#type, sizeof(struct type), \
24482+ __alignof__(struct type), AuCacheFlags, ctor)
1facf9fc 24483+
1facf9fc 24484+#define AuCacheFuncs(name, index) \
4a4d8108 24485+static inline struct au_##name *au_cache_alloc_##name(void) \
ae9dfd79 24486+{ return kmem_cache_alloc(au_cache[AuCache_##index], GFP_NOFS); } \
4a4d8108 24487+static inline void au_cache_free_##name(struct au_##name *p) \
ae9dfd79 24488+{ kmem_cache_free(au_cache[AuCache_##index], p); }
1facf9fc 24489+
24490+AuCacheFuncs(dinfo, DINFO);
24491+AuCacheFuncs(icntnr, ICNTNR);
24492+AuCacheFuncs(finfo, FINFO);
24493+AuCacheFuncs(vdir, VDIR);
4a4d8108
AM
24494+AuCacheFuncs(vdir_dehstr, DEHSTR);
24495+#ifdef CONFIG_AUFS_HNOTIFY
24496+AuCacheFuncs(hnotify, HNOTIFY);
24497+#endif
1facf9fc 24498+
4a4d8108
AM
24499+#endif /* __KERNEL__ */
24500+#endif /* __AUFS_MODULE_H__ */
c2b27bf2
AM
24501diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
24502--- /usr/share/empty/fs/aufs/mvdown.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 24503+++ linux/fs/aufs/mvdown.c 2018-04-15 08:49:13.401150731 +0200
5afbbe0d 24504@@ -0,0 +1,704 @@
c2b27bf2 24505+/*
ae9dfd79 24506+ * Copyright (C) 2011-2018 Junjiro R. Okajima
c2b27bf2
AM
24507+ *
24508+ * This program, aufs is free software; you can redistribute it and/or modify
24509+ * it under the terms of the GNU General Public License as published by
24510+ * the Free Software Foundation; either version 2 of the License, or
24511+ * (at your option) any later version.
24512+ *
24513+ * This program is distributed in the hope that it will be useful,
24514+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24515+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24516+ * GNU General Public License for more details.
24517+ *
24518+ * You should have received a copy of the GNU General Public License
523b37e3
AM
24519+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
24520+ */
24521+
24522+/*
24523+ * move-down, opposite of copy-up
c2b27bf2
AM
24524+ */
24525+
24526+#include "aufs.h"
24527+
c2b27bf2
AM
24528+struct au_mvd_args {
24529+ struct {
c2b27bf2
AM
24530+ struct super_block *h_sb;
24531+ struct dentry *h_parent;
24532+ struct au_hinode *hdir;
392086de 24533+ struct inode *h_dir, *h_inode;
c1595e42 24534+ struct au_pin pin;
c2b27bf2
AM
24535+ } info[AUFS_MVDOWN_NARRAY];
24536+
24537+ struct aufs_mvdown mvdown;
24538+ struct dentry *dentry, *parent;
24539+ struct inode *inode, *dir;
24540+ struct super_block *sb;
24541+ aufs_bindex_t bopq, bwh, bfound;
24542+ unsigned char rename_lock;
c2b27bf2
AM
24543+};
24544+
392086de 24545+#define mvd_errno mvdown.au_errno
076b876e
AM
24546+#define mvd_bsrc mvdown.stbr[AUFS_MVDOWN_UPPER].bindex
24547+#define mvd_src_brid mvdown.stbr[AUFS_MVDOWN_UPPER].brid
24548+#define mvd_bdst mvdown.stbr[AUFS_MVDOWN_LOWER].bindex
24549+#define mvd_dst_brid mvdown.stbr[AUFS_MVDOWN_LOWER].brid
c2b27bf2 24550+
392086de
AM
24551+#define mvd_h_src_sb info[AUFS_MVDOWN_UPPER].h_sb
24552+#define mvd_h_src_parent info[AUFS_MVDOWN_UPPER].h_parent
24553+#define mvd_hdir_src info[AUFS_MVDOWN_UPPER].hdir
24554+#define mvd_h_src_dir info[AUFS_MVDOWN_UPPER].h_dir
24555+#define mvd_h_src_inode info[AUFS_MVDOWN_UPPER].h_inode
c1595e42 24556+#define mvd_pin_src info[AUFS_MVDOWN_UPPER].pin
392086de
AM
24557+
24558+#define mvd_h_dst_sb info[AUFS_MVDOWN_LOWER].h_sb
24559+#define mvd_h_dst_parent info[AUFS_MVDOWN_LOWER].h_parent
24560+#define mvd_hdir_dst info[AUFS_MVDOWN_LOWER].hdir
24561+#define mvd_h_dst_dir info[AUFS_MVDOWN_LOWER].h_dir
24562+#define mvd_h_dst_inode info[AUFS_MVDOWN_LOWER].h_inode
c1595e42 24563+#define mvd_pin_dst info[AUFS_MVDOWN_LOWER].pin
c2b27bf2
AM
24564+
24565+#define AU_MVD_PR(flag, ...) do { \
24566+ if (flag) \
24567+ pr_err(__VA_ARGS__); \
24568+ } while (0)
24569+
076b876e
AM
24570+static int find_lower_writable(struct au_mvd_args *a)
24571+{
24572+ struct super_block *sb;
5afbbe0d 24573+ aufs_bindex_t bindex, bbot;
076b876e
AM
24574+ struct au_branch *br;
24575+
24576+ sb = a->sb;
24577+ bindex = a->mvd_bsrc;
5afbbe0d 24578+ bbot = au_sbbot(sb);
076b876e 24579+ if (a->mvdown.flags & AUFS_MVDOWN_FHSM_LOWER)
5afbbe0d 24580+ for (bindex++; bindex <= bbot; bindex++) {
076b876e
AM
24581+ br = au_sbr(sb, bindex);
24582+ if (au_br_fhsm(br->br_perm)
24583+ && (!(au_br_sb(br)->s_flags & MS_RDONLY)))
24584+ return bindex;
24585+ }
24586+ else if (!(a->mvdown.flags & AUFS_MVDOWN_ROLOWER))
5afbbe0d 24587+ for (bindex++; bindex <= bbot; bindex++) {
076b876e
AM
24588+ br = au_sbr(sb, bindex);
24589+ if (!au_br_rdonly(br))
24590+ return bindex;
24591+ }
24592+ else
5afbbe0d 24593+ for (bindex++; bindex <= bbot; bindex++) {
076b876e
AM
24594+ br = au_sbr(sb, bindex);
24595+ if (!(au_br_sb(br)->s_flags & MS_RDONLY)) {
24596+ if (au_br_rdonly(br))
24597+ a->mvdown.flags
24598+ |= AUFS_MVDOWN_ROLOWER_R;
24599+ return bindex;
24600+ }
24601+ }
24602+
24603+ return -1;
24604+}
24605+
c2b27bf2 24606+/* make the parent dir on bdst */
392086de 24607+static int au_do_mkdir(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
24608+{
24609+ int err;
24610+
24611+ err = 0;
24612+ a->mvd_hdir_src = au_hi(a->dir, a->mvd_bsrc);
24613+ a->mvd_hdir_dst = au_hi(a->dir, a->mvd_bdst);
24614+ a->mvd_h_src_parent = au_h_dptr(a->parent, a->mvd_bsrc);
24615+ a->mvd_h_dst_parent = NULL;
5afbbe0d 24616+ if (au_dbbot(a->parent) >= a->mvd_bdst)
c2b27bf2
AM
24617+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
24618+ if (!a->mvd_h_dst_parent) {
24619+ err = au_cpdown_dirs(a->dentry, a->mvd_bdst);
24620+ if (unlikely(err)) {
392086de 24621+ AU_MVD_PR(dmsg, "cpdown_dirs failed\n");
c2b27bf2
AM
24622+ goto out;
24623+ }
24624+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
24625+ }
24626+
24627+out:
24628+ AuTraceErr(err);
24629+ return err;
24630+}
24631+
24632+/* lock them all */
392086de 24633+static int au_do_lock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
24634+{
24635+ int err;
24636+ struct dentry *h_trap;
24637+
24638+ a->mvd_h_src_sb = au_sbr_sb(a->sb, a->mvd_bsrc);
24639+ a->mvd_h_dst_sb = au_sbr_sb(a->sb, a->mvd_bdst);
c1595e42
JR
24640+ err = au_pin(&a->mvd_pin_dst, a->dentry, a->mvd_bdst,
24641+ au_opt_udba(a->sb),
24642+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
24643+ AuTraceErr(err);
24644+ if (unlikely(err)) {
24645+ AU_MVD_PR(dmsg, "pin_dst failed\n");
24646+ goto out;
24647+ }
24648+
c2b27bf2
AM
24649+ if (a->mvd_h_src_sb != a->mvd_h_dst_sb) {
24650+ a->rename_lock = 0;
c1595e42
JR
24651+ au_pin_init(&a->mvd_pin_src, a->dentry, a->mvd_bsrc,
24652+ AuLsc_DI_PARENT, AuLsc_I_PARENT3,
24653+ au_opt_udba(a->sb),
24654+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
24655+ err = au_do_pin(&a->mvd_pin_src);
24656+ AuTraceErr(err);
5527c038 24657+ a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent);
c1595e42
JR
24658+ if (unlikely(err)) {
24659+ AU_MVD_PR(dmsg, "pin_src failed\n");
24660+ goto out_dst;
24661+ }
24662+ goto out; /* success */
c2b27bf2
AM
24663+ }
24664+
c2b27bf2 24665+ a->rename_lock = 1;
c1595e42
JR
24666+ au_pin_hdir_unlock(&a->mvd_pin_dst);
24667+ err = au_pin(&a->mvd_pin_src, a->dentry, a->mvd_bsrc,
24668+ au_opt_udba(a->sb),
24669+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
24670+ AuTraceErr(err);
5527c038 24671+ a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent);
c1595e42
JR
24672+ if (unlikely(err)) {
24673+ AU_MVD_PR(dmsg, "pin_src failed\n");
24674+ au_pin_hdir_lock(&a->mvd_pin_dst);
24675+ goto out_dst;
24676+ }
24677+ au_pin_hdir_unlock(&a->mvd_pin_src);
c2b27bf2
AM
24678+ h_trap = vfsub_lock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
24679+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
24680+ if (h_trap) {
24681+ err = (h_trap != a->mvd_h_src_parent);
24682+ if (err)
24683+ err = (h_trap != a->mvd_h_dst_parent);
24684+ }
24685+ BUG_ON(err); /* it should never happen */
c1595e42
JR
24686+ if (unlikely(a->mvd_h_src_dir != au_pinned_h_dir(&a->mvd_pin_src))) {
24687+ err = -EBUSY;
24688+ AuTraceErr(err);
24689+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
24690+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
24691+ au_pin_hdir_lock(&a->mvd_pin_src);
24692+ au_unpin(&a->mvd_pin_src);
24693+ au_pin_hdir_lock(&a->mvd_pin_dst);
24694+ goto out_dst;
24695+ }
24696+ goto out; /* success */
c2b27bf2 24697+
c1595e42
JR
24698+out_dst:
24699+ au_unpin(&a->mvd_pin_dst);
c2b27bf2
AM
24700+out:
24701+ AuTraceErr(err);
24702+ return err;
24703+}
24704+
392086de 24705+static void au_do_unlock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2 24706+{
c1595e42
JR
24707+ if (!a->rename_lock)
24708+ au_unpin(&a->mvd_pin_src);
24709+ else {
c2b27bf2
AM
24710+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
24711+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
c1595e42
JR
24712+ au_pin_hdir_lock(&a->mvd_pin_src);
24713+ au_unpin(&a->mvd_pin_src);
24714+ au_pin_hdir_lock(&a->mvd_pin_dst);
24715+ }
24716+ au_unpin(&a->mvd_pin_dst);
c2b27bf2
AM
24717+}
24718+
24719+/* copy-down the file */
392086de 24720+static int au_do_cpdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
24721+{
24722+ int err;
24723+ struct au_cp_generic cpg = {
24724+ .dentry = a->dentry,
24725+ .bdst = a->mvd_bdst,
24726+ .bsrc = a->mvd_bsrc,
24727+ .len = -1,
c1595e42 24728+ .pin = &a->mvd_pin_dst,
c2b27bf2
AM
24729+ .flags = AuCpup_DTIME | AuCpup_HOPEN
24730+ };
24731+
24732+ AuDbg("b%d, b%d\n", cpg.bsrc, cpg.bdst);
392086de
AM
24733+ if (a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
24734+ au_fset_cpup(cpg.flags, OVERWRITE);
24735+ if (a->mvdown.flags & AUFS_MVDOWN_ROLOWER)
24736+ au_fset_cpup(cpg.flags, RWDST);
c2b27bf2
AM
24737+ err = au_sio_cpdown_simple(&cpg);
24738+ if (unlikely(err))
392086de 24739+ AU_MVD_PR(dmsg, "cpdown failed\n");
c2b27bf2
AM
24740+
24741+ AuTraceErr(err);
24742+ return err;
24743+}
24744+
24745+/*
24746+ * unlink the whiteout on bdst if exist which may be created by UDBA while we
24747+ * were sleeping
24748+ */
392086de 24749+static int au_do_unlink_wh(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
24750+{
24751+ int err;
24752+ struct path h_path;
24753+ struct au_branch *br;
523b37e3 24754+ struct inode *delegated;
c2b27bf2
AM
24755+
24756+ br = au_sbr(a->sb, a->mvd_bdst);
24757+ h_path.dentry = au_wh_lkup(a->mvd_h_dst_parent, &a->dentry->d_name, br);
24758+ err = PTR_ERR(h_path.dentry);
24759+ if (IS_ERR(h_path.dentry)) {
392086de 24760+ AU_MVD_PR(dmsg, "wh_lkup failed\n");
c2b27bf2
AM
24761+ goto out;
24762+ }
24763+
24764+ err = 0;
5527c038 24765+ if (d_is_positive(h_path.dentry)) {
c2b27bf2 24766+ h_path.mnt = au_br_mnt(br);
523b37e3 24767+ delegated = NULL;
5527c038 24768+ err = vfsub_unlink(d_inode(a->mvd_h_dst_parent), &h_path,
523b37e3
AM
24769+ &delegated, /*force*/0);
24770+ if (unlikely(err == -EWOULDBLOCK)) {
24771+ pr_warn("cannot retry for NFSv4 delegation"
24772+ " for an internal unlink\n");
24773+ iput(delegated);
24774+ }
c2b27bf2 24775+ if (unlikely(err))
392086de 24776+ AU_MVD_PR(dmsg, "wh_unlink failed\n");
c2b27bf2
AM
24777+ }
24778+ dput(h_path.dentry);
24779+
24780+out:
24781+ AuTraceErr(err);
24782+ return err;
24783+}
24784+
24785+/*
24786+ * unlink the topmost h_dentry
c2b27bf2 24787+ */
392086de 24788+static int au_do_unlink(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
24789+{
24790+ int err;
24791+ struct path h_path;
523b37e3 24792+ struct inode *delegated;
c2b27bf2
AM
24793+
24794+ h_path.mnt = au_sbr_mnt(a->sb, a->mvd_bsrc);
24795+ h_path.dentry = au_h_dptr(a->dentry, a->mvd_bsrc);
523b37e3
AM
24796+ delegated = NULL;
24797+ err = vfsub_unlink(a->mvd_h_src_dir, &h_path, &delegated, /*force*/0);
24798+ if (unlikely(err == -EWOULDBLOCK)) {
24799+ pr_warn("cannot retry for NFSv4 delegation"
24800+ " for an internal unlink\n");
24801+ iput(delegated);
24802+ }
c2b27bf2 24803+ if (unlikely(err))
392086de 24804+ AU_MVD_PR(dmsg, "unlink failed\n");
c2b27bf2
AM
24805+
24806+ AuTraceErr(err);
24807+ return err;
24808+}
24809+
076b876e
AM
24810+/* Since mvdown succeeded, we ignore an error of this function */
24811+static void au_do_stfs(const unsigned char dmsg, struct au_mvd_args *a)
24812+{
24813+ int err;
24814+ struct au_branch *br;
24815+
24816+ a->mvdown.flags |= AUFS_MVDOWN_STFS_FAILED;
24817+ br = au_sbr(a->sb, a->mvd_bsrc);
24818+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_UPPER].stfs);
24819+ if (!err) {
24820+ br = au_sbr(a->sb, a->mvd_bdst);
24821+ a->mvdown.stbr[AUFS_MVDOWN_LOWER].brid = br->br_id;
24822+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_LOWER].stfs);
24823+ }
24824+ if (!err)
24825+ a->mvdown.flags &= ~AUFS_MVDOWN_STFS_FAILED;
24826+ else
24827+ AU_MVD_PR(dmsg, "statfs failed (%d), ignored\n", err);
24828+}
24829+
c2b27bf2
AM
24830+/*
24831+ * copy-down the file and unlink the bsrc file.
24832+ * - unlink the bdst whout if exist
24833+ * - copy-down the file (with whtmp name and rename)
24834+ * - unlink the bsrc file
24835+ */
392086de 24836+static int au_do_mvdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
24837+{
24838+ int err;
24839+
392086de 24840+ err = au_do_mkdir(dmsg, a);
c2b27bf2 24841+ if (!err)
392086de 24842+ err = au_do_lock(dmsg, a);
c2b27bf2
AM
24843+ if (unlikely(err))
24844+ goto out;
24845+
24846+ /*
24847+ * do not revert the activities we made on bdst since they should be
24848+ * harmless in aufs.
24849+ */
24850+
392086de 24851+ err = au_do_cpdown(dmsg, a);
c2b27bf2 24852+ if (!err)
392086de
AM
24853+ err = au_do_unlink_wh(dmsg, a);
24854+ if (!err && !(a->mvdown.flags & AUFS_MVDOWN_KUPPER))
24855+ err = au_do_unlink(dmsg, a);
c2b27bf2
AM
24856+ if (unlikely(err))
24857+ goto out_unlock;
24858+
c1595e42
JR
24859+ AuDbg("%pd2, 0x%x, %d --> %d\n",
24860+ a->dentry, a->mvdown.flags, a->mvd_bsrc, a->mvd_bdst);
076b876e
AM
24861+ if (find_lower_writable(a) < 0)
24862+ a->mvdown.flags |= AUFS_MVDOWN_BOTTOM;
24863+
24864+ if (a->mvdown.flags & AUFS_MVDOWN_STFS)
24865+ au_do_stfs(dmsg, a);
24866+
c2b27bf2 24867+ /* maintain internal array */
392086de
AM
24868+ if (!(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) {
24869+ au_set_h_dptr(a->dentry, a->mvd_bsrc, NULL);
5afbbe0d 24870+ au_set_dbtop(a->dentry, a->mvd_bdst);
392086de 24871+ au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0);
5afbbe0d 24872+ au_set_ibtop(a->inode, a->mvd_bdst);
79b8bda9
AM
24873+ } else {
24874+ /* hide the lower */
24875+ au_set_h_dptr(a->dentry, a->mvd_bdst, NULL);
5afbbe0d 24876+ au_set_dbbot(a->dentry, a->mvd_bsrc);
79b8bda9 24877+ au_set_h_iptr(a->inode, a->mvd_bdst, NULL, /*flags*/0);
5afbbe0d 24878+ au_set_ibbot(a->inode, a->mvd_bsrc);
392086de 24879+ }
5afbbe0d
AM
24880+ if (au_dbbot(a->dentry) < a->mvd_bdst)
24881+ au_set_dbbot(a->dentry, a->mvd_bdst);
24882+ if (au_ibbot(a->inode) < a->mvd_bdst)
24883+ au_set_ibbot(a->inode, a->mvd_bdst);
c2b27bf2
AM
24884+
24885+out_unlock:
392086de 24886+ au_do_unlock(dmsg, a);
c2b27bf2
AM
24887+out:
24888+ AuTraceErr(err);
24889+ return err;
24890+}
24891+
24892+/* ---------------------------------------------------------------------- */
24893+
c2b27bf2 24894+/* make sure the file is idle */
392086de 24895+static int au_mvd_args_busy(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
24896+{
24897+ int err, plinked;
c2b27bf2
AM
24898+
24899+ err = 0;
c2b27bf2 24900+ plinked = !!au_opt_test(au_mntflags(a->sb), PLINK);
5afbbe0d 24901+ if (au_dbtop(a->dentry) == a->mvd_bsrc
c1595e42 24902+ && au_dcount(a->dentry) == 1
c2b27bf2 24903+ && atomic_read(&a->inode->i_count) == 1
392086de 24904+ /* && a->mvd_h_src_inode->i_nlink == 1 */
c2b27bf2
AM
24905+ && (!plinked || !au_plink_test(a->inode))
24906+ && a->inode->i_nlink == 1)
24907+ goto out;
24908+
24909+ err = -EBUSY;
392086de 24910+ AU_MVD_PR(dmsg,
c1595e42 24911+ "b%d, d{b%d, c%d?}, i{c%d?, l%u}, hi{l%u}, p{%d, %d}\n",
5afbbe0d 24912+ a->mvd_bsrc, au_dbtop(a->dentry), au_dcount(a->dentry),
c2b27bf2 24913+ atomic_read(&a->inode->i_count), a->inode->i_nlink,
392086de 24914+ a->mvd_h_src_inode->i_nlink,
c2b27bf2
AM
24915+ plinked, plinked ? au_plink_test(a->inode) : 0);
24916+
24917+out:
24918+ AuTraceErr(err);
24919+ return err;
24920+}
24921+
24922+/* make sure the parent dir is fine */
392086de 24923+static int au_mvd_args_parent(const unsigned char dmsg,
c2b27bf2
AM
24924+ struct au_mvd_args *a)
24925+{
24926+ int err;
24927+ aufs_bindex_t bindex;
24928+
24929+ err = 0;
24930+ if (unlikely(au_alive_dir(a->parent))) {
24931+ err = -ENOENT;
392086de 24932+ AU_MVD_PR(dmsg, "parent dir is dead\n");
c2b27bf2
AM
24933+ goto out;
24934+ }
24935+
24936+ a->bopq = au_dbdiropq(a->parent);
24937+ bindex = au_wbr_nonopq(a->dentry, a->mvd_bdst);
24938+ AuDbg("b%d\n", bindex);
24939+ if (unlikely((bindex >= 0 && bindex < a->mvd_bdst)
24940+ || (a->bopq != -1 && a->bopq < a->mvd_bdst))) {
24941+ err = -EINVAL;
392086de
AM
24942+ a->mvd_errno = EAU_MVDOWN_OPAQUE;
24943+ AU_MVD_PR(dmsg, "ancestor is opaque b%d, b%d\n",
c2b27bf2
AM
24944+ a->bopq, a->mvd_bdst);
24945+ }
24946+
24947+out:
24948+ AuTraceErr(err);
24949+ return err;
24950+}
24951+
392086de 24952+static int au_mvd_args_intermediate(const unsigned char dmsg,
c2b27bf2
AM
24953+ struct au_mvd_args *a)
24954+{
24955+ int err;
24956+ struct au_dinfo *dinfo, *tmp;
24957+
24958+ /* lookup the next lower positive entry */
24959+ err = -ENOMEM;
24960+ tmp = au_di_alloc(a->sb, AuLsc_DI_TMP);
24961+ if (unlikely(!tmp))
24962+ goto out;
24963+
24964+ a->bfound = -1;
24965+ a->bwh = -1;
24966+ dinfo = au_di(a->dentry);
24967+ au_di_cp(tmp, dinfo);
24968+ au_di_swap(tmp, dinfo);
24969+
24970+ /* returns the number of positive dentries */
5afbbe0d
AM
24971+ err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1,
24972+ /* AuLkup_IGNORE_PERM */ 0);
c2b27bf2
AM
24973+ if (!err)
24974+ a->bwh = au_dbwh(a->dentry);
24975+ else if (err > 0)
5afbbe0d 24976+ a->bfound = au_dbtop(a->dentry);
c2b27bf2
AM
24977+
24978+ au_di_swap(tmp, dinfo);
24979+ au_rw_write_unlock(&tmp->di_rwsem);
24980+ au_di_free(tmp);
24981+ if (unlikely(err < 0))
392086de 24982+ AU_MVD_PR(dmsg, "failed look-up lower\n");
c2b27bf2
AM
24983+
24984+ /*
24985+ * here, we have these cases.
24986+ * bfound == -1
24987+ * no positive dentry under bsrc. there are more sub-cases.
24988+ * bwh < 0
24989+ * there no whiteout, we can safely move-down.
24990+ * bwh <= bsrc
24991+ * impossible
24992+ * bsrc < bwh && bwh < bdst
24993+ * there is a whiteout on RO branch. cannot proceed.
24994+ * bwh == bdst
24995+ * there is a whiteout on the RW target branch. it should
24996+ * be removed.
24997+ * bdst < bwh
24998+ * there is a whiteout somewhere unrelated branch.
24999+ * -1 < bfound && bfound <= bsrc
25000+ * impossible.
25001+ * bfound < bdst
25002+ * found, but it is on RO branch between bsrc and bdst. cannot
25003+ * proceed.
25004+ * bfound == bdst
25005+ * found, replace it if AUFS_MVDOWN_FORCE is set. otherwise return
25006+ * error.
25007+ * bdst < bfound
25008+ * found, after we create the file on bdst, it will be hidden.
25009+ */
25010+
25011+ AuDebugOn(a->bfound == -1
25012+ && a->bwh != -1
25013+ && a->bwh <= a->mvd_bsrc);
25014+ AuDebugOn(-1 < a->bfound
25015+ && a->bfound <= a->mvd_bsrc);
25016+
25017+ err = -EINVAL;
25018+ if (a->bfound == -1
25019+ && a->mvd_bsrc < a->bwh
25020+ && a->bwh != -1
25021+ && a->bwh < a->mvd_bdst) {
392086de
AM
25022+ a->mvd_errno = EAU_MVDOWN_WHITEOUT;
25023+ AU_MVD_PR(dmsg, "bsrc %d, bdst %d, bfound %d, bwh %d\n",
c2b27bf2
AM
25024+ a->mvd_bsrc, a->mvd_bdst, a->bfound, a->bwh);
25025+ goto out;
25026+ } else if (a->bfound != -1 && a->bfound < a->mvd_bdst) {
392086de
AM
25027+ a->mvd_errno = EAU_MVDOWN_UPPER;
25028+ AU_MVD_PR(dmsg, "bdst %d, bfound %d\n",
c2b27bf2
AM
25029+ a->mvd_bdst, a->bfound);
25030+ goto out;
25031+ }
25032+
25033+ err = 0; /* success */
25034+
25035+out:
25036+ AuTraceErr(err);
25037+ return err;
25038+}
25039+
392086de 25040+static int au_mvd_args_exist(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
25041+{
25042+ int err;
25043+
392086de
AM
25044+ err = 0;
25045+ if (!(a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
25046+ && a->bfound == a->mvd_bdst)
25047+ err = -EEXIST;
c2b27bf2
AM
25048+ AuTraceErr(err);
25049+ return err;
25050+}
25051+
392086de 25052+static int au_mvd_args(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
25053+{
25054+ int err;
25055+ struct au_branch *br;
25056+
25057+ err = -EISDIR;
25058+ if (unlikely(S_ISDIR(a->inode->i_mode)))
25059+ goto out;
25060+
25061+ err = -EINVAL;
392086de 25062+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_UPPER))
5afbbe0d 25063+ a->mvd_bsrc = au_ibtop(a->inode);
392086de
AM
25064+ else {
25065+ a->mvd_bsrc = au_br_index(a->sb, a->mvd_src_brid);
25066+ if (unlikely(a->mvd_bsrc < 0
5afbbe0d
AM
25067+ || (a->mvd_bsrc < au_dbtop(a->dentry)
25068+ || au_dbbot(a->dentry) < a->mvd_bsrc
392086de 25069+ || !au_h_dptr(a->dentry, a->mvd_bsrc))
5afbbe0d
AM
25070+ || (a->mvd_bsrc < au_ibtop(a->inode)
25071+ || au_ibbot(a->inode) < a->mvd_bsrc
392086de
AM
25072+ || !au_h_iptr(a->inode, a->mvd_bsrc)))) {
25073+ a->mvd_errno = EAU_MVDOWN_NOUPPER;
25074+ AU_MVD_PR(dmsg, "no upper\n");
25075+ goto out;
25076+ }
25077+ }
5afbbe0d 25078+ if (unlikely(a->mvd_bsrc == au_sbbot(a->sb))) {
392086de
AM
25079+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
25080+ AU_MVD_PR(dmsg, "on the bottom\n");
c2b27bf2
AM
25081+ goto out;
25082+ }
392086de 25083+ a->mvd_h_src_inode = au_h_iptr(a->inode, a->mvd_bsrc);
c2b27bf2
AM
25084+ br = au_sbr(a->sb, a->mvd_bsrc);
25085+ err = au_br_rdonly(br);
392086de
AM
25086+ if (!(a->mvdown.flags & AUFS_MVDOWN_ROUPPER)) {
25087+ if (unlikely(err))
25088+ goto out;
25089+ } else if (!(vfsub_native_ro(a->mvd_h_src_inode)
25090+ || IS_APPEND(a->mvd_h_src_inode))) {
25091+ if (err)
25092+ a->mvdown.flags |= AUFS_MVDOWN_ROUPPER_R;
25093+ /* go on */
25094+ } else
c2b27bf2
AM
25095+ goto out;
25096+
25097+ err = -EINVAL;
392086de
AM
25098+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_LOWER)) {
25099+ a->mvd_bdst = find_lower_writable(a);
25100+ if (unlikely(a->mvd_bdst < 0)) {
25101+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
25102+ AU_MVD_PR(dmsg, "no writable lower branch\n");
25103+ goto out;
25104+ }
25105+ } else {
25106+ a->mvd_bdst = au_br_index(a->sb, a->mvd_dst_brid);
25107+ if (unlikely(a->mvd_bdst < 0
5afbbe0d 25108+ || au_sbbot(a->sb) < a->mvd_bdst)) {
392086de
AM
25109+ a->mvd_errno = EAU_MVDOWN_NOLOWERBR;
25110+ AU_MVD_PR(dmsg, "no lower brid\n");
25111+ goto out;
25112+ }
c2b27bf2
AM
25113+ }
25114+
392086de 25115+ err = au_mvd_args_busy(dmsg, a);
c2b27bf2 25116+ if (!err)
392086de 25117+ err = au_mvd_args_parent(dmsg, a);
c2b27bf2 25118+ if (!err)
392086de 25119+ err = au_mvd_args_intermediate(dmsg, a);
c2b27bf2 25120+ if (!err)
392086de 25121+ err = au_mvd_args_exist(dmsg, a);
c2b27bf2
AM
25122+ if (!err)
25123+ AuDbg("b%d, b%d\n", a->mvd_bsrc, a->mvd_bdst);
25124+
25125+out:
25126+ AuTraceErr(err);
25127+ return err;
25128+}
25129+
25130+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg)
25131+{
392086de
AM
25132+ int err, e;
25133+ unsigned char dmsg;
25134+ struct au_mvd_args *args;
79b8bda9 25135+ struct inode *inode;
c2b27bf2 25136+
79b8bda9 25137+ inode = d_inode(dentry);
c2b27bf2
AM
25138+ err = -EPERM;
25139+ if (unlikely(!capable(CAP_SYS_ADMIN)))
25140+ goto out;
25141+
392086de
AM
25142+ err = -ENOMEM;
25143+ args = kmalloc(sizeof(*args), GFP_NOFS);
25144+ if (unlikely(!args))
25145+ goto out;
25146+
25147+ err = copy_from_user(&args->mvdown, uarg, sizeof(args->mvdown));
25148+ if (!err)
25149+ err = !access_ok(VERIFY_WRITE, uarg, sizeof(*uarg));
c2b27bf2
AM
25150+ if (unlikely(err)) {
25151+ err = -EFAULT;
392086de
AM
25152+ AuTraceErr(err);
25153+ goto out_free;
c2b27bf2 25154+ }
392086de
AM
25155+ AuDbg("flags 0x%x\n", args->mvdown.flags);
25156+ args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R);
25157+ args->mvdown.au_errno = 0;
25158+ args->dentry = dentry;
79b8bda9 25159+ args->inode = inode;
392086de 25160+ args->sb = dentry->d_sb;
c2b27bf2 25161+
392086de
AM
25162+ err = -ENOENT;
25163+ dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG);
25164+ args->parent = dget_parent(dentry);
5527c038 25165+ args->dir = d_inode(args->parent);
febd17d6 25166+ inode_lock_nested(args->dir, I_MUTEX_PARENT);
392086de
AM
25167+ dput(args->parent);
25168+ if (unlikely(args->parent != dentry->d_parent)) {
25169+ AU_MVD_PR(dmsg, "parent dir is moved\n");
c2b27bf2
AM
25170+ goto out_dir;
25171+ }
25172+
febd17d6 25173+ inode_lock_nested(inode, I_MUTEX_CHILD);
b95c5147 25174+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_NOPLMW);
c2b27bf2
AM
25175+ if (unlikely(err))
25176+ goto out_inode;
25177+
392086de
AM
25178+ di_write_lock_parent(args->parent);
25179+ err = au_mvd_args(dmsg, args);
c2b27bf2
AM
25180+ if (unlikely(err))
25181+ goto out_parent;
25182+
392086de 25183+ err = au_do_mvdown(dmsg, args);
c2b27bf2
AM
25184+ if (unlikely(err))
25185+ goto out_parent;
c2b27bf2 25186+
392086de 25187+ au_cpup_attr_timesizes(args->dir);
79b8bda9
AM
25188+ au_cpup_attr_timesizes(inode);
25189+ if (!(args->mvdown.flags & AUFS_MVDOWN_KUPPER))
25190+ au_cpup_igen(inode, au_h_iptr(inode, args->mvd_bdst));
c2b27bf2
AM
25191+ /* au_digen_dec(dentry); */
25192+
25193+out_parent:
392086de 25194+ di_write_unlock(args->parent);
c2b27bf2
AM
25195+ aufs_read_unlock(dentry, AuLock_DW);
25196+out_inode:
febd17d6 25197+ inode_unlock(inode);
c2b27bf2 25198+out_dir:
febd17d6 25199+ inode_unlock(args->dir);
392086de
AM
25200+out_free:
25201+ e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown));
25202+ if (unlikely(e))
25203+ err = -EFAULT;
ae9dfd79 25204+ kfree(args);
c2b27bf2
AM
25205+out:
25206+ AuTraceErr(err);
25207+ return err;
25208+}
25209diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
25210--- /usr/share/empty/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
25211+++ linux/fs/aufs/opts.c 2018-04-15 08:49:13.401150731 +0200
25212@@ -0,0 +1,1913 @@
1facf9fc 25213+/*
ae9dfd79 25214+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 25215+ *
25216+ * This program, aufs is free software; you can redistribute it and/or modify
25217+ * it under the terms of the GNU General Public License as published by
25218+ * the Free Software Foundation; either version 2 of the License, or
25219+ * (at your option) any later version.
dece6358
AM
25220+ *
25221+ * This program is distributed in the hope that it will be useful,
25222+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25223+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25224+ * GNU General Public License for more details.
25225+ *
25226+ * You should have received a copy of the GNU General Public License
523b37e3 25227+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 25228+ */
25229+
25230+/*
25231+ * mount options/flags
25232+ */
25233+
dece6358 25234+#include <linux/namei.h>
1facf9fc 25235+#include <linux/types.h> /* a distribution requires */
25236+#include <linux/parser.h>
25237+#include "aufs.h"
25238+
25239+/* ---------------------------------------------------------------------- */
25240+
25241+enum {
25242+ Opt_br,
7e9cd9fe
AM
25243+ Opt_add, Opt_del, Opt_mod, Opt_append, Opt_prepend,
25244+ Opt_idel, Opt_imod,
25245+ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash,
dece6358 25246+ Opt_rdblk_def, Opt_rdhash_def,
7e9cd9fe 25247+ Opt_xino, Opt_noxino,
1facf9fc 25248+ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
25249+ Opt_trunc_xino_path, Opt_itrunc_xino,
25250+ Opt_trunc_xib, Opt_notrunc_xib,
dece6358 25251+ Opt_shwh, Opt_noshwh,
1facf9fc 25252+ Opt_plink, Opt_noplink, Opt_list_plink,
25253+ Opt_udba,
4a4d8108 25254+ Opt_dio, Opt_nodio,
1facf9fc 25255+ Opt_diropq_a, Opt_diropq_w,
25256+ Opt_warn_perm, Opt_nowarn_perm,
25257+ Opt_wbr_copyup, Opt_wbr_create,
076b876e 25258+ Opt_fhsm_sec,
1facf9fc 25259+ Opt_verbose, Opt_noverbose,
25260+ Opt_sum, Opt_nosum, Opt_wsum,
076b876e 25261+ Opt_dirperm1, Opt_nodirperm1,
ae9dfd79 25262+ Opt_dirren, Opt_nodirren,
c1595e42 25263+ Opt_acl, Opt_noacl,
1facf9fc 25264+ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
25265+};
25266+
25267+static match_table_t options = {
25268+ {Opt_br, "br=%s"},
25269+ {Opt_br, "br:%s"},
25270+
25271+ {Opt_add, "add=%d:%s"},
25272+ {Opt_add, "add:%d:%s"},
25273+ {Opt_add, "ins=%d:%s"},
25274+ {Opt_add, "ins:%d:%s"},
25275+ {Opt_append, "append=%s"},
25276+ {Opt_append, "append:%s"},
25277+ {Opt_prepend, "prepend=%s"},
25278+ {Opt_prepend, "prepend:%s"},
25279+
25280+ {Opt_del, "del=%s"},
25281+ {Opt_del, "del:%s"},
25282+ /* {Opt_idel, "idel:%d"}, */
25283+ {Opt_mod, "mod=%s"},
25284+ {Opt_mod, "mod:%s"},
25285+ /* {Opt_imod, "imod:%d:%s"}, */
25286+
25287+ {Opt_dirwh, "dirwh=%d"},
25288+
25289+ {Opt_xino, "xino=%s"},
25290+ {Opt_noxino, "noxino"},
25291+ {Opt_trunc_xino, "trunc_xino"},
25292+ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
25293+ {Opt_notrunc_xino, "notrunc_xino"},
25294+ {Opt_trunc_xino_path, "trunc_xino=%s"},
25295+ {Opt_itrunc_xino, "itrunc_xino=%d"},
25296+ /* {Opt_zxino, "zxino=%s"}, */
25297+ {Opt_trunc_xib, "trunc_xib"},
25298+ {Opt_notrunc_xib, "notrunc_xib"},
25299+
e49829fe 25300+#ifdef CONFIG_PROC_FS
1facf9fc 25301+ {Opt_plink, "plink"},
e49829fe
JR
25302+#else
25303+ {Opt_ignore_silent, "plink"},
25304+#endif
25305+
1facf9fc 25306+ {Opt_noplink, "noplink"},
e49829fe 25307+
1facf9fc 25308+#ifdef CONFIG_AUFS_DEBUG
25309+ {Opt_list_plink, "list_plink"},
25310+#endif
25311+
25312+ {Opt_udba, "udba=%s"},
25313+
4a4d8108
AM
25314+ {Opt_dio, "dio"},
25315+ {Opt_nodio, "nodio"},
25316+
ae9dfd79
AM
25317+#ifdef CONFIG_AUFS_DIRREN
25318+ {Opt_dirren, "dirren"},
25319+ {Opt_nodirren, "nodirren"},
25320+#else
25321+ {Opt_ignore, "dirren"},
25322+ {Opt_ignore_silent, "nodirren"},
25323+#endif
25324+
076b876e
AM
25325+#ifdef CONFIG_AUFS_FHSM
25326+ {Opt_fhsm_sec, "fhsm_sec=%d"},
25327+#else
ae9dfd79 25328+ {Opt_ignore, "fhsm_sec=%d"},
076b876e
AM
25329+#endif
25330+
1facf9fc 25331+ {Opt_diropq_a, "diropq=always"},
25332+ {Opt_diropq_a, "diropq=a"},
25333+ {Opt_diropq_w, "diropq=whiteouted"},
25334+ {Opt_diropq_w, "diropq=w"},
25335+
25336+ {Opt_warn_perm, "warn_perm"},
25337+ {Opt_nowarn_perm, "nowarn_perm"},
25338+
25339+ /* keep them temporary */
1facf9fc 25340+ {Opt_ignore_silent, "nodlgt"},
ae9dfd79 25341+ {Opt_ignore, "clean_plink"},
1facf9fc 25342+
dece6358
AM
25343+#ifdef CONFIG_AUFS_SHWH
25344+ {Opt_shwh, "shwh"},
25345+#endif
25346+ {Opt_noshwh, "noshwh"},
25347+
076b876e
AM
25348+ {Opt_dirperm1, "dirperm1"},
25349+ {Opt_nodirperm1, "nodirperm1"},
25350+
1facf9fc 25351+ {Opt_verbose, "verbose"},
25352+ {Opt_verbose, "v"},
25353+ {Opt_noverbose, "noverbose"},
25354+ {Opt_noverbose, "quiet"},
25355+ {Opt_noverbose, "q"},
25356+ {Opt_noverbose, "silent"},
25357+
25358+ {Opt_sum, "sum"},
25359+ {Opt_nosum, "nosum"},
25360+ {Opt_wsum, "wsum"},
25361+
25362+ {Opt_rdcache, "rdcache=%d"},
25363+ {Opt_rdblk, "rdblk=%d"},
dece6358 25364+ {Opt_rdblk_def, "rdblk=def"},
1facf9fc 25365+ {Opt_rdhash, "rdhash=%d"},
dece6358 25366+ {Opt_rdhash_def, "rdhash=def"},
1facf9fc 25367+
25368+ {Opt_wbr_create, "create=%s"},
25369+ {Opt_wbr_create, "create_policy=%s"},
25370+ {Opt_wbr_copyup, "cpup=%s"},
25371+ {Opt_wbr_copyup, "copyup=%s"},
25372+ {Opt_wbr_copyup, "copyup_policy=%s"},
25373+
c1595e42
JR
25374+ /* generic VFS flag */
25375+#ifdef CONFIG_FS_POSIX_ACL
25376+ {Opt_acl, "acl"},
25377+ {Opt_noacl, "noacl"},
25378+#else
ae9dfd79 25379+ {Opt_ignore, "acl"},
c1595e42
JR
25380+ {Opt_ignore_silent, "noacl"},
25381+#endif
25382+
1facf9fc 25383+ /* internal use for the scripts */
25384+ {Opt_ignore_silent, "si=%s"},
25385+
25386+ {Opt_br, "dirs=%s"},
25387+ {Opt_ignore, "debug=%d"},
25388+ {Opt_ignore, "delete=whiteout"},
25389+ {Opt_ignore, "delete=all"},
25390+ {Opt_ignore, "imap=%s"},
25391+
1308ab2a 25392+ /* temporary workaround, due to old mount(8)? */
25393+ {Opt_ignore_silent, "relatime"},
25394+
1facf9fc 25395+ {Opt_err, NULL}
25396+};
25397+
25398+/* ---------------------------------------------------------------------- */
25399+
076b876e 25400+static const char *au_parser_pattern(int val, match_table_t tbl)
1facf9fc 25401+{
076b876e
AM
25402+ struct match_token *p;
25403+
25404+ p = tbl;
25405+ while (p->pattern) {
25406+ if (p->token == val)
25407+ return p->pattern;
25408+ p++;
1facf9fc 25409+ }
25410+ BUG();
25411+ return "??";
25412+}
25413+
076b876e
AM
25414+static const char *au_optstr(int *val, match_table_t tbl)
25415+{
25416+ struct match_token *p;
25417+ int v;
25418+
25419+ v = *val;
2000de60
JR
25420+ if (!v)
25421+ goto out;
076b876e 25422+ p = tbl;
2000de60
JR
25423+ while (p->pattern) {
25424+ if (p->token
25425+ && (v & p->token) == p->token) {
076b876e
AM
25426+ *val &= ~p->token;
25427+ return p->pattern;
25428+ }
25429+ p++;
25430+ }
2000de60
JR
25431+
25432+out:
076b876e
AM
25433+ return NULL;
25434+}
25435+
1facf9fc 25436+/* ---------------------------------------------------------------------- */
25437+
1e00d052 25438+static match_table_t brperm = {
1facf9fc 25439+ {AuBrPerm_RO, AUFS_BRPERM_RO},
25440+ {AuBrPerm_RR, AUFS_BRPERM_RR},
25441+ {AuBrPerm_RW, AUFS_BRPERM_RW},
1e00d052
AM
25442+ {0, NULL}
25443+};
1facf9fc 25444+
86dc4139 25445+static match_table_t brattr = {
076b876e
AM
25446+ /* general */
25447+ {AuBrAttr_COO_REG, AUFS_BRATTR_COO_REG},
25448+ {AuBrAttr_COO_ALL, AUFS_BRATTR_COO_ALL},
c1595e42 25449+ /* 'unpin' attrib is meaningless since linux-3.18-rc1 */
86dc4139 25450+ {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN},
2000de60 25451+#ifdef CONFIG_AUFS_FHSM
076b876e 25452+ {AuBrAttr_FHSM, AUFS_BRATTR_FHSM},
2000de60
JR
25453+#endif
25454+#ifdef CONFIG_AUFS_XATTR
c1595e42
JR
25455+ {AuBrAttr_ICEX, AUFS_BRATTR_ICEX},
25456+ {AuBrAttr_ICEX_SEC, AUFS_BRATTR_ICEX_SEC},
25457+ {AuBrAttr_ICEX_SYS, AUFS_BRATTR_ICEX_SYS},
25458+ {AuBrAttr_ICEX_TR, AUFS_BRATTR_ICEX_TR},
25459+ {AuBrAttr_ICEX_USR, AUFS_BRATTR_ICEX_USR},
25460+ {AuBrAttr_ICEX_OTH, AUFS_BRATTR_ICEX_OTH},
2000de60 25461+#endif
076b876e
AM
25462+
25463+ /* ro/rr branch */
1e00d052 25464+ {AuBrRAttr_WH, AUFS_BRRATTR_WH},
076b876e
AM
25465+
25466+ /* rw branch */
25467+ {AuBrWAttr_MOO, AUFS_BRWATTR_MOO},
1e00d052 25468+ {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
076b876e 25469+
1e00d052 25470+ {0, NULL}
1facf9fc 25471+};
25472+
1e00d052
AM
25473+static int br_attr_val(char *str, match_table_t table, substring_t args[])
25474+{
25475+ int attr, v;
25476+ char *p;
25477+
25478+ attr = 0;
25479+ do {
25480+ p = strchr(str, '+');
25481+ if (p)
25482+ *p = 0;
25483+ v = match_token(str, table, args);
076b876e
AM
25484+ if (v) {
25485+ if (v & AuBrAttr_CMOO_Mask)
25486+ attr &= ~AuBrAttr_CMOO_Mask;
1e00d052 25487+ attr |= v;
076b876e 25488+ } else {
1e00d052
AM
25489+ if (p)
25490+ *p = '+';
0c3ec466 25491+ pr_warn("ignored branch attribute %s\n", str);
1e00d052
AM
25492+ break;
25493+ }
25494+ if (p)
25495+ str = p + 1;
25496+ } while (p);
25497+
25498+ return attr;
25499+}
25500+
076b876e
AM
25501+static int au_do_optstr_br_attr(au_br_perm_str_t *str, int perm)
25502+{
25503+ int sz;
25504+ const char *p;
25505+ char *q;
25506+
076b876e
AM
25507+ q = str->a;
25508+ *q = 0;
25509+ p = au_optstr(&perm, brattr);
25510+ if (p) {
25511+ sz = strlen(p);
25512+ memcpy(q, p, sz + 1);
25513+ q += sz;
25514+ } else
25515+ goto out;
25516+
25517+ do {
25518+ p = au_optstr(&perm, brattr);
25519+ if (p) {
25520+ *q++ = '+';
25521+ sz = strlen(p);
25522+ memcpy(q, p, sz + 1);
25523+ q += sz;
25524+ }
25525+ } while (p);
25526+
25527+out:
c1595e42 25528+ return q - str->a;
076b876e
AM
25529+}
25530+
4a4d8108 25531+static int noinline_for_stack br_perm_val(char *perm)
1facf9fc 25532+{
076b876e
AM
25533+ int val, bad, sz;
25534+ char *p;
1facf9fc 25535+ substring_t args[MAX_OPT_ARGS];
076b876e 25536+ au_br_perm_str_t attr;
1facf9fc 25537+
1e00d052
AM
25538+ p = strchr(perm, '+');
25539+ if (p)
25540+ *p = 0;
25541+ val = match_token(perm, brperm, args);
25542+ if (!val) {
25543+ if (p)
25544+ *p = '+';
0c3ec466 25545+ pr_warn("ignored branch permission %s\n", perm);
1e00d052
AM
25546+ val = AuBrPerm_RO;
25547+ goto out;
25548+ }
25549+ if (!p)
25550+ goto out;
25551+
076b876e
AM
25552+ val |= br_attr_val(p + 1, brattr, args);
25553+
25554+ bad = 0;
86dc4139 25555+ switch (val & AuBrPerm_Mask) {
1e00d052
AM
25556+ case AuBrPerm_RO:
25557+ case AuBrPerm_RR:
076b876e
AM
25558+ bad = val & AuBrWAttr_Mask;
25559+ val &= ~AuBrWAttr_Mask;
1e00d052
AM
25560+ break;
25561+ case AuBrPerm_RW:
076b876e
AM
25562+ bad = val & AuBrRAttr_Mask;
25563+ val &= ~AuBrRAttr_Mask;
1e00d052
AM
25564+ break;
25565+ }
c1595e42
JR
25566+
25567+ /*
25568+ * 'unpin' attrib becomes meaningless since linux-3.18-rc1, but aufs
25569+ * does not treat it as an error, just warning.
25570+ * this is a tiny guard for the user operation.
25571+ */
25572+ if (val & AuBrAttr_UNPIN) {
25573+ bad |= AuBrAttr_UNPIN;
25574+ val &= ~AuBrAttr_UNPIN;
25575+ }
25576+
076b876e
AM
25577+ if (unlikely(bad)) {
25578+ sz = au_do_optstr_br_attr(&attr, bad);
25579+ AuDebugOn(!sz);
25580+ pr_warn("ignored branch attribute %s\n", attr.a);
25581+ }
1e00d052
AM
25582+
25583+out:
1facf9fc 25584+ return val;
25585+}
25586+
076b876e 25587+void au_optstr_br_perm(au_br_perm_str_t *str, int perm)
1facf9fc 25588+{
076b876e
AM
25589+ au_br_perm_str_t attr;
25590+ const char *p;
25591+ char *q;
1e00d052
AM
25592+ int sz;
25593+
076b876e
AM
25594+ q = str->a;
25595+ p = au_optstr(&perm, brperm);
25596+ AuDebugOn(!p || !*p);
25597+ sz = strlen(p);
25598+ memcpy(q, p, sz + 1);
25599+ q += sz;
1e00d052 25600+
076b876e
AM
25601+ sz = au_do_optstr_br_attr(&attr, perm);
25602+ if (sz) {
25603+ *q++ = '+';
25604+ memcpy(q, attr.a, sz + 1);
1e00d052
AM
25605+ }
25606+
076b876e 25607+ AuDebugOn(strlen(str->a) >= sizeof(str->a));
1facf9fc 25608+}
25609+
25610+/* ---------------------------------------------------------------------- */
25611+
25612+static match_table_t udbalevel = {
25613+ {AuOpt_UDBA_REVAL, "reval"},
25614+ {AuOpt_UDBA_NONE, "none"},
4a4d8108
AM
25615+#ifdef CONFIG_AUFS_HNOTIFY
25616+ {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
25617+#ifdef CONFIG_AUFS_HFSNOTIFY
25618+ {AuOpt_UDBA_HNOTIFY, "fsnotify"},
4a4d8108 25619+#endif
1facf9fc 25620+#endif
25621+ {-1, NULL}
25622+};
25623+
4a4d8108 25624+static int noinline_for_stack udba_val(char *str)
1facf9fc 25625+{
25626+ substring_t args[MAX_OPT_ARGS];
25627+
7f207e10 25628+ return match_token(str, udbalevel, args);
1facf9fc 25629+}
25630+
25631+const char *au_optstr_udba(int udba)
25632+{
076b876e 25633+ return au_parser_pattern(udba, udbalevel);
1facf9fc 25634+}
25635+
25636+/* ---------------------------------------------------------------------- */
25637+
25638+static match_table_t au_wbr_create_policy = {
25639+ {AuWbrCreate_TDP, "tdp"},
25640+ {AuWbrCreate_TDP, "top-down-parent"},
25641+ {AuWbrCreate_RR, "rr"},
25642+ {AuWbrCreate_RR, "round-robin"},
25643+ {AuWbrCreate_MFS, "mfs"},
25644+ {AuWbrCreate_MFS, "most-free-space"},
25645+ {AuWbrCreate_MFSV, "mfs:%d"},
25646+ {AuWbrCreate_MFSV, "most-free-space:%d"},
25647+
f2c43d5f
AM
25648+ /* top-down regardless the parent, and then mfs */
25649+ {AuWbrCreate_TDMFS, "tdmfs:%d"},
25650+ {AuWbrCreate_TDMFSV, "tdmfs:%d:%d"},
25651+
1facf9fc 25652+ {AuWbrCreate_MFSRR, "mfsrr:%d"},
25653+ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
25654+ {AuWbrCreate_PMFS, "pmfs"},
25655+ {AuWbrCreate_PMFSV, "pmfs:%d"},
392086de
AM
25656+ {AuWbrCreate_PMFSRR, "pmfsrr:%d"},
25657+ {AuWbrCreate_PMFSRRV, "pmfsrr:%d:%d"},
1facf9fc 25658+
25659+ {-1, NULL}
25660+};
25661+
dece6358
AM
25662+/*
25663+ * cf. linux/lib/parser.c and cmdline.c
25664+ * gave up calling memparse() since it uses simple_strtoull() instead of
9dbd164d 25665+ * kstrto...().
dece6358 25666+ */
4a4d8108
AM
25667+static int noinline_for_stack
25668+au_match_ull(substring_t *s, unsigned long long *result)
1facf9fc 25669+{
25670+ int err;
25671+ unsigned int len;
25672+ char a[32];
25673+
25674+ err = -ERANGE;
25675+ len = s->to - s->from;
25676+ if (len + 1 <= sizeof(a)) {
25677+ memcpy(a, s->from, len);
25678+ a[len] = '\0';
9dbd164d 25679+ err = kstrtoull(a, 0, result);
1facf9fc 25680+ }
25681+ return err;
25682+}
25683+
25684+static int au_wbr_mfs_wmark(substring_t *arg, char *str,
25685+ struct au_opt_wbr_create *create)
25686+{
25687+ int err;
25688+ unsigned long long ull;
25689+
25690+ err = 0;
25691+ if (!au_match_ull(arg, &ull))
25692+ create->mfsrr_watermark = ull;
25693+ else {
4a4d8108 25694+ pr_err("bad integer in %s\n", str);
1facf9fc 25695+ err = -EINVAL;
25696+ }
25697+
25698+ return err;
25699+}
25700+
25701+static int au_wbr_mfs_sec(substring_t *arg, char *str,
25702+ struct au_opt_wbr_create *create)
25703+{
25704+ int n, err;
25705+
25706+ err = 0;
027c5e7a 25707+ if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
1facf9fc 25708+ create->mfs_second = n;
25709+ else {
4a4d8108 25710+ pr_err("bad integer in %s\n", str);
1facf9fc 25711+ err = -EINVAL;
25712+ }
25713+
25714+ return err;
25715+}
25716+
4a4d8108
AM
25717+static int noinline_for_stack
25718+au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
1facf9fc 25719+{
25720+ int err, e;
25721+ substring_t args[MAX_OPT_ARGS];
25722+
25723+ err = match_token(str, au_wbr_create_policy, args);
25724+ create->wbr_create = err;
25725+ switch (err) {
25726+ case AuWbrCreate_MFSRRV:
f2c43d5f 25727+ case AuWbrCreate_TDMFSV:
392086de 25728+ case AuWbrCreate_PMFSRRV:
1facf9fc 25729+ e = au_wbr_mfs_wmark(&args[0], str, create);
25730+ if (!e)
25731+ e = au_wbr_mfs_sec(&args[1], str, create);
25732+ if (unlikely(e))
25733+ err = e;
25734+ break;
25735+ case AuWbrCreate_MFSRR:
f2c43d5f 25736+ case AuWbrCreate_TDMFS:
392086de 25737+ case AuWbrCreate_PMFSRR:
1facf9fc 25738+ e = au_wbr_mfs_wmark(&args[0], str, create);
25739+ if (unlikely(e)) {
25740+ err = e;
25741+ break;
25742+ }
25743+ /*FALLTHROUGH*/
25744+ case AuWbrCreate_MFS:
25745+ case AuWbrCreate_PMFS:
027c5e7a 25746+ create->mfs_second = AUFS_MFS_DEF_SEC;
1facf9fc 25747+ break;
25748+ case AuWbrCreate_MFSV:
25749+ case AuWbrCreate_PMFSV:
25750+ e = au_wbr_mfs_sec(&args[0], str, create);
25751+ if (unlikely(e))
25752+ err = e;
25753+ break;
25754+ }
25755+
25756+ return err;
25757+}
25758+
25759+const char *au_optstr_wbr_create(int wbr_create)
25760+{
076b876e 25761+ return au_parser_pattern(wbr_create, au_wbr_create_policy);
1facf9fc 25762+}
25763+
25764+static match_table_t au_wbr_copyup_policy = {
25765+ {AuWbrCopyup_TDP, "tdp"},
25766+ {AuWbrCopyup_TDP, "top-down-parent"},
25767+ {AuWbrCopyup_BUP, "bup"},
25768+ {AuWbrCopyup_BUP, "bottom-up-parent"},
25769+ {AuWbrCopyup_BU, "bu"},
25770+ {AuWbrCopyup_BU, "bottom-up"},
25771+ {-1, NULL}
25772+};
25773+
4a4d8108 25774+static int noinline_for_stack au_wbr_copyup_val(char *str)
1facf9fc 25775+{
25776+ substring_t args[MAX_OPT_ARGS];
25777+
25778+ return match_token(str, au_wbr_copyup_policy, args);
25779+}
25780+
25781+const char *au_optstr_wbr_copyup(int wbr_copyup)
25782+{
076b876e 25783+ return au_parser_pattern(wbr_copyup, au_wbr_copyup_policy);
1facf9fc 25784+}
25785+
25786+/* ---------------------------------------------------------------------- */
25787+
25788+static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
25789+
25790+static void dump_opts(struct au_opts *opts)
25791+{
25792+#ifdef CONFIG_AUFS_DEBUG
25793+ /* reduce stack space */
25794+ union {
25795+ struct au_opt_add *add;
25796+ struct au_opt_del *del;
25797+ struct au_opt_mod *mod;
25798+ struct au_opt_xino *xino;
25799+ struct au_opt_xino_itrunc *xino_itrunc;
25800+ struct au_opt_wbr_create *create;
25801+ } u;
25802+ struct au_opt *opt;
25803+
25804+ opt = opts->opt;
25805+ while (opt->type != Opt_tail) {
25806+ switch (opt->type) {
25807+ case Opt_add:
25808+ u.add = &opt->add;
25809+ AuDbg("add {b%d, %s, 0x%x, %p}\n",
25810+ u.add->bindex, u.add->pathname, u.add->perm,
25811+ u.add->path.dentry);
25812+ break;
25813+ case Opt_del:
25814+ case Opt_idel:
25815+ u.del = &opt->del;
25816+ AuDbg("del {%s, %p}\n",
25817+ u.del->pathname, u.del->h_path.dentry);
25818+ break;
25819+ case Opt_mod:
25820+ case Opt_imod:
25821+ u.mod = &opt->mod;
25822+ AuDbg("mod {%s, 0x%x, %p}\n",
25823+ u.mod->path, u.mod->perm, u.mod->h_root);
25824+ break;
25825+ case Opt_append:
25826+ u.add = &opt->add;
25827+ AuDbg("append {b%d, %s, 0x%x, %p}\n",
25828+ u.add->bindex, u.add->pathname, u.add->perm,
25829+ u.add->path.dentry);
25830+ break;
25831+ case Opt_prepend:
25832+ u.add = &opt->add;
25833+ AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
25834+ u.add->bindex, u.add->pathname, u.add->perm,
25835+ u.add->path.dentry);
25836+ break;
25837+ case Opt_dirwh:
25838+ AuDbg("dirwh %d\n", opt->dirwh);
25839+ break;
25840+ case Opt_rdcache:
25841+ AuDbg("rdcache %d\n", opt->rdcache);
25842+ break;
25843+ case Opt_rdblk:
25844+ AuDbg("rdblk %u\n", opt->rdblk);
25845+ break;
dece6358
AM
25846+ case Opt_rdblk_def:
25847+ AuDbg("rdblk_def\n");
25848+ break;
1facf9fc 25849+ case Opt_rdhash:
25850+ AuDbg("rdhash %u\n", opt->rdhash);
25851+ break;
dece6358
AM
25852+ case Opt_rdhash_def:
25853+ AuDbg("rdhash_def\n");
25854+ break;
1facf9fc 25855+ case Opt_xino:
25856+ u.xino = &opt->xino;
523b37e3 25857+ AuDbg("xino {%s %pD}\n", u.xino->path, u.xino->file);
1facf9fc 25858+ break;
25859+ case Opt_trunc_xino:
25860+ AuLabel(trunc_xino);
25861+ break;
25862+ case Opt_notrunc_xino:
25863+ AuLabel(notrunc_xino);
25864+ break;
25865+ case Opt_trunc_xino_path:
25866+ case Opt_itrunc_xino:
25867+ u.xino_itrunc = &opt->xino_itrunc;
25868+ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
25869+ break;
1facf9fc 25870+ case Opt_noxino:
25871+ AuLabel(noxino);
25872+ break;
25873+ case Opt_trunc_xib:
25874+ AuLabel(trunc_xib);
25875+ break;
25876+ case Opt_notrunc_xib:
25877+ AuLabel(notrunc_xib);
25878+ break;
dece6358
AM
25879+ case Opt_shwh:
25880+ AuLabel(shwh);
25881+ break;
25882+ case Opt_noshwh:
25883+ AuLabel(noshwh);
25884+ break;
076b876e
AM
25885+ case Opt_dirperm1:
25886+ AuLabel(dirperm1);
25887+ break;
25888+ case Opt_nodirperm1:
25889+ AuLabel(nodirperm1);
25890+ break;
1facf9fc 25891+ case Opt_plink:
25892+ AuLabel(plink);
25893+ break;
25894+ case Opt_noplink:
25895+ AuLabel(noplink);
25896+ break;
25897+ case Opt_list_plink:
25898+ AuLabel(list_plink);
25899+ break;
25900+ case Opt_udba:
25901+ AuDbg("udba %d, %s\n",
25902+ opt->udba, au_optstr_udba(opt->udba));
25903+ break;
4a4d8108
AM
25904+ case Opt_dio:
25905+ AuLabel(dio);
25906+ break;
25907+ case Opt_nodio:
25908+ AuLabel(nodio);
25909+ break;
1facf9fc 25910+ case Opt_diropq_a:
25911+ AuLabel(diropq_a);
25912+ break;
25913+ case Opt_diropq_w:
25914+ AuLabel(diropq_w);
25915+ break;
25916+ case Opt_warn_perm:
25917+ AuLabel(warn_perm);
25918+ break;
25919+ case Opt_nowarn_perm:
25920+ AuLabel(nowarn_perm);
25921+ break;
1facf9fc 25922+ case Opt_verbose:
25923+ AuLabel(verbose);
25924+ break;
25925+ case Opt_noverbose:
25926+ AuLabel(noverbose);
25927+ break;
25928+ case Opt_sum:
25929+ AuLabel(sum);
25930+ break;
25931+ case Opt_nosum:
25932+ AuLabel(nosum);
25933+ break;
25934+ case Opt_wsum:
25935+ AuLabel(wsum);
25936+ break;
25937+ case Opt_wbr_create:
25938+ u.create = &opt->wbr_create;
25939+ AuDbg("create %d, %s\n", u.create->wbr_create,
25940+ au_optstr_wbr_create(u.create->wbr_create));
25941+ switch (u.create->wbr_create) {
25942+ case AuWbrCreate_MFSV:
25943+ case AuWbrCreate_PMFSV:
25944+ AuDbg("%d sec\n", u.create->mfs_second);
25945+ break;
25946+ case AuWbrCreate_MFSRR:
f2c43d5f 25947+ case AuWbrCreate_TDMFS:
1facf9fc 25948+ AuDbg("%llu watermark\n",
25949+ u.create->mfsrr_watermark);
25950+ break;
25951+ case AuWbrCreate_MFSRRV:
f2c43d5f 25952+ case AuWbrCreate_TDMFSV:
392086de 25953+ case AuWbrCreate_PMFSRRV:
1facf9fc 25954+ AuDbg("%llu watermark, %d sec\n",
25955+ u.create->mfsrr_watermark,
25956+ u.create->mfs_second);
25957+ break;
25958+ }
25959+ break;
25960+ case Opt_wbr_copyup:
25961+ AuDbg("copyup %d, %s\n", opt->wbr_copyup,
25962+ au_optstr_wbr_copyup(opt->wbr_copyup));
25963+ break;
076b876e
AM
25964+ case Opt_fhsm_sec:
25965+ AuDbg("fhsm_sec %u\n", opt->fhsm_second);
25966+ break;
ae9dfd79
AM
25967+ case Opt_dirren:
25968+ AuLabel(dirren);
25969+ break;
25970+ case Opt_nodirren:
25971+ AuLabel(nodirren);
25972+ break;
c1595e42
JR
25973+ case Opt_acl:
25974+ AuLabel(acl);
25975+ break;
25976+ case Opt_noacl:
25977+ AuLabel(noacl);
25978+ break;
1facf9fc 25979+ default:
25980+ BUG();
25981+ }
25982+ opt++;
25983+ }
25984+#endif
25985+}
25986+
25987+void au_opts_free(struct au_opts *opts)
25988+{
25989+ struct au_opt *opt;
25990+
25991+ opt = opts->opt;
25992+ while (opt->type != Opt_tail) {
25993+ switch (opt->type) {
25994+ case Opt_add:
25995+ case Opt_append:
25996+ case Opt_prepend:
25997+ path_put(&opt->add.path);
25998+ break;
25999+ case Opt_del:
26000+ case Opt_idel:
26001+ path_put(&opt->del.h_path);
26002+ break;
26003+ case Opt_mod:
26004+ case Opt_imod:
26005+ dput(opt->mod.h_root);
26006+ break;
26007+ case Opt_xino:
26008+ fput(opt->xino.file);
26009+ break;
26010+ }
26011+ opt++;
26012+ }
26013+}
26014+
26015+static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
26016+ aufs_bindex_t bindex)
26017+{
26018+ int err;
26019+ struct au_opt_add *add = &opt->add;
26020+ char *p;
26021+
26022+ add->bindex = bindex;
1e00d052 26023+ add->perm = AuBrPerm_RO;
1facf9fc 26024+ add->pathname = opt_str;
26025+ p = strchr(opt_str, '=');
26026+ if (p) {
26027+ *p++ = 0;
26028+ if (*p)
26029+ add->perm = br_perm_val(p);
26030+ }
26031+
26032+ err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
26033+ if (!err) {
26034+ if (!p) {
26035+ add->perm = AuBrPerm_RO;
26036+ if (au_test_fs_rr(add->path.dentry->d_sb))
26037+ add->perm = AuBrPerm_RR;
26038+ else if (!bindex && !(sb_flags & MS_RDONLY))
26039+ add->perm = AuBrPerm_RW;
26040+ }
26041+ opt->type = Opt_add;
26042+ goto out;
26043+ }
4a4d8108 26044+ pr_err("lookup failed %s (%d)\n", add->pathname, err);
1facf9fc 26045+ err = -EINVAL;
26046+
4f0767ce 26047+out:
1facf9fc 26048+ return err;
26049+}
26050+
26051+static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
26052+{
26053+ int err;
26054+
26055+ del->pathname = args[0].from;
26056+ AuDbg("del path %s\n", del->pathname);
26057+
26058+ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
26059+ if (unlikely(err))
4a4d8108 26060+ pr_err("lookup failed %s (%d)\n", del->pathname, err);
1facf9fc 26061+
26062+ return err;
26063+}
26064+
26065+#if 0 /* reserved for future use */
26066+static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
26067+ struct au_opt_del *del, substring_t args[])
26068+{
26069+ int err;
26070+ struct dentry *root;
26071+
26072+ err = -EINVAL;
26073+ root = sb->s_root;
26074+ aufs_read_lock(root, AuLock_FLUSH);
5afbbe0d 26075+ if (bindex < 0 || au_sbbot(sb) < bindex) {
4a4d8108 26076+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 26077+ goto out;
26078+ }
26079+
26080+ err = 0;
26081+ del->h_path.dentry = dget(au_h_dptr(root, bindex));
26082+ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
26083+
4f0767ce 26084+out:
1facf9fc 26085+ aufs_read_unlock(root, !AuLock_IR);
26086+ return err;
26087+}
26088+#endif
26089+
4a4d8108
AM
26090+static int noinline_for_stack
26091+au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
1facf9fc 26092+{
26093+ int err;
26094+ struct path path;
26095+ char *p;
26096+
26097+ err = -EINVAL;
26098+ mod->path = args[0].from;
26099+ p = strchr(mod->path, '=');
26100+ if (unlikely(!p)) {
4a4d8108 26101+ pr_err("no permssion %s\n", args[0].from);
1facf9fc 26102+ goto out;
26103+ }
26104+
26105+ *p++ = 0;
26106+ err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
26107+ if (unlikely(err)) {
4a4d8108 26108+ pr_err("lookup failed %s (%d)\n", mod->path, err);
1facf9fc 26109+ goto out;
26110+ }
26111+
26112+ mod->perm = br_perm_val(p);
26113+ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
26114+ mod->h_root = dget(path.dentry);
26115+ path_put(&path);
26116+
4f0767ce 26117+out:
1facf9fc 26118+ return err;
26119+}
26120+
26121+#if 0 /* reserved for future use */
26122+static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
26123+ struct au_opt_mod *mod, substring_t args[])
26124+{
26125+ int err;
26126+ struct dentry *root;
26127+
26128+ err = -EINVAL;
26129+ root = sb->s_root;
26130+ aufs_read_lock(root, AuLock_FLUSH);
5afbbe0d 26131+ if (bindex < 0 || au_sbbot(sb) < bindex) {
4a4d8108 26132+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 26133+ goto out;
26134+ }
26135+
26136+ err = 0;
26137+ mod->perm = br_perm_val(args[1].from);
26138+ AuDbg("mod path %s, perm 0x%x, %s\n",
26139+ mod->path, mod->perm, args[1].from);
26140+ mod->h_root = dget(au_h_dptr(root, bindex));
26141+
4f0767ce 26142+out:
1facf9fc 26143+ aufs_read_unlock(root, !AuLock_IR);
26144+ return err;
26145+}
26146+#endif
26147+
26148+static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
26149+ substring_t args[])
26150+{
26151+ int err;
26152+ struct file *file;
26153+
26154+ file = au_xino_create(sb, args[0].from, /*silent*/0);
26155+ err = PTR_ERR(file);
26156+ if (IS_ERR(file))
26157+ goto out;
26158+
26159+ err = -EINVAL;
2000de60 26160+ if (unlikely(file->f_path.dentry->d_sb == sb)) {
1facf9fc 26161+ fput(file);
4a4d8108 26162+ pr_err("%s must be outside\n", args[0].from);
1facf9fc 26163+ goto out;
26164+ }
26165+
26166+ err = 0;
26167+ xino->file = file;
26168+ xino->path = args[0].from;
26169+
4f0767ce 26170+out:
1facf9fc 26171+ return err;
26172+}
26173+
4a4d8108
AM
26174+static int noinline_for_stack
26175+au_opts_parse_xino_itrunc_path(struct super_block *sb,
26176+ struct au_opt_xino_itrunc *xino_itrunc,
26177+ substring_t args[])
1facf9fc 26178+{
26179+ int err;
5afbbe0d 26180+ aufs_bindex_t bbot, bindex;
1facf9fc 26181+ struct path path;
26182+ struct dentry *root;
26183+
26184+ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
26185+ if (unlikely(err)) {
4a4d8108 26186+ pr_err("lookup failed %s (%d)\n", args[0].from, err);
1facf9fc 26187+ goto out;
26188+ }
26189+
26190+ xino_itrunc->bindex = -1;
26191+ root = sb->s_root;
26192+ aufs_read_lock(root, AuLock_FLUSH);
5afbbe0d
AM
26193+ bbot = au_sbbot(sb);
26194+ for (bindex = 0; bindex <= bbot; bindex++) {
1facf9fc 26195+ if (au_h_dptr(root, bindex) == path.dentry) {
26196+ xino_itrunc->bindex = bindex;
26197+ break;
26198+ }
26199+ }
26200+ aufs_read_unlock(root, !AuLock_IR);
26201+ path_put(&path);
26202+
26203+ if (unlikely(xino_itrunc->bindex < 0)) {
4a4d8108 26204+ pr_err("no such branch %s\n", args[0].from);
1facf9fc 26205+ err = -EINVAL;
26206+ }
26207+
4f0767ce 26208+out:
1facf9fc 26209+ return err;
26210+}
26211+
26212+/* called without aufs lock */
26213+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
26214+{
26215+ int err, n, token;
26216+ aufs_bindex_t bindex;
26217+ unsigned char skipped;
26218+ struct dentry *root;
26219+ struct au_opt *opt, *opt_tail;
26220+ char *opt_str;
26221+ /* reduce the stack space */
26222+ union {
26223+ struct au_opt_xino_itrunc *xino_itrunc;
26224+ struct au_opt_wbr_create *create;
26225+ } u;
26226+ struct {
26227+ substring_t args[MAX_OPT_ARGS];
26228+ } *a;
26229+
26230+ err = -ENOMEM;
26231+ a = kmalloc(sizeof(*a), GFP_NOFS);
26232+ if (unlikely(!a))
26233+ goto out;
26234+
26235+ root = sb->s_root;
26236+ err = 0;
26237+ bindex = 0;
26238+ opt = opts->opt;
26239+ opt_tail = opt + opts->max_opt - 1;
26240+ opt->type = Opt_tail;
26241+ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
26242+ err = -EINVAL;
26243+ skipped = 0;
26244+ token = match_token(opt_str, options, a->args);
26245+ switch (token) {
26246+ case Opt_br:
26247+ err = 0;
26248+ while (!err && (opt_str = strsep(&a->args[0].from, ":"))
26249+ && *opt_str) {
26250+ err = opt_add(opt, opt_str, opts->sb_flags,
26251+ bindex++);
26252+ if (unlikely(!err && ++opt > opt_tail)) {
26253+ err = -E2BIG;
26254+ break;
26255+ }
26256+ opt->type = Opt_tail;
26257+ skipped = 1;
26258+ }
26259+ break;
26260+ case Opt_add:
26261+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 26262+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26263+ break;
26264+ }
26265+ bindex = n;
26266+ err = opt_add(opt, a->args[1].from, opts->sb_flags,
26267+ bindex);
26268+ if (!err)
26269+ opt->type = token;
26270+ break;
26271+ case Opt_append:
26272+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
26273+ /*dummy bindex*/1);
26274+ if (!err)
26275+ opt->type = token;
26276+ break;
26277+ case Opt_prepend:
26278+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
26279+ /*bindex*/0);
26280+ if (!err)
26281+ opt->type = token;
26282+ break;
26283+ case Opt_del:
26284+ err = au_opts_parse_del(&opt->del, a->args);
26285+ if (!err)
26286+ opt->type = token;
26287+ break;
26288+#if 0 /* reserved for future use */
26289+ case Opt_idel:
26290+ del->pathname = "(indexed)";
26291+ if (unlikely(match_int(&args[0], &n))) {
4a4d8108 26292+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26293+ break;
26294+ }
26295+ err = au_opts_parse_idel(sb, n, &opt->del, a->args);
26296+ if (!err)
26297+ opt->type = token;
26298+ break;
26299+#endif
26300+ case Opt_mod:
26301+ err = au_opts_parse_mod(&opt->mod, a->args);
26302+ if (!err)
26303+ opt->type = token;
26304+ break;
26305+#ifdef IMOD /* reserved for future use */
26306+ case Opt_imod:
26307+ u.mod->path = "(indexed)";
26308+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 26309+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26310+ break;
26311+ }
26312+ err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
26313+ if (!err)
26314+ opt->type = token;
26315+ break;
26316+#endif
26317+ case Opt_xino:
26318+ err = au_opts_parse_xino(sb, &opt->xino, a->args);
26319+ if (!err)
26320+ opt->type = token;
26321+ break;
26322+
26323+ case Opt_trunc_xino_path:
26324+ err = au_opts_parse_xino_itrunc_path
26325+ (sb, &opt->xino_itrunc, a->args);
26326+ if (!err)
26327+ opt->type = token;
26328+ break;
26329+
26330+ case Opt_itrunc_xino:
26331+ u.xino_itrunc = &opt->xino_itrunc;
26332+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 26333+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26334+ break;
26335+ }
26336+ u.xino_itrunc->bindex = n;
26337+ aufs_read_lock(root, AuLock_FLUSH);
5afbbe0d 26338+ if (n < 0 || au_sbbot(sb) < n) {
4a4d8108 26339+ pr_err("out of bounds, %d\n", n);
1facf9fc 26340+ aufs_read_unlock(root, !AuLock_IR);
26341+ break;
26342+ }
26343+ aufs_read_unlock(root, !AuLock_IR);
26344+ err = 0;
26345+ opt->type = token;
26346+ break;
26347+
26348+ case Opt_dirwh:
26349+ if (unlikely(match_int(&a->args[0], &opt->dirwh)))
26350+ break;
26351+ err = 0;
26352+ opt->type = token;
26353+ break;
26354+
26355+ case Opt_rdcache:
027c5e7a
AM
26356+ if (unlikely(match_int(&a->args[0], &n))) {
26357+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26358+ break;
027c5e7a
AM
26359+ }
26360+ if (unlikely(n > AUFS_RDCACHE_MAX)) {
26361+ pr_err("rdcache must be smaller than %d\n",
26362+ AUFS_RDCACHE_MAX);
26363+ break;
26364+ }
26365+ opt->rdcache = n;
1facf9fc 26366+ err = 0;
26367+ opt->type = token;
26368+ break;
26369+ case Opt_rdblk:
26370+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 26371+ || n < 0
1facf9fc 26372+ || n > KMALLOC_MAX_SIZE)) {
4a4d8108 26373+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26374+ break;
26375+ }
1308ab2a 26376+ if (unlikely(n && n < NAME_MAX)) {
4a4d8108
AM
26377+ pr_err("rdblk must be larger than %d\n",
26378+ NAME_MAX);
1facf9fc 26379+ break;
26380+ }
26381+ opt->rdblk = n;
26382+ err = 0;
26383+ opt->type = token;
26384+ break;
26385+ case Opt_rdhash:
26386+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 26387+ || n < 0
1facf9fc 26388+ || n * sizeof(struct hlist_head)
26389+ > KMALLOC_MAX_SIZE)) {
4a4d8108 26390+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26391+ break;
26392+ }
26393+ opt->rdhash = n;
26394+ err = 0;
26395+ opt->type = token;
26396+ break;
26397+
26398+ case Opt_trunc_xino:
26399+ case Opt_notrunc_xino:
26400+ case Opt_noxino:
26401+ case Opt_trunc_xib:
26402+ case Opt_notrunc_xib:
dece6358
AM
26403+ case Opt_shwh:
26404+ case Opt_noshwh:
076b876e
AM
26405+ case Opt_dirperm1:
26406+ case Opt_nodirperm1:
1facf9fc 26407+ case Opt_plink:
26408+ case Opt_noplink:
26409+ case Opt_list_plink:
4a4d8108
AM
26410+ case Opt_dio:
26411+ case Opt_nodio:
1facf9fc 26412+ case Opt_diropq_a:
26413+ case Opt_diropq_w:
26414+ case Opt_warn_perm:
26415+ case Opt_nowarn_perm:
1facf9fc 26416+ case Opt_verbose:
26417+ case Opt_noverbose:
26418+ case Opt_sum:
26419+ case Opt_nosum:
26420+ case Opt_wsum:
dece6358
AM
26421+ case Opt_rdblk_def:
26422+ case Opt_rdhash_def:
ae9dfd79
AM
26423+ case Opt_dirren:
26424+ case Opt_nodirren:
c1595e42
JR
26425+ case Opt_acl:
26426+ case Opt_noacl:
1facf9fc 26427+ err = 0;
26428+ opt->type = token;
26429+ break;
26430+
26431+ case Opt_udba:
26432+ opt->udba = udba_val(a->args[0].from);
26433+ if (opt->udba >= 0) {
26434+ err = 0;
26435+ opt->type = token;
26436+ } else
4a4d8108 26437+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 26438+ break;
26439+
26440+ case Opt_wbr_create:
26441+ u.create = &opt->wbr_create;
26442+ u.create->wbr_create
26443+ = au_wbr_create_val(a->args[0].from, u.create);
26444+ if (u.create->wbr_create >= 0) {
26445+ err = 0;
26446+ opt->type = token;
26447+ } else
4a4d8108 26448+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 26449+ break;
26450+ case Opt_wbr_copyup:
26451+ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
26452+ if (opt->wbr_copyup >= 0) {
26453+ err = 0;
26454+ opt->type = token;
26455+ } else
4a4d8108 26456+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 26457+ break;
26458+
076b876e
AM
26459+ case Opt_fhsm_sec:
26460+ if (unlikely(match_int(&a->args[0], &n)
26461+ || n < 0)) {
26462+ pr_err("bad integer in %s\n", opt_str);
26463+ break;
26464+ }
26465+ if (sysaufs_brs) {
26466+ opt->fhsm_second = n;
26467+ opt->type = token;
26468+ } else
26469+ pr_warn("ignored %s\n", opt_str);
26470+ err = 0;
26471+ break;
26472+
1facf9fc 26473+ case Opt_ignore:
0c3ec466 26474+ pr_warn("ignored %s\n", opt_str);
1facf9fc 26475+ /*FALLTHROUGH*/
26476+ case Opt_ignore_silent:
26477+ skipped = 1;
26478+ err = 0;
26479+ break;
26480+ case Opt_err:
4a4d8108 26481+ pr_err("unknown option %s\n", opt_str);
1facf9fc 26482+ break;
26483+ }
26484+
26485+ if (!err && !skipped) {
26486+ if (unlikely(++opt > opt_tail)) {
26487+ err = -E2BIG;
26488+ opt--;
26489+ opt->type = Opt_tail;
26490+ break;
26491+ }
26492+ opt->type = Opt_tail;
26493+ }
26494+ }
26495+
ae9dfd79 26496+ kfree(a);
1facf9fc 26497+ dump_opts(opts);
26498+ if (unlikely(err))
26499+ au_opts_free(opts);
26500+
4f0767ce 26501+out:
1facf9fc 26502+ return err;
26503+}
26504+
26505+static int au_opt_wbr_create(struct super_block *sb,
26506+ struct au_opt_wbr_create *create)
26507+{
26508+ int err;
26509+ struct au_sbinfo *sbinfo;
26510+
dece6358
AM
26511+ SiMustWriteLock(sb);
26512+
1facf9fc 26513+ err = 1; /* handled */
26514+ sbinfo = au_sbi(sb);
26515+ if (sbinfo->si_wbr_create_ops->fin) {
26516+ err = sbinfo->si_wbr_create_ops->fin(sb);
26517+ if (!err)
26518+ err = 1;
26519+ }
26520+
26521+ sbinfo->si_wbr_create = create->wbr_create;
26522+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
26523+ switch (create->wbr_create) {
26524+ case AuWbrCreate_MFSRRV:
26525+ case AuWbrCreate_MFSRR:
f2c43d5f
AM
26526+ case AuWbrCreate_TDMFS:
26527+ case AuWbrCreate_TDMFSV:
392086de
AM
26528+ case AuWbrCreate_PMFSRR:
26529+ case AuWbrCreate_PMFSRRV:
1facf9fc 26530+ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
26531+ /*FALLTHROUGH*/
26532+ case AuWbrCreate_MFS:
26533+ case AuWbrCreate_MFSV:
26534+ case AuWbrCreate_PMFS:
26535+ case AuWbrCreate_PMFSV:
e49829fe
JR
26536+ sbinfo->si_wbr_mfs.mfs_expire
26537+ = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
1facf9fc 26538+ break;
26539+ }
26540+
26541+ if (sbinfo->si_wbr_create_ops->init)
26542+ sbinfo->si_wbr_create_ops->init(sb); /* ignore */
26543+
26544+ return err;
26545+}
26546+
26547+/*
26548+ * returns,
26549+ * plus: processed without an error
26550+ * zero: unprocessed
26551+ */
26552+static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
26553+ struct au_opts *opts)
26554+{
26555+ int err;
26556+ struct au_sbinfo *sbinfo;
26557+
dece6358
AM
26558+ SiMustWriteLock(sb);
26559+
1facf9fc 26560+ err = 1; /* handled */
26561+ sbinfo = au_sbi(sb);
26562+ switch (opt->type) {
26563+ case Opt_udba:
26564+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
26565+ sbinfo->si_mntflags |= opt->udba;
26566+ opts->given_udba |= opt->udba;
26567+ break;
26568+
26569+ case Opt_plink:
26570+ au_opt_set(sbinfo->si_mntflags, PLINK);
26571+ break;
26572+ case Opt_noplink:
26573+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
e49829fe 26574+ au_plink_put(sb, /*verbose*/1);
1facf9fc 26575+ au_opt_clr(sbinfo->si_mntflags, PLINK);
26576+ break;
26577+ case Opt_list_plink:
26578+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
26579+ au_plink_list(sb);
26580+ break;
26581+
4a4d8108
AM
26582+ case Opt_dio:
26583+ au_opt_set(sbinfo->si_mntflags, DIO);
26584+ au_fset_opts(opts->flags, REFRESH_DYAOP);
26585+ break;
26586+ case Opt_nodio:
26587+ au_opt_clr(sbinfo->si_mntflags, DIO);
26588+ au_fset_opts(opts->flags, REFRESH_DYAOP);
26589+ break;
26590+
076b876e
AM
26591+ case Opt_fhsm_sec:
26592+ au_fhsm_set(sbinfo, opt->fhsm_second);
26593+ break;
26594+
1facf9fc 26595+ case Opt_diropq_a:
26596+ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
26597+ break;
26598+ case Opt_diropq_w:
26599+ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
26600+ break;
26601+
26602+ case Opt_warn_perm:
26603+ au_opt_set(sbinfo->si_mntflags, WARN_PERM);
26604+ break;
26605+ case Opt_nowarn_perm:
26606+ au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
26607+ break;
26608+
1facf9fc 26609+ case Opt_verbose:
26610+ au_opt_set(sbinfo->si_mntflags, VERBOSE);
26611+ break;
26612+ case Opt_noverbose:
26613+ au_opt_clr(sbinfo->si_mntflags, VERBOSE);
26614+ break;
26615+
26616+ case Opt_sum:
26617+ au_opt_set(sbinfo->si_mntflags, SUM);
26618+ break;
26619+ case Opt_wsum:
26620+ au_opt_clr(sbinfo->si_mntflags, SUM);
26621+ au_opt_set(sbinfo->si_mntflags, SUM_W);
26622+ case Opt_nosum:
26623+ au_opt_clr(sbinfo->si_mntflags, SUM);
26624+ au_opt_clr(sbinfo->si_mntflags, SUM_W);
26625+ break;
26626+
26627+ case Opt_wbr_create:
26628+ err = au_opt_wbr_create(sb, &opt->wbr_create);
26629+ break;
26630+ case Opt_wbr_copyup:
26631+ sbinfo->si_wbr_copyup = opt->wbr_copyup;
26632+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
26633+ break;
26634+
26635+ case Opt_dirwh:
26636+ sbinfo->si_dirwh = opt->dirwh;
26637+ break;
26638+
26639+ case Opt_rdcache:
e49829fe
JR
26640+ sbinfo->si_rdcache
26641+ = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
1facf9fc 26642+ break;
26643+ case Opt_rdblk:
26644+ sbinfo->si_rdblk = opt->rdblk;
26645+ break;
dece6358
AM
26646+ case Opt_rdblk_def:
26647+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
26648+ break;
1facf9fc 26649+ case Opt_rdhash:
26650+ sbinfo->si_rdhash = opt->rdhash;
26651+ break;
dece6358
AM
26652+ case Opt_rdhash_def:
26653+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
26654+ break;
26655+
26656+ case Opt_shwh:
26657+ au_opt_set(sbinfo->si_mntflags, SHWH);
26658+ break;
26659+ case Opt_noshwh:
26660+ au_opt_clr(sbinfo->si_mntflags, SHWH);
26661+ break;
1facf9fc 26662+
076b876e
AM
26663+ case Opt_dirperm1:
26664+ au_opt_set(sbinfo->si_mntflags, DIRPERM1);
26665+ break;
26666+ case Opt_nodirperm1:
26667+ au_opt_clr(sbinfo->si_mntflags, DIRPERM1);
26668+ break;
26669+
1facf9fc 26670+ case Opt_trunc_xino:
26671+ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
26672+ break;
26673+ case Opt_notrunc_xino:
26674+ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
26675+ break;
26676+
26677+ case Opt_trunc_xino_path:
26678+ case Opt_itrunc_xino:
26679+ err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
26680+ if (!err)
26681+ err = 1;
26682+ break;
26683+
26684+ case Opt_trunc_xib:
26685+ au_fset_opts(opts->flags, TRUNC_XIB);
26686+ break;
26687+ case Opt_notrunc_xib:
26688+ au_fclr_opts(opts->flags, TRUNC_XIB);
26689+ break;
26690+
ae9dfd79
AM
26691+ case Opt_dirren:
26692+ err = 1;
26693+ if (!au_opt_test(sbinfo->si_mntflags, DIRREN)) {
26694+ err = au_dr_opt_set(sb);
26695+ if (!err)
26696+ err = 1;
26697+ }
26698+ if (err == 1)
26699+ au_opt_set(sbinfo->si_mntflags, DIRREN);
26700+ break;
26701+ case Opt_nodirren:
26702+ err = 1;
26703+ if (au_opt_test(sbinfo->si_mntflags, DIRREN)) {
26704+ err = au_dr_opt_clr(sb, au_ftest_opts(opts->flags,
26705+ DR_FLUSHED));
26706+ if (!err)
26707+ err = 1;
26708+ }
26709+ if (err == 1)
26710+ au_opt_clr(sbinfo->si_mntflags, DIRREN);
26711+ break;
26712+
c1595e42
JR
26713+ case Opt_acl:
26714+ sb->s_flags |= MS_POSIXACL;
26715+ break;
26716+ case Opt_noacl:
26717+ sb->s_flags &= ~MS_POSIXACL;
26718+ break;
26719+
1facf9fc 26720+ default:
26721+ err = 0;
26722+ break;
26723+ }
26724+
26725+ return err;
26726+}
26727+
26728+/*
26729+ * returns tri-state.
26730+ * plus: processed without an error
26731+ * zero: unprocessed
26732+ * minus: error
26733+ */
26734+static int au_opt_br(struct super_block *sb, struct au_opt *opt,
26735+ struct au_opts *opts)
26736+{
26737+ int err, do_refresh;
26738+
26739+ err = 0;
26740+ switch (opt->type) {
26741+ case Opt_append:
5afbbe0d 26742+ opt->add.bindex = au_sbbot(sb) + 1;
1facf9fc 26743+ if (opt->add.bindex < 0)
26744+ opt->add.bindex = 0;
26745+ goto add;
26746+ case Opt_prepend:
26747+ opt->add.bindex = 0;
f6b6e03d 26748+ add: /* indented label */
1facf9fc 26749+ case Opt_add:
26750+ err = au_br_add(sb, &opt->add,
26751+ au_ftest_opts(opts->flags, REMOUNT));
26752+ if (!err) {
26753+ err = 1;
027c5e7a 26754+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 26755+ }
26756+ break;
26757+
26758+ case Opt_del:
26759+ case Opt_idel:
26760+ err = au_br_del(sb, &opt->del,
26761+ au_ftest_opts(opts->flags, REMOUNT));
26762+ if (!err) {
26763+ err = 1;
26764+ au_fset_opts(opts->flags, TRUNC_XIB);
027c5e7a 26765+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 26766+ }
26767+ break;
26768+
26769+ case Opt_mod:
26770+ case Opt_imod:
26771+ err = au_br_mod(sb, &opt->mod,
26772+ au_ftest_opts(opts->flags, REMOUNT),
26773+ &do_refresh);
26774+ if (!err) {
26775+ err = 1;
027c5e7a
AM
26776+ if (do_refresh)
26777+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 26778+ }
26779+ break;
26780+ }
1facf9fc 26781+ return err;
26782+}
26783+
26784+static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
26785+ struct au_opt_xino **opt_xino,
26786+ struct au_opts *opts)
26787+{
26788+ int err;
5afbbe0d 26789+ aufs_bindex_t bbot, bindex;
1facf9fc 26790+ struct dentry *root, *parent, *h_root;
26791+
26792+ err = 0;
26793+ switch (opt->type) {
26794+ case Opt_xino:
26795+ err = au_xino_set(sb, &opt->xino,
26796+ !!au_ftest_opts(opts->flags, REMOUNT));
26797+ if (unlikely(err))
26798+ break;
26799+
26800+ *opt_xino = &opt->xino;
26801+ au_xino_brid_set(sb, -1);
26802+
26803+ /* safe d_parent access */
2000de60 26804+ parent = opt->xino.file->f_path.dentry->d_parent;
1facf9fc 26805+ root = sb->s_root;
5afbbe0d
AM
26806+ bbot = au_sbbot(sb);
26807+ for (bindex = 0; bindex <= bbot; bindex++) {
1facf9fc 26808+ h_root = au_h_dptr(root, bindex);
26809+ if (h_root == parent) {
26810+ au_xino_brid_set(sb, au_sbr_id(sb, bindex));
26811+ break;
26812+ }
26813+ }
26814+ break;
26815+
26816+ case Opt_noxino:
26817+ au_xino_clr(sb);
26818+ au_xino_brid_set(sb, -1);
26819+ *opt_xino = (void *)-1;
26820+ break;
26821+ }
26822+
26823+ return err;
26824+}
26825+
26826+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
26827+ unsigned int pending)
26828+{
076b876e 26829+ int err, fhsm;
5afbbe0d 26830+ aufs_bindex_t bindex, bbot;
79b8bda9 26831+ unsigned char do_plink, skip, do_free, can_no_dreval;
1facf9fc 26832+ struct au_branch *br;
26833+ struct au_wbr *wbr;
79b8bda9 26834+ struct dentry *root, *dentry;
1facf9fc 26835+ struct inode *dir, *h_dir;
26836+ struct au_sbinfo *sbinfo;
26837+ struct au_hinode *hdir;
26838+
dece6358
AM
26839+ SiMustAnyLock(sb);
26840+
1facf9fc 26841+ sbinfo = au_sbi(sb);
26842+ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
26843+
dece6358
AM
26844+ if (!(sb_flags & MS_RDONLY)) {
26845+ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
0c3ec466 26846+ pr_warn("first branch should be rw\n");
dece6358 26847+ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
febd17d6 26848+ pr_warn_once("shwh should be used with ro\n");
dece6358 26849+ }
1facf9fc 26850+
4a4d8108 26851+ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
1facf9fc 26852+ && !au_opt_test(sbinfo->si_mntflags, XINO))
febd17d6 26853+ pr_warn_once("udba=*notify requires xino\n");
1facf9fc 26854+
076b876e 26855+ if (au_opt_test(sbinfo->si_mntflags, DIRPERM1))
febd17d6
JR
26856+ pr_warn_once("dirperm1 breaks the protection"
26857+ " by the permission bits on the lower branch\n");
076b876e 26858+
1facf9fc 26859+ err = 0;
076b876e 26860+ fhsm = 0;
1facf9fc 26861+ root = sb->s_root;
5527c038 26862+ dir = d_inode(root);
1facf9fc 26863+ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
79b8bda9
AM
26864+ can_no_dreval = !!au_opt_test((sbinfo->si_mntflags | pending),
26865+ UDBA_NONE);
5afbbe0d
AM
26866+ bbot = au_sbbot(sb);
26867+ for (bindex = 0; !err && bindex <= bbot; bindex++) {
1facf9fc 26868+ skip = 0;
26869+ h_dir = au_h_iptr(dir, bindex);
26870+ br = au_sbr(sb, bindex);
1facf9fc 26871+
c1595e42
JR
26872+ if ((br->br_perm & AuBrAttr_ICEX)
26873+ && !h_dir->i_op->listxattr)
26874+ br->br_perm &= ~AuBrAttr_ICEX;
26875+#if 0
26876+ if ((br->br_perm & AuBrAttr_ICEX_SEC)
26877+ && (au_br_sb(br)->s_flags & MS_NOSEC))
26878+ br->br_perm &= ~AuBrAttr_ICEX_SEC;
26879+#endif
26880+
26881+ do_free = 0;
1facf9fc 26882+ wbr = br->br_wbr;
26883+ if (wbr)
26884+ wbr_wh_read_lock(wbr);
26885+
1e00d052 26886+ if (!au_br_writable(br->br_perm)) {
1facf9fc 26887+ do_free = !!wbr;
26888+ skip = (!wbr
26889+ || (!wbr->wbr_whbase
26890+ && !wbr->wbr_plink
26891+ && !wbr->wbr_orph));
1e00d052 26892+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 26893+ /* skip = (!br->br_whbase && !br->br_orph); */
26894+ skip = (!wbr || !wbr->wbr_whbase);
26895+ if (skip && wbr) {
26896+ if (do_plink)
26897+ skip = !!wbr->wbr_plink;
26898+ else
26899+ skip = !wbr->wbr_plink;
26900+ }
1e00d052 26901+ } else {
1facf9fc 26902+ /* skip = (br->br_whbase && br->br_ohph); */
26903+ skip = (wbr && wbr->wbr_whbase);
26904+ if (skip) {
26905+ if (do_plink)
26906+ skip = !!wbr->wbr_plink;
26907+ else
26908+ skip = !wbr->wbr_plink;
26909+ }
1facf9fc 26910+ }
26911+ if (wbr)
26912+ wbr_wh_read_unlock(wbr);
26913+
79b8bda9
AM
26914+ if (can_no_dreval) {
26915+ dentry = br->br_path.dentry;
26916+ spin_lock(&dentry->d_lock);
26917+ if (dentry->d_flags &
26918+ (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE))
26919+ can_no_dreval = 0;
26920+ spin_unlock(&dentry->d_lock);
26921+ }
26922+
076b876e
AM
26923+ if (au_br_fhsm(br->br_perm)) {
26924+ fhsm++;
26925+ AuDebugOn(!br->br_fhsm);
26926+ }
26927+
1facf9fc 26928+ if (skip)
26929+ continue;
26930+
26931+ hdir = au_hi(dir, bindex);
5afbbe0d 26932+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 26933+ if (wbr)
26934+ wbr_wh_write_lock(wbr);
86dc4139 26935+ err = au_wh_init(br, sb);
1facf9fc 26936+ if (wbr)
26937+ wbr_wh_write_unlock(wbr);
5afbbe0d 26938+ au_hn_inode_unlock(hdir);
1facf9fc 26939+
26940+ if (!err && do_free) {
ae9dfd79 26941+ kfree(wbr);
1facf9fc 26942+ br->br_wbr = NULL;
26943+ }
26944+ }
26945+
79b8bda9
AM
26946+ if (can_no_dreval)
26947+ au_fset_si(sbinfo, NO_DREVAL);
26948+ else
26949+ au_fclr_si(sbinfo, NO_DREVAL);
26950+
c1595e42 26951+ if (fhsm >= 2) {
076b876e 26952+ au_fset_si(sbinfo, FHSM);
5afbbe0d 26953+ for (bindex = bbot; bindex >= 0; bindex--) {
c1595e42
JR
26954+ br = au_sbr(sb, bindex);
26955+ if (au_br_fhsm(br->br_perm)) {
26956+ au_fhsm_set_bottom(sb, bindex);
26957+ break;
26958+ }
26959+ }
26960+ } else {
076b876e 26961+ au_fclr_si(sbinfo, FHSM);
c1595e42
JR
26962+ au_fhsm_set_bottom(sb, -1);
26963+ }
076b876e 26964+
1facf9fc 26965+ return err;
26966+}
26967+
26968+int au_opts_mount(struct super_block *sb, struct au_opts *opts)
26969+{
26970+ int err;
26971+ unsigned int tmp;
5afbbe0d 26972+ aufs_bindex_t bindex, bbot;
1facf9fc 26973+ struct au_opt *opt;
26974+ struct au_opt_xino *opt_xino, xino;
26975+ struct au_sbinfo *sbinfo;
027c5e7a 26976+ struct au_branch *br;
076b876e 26977+ struct inode *dir;
1facf9fc 26978+
dece6358
AM
26979+ SiMustWriteLock(sb);
26980+
1facf9fc 26981+ err = 0;
26982+ opt_xino = NULL;
26983+ opt = opts->opt;
26984+ while (err >= 0 && opt->type != Opt_tail)
26985+ err = au_opt_simple(sb, opt++, opts);
26986+ if (err > 0)
26987+ err = 0;
26988+ else if (unlikely(err < 0))
26989+ goto out;
26990+
26991+ /* disable xino and udba temporary */
26992+ sbinfo = au_sbi(sb);
26993+ tmp = sbinfo->si_mntflags;
26994+ au_opt_clr(sbinfo->si_mntflags, XINO);
26995+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
26996+
26997+ opt = opts->opt;
26998+ while (err >= 0 && opt->type != Opt_tail)
26999+ err = au_opt_br(sb, opt++, opts);
27000+ if (err > 0)
27001+ err = 0;
27002+ else if (unlikely(err < 0))
27003+ goto out;
27004+
5afbbe0d
AM
27005+ bbot = au_sbbot(sb);
27006+ if (unlikely(bbot < 0)) {
1facf9fc 27007+ err = -EINVAL;
4a4d8108 27008+ pr_err("no branches\n");
1facf9fc 27009+ goto out;
27010+ }
27011+
27012+ if (au_opt_test(tmp, XINO))
27013+ au_opt_set(sbinfo->si_mntflags, XINO);
27014+ opt = opts->opt;
27015+ while (!err && opt->type != Opt_tail)
27016+ err = au_opt_xino(sb, opt++, &opt_xino, opts);
27017+ if (unlikely(err))
27018+ goto out;
27019+
27020+ err = au_opts_verify(sb, sb->s_flags, tmp);
27021+ if (unlikely(err))
27022+ goto out;
27023+
27024+ /* restore xino */
27025+ if (au_opt_test(tmp, XINO) && !opt_xino) {
27026+ xino.file = au_xino_def(sb);
27027+ err = PTR_ERR(xino.file);
27028+ if (IS_ERR(xino.file))
27029+ goto out;
27030+
27031+ err = au_xino_set(sb, &xino, /*remount*/0);
27032+ fput(xino.file);
27033+ if (unlikely(err))
27034+ goto out;
27035+ }
27036+
27037+ /* restore udba */
027c5e7a 27038+ tmp &= AuOptMask_UDBA;
1facf9fc 27039+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
027c5e7a 27040+ sbinfo->si_mntflags |= tmp;
5afbbe0d
AM
27041+ bbot = au_sbbot(sb);
27042+ for (bindex = 0; bindex <= bbot; bindex++) {
027c5e7a
AM
27043+ br = au_sbr(sb, bindex);
27044+ err = au_hnotify_reset_br(tmp, br, br->br_perm);
27045+ if (unlikely(err))
27046+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
27047+ bindex, err);
27048+ /* go on even if err */
27049+ }
4a4d8108 27050+ if (au_opt_test(tmp, UDBA_HNOTIFY)) {
5527c038 27051+ dir = d_inode(sb->s_root);
4a4d8108 27052+ au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
1facf9fc 27053+ }
27054+
4f0767ce 27055+out:
1facf9fc 27056+ return err;
27057+}
27058+
27059+int au_opts_remount(struct super_block *sb, struct au_opts *opts)
27060+{
27061+ int err, rerr;
79b8bda9 27062+ unsigned char no_dreval;
1facf9fc 27063+ struct inode *dir;
27064+ struct au_opt_xino *opt_xino;
27065+ struct au_opt *opt;
27066+ struct au_sbinfo *sbinfo;
27067+
dece6358
AM
27068+ SiMustWriteLock(sb);
27069+
ae9dfd79
AM
27070+ err = au_dr_opt_flush(sb);
27071+ if (unlikely(err))
27072+ goto out;
27073+ au_fset_opts(opts->flags, DR_FLUSHED);
27074+
5527c038 27075+ dir = d_inode(sb->s_root);
1facf9fc 27076+ sbinfo = au_sbi(sb);
1facf9fc 27077+ opt_xino = NULL;
27078+ opt = opts->opt;
27079+ while (err >= 0 && opt->type != Opt_tail) {
27080+ err = au_opt_simple(sb, opt, opts);
27081+ if (!err)
27082+ err = au_opt_br(sb, opt, opts);
27083+ if (!err)
27084+ err = au_opt_xino(sb, opt, &opt_xino, opts);
27085+ opt++;
27086+ }
27087+ if (err > 0)
27088+ err = 0;
27089+ AuTraceErr(err);
27090+ /* go on even err */
27091+
79b8bda9 27092+ no_dreval = !!au_ftest_si(sbinfo, NO_DREVAL);
1facf9fc 27093+ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
27094+ if (unlikely(rerr && !err))
27095+ err = rerr;
27096+
79b8bda9 27097+ if (no_dreval != !!au_ftest_si(sbinfo, NO_DREVAL))
b95c5147 27098+ au_fset_opts(opts->flags, REFRESH_IDOP);
79b8bda9 27099+
1facf9fc 27100+ if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
27101+ rerr = au_xib_trunc(sb);
27102+ if (unlikely(rerr && !err))
27103+ err = rerr;
27104+ }
27105+
27106+ /* will be handled by the caller */
027c5e7a 27107+ if (!au_ftest_opts(opts->flags, REFRESH)
79b8bda9
AM
27108+ && (opts->given_udba
27109+ || au_opt_test(sbinfo->si_mntflags, XINO)
b95c5147 27110+ || au_ftest_opts(opts->flags, REFRESH_IDOP)
79b8bda9 27111+ ))
027c5e7a 27112+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 27113+
27114+ AuDbg("status 0x%x\n", opts->flags);
ae9dfd79
AM
27115+
27116+out:
1facf9fc 27117+ return err;
27118+}
27119+
27120+/* ---------------------------------------------------------------------- */
27121+
27122+unsigned int au_opt_udba(struct super_block *sb)
27123+{
27124+ return au_mntflags(sb) & AuOptMask_UDBA;
27125+}
7f207e10
AM
27126diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
27127--- /usr/share/empty/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
27128+++ linux/fs/aufs/opts.h 2018-04-15 08:49:13.401150731 +0200
27129@@ -0,0 +1,224 @@
1facf9fc 27130+/*
ae9dfd79 27131+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 27132+ *
27133+ * This program, aufs is free software; you can redistribute it and/or modify
27134+ * it under the terms of the GNU General Public License as published by
27135+ * the Free Software Foundation; either version 2 of the License, or
27136+ * (at your option) any later version.
dece6358
AM
27137+ *
27138+ * This program is distributed in the hope that it will be useful,
27139+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27140+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27141+ * GNU General Public License for more details.
27142+ *
27143+ * You should have received a copy of the GNU General Public License
523b37e3 27144+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27145+ */
27146+
27147+/*
27148+ * mount options/flags
27149+ */
27150+
27151+#ifndef __AUFS_OPTS_H__
27152+#define __AUFS_OPTS_H__
27153+
27154+#ifdef __KERNEL__
27155+
dece6358 27156+#include <linux/path.h>
1facf9fc 27157+
dece6358 27158+struct file;
dece6358 27159+
1facf9fc 27160+/* ---------------------------------------------------------------------- */
27161+
27162+/* mount flags */
27163+#define AuOpt_XINO 1 /* external inode number bitmap
27164+ and translation table */
27165+#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */
27166+#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */
27167+#define AuOpt_UDBA_REVAL (1 << 3)
4a4d8108 27168+#define AuOpt_UDBA_HNOTIFY (1 << 4)
dece6358
AM
27169+#define AuOpt_SHWH (1 << 5) /* show whiteout */
27170+#define AuOpt_PLINK (1 << 6) /* pseudo-link */
076b876e
AM
27171+#define AuOpt_DIRPERM1 (1 << 7) /* ignore the lower dir's perm
27172+ bits */
dece6358
AM
27173+#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */
27174+#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
27175+#define AuOpt_SUM_W (1 << 11) /* unimplemented */
27176+#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */
27177+#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */
4a4d8108 27178+#define AuOpt_DIO (1 << 14) /* direct io */
ae9dfd79 27179+#define AuOpt_DIRREN (1 << 15) /* directory rename */
1facf9fc 27180+
4a4d8108
AM
27181+#ifndef CONFIG_AUFS_HNOTIFY
27182+#undef AuOpt_UDBA_HNOTIFY
27183+#define AuOpt_UDBA_HNOTIFY 0
1facf9fc 27184+#endif
ae9dfd79
AM
27185+#ifndef CONFIG_AUFS_DIRREN
27186+#undef AuOpt_DIRREN
27187+#define AuOpt_DIRREN 0
27188+#endif
dece6358
AM
27189+#ifndef CONFIG_AUFS_SHWH
27190+#undef AuOpt_SHWH
27191+#define AuOpt_SHWH 0
27192+#endif
1facf9fc 27193+
27194+#define AuOpt_Def (AuOpt_XINO \
27195+ | AuOpt_UDBA_REVAL \
27196+ | AuOpt_PLINK \
27197+ /* | AuOpt_DIRPERM1 */ \
27198+ | AuOpt_WARN_PERM)
27199+#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
27200+ | AuOpt_UDBA_REVAL \
4a4d8108 27201+ | AuOpt_UDBA_HNOTIFY)
1facf9fc 27202+
27203+#define au_opt_test(flags, name) (flags & AuOpt_##name)
27204+#define au_opt_set(flags, name) do { \
27205+ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
27206+ ((flags) |= AuOpt_##name); \
27207+} while (0)
27208+#define au_opt_set_udba(flags, name) do { \
27209+ (flags) &= ~AuOptMask_UDBA; \
27210+ ((flags) |= AuOpt_##name); \
27211+} while (0)
7f207e10
AM
27212+#define au_opt_clr(flags, name) do { \
27213+ ((flags) &= ~AuOpt_##name); \
27214+} while (0)
1facf9fc 27215+
e49829fe
JR
27216+static inline unsigned int au_opts_plink(unsigned int mntflags)
27217+{
27218+#ifdef CONFIG_PROC_FS
27219+ return mntflags;
27220+#else
27221+ return mntflags & ~AuOpt_PLINK;
27222+#endif
27223+}
27224+
1facf9fc 27225+/* ---------------------------------------------------------------------- */
27226+
27227+/* policies to select one among multiple writable branches */
27228+enum {
27229+ AuWbrCreate_TDP, /* top down parent */
27230+ AuWbrCreate_RR, /* round robin */
27231+ AuWbrCreate_MFS, /* most free space */
27232+ AuWbrCreate_MFSV, /* mfs with seconds */
27233+ AuWbrCreate_MFSRR, /* mfs then rr */
27234+ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */
f2c43d5f
AM
27235+ AuWbrCreate_TDMFS, /* top down regardless parent and mfs */
27236+ AuWbrCreate_TDMFSV, /* top down regardless parent and mfs */
1facf9fc 27237+ AuWbrCreate_PMFS, /* parent and mfs */
27238+ AuWbrCreate_PMFSV, /* parent and mfs with seconds */
392086de
AM
27239+ AuWbrCreate_PMFSRR, /* parent, mfs and round-robin */
27240+ AuWbrCreate_PMFSRRV, /* plus seconds */
1facf9fc 27241+
27242+ AuWbrCreate_Def = AuWbrCreate_TDP
27243+};
27244+
27245+enum {
27246+ AuWbrCopyup_TDP, /* top down parent */
27247+ AuWbrCopyup_BUP, /* bottom up parent */
27248+ AuWbrCopyup_BU, /* bottom up */
27249+
27250+ AuWbrCopyup_Def = AuWbrCopyup_TDP
27251+};
27252+
27253+/* ---------------------------------------------------------------------- */
27254+
27255+struct au_opt_add {
27256+ aufs_bindex_t bindex;
27257+ char *pathname;
27258+ int perm;
27259+ struct path path;
27260+};
27261+
27262+struct au_opt_del {
27263+ char *pathname;
27264+ struct path h_path;
27265+};
27266+
27267+struct au_opt_mod {
27268+ char *path;
27269+ int perm;
27270+ struct dentry *h_root;
27271+};
27272+
27273+struct au_opt_xino {
27274+ char *path;
27275+ struct file *file;
27276+};
27277+
27278+struct au_opt_xino_itrunc {
27279+ aufs_bindex_t bindex;
27280+};
27281+
27282+struct au_opt_wbr_create {
27283+ int wbr_create;
27284+ int mfs_second;
27285+ unsigned long long mfsrr_watermark;
27286+};
27287+
27288+struct au_opt {
27289+ int type;
27290+ union {
27291+ struct au_opt_xino xino;
27292+ struct au_opt_xino_itrunc xino_itrunc;
27293+ struct au_opt_add add;
27294+ struct au_opt_del del;
27295+ struct au_opt_mod mod;
27296+ int dirwh;
27297+ int rdcache;
27298+ unsigned int rdblk;
27299+ unsigned int rdhash;
27300+ int udba;
27301+ struct au_opt_wbr_create wbr_create;
27302+ int wbr_copyup;
076b876e 27303+ unsigned int fhsm_second;
1facf9fc 27304+ };
27305+};
27306+
27307+/* opts flags */
27308+#define AuOpts_REMOUNT 1
027c5e7a
AM
27309+#define AuOpts_REFRESH (1 << 1)
27310+#define AuOpts_TRUNC_XIB (1 << 2)
27311+#define AuOpts_REFRESH_DYAOP (1 << 3)
b95c5147 27312+#define AuOpts_REFRESH_IDOP (1 << 4)
ae9dfd79 27313+#define AuOpts_DR_FLUSHED (1 << 5)
1facf9fc 27314+#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
7f207e10
AM
27315+#define au_fset_opts(flags, name) \
27316+ do { (flags) |= AuOpts_##name; } while (0)
27317+#define au_fclr_opts(flags, name) \
27318+ do { (flags) &= ~AuOpts_##name; } while (0)
1facf9fc 27319+
ae9dfd79
AM
27320+#ifndef CONFIG_AUFS_DIRREN
27321+#undef AuOpts_DR_FLUSHED
27322+#define AuOpts_DR_FLUSHED 0
27323+#endif
27324+
1facf9fc 27325+struct au_opts {
27326+ struct au_opt *opt;
27327+ int max_opt;
27328+
27329+ unsigned int given_udba;
27330+ unsigned int flags;
27331+ unsigned long sb_flags;
27332+};
27333+
27334+/* ---------------------------------------------------------------------- */
27335+
7e9cd9fe 27336+/* opts.c */
076b876e 27337+void au_optstr_br_perm(au_br_perm_str_t *str, int perm);
1facf9fc 27338+const char *au_optstr_udba(int udba);
27339+const char *au_optstr_wbr_copyup(int wbr_copyup);
27340+const char *au_optstr_wbr_create(int wbr_create);
27341+
27342+void au_opts_free(struct au_opts *opts);
ae9dfd79 27343+struct super_block;
1facf9fc 27344+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
27345+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
27346+ unsigned int pending);
27347+int au_opts_mount(struct super_block *sb, struct au_opts *opts);
27348+int au_opts_remount(struct super_block *sb, struct au_opts *opts);
27349+
27350+unsigned int au_opt_udba(struct super_block *sb);
27351+
1facf9fc 27352+#endif /* __KERNEL__ */
27353+#endif /* __AUFS_OPTS_H__ */
7f207e10
AM
27354diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
27355--- /usr/share/empty/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
27356+++ linux/fs/aufs/plink.c 2018-04-15 08:49:13.401150731 +0200
27357@@ -0,0 +1,515 @@
1facf9fc 27358+/*
ae9dfd79 27359+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 27360+ *
27361+ * This program, aufs is free software; you can redistribute it and/or modify
27362+ * it under the terms of the GNU General Public License as published by
27363+ * the Free Software Foundation; either version 2 of the License, or
27364+ * (at your option) any later version.
dece6358
AM
27365+ *
27366+ * This program is distributed in the hope that it will be useful,
27367+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27368+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27369+ * GNU General Public License for more details.
27370+ *
27371+ * You should have received a copy of the GNU General Public License
523b37e3 27372+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27373+ */
27374+
27375+/*
27376+ * pseudo-link
27377+ */
27378+
27379+#include "aufs.h"
27380+
27381+/*
e49829fe 27382+ * the pseudo-link maintenance mode.
1facf9fc 27383+ * during a user process maintains the pseudo-links,
27384+ * prohibit adding a new plink and branch manipulation.
e49829fe
JR
27385+ *
27386+ * Flags
27387+ * NOPLM:
27388+ * For entry functions which will handle plink, and i_mutex is already held
27389+ * in VFS.
27390+ * They cannot wait and should return an error at once.
27391+ * Callers has to check the error.
27392+ * NOPLMW:
27393+ * For entry functions which will handle plink, but i_mutex is not held
27394+ * in VFS.
27395+ * They can wait the plink maintenance mode to finish.
27396+ *
27397+ * They behave like F_SETLK and F_SETLKW.
27398+ * If the caller never handle plink, then both flags are unnecessary.
1facf9fc 27399+ */
e49829fe
JR
27400+
27401+int au_plink_maint(struct super_block *sb, int flags)
1facf9fc 27402+{
e49829fe
JR
27403+ int err;
27404+ pid_t pid, ppid;
f0c0a007 27405+ struct task_struct *parent, *prev;
e49829fe 27406+ struct au_sbinfo *sbi;
dece6358
AM
27407+
27408+ SiMustAnyLock(sb);
27409+
e49829fe
JR
27410+ err = 0;
27411+ if (!au_opt_test(au_mntflags(sb), PLINK))
27412+ goto out;
27413+
27414+ sbi = au_sbi(sb);
27415+ pid = sbi->si_plink_maint_pid;
27416+ if (!pid || pid == current->pid)
27417+ goto out;
27418+
27419+ /* todo: it highly depends upon /sbin/mount.aufs */
f0c0a007
AM
27420+ prev = NULL;
27421+ parent = current;
27422+ ppid = 0;
e49829fe 27423+ rcu_read_lock();
f0c0a007
AM
27424+ while (1) {
27425+ parent = rcu_dereference(parent->real_parent);
27426+ if (parent == prev)
27427+ break;
27428+ ppid = task_pid_vnr(parent);
27429+ if (pid == ppid) {
27430+ rcu_read_unlock();
27431+ goto out;
27432+ }
27433+ prev = parent;
27434+ }
e49829fe 27435+ rcu_read_unlock();
e49829fe
JR
27436+
27437+ if (au_ftest_lock(flags, NOPLMW)) {
027c5e7a
AM
27438+ /* if there is no i_mutex lock in VFS, we don't need to wait */
27439+ /* AuDebugOn(!lockdep_depth(current)); */
e49829fe
JR
27440+ while (sbi->si_plink_maint_pid) {
27441+ si_read_unlock(sb);
27442+ /* gave up wake_up_bit() */
27443+ wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
27444+
27445+ if (au_ftest_lock(flags, FLUSH))
27446+ au_nwt_flush(&sbi->si_nowait);
27447+ si_noflush_read_lock(sb);
27448+ }
27449+ } else if (au_ftest_lock(flags, NOPLM)) {
27450+ AuDbg("ppid %d, pid %d\n", ppid, pid);
27451+ err = -EAGAIN;
27452+ }
27453+
27454+out:
27455+ return err;
4a4d8108
AM
27456+}
27457+
e49829fe 27458+void au_plink_maint_leave(struct au_sbinfo *sbinfo)
4a4d8108 27459+{
4a4d8108 27460+ spin_lock(&sbinfo->si_plink_maint_lock);
027c5e7a 27461+ sbinfo->si_plink_maint_pid = 0;
4a4d8108 27462+ spin_unlock(&sbinfo->si_plink_maint_lock);
027c5e7a 27463+ wake_up_all(&sbinfo->si_plink_wq);
4a4d8108
AM
27464+}
27465+
e49829fe 27466+int au_plink_maint_enter(struct super_block *sb)
4a4d8108
AM
27467+{
27468+ int err;
4a4d8108
AM
27469+ struct au_sbinfo *sbinfo;
27470+
27471+ err = 0;
4a4d8108
AM
27472+ sbinfo = au_sbi(sb);
27473+ /* make sure i am the only one in this fs */
e49829fe
JR
27474+ si_write_lock(sb, AuLock_FLUSH);
27475+ if (au_opt_test(au_mntflags(sb), PLINK)) {
27476+ spin_lock(&sbinfo->si_plink_maint_lock);
27477+ if (!sbinfo->si_plink_maint_pid)
27478+ sbinfo->si_plink_maint_pid = current->pid;
27479+ else
27480+ err = -EBUSY;
27481+ spin_unlock(&sbinfo->si_plink_maint_lock);
27482+ }
4a4d8108
AM
27483+ si_write_unlock(sb);
27484+
27485+ return err;
1facf9fc 27486+}
27487+
27488+/* ---------------------------------------------------------------------- */
27489+
1facf9fc 27490+#ifdef CONFIG_AUFS_DEBUG
27491+void au_plink_list(struct super_block *sb)
27492+{
86dc4139 27493+ int i;
1facf9fc 27494+ struct au_sbinfo *sbinfo;
ae9dfd79
AM
27495+ struct hlist_bl_head *hbl;
27496+ struct hlist_bl_node *pos;
5afbbe0d 27497+ struct au_icntnr *icntnr;
1facf9fc 27498+
dece6358
AM
27499+ SiMustAnyLock(sb);
27500+
1facf9fc 27501+ sbinfo = au_sbi(sb);
27502+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 27503+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 27504+
86dc4139 27505+ for (i = 0; i < AuPlink_NHASH; i++) {
ae9dfd79
AM
27506+ hbl = sbinfo->si_plink + i;
27507+ hlist_bl_lock(hbl);
27508+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink)
5afbbe0d 27509+ AuDbg("%lu\n", icntnr->vfs_inode.i_ino);
ae9dfd79 27510+ hlist_bl_unlock(hbl);
86dc4139 27511+ }
1facf9fc 27512+}
27513+#endif
27514+
27515+/* is the inode pseudo-linked? */
27516+int au_plink_test(struct inode *inode)
27517+{
86dc4139 27518+ int found, i;
1facf9fc 27519+ struct au_sbinfo *sbinfo;
ae9dfd79
AM
27520+ struct hlist_bl_head *hbl;
27521+ struct hlist_bl_node *pos;
5afbbe0d 27522+ struct au_icntnr *icntnr;
1facf9fc 27523+
27524+ sbinfo = au_sbi(inode->i_sb);
dece6358 27525+ AuRwMustAnyLock(&sbinfo->si_rwsem);
1facf9fc 27526+ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
e49829fe 27527+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
1facf9fc 27528+
27529+ found = 0;
86dc4139 27530+ i = au_plink_hash(inode->i_ino);
ae9dfd79
AM
27531+ hbl = sbinfo->si_plink + i;
27532+ hlist_bl_lock(hbl);
27533+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink)
5afbbe0d 27534+ if (&icntnr->vfs_inode == inode) {
1facf9fc 27535+ found = 1;
27536+ break;
27537+ }
ae9dfd79 27538+ hlist_bl_unlock(hbl);
1facf9fc 27539+ return found;
27540+}
27541+
27542+/* ---------------------------------------------------------------------- */
27543+
27544+/*
27545+ * generate a name for plink.
27546+ * the file will be stored under AUFS_WH_PLINKDIR.
27547+ */
27548+/* 20 is max digits length of ulong 64 */
27549+#define PLINK_NAME_LEN ((20 + 1) * 2)
27550+
27551+static int plink_name(char *name, int len, struct inode *inode,
27552+ aufs_bindex_t bindex)
27553+{
27554+ int rlen;
27555+ struct inode *h_inode;
27556+
27557+ h_inode = au_h_iptr(inode, bindex);
27558+ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
27559+ return rlen;
27560+}
27561+
7f207e10
AM
27562+struct au_do_plink_lkup_args {
27563+ struct dentry **errp;
27564+ struct qstr *tgtname;
27565+ struct dentry *h_parent;
27566+ struct au_branch *br;
27567+};
27568+
27569+static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
27570+ struct dentry *h_parent,
27571+ struct au_branch *br)
27572+{
27573+ struct dentry *h_dentry;
febd17d6 27574+ struct inode *h_inode;
7f207e10 27575+
febd17d6 27576+ h_inode = d_inode(h_parent);
ae9dfd79 27577+ vfsub_inode_lock_shared_nested(h_inode, AuLsc_I_CHILD2);
b4510431 27578+ h_dentry = vfsub_lkup_one(tgtname, h_parent);
ae9dfd79 27579+ inode_unlock_shared(h_inode);
7f207e10
AM
27580+ return h_dentry;
27581+}
27582+
27583+static void au_call_do_plink_lkup(void *args)
27584+{
27585+ struct au_do_plink_lkup_args *a = args;
27586+ *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
27587+}
27588+
1facf9fc 27589+/* lookup the plink-ed @inode under the branch at @bindex */
27590+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
27591+{
27592+ struct dentry *h_dentry, *h_parent;
27593+ struct au_branch *br;
7f207e10 27594+ int wkq_err;
1facf9fc 27595+ char a[PLINK_NAME_LEN];
0c3ec466 27596+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 27597+
e49829fe
JR
27598+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
27599+
1facf9fc 27600+ br = au_sbr(inode->i_sb, bindex);
27601+ h_parent = br->br_wbr->wbr_plink;
1facf9fc 27602+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
27603+
2dfbb274 27604+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
7f207e10
AM
27605+ struct au_do_plink_lkup_args args = {
27606+ .errp = &h_dentry,
27607+ .tgtname = &tgtname,
27608+ .h_parent = h_parent,
27609+ .br = br
27610+ };
27611+
27612+ wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
27613+ if (unlikely(wkq_err))
27614+ h_dentry = ERR_PTR(wkq_err);
27615+ } else
27616+ h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
27617+
1facf9fc 27618+ return h_dentry;
27619+}
27620+
27621+/* create a pseudo-link */
27622+static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
27623+ struct dentry *h_dentry, struct au_branch *br)
27624+{
27625+ int err;
27626+ struct path h_path = {
86dc4139 27627+ .mnt = au_br_mnt(br)
1facf9fc 27628+ };
523b37e3 27629+ struct inode *h_dir, *delegated;
1facf9fc 27630+
5527c038 27631+ h_dir = d_inode(h_parent);
febd17d6 27632+ inode_lock_nested(h_dir, AuLsc_I_CHILD2);
4f0767ce 27633+again:
b4510431 27634+ h_path.dentry = vfsub_lkup_one(tgt, h_parent);
1facf9fc 27635+ err = PTR_ERR(h_path.dentry);
27636+ if (IS_ERR(h_path.dentry))
27637+ goto out;
27638+
27639+ err = 0;
27640+ /* wh.plink dir is not monitored */
7f207e10 27641+ /* todo: is it really safe? */
5527c038
JR
27642+ if (d_is_positive(h_path.dentry)
27643+ && d_inode(h_path.dentry) != d_inode(h_dentry)) {
523b37e3
AM
27644+ delegated = NULL;
27645+ err = vfsub_unlink(h_dir, &h_path, &delegated, /*force*/0);
27646+ if (unlikely(err == -EWOULDBLOCK)) {
27647+ pr_warn("cannot retry for NFSv4 delegation"
27648+ " for an internal unlink\n");
27649+ iput(delegated);
27650+ }
1facf9fc 27651+ dput(h_path.dentry);
27652+ h_path.dentry = NULL;
27653+ if (!err)
27654+ goto again;
27655+ }
5527c038 27656+ if (!err && d_is_negative(h_path.dentry)) {
523b37e3
AM
27657+ delegated = NULL;
27658+ err = vfsub_link(h_dentry, h_dir, &h_path, &delegated);
27659+ if (unlikely(err == -EWOULDBLOCK)) {
27660+ pr_warn("cannot retry for NFSv4 delegation"
27661+ " for an internal link\n");
27662+ iput(delegated);
27663+ }
27664+ }
1facf9fc 27665+ dput(h_path.dentry);
27666+
4f0767ce 27667+out:
febd17d6 27668+ inode_unlock(h_dir);
1facf9fc 27669+ return err;
27670+}
27671+
27672+struct do_whplink_args {
27673+ int *errp;
27674+ struct qstr *tgt;
27675+ struct dentry *h_parent;
27676+ struct dentry *h_dentry;
27677+ struct au_branch *br;
27678+};
27679+
27680+static void call_do_whplink(void *args)
27681+{
27682+ struct do_whplink_args *a = args;
27683+ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
27684+}
27685+
27686+static int whplink(struct dentry *h_dentry, struct inode *inode,
27687+ aufs_bindex_t bindex, struct au_branch *br)
27688+{
27689+ int err, wkq_err;
27690+ struct au_wbr *wbr;
27691+ struct dentry *h_parent;
1facf9fc 27692+ char a[PLINK_NAME_LEN];
0c3ec466 27693+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 27694+
27695+ wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
27696+ h_parent = wbr->wbr_plink;
1facf9fc 27697+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
27698+
27699+ /* always superio. */
2dfbb274 27700+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
1facf9fc 27701+ struct do_whplink_args args = {
27702+ .errp = &err,
27703+ .tgt = &tgtname,
27704+ .h_parent = h_parent,
27705+ .h_dentry = h_dentry,
27706+ .br = br
27707+ };
27708+ wkq_err = au_wkq_wait(call_do_whplink, &args);
27709+ if (unlikely(wkq_err))
27710+ err = wkq_err;
27711+ } else
27712+ err = do_whplink(&tgtname, h_parent, h_dentry, br);
1facf9fc 27713+
27714+ return err;
27715+}
27716+
1facf9fc 27717+/*
27718+ * create a new pseudo-link for @h_dentry on @bindex.
27719+ * the linked inode is held in aufs @inode.
27720+ */
27721+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
27722+ struct dentry *h_dentry)
27723+{
27724+ struct super_block *sb;
27725+ struct au_sbinfo *sbinfo;
ae9dfd79
AM
27726+ struct hlist_bl_head *hbl;
27727+ struct hlist_bl_node *pos;
5afbbe0d 27728+ struct au_icntnr *icntnr;
86dc4139 27729+ int found, err, cnt, i;
1facf9fc 27730+
27731+ sb = inode->i_sb;
27732+ sbinfo = au_sbi(sb);
27733+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 27734+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 27735+
86dc4139 27736+ found = au_plink_test(inode);
4a4d8108 27737+ if (found)
1facf9fc 27738+ return;
4a4d8108 27739+
86dc4139 27740+ i = au_plink_hash(inode->i_ino);
ae9dfd79 27741+ hbl = sbinfo->si_plink + i;
5afbbe0d 27742+ au_igrab(inode);
1facf9fc 27743+
ae9dfd79
AM
27744+ hlist_bl_lock(hbl);
27745+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink) {
5afbbe0d 27746+ if (&icntnr->vfs_inode == inode) {
4a4d8108
AM
27747+ found = 1;
27748+ break;
27749+ }
1facf9fc 27750+ }
5afbbe0d
AM
27751+ if (!found) {
27752+ icntnr = container_of(inode, struct au_icntnr, vfs_inode);
ae9dfd79 27753+ hlist_bl_add_head(&icntnr->plink, hbl);
5afbbe0d 27754+ }
ae9dfd79 27755+ hlist_bl_unlock(hbl);
4a4d8108 27756+ if (!found) {
ae9dfd79 27757+ cnt = au_hbl_count(hbl);
86dc4139
AM
27758+#define msg "unexpectedly unblanced or too many pseudo-links"
27759+ if (cnt > AUFS_PLINK_WARN)
27760+ AuWarn1(msg ", %d\n", cnt);
27761+#undef msg
1facf9fc 27762+ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
5afbbe0d
AM
27763+ if (unlikely(err)) {
27764+ pr_warn("err %d, damaged pseudo link.\n", err);
ae9dfd79 27765+ au_hbl_del(&icntnr->plink, hbl);
5afbbe0d 27766+ iput(&icntnr->vfs_inode);
4a4d8108 27767+ }
5afbbe0d
AM
27768+ } else
27769+ iput(&icntnr->vfs_inode);
1facf9fc 27770+}
27771+
27772+/* free all plinks */
e49829fe 27773+void au_plink_put(struct super_block *sb, int verbose)
1facf9fc 27774+{
86dc4139 27775+ int i, warned;
1facf9fc 27776+ struct au_sbinfo *sbinfo;
ae9dfd79
AM
27777+ struct hlist_bl_head *hbl;
27778+ struct hlist_bl_node *pos, *tmp;
5afbbe0d 27779+ struct au_icntnr *icntnr;
1facf9fc 27780+
dece6358
AM
27781+ SiMustWriteLock(sb);
27782+
1facf9fc 27783+ sbinfo = au_sbi(sb);
27784+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 27785+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 27786+
1facf9fc 27787+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
27788+ warned = 0;
27789+ for (i = 0; i < AuPlink_NHASH; i++) {
ae9dfd79
AM
27790+ hbl = sbinfo->si_plink + i;
27791+ if (!warned && verbose && !hlist_bl_empty(hbl)) {
86dc4139
AM
27792+ pr_warn("pseudo-link is not flushed");
27793+ warned = 1;
27794+ }
ae9dfd79 27795+ hlist_bl_for_each_entry_safe(icntnr, pos, tmp, hbl, plink)
5afbbe0d 27796+ iput(&icntnr->vfs_inode);
ae9dfd79 27797+ INIT_HLIST_BL_HEAD(hbl);
86dc4139 27798+ }
1facf9fc 27799+}
27800+
e49829fe
JR
27801+void au_plink_clean(struct super_block *sb, int verbose)
27802+{
27803+ struct dentry *root;
27804+
27805+ root = sb->s_root;
27806+ aufs_write_lock(root);
27807+ if (au_opt_test(au_mntflags(sb), PLINK))
27808+ au_plink_put(sb, verbose);
27809+ aufs_write_unlock(root);
27810+}
27811+
86dc4139
AM
27812+static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id)
27813+{
27814+ int do_put;
5afbbe0d 27815+ aufs_bindex_t btop, bbot, bindex;
86dc4139
AM
27816+
27817+ do_put = 0;
5afbbe0d
AM
27818+ btop = au_ibtop(inode);
27819+ bbot = au_ibbot(inode);
27820+ if (btop >= 0) {
27821+ for (bindex = btop; bindex <= bbot; bindex++) {
86dc4139
AM
27822+ if (!au_h_iptr(inode, bindex)
27823+ || au_ii_br_id(inode, bindex) != br_id)
27824+ continue;
27825+ au_set_h_iptr(inode, bindex, NULL, 0);
27826+ do_put = 1;
27827+ break;
27828+ }
27829+ if (do_put)
5afbbe0d 27830+ for (bindex = btop; bindex <= bbot; bindex++)
86dc4139
AM
27831+ if (au_h_iptr(inode, bindex)) {
27832+ do_put = 0;
27833+ break;
27834+ }
27835+ } else
27836+ do_put = 1;
27837+
27838+ return do_put;
27839+}
27840+
1facf9fc 27841+/* free the plinks on a branch specified by @br_id */
27842+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
27843+{
27844+ struct au_sbinfo *sbinfo;
ae9dfd79
AM
27845+ struct hlist_bl_head *hbl;
27846+ struct hlist_bl_node *pos, *tmp;
5afbbe0d 27847+ struct au_icntnr *icntnr;
1facf9fc 27848+ struct inode *inode;
86dc4139 27849+ int i, do_put;
1facf9fc 27850+
dece6358
AM
27851+ SiMustWriteLock(sb);
27852+
1facf9fc 27853+ sbinfo = au_sbi(sb);
27854+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 27855+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 27856+
ae9dfd79 27857+ /* no bit_lock since sbinfo is write-locked */
86dc4139 27858+ for (i = 0; i < AuPlink_NHASH; i++) {
ae9dfd79
AM
27859+ hbl = sbinfo->si_plink + i;
27860+ hlist_bl_for_each_entry_safe(icntnr, pos, tmp, hbl, plink) {
5afbbe0d 27861+ inode = au_igrab(&icntnr->vfs_inode);
86dc4139
AM
27862+ ii_write_lock_child(inode);
27863+ do_put = au_plink_do_half_refresh(inode, br_id);
5afbbe0d 27864+ if (do_put) {
ae9dfd79 27865+ hlist_bl_del(&icntnr->plink);
5afbbe0d
AM
27866+ iput(inode);
27867+ }
86dc4139
AM
27868+ ii_write_unlock(inode);
27869+ iput(inode);
dece6358 27870+ }
dece6358
AM
27871+ }
27872+}
7f207e10
AM
27873diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
27874--- /usr/share/empty/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
27875+++ linux/fs/aufs/poll.c 2018-04-15 08:49:13.401150731 +0200
27876@@ -0,0 +1,53 @@
dece6358 27877+/*
ae9dfd79 27878+ * Copyright (C) 2005-2018 Junjiro R. Okajima
dece6358
AM
27879+ *
27880+ * This program, aufs is free software; you can redistribute it and/or modify
27881+ * it under the terms of the GNU General Public License as published by
27882+ * the Free Software Foundation; either version 2 of the License, or
27883+ * (at your option) any later version.
27884+ *
27885+ * This program is distributed in the hope that it will be useful,
27886+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27887+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27888+ * GNU General Public License for more details.
27889+ *
27890+ * You should have received a copy of the GNU General Public License
523b37e3 27891+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358
AM
27892+ */
27893+
1308ab2a 27894+/*
27895+ * poll operation
27896+ * There is only one filesystem which implements ->poll operation, currently.
27897+ */
27898+
27899+#include "aufs.h"
27900+
27901+unsigned int aufs_poll(struct file *file, poll_table *wait)
27902+{
27903+ unsigned int mask;
27904+ int err;
27905+ struct file *h_file;
1308ab2a 27906+ struct super_block *sb;
27907+
27908+ /* We should pretend an error happened. */
27909+ mask = POLLERR /* | POLLIN | POLLOUT */;
b912730e 27910+ sb = file->f_path.dentry->d_sb;
e49829fe 27911+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
b912730e 27912+
ae9dfd79 27913+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
b912730e
AM
27914+ err = PTR_ERR(h_file);
27915+ if (IS_ERR(h_file))
1308ab2a 27916+ goto out;
27917+
27918+ /* it is not an error if h_file has no operation */
27919+ mask = DEFAULT_POLLMASK;
523b37e3 27920+ if (h_file->f_op->poll)
1308ab2a 27921+ mask = h_file->f_op->poll(h_file, wait);
b912730e 27922+ fput(h_file); /* instead of au_read_post() */
1308ab2a 27923+
4f0767ce 27924+out:
1308ab2a 27925+ si_read_unlock(sb);
ae9dfd79
AM
27926+ if (mask & POLLERR)
27927+ AuDbg("mask 0x%x\n", mask);
1308ab2a 27928+ return mask;
27929+}
c1595e42
JR
27930diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c
27931--- /usr/share/empty/fs/aufs/posix_acl.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
27932+++ linux/fs/aufs/posix_acl.c 2018-04-15 08:49:13.401150731 +0200
27933@@ -0,0 +1,102 @@
c1595e42 27934+/*
ae9dfd79 27935+ * Copyright (C) 2014-2018 Junjiro R. Okajima
c1595e42
JR
27936+ *
27937+ * This program, aufs is free software; you can redistribute it and/or modify
27938+ * it under the terms of the GNU General Public License as published by
27939+ * the Free Software Foundation; either version 2 of the License, or
27940+ * (at your option) any later version.
27941+ *
27942+ * This program is distributed in the hope that it will be useful,
27943+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27944+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27945+ * GNU General Public License for more details.
27946+ *
27947+ * You should have received a copy of the GNU General Public License
27948+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
27949+ */
27950+
27951+/*
27952+ * posix acl operations
27953+ */
27954+
27955+#include <linux/fs.h>
c1595e42
JR
27956+#include "aufs.h"
27957+
27958+struct posix_acl *aufs_get_acl(struct inode *inode, int type)
27959+{
27960+ struct posix_acl *acl;
27961+ int err;
27962+ aufs_bindex_t bindex;
27963+ struct inode *h_inode;
27964+ struct super_block *sb;
27965+
27966+ acl = NULL;
27967+ sb = inode->i_sb;
27968+ si_read_lock(sb, AuLock_FLUSH);
27969+ ii_read_lock_child(inode);
27970+ if (!(sb->s_flags & MS_POSIXACL))
27971+ goto out;
27972+
5afbbe0d 27973+ bindex = au_ibtop(inode);
c1595e42
JR
27974+ h_inode = au_h_iptr(inode, bindex);
27975+ if (unlikely(!h_inode
27976+ || ((h_inode->i_mode & S_IFMT)
27977+ != (inode->i_mode & S_IFMT)))) {
27978+ err = au_busy_or_stale();
27979+ acl = ERR_PTR(err);
27980+ goto out;
27981+ }
27982+
27983+ /* always topmost only */
27984+ acl = get_acl(h_inode, type);
ae9dfd79
AM
27985+ if (!IS_ERR_OR_NULL(acl))
27986+ set_cached_acl(inode, type, acl);
c1595e42
JR
27987+
27988+out:
27989+ ii_read_unlock(inode);
27990+ si_read_unlock(sb);
27991+
27992+ AuTraceErrPtr(acl);
27993+ return acl;
27994+}
27995+
27996+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
27997+{
27998+ int err;
27999+ ssize_t ssz;
28000+ struct dentry *dentry;
f2c43d5f 28001+ struct au_sxattr arg = {
c1595e42
JR
28002+ .type = AU_ACL_SET,
28003+ .u.acl_set = {
28004+ .acl = acl,
28005+ .type = type
28006+ },
28007+ };
28008+
5afbbe0d
AM
28009+ IMustLock(inode);
28010+
c1595e42
JR
28011+ if (inode->i_ino == AUFS_ROOT_INO)
28012+ dentry = dget(inode->i_sb->s_root);
28013+ else {
28014+ dentry = d_find_alias(inode);
28015+ if (!dentry)
28016+ dentry = d_find_any_alias(inode);
28017+ if (!dentry) {
28018+ pr_warn("cannot handle this inode, "
28019+ "please report to aufs-users ML\n");
28020+ err = -ENOENT;
28021+ goto out;
28022+ }
28023+ }
28024+
f2c43d5f 28025+ ssz = au_sxattr(dentry, inode, &arg);
c1595e42
JR
28026+ dput(dentry);
28027+ err = ssz;
ae9dfd79 28028+ if (ssz >= 0) {
c1595e42 28029+ err = 0;
ae9dfd79
AM
28030+ set_cached_acl(inode, type, acl);
28031+ }
c1595e42
JR
28032+
28033+out:
c1595e42
JR
28034+ return err;
28035+}
7f207e10
AM
28036diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
28037--- /usr/share/empty/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
28038+++ linux/fs/aufs/procfs.c 2018-04-15 08:49:13.401150731 +0200
28039@@ -0,0 +1,170 @@
e49829fe 28040+/*
ae9dfd79 28041+ * Copyright (C) 2010-2018 Junjiro R. Okajima
e49829fe
JR
28042+ *
28043+ * This program, aufs is free software; you can redistribute it and/or modify
28044+ * it under the terms of the GNU General Public License as published by
28045+ * the Free Software Foundation; either version 2 of the License, or
28046+ * (at your option) any later version.
28047+ *
28048+ * This program is distributed in the hope that it will be useful,
28049+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28050+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28051+ * GNU General Public License for more details.
28052+ *
28053+ * You should have received a copy of the GNU General Public License
523b37e3 28054+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
28055+ */
28056+
28057+/*
28058+ * procfs interfaces
28059+ */
28060+
28061+#include <linux/proc_fs.h>
28062+#include "aufs.h"
28063+
28064+static int au_procfs_plm_release(struct inode *inode, struct file *file)
28065+{
28066+ struct au_sbinfo *sbinfo;
28067+
28068+ sbinfo = file->private_data;
28069+ if (sbinfo) {
28070+ au_plink_maint_leave(sbinfo);
28071+ kobject_put(&sbinfo->si_kobj);
28072+ }
28073+
28074+ return 0;
28075+}
28076+
28077+static void au_procfs_plm_write_clean(struct file *file)
28078+{
28079+ struct au_sbinfo *sbinfo;
28080+
28081+ sbinfo = file->private_data;
28082+ if (sbinfo)
28083+ au_plink_clean(sbinfo->si_sb, /*verbose*/0);
28084+}
28085+
28086+static int au_procfs_plm_write_si(struct file *file, unsigned long id)
28087+{
28088+ int err;
28089+ struct super_block *sb;
28090+ struct au_sbinfo *sbinfo;
ae9dfd79 28091+ struct hlist_bl_node *pos;
e49829fe
JR
28092+
28093+ err = -EBUSY;
28094+ if (unlikely(file->private_data))
28095+ goto out;
28096+
28097+ sb = NULL;
53392da6 28098+ /* don't use au_sbilist_lock() here */
ae9dfd79
AM
28099+ hlist_bl_lock(&au_sbilist);
28100+ hlist_bl_for_each_entry(sbinfo, pos, &au_sbilist, si_list)
e49829fe
JR
28101+ if (id == sysaufs_si_id(sbinfo)) {
28102+ kobject_get(&sbinfo->si_kobj);
28103+ sb = sbinfo->si_sb;
28104+ break;
28105+ }
ae9dfd79 28106+ hlist_bl_unlock(&au_sbilist);
e49829fe
JR
28107+
28108+ err = -EINVAL;
28109+ if (unlikely(!sb))
28110+ goto out;
28111+
28112+ err = au_plink_maint_enter(sb);
28113+ if (!err)
28114+ /* keep kobject_get() */
28115+ file->private_data = sbinfo;
28116+ else
28117+ kobject_put(&sbinfo->si_kobj);
28118+out:
28119+ return err;
28120+}
28121+
28122+/*
28123+ * Accept a valid "si=xxxx" only.
28124+ * Once it is accepted successfully, accept "clean" too.
28125+ */
28126+static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf,
28127+ size_t count, loff_t *ppos)
28128+{
28129+ ssize_t err;
28130+ unsigned long id;
28131+ /* last newline is allowed */
28132+ char buf[3 + sizeof(unsigned long) * 2 + 1];
28133+
28134+ err = -EACCES;
28135+ if (unlikely(!capable(CAP_SYS_ADMIN)))
28136+ goto out;
28137+
28138+ err = -EINVAL;
28139+ if (unlikely(count > sizeof(buf)))
28140+ goto out;
28141+
28142+ err = copy_from_user(buf, ubuf, count);
28143+ if (unlikely(err)) {
28144+ err = -EFAULT;
28145+ goto out;
28146+ }
28147+ buf[count] = 0;
28148+
28149+ err = -EINVAL;
28150+ if (!strcmp("clean", buf)) {
28151+ au_procfs_plm_write_clean(file);
28152+ goto out_success;
28153+ } else if (unlikely(strncmp("si=", buf, 3)))
28154+ goto out;
28155+
9dbd164d 28156+ err = kstrtoul(buf + 3, 16, &id);
e49829fe
JR
28157+ if (unlikely(err))
28158+ goto out;
28159+
28160+ err = au_procfs_plm_write_si(file, id);
28161+ if (unlikely(err))
28162+ goto out;
28163+
28164+out_success:
28165+ err = count; /* success */
28166+out:
28167+ return err;
28168+}
28169+
28170+static const struct file_operations au_procfs_plm_fop = {
28171+ .write = au_procfs_plm_write,
28172+ .release = au_procfs_plm_release,
28173+ .owner = THIS_MODULE
28174+};
28175+
28176+/* ---------------------------------------------------------------------- */
28177+
28178+static struct proc_dir_entry *au_procfs_dir;
28179+
28180+void au_procfs_fin(void)
28181+{
28182+ remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir);
28183+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
28184+}
28185+
28186+int __init au_procfs_init(void)
28187+{
28188+ int err;
28189+ struct proc_dir_entry *entry;
28190+
28191+ err = -ENOMEM;
28192+ au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL);
28193+ if (unlikely(!au_procfs_dir))
28194+ goto out;
28195+
28196+ entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | S_IWUSR,
28197+ au_procfs_dir, &au_procfs_plm_fop);
28198+ if (unlikely(!entry))
28199+ goto out_dir;
28200+
28201+ err = 0;
28202+ goto out; /* success */
28203+
28204+
28205+out_dir:
28206+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
28207+out:
28208+ return err;
28209+}
7f207e10
AM
28210diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
28211--- /usr/share/empty/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 28212+++ linux/fs/aufs/rdu.c 2018-04-15 08:49:13.404484168 +0200
5afbbe0d 28213@@ -0,0 +1,381 @@
1308ab2a 28214+/*
ae9dfd79 28215+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1308ab2a 28216+ *
28217+ * This program, aufs is free software; you can redistribute it and/or modify
28218+ * it under the terms of the GNU General Public License as published by
28219+ * the Free Software Foundation; either version 2 of the License, or
28220+ * (at your option) any later version.
28221+ *
28222+ * This program is distributed in the hope that it will be useful,
28223+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28224+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28225+ * GNU General Public License for more details.
28226+ *
28227+ * You should have received a copy of the GNU General Public License
523b37e3 28228+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1308ab2a 28229+ */
28230+
28231+/*
28232+ * readdir in userspace.
28233+ */
28234+
b752ccd1 28235+#include <linux/compat.h>
4a4d8108 28236+#include <linux/fs_stack.h>
1308ab2a 28237+#include <linux/security.h>
1308ab2a 28238+#include "aufs.h"
28239+
28240+/* bits for struct aufs_rdu.flags */
28241+#define AuRdu_CALLED 1
28242+#define AuRdu_CONT (1 << 1)
28243+#define AuRdu_FULL (1 << 2)
28244+#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name)
7f207e10
AM
28245+#define au_fset_rdu(flags, name) \
28246+ do { (flags) |= AuRdu_##name; } while (0)
28247+#define au_fclr_rdu(flags, name) \
28248+ do { (flags) &= ~AuRdu_##name; } while (0)
1308ab2a 28249+
28250+struct au_rdu_arg {
392086de 28251+ struct dir_context ctx;
1308ab2a 28252+ struct aufs_rdu *rdu;
28253+ union au_rdu_ent_ul ent;
28254+ unsigned long end;
28255+
28256+ struct super_block *sb;
28257+ int err;
28258+};
28259+
392086de 28260+static int au_rdu_fill(struct dir_context *ctx, const char *name, int nlen,
1308ab2a 28261+ loff_t offset, u64 h_ino, unsigned int d_type)
28262+{
28263+ int err, len;
392086de 28264+ struct au_rdu_arg *arg = container_of(ctx, struct au_rdu_arg, ctx);
1308ab2a 28265+ struct aufs_rdu *rdu = arg->rdu;
28266+ struct au_rdu_ent ent;
28267+
28268+ err = 0;
28269+ arg->err = 0;
28270+ au_fset_rdu(rdu->cookie.flags, CALLED);
28271+ len = au_rdu_len(nlen);
28272+ if (arg->ent.ul + len < arg->end) {
28273+ ent.ino = h_ino;
28274+ ent.bindex = rdu->cookie.bindex;
28275+ ent.type = d_type;
28276+ ent.nlen = nlen;
4a4d8108
AM
28277+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
28278+ ent.type = DT_UNKNOWN;
1308ab2a 28279+
9dbd164d 28280+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 28281+ err = -EFAULT;
28282+ if (copy_to_user(arg->ent.e, &ent, sizeof(ent)))
28283+ goto out;
28284+ if (copy_to_user(arg->ent.e->name, name, nlen))
28285+ goto out;
28286+ /* the terminating NULL */
28287+ if (__put_user(0, arg->ent.e->name + nlen))
28288+ goto out;
28289+ err = 0;
28290+ /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */
28291+ arg->ent.ul += len;
28292+ rdu->rent++;
28293+ } else {
28294+ err = -EFAULT;
28295+ au_fset_rdu(rdu->cookie.flags, FULL);
28296+ rdu->full = 1;
28297+ rdu->tail = arg->ent;
28298+ }
28299+
4f0767ce 28300+out:
1308ab2a 28301+ /* AuTraceErr(err); */
28302+ return err;
28303+}
28304+
28305+static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg)
28306+{
28307+ int err;
28308+ loff_t offset;
28309+ struct au_rdu_cookie *cookie = &arg->rdu->cookie;
28310+
92d182d2 28311+ /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */
1308ab2a 28312+ offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET);
28313+ err = offset;
28314+ if (unlikely(offset != cookie->h_pos))
28315+ goto out;
28316+
28317+ err = 0;
28318+ do {
28319+ arg->err = 0;
28320+ au_fclr_rdu(cookie->flags, CALLED);
28321+ /* smp_mb(); */
392086de 28322+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1308ab2a 28323+ if (err >= 0)
28324+ err = arg->err;
28325+ } while (!err
28326+ && au_ftest_rdu(cookie->flags, CALLED)
28327+ && !au_ftest_rdu(cookie->flags, FULL));
28328+ cookie->h_pos = h_file->f_pos;
28329+
4f0767ce 28330+out:
1308ab2a 28331+ AuTraceErr(err);
28332+ return err;
28333+}
28334+
28335+static int au_rdu(struct file *file, struct aufs_rdu *rdu)
28336+{
28337+ int err;
5afbbe0d 28338+ aufs_bindex_t bbot;
392086de
AM
28339+ struct au_rdu_arg arg = {
28340+ .ctx = {
2000de60 28341+ .actor = au_rdu_fill
392086de
AM
28342+ }
28343+ };
1308ab2a 28344+ struct dentry *dentry;
28345+ struct inode *inode;
28346+ struct file *h_file;
28347+ struct au_rdu_cookie *cookie = &rdu->cookie;
28348+
28349+ err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz);
28350+ if (unlikely(err)) {
28351+ err = -EFAULT;
28352+ AuTraceErr(err);
28353+ goto out;
28354+ }
28355+ rdu->rent = 0;
28356+ rdu->tail = rdu->ent;
28357+ rdu->full = 0;
28358+ arg.rdu = rdu;
28359+ arg.ent = rdu->ent;
28360+ arg.end = arg.ent.ul;
28361+ arg.end += rdu->sz;
28362+
28363+ err = -ENOTDIR;
5afbbe0d 28364+ if (unlikely(!file->f_op->iterate && !file->f_op->iterate_shared))
1308ab2a 28365+ goto out;
28366+
28367+ err = security_file_permission(file, MAY_READ);
28368+ AuTraceErr(err);
28369+ if (unlikely(err))
28370+ goto out;
28371+
2000de60 28372+ dentry = file->f_path.dentry;
5527c038 28373+ inode = d_inode(dentry);
5afbbe0d 28374+ inode_lock_shared(inode);
1308ab2a 28375+
28376+ arg.sb = inode->i_sb;
e49829fe
JR
28377+ err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM);
28378+ if (unlikely(err))
28379+ goto out_mtx;
027c5e7a
AM
28380+ err = au_alive_dir(dentry);
28381+ if (unlikely(err))
28382+ goto out_si;
e49829fe 28383+ /* todo: reval? */
1308ab2a 28384+ fi_read_lock(file);
28385+
28386+ err = -EAGAIN;
28387+ if (unlikely(au_ftest_rdu(cookie->flags, CONT)
28388+ && cookie->generation != au_figen(file)))
28389+ goto out_unlock;
28390+
28391+ err = 0;
28392+ if (!rdu->blk) {
28393+ rdu->blk = au_sbi(arg.sb)->si_rdblk;
28394+ if (!rdu->blk)
28395+ rdu->blk = au_dir_size(file, /*dentry*/NULL);
28396+ }
5afbbe0d
AM
28397+ bbot = au_fbtop(file);
28398+ if (cookie->bindex < bbot)
28399+ cookie->bindex = bbot;
28400+ bbot = au_fbbot_dir(file);
28401+ /* AuDbg("b%d, b%d\n", cookie->bindex, bbot); */
28402+ for (; !err && cookie->bindex <= bbot;
1308ab2a 28403+ cookie->bindex++, cookie->h_pos = 0) {
4a4d8108 28404+ h_file = au_hf_dir(file, cookie->bindex);
1308ab2a 28405+ if (!h_file)
28406+ continue;
28407+
28408+ au_fclr_rdu(cookie->flags, FULL);
28409+ err = au_rdu_do(h_file, &arg);
28410+ AuTraceErr(err);
28411+ if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err))
28412+ break;
28413+ }
28414+ AuDbg("rent %llu\n", rdu->rent);
28415+
28416+ if (!err && !au_ftest_rdu(cookie->flags, CONT)) {
28417+ rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH);
28418+ au_fset_rdu(cookie->flags, CONT);
28419+ cookie->generation = au_figen(file);
28420+ }
28421+
28422+ ii_read_lock_child(inode);
5afbbe0d 28423+ fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibtop(inode)));
1308ab2a 28424+ ii_read_unlock(inode);
28425+
4f0767ce 28426+out_unlock:
1308ab2a 28427+ fi_read_unlock(file);
027c5e7a 28428+out_si:
1308ab2a 28429+ si_read_unlock(arg.sb);
4f0767ce 28430+out_mtx:
5afbbe0d 28431+ inode_unlock_shared(inode);
4f0767ce 28432+out:
1308ab2a 28433+ AuTraceErr(err);
28434+ return err;
28435+}
28436+
28437+static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu)
28438+{
28439+ int err;
28440+ ino_t ino;
28441+ unsigned long long nent;
28442+ union au_rdu_ent_ul *u;
28443+ struct au_rdu_ent ent;
28444+ struct super_block *sb;
28445+
28446+ err = 0;
28447+ nent = rdu->nent;
28448+ u = &rdu->ent;
2000de60 28449+ sb = file->f_path.dentry->d_sb;
1308ab2a 28450+ si_read_lock(sb, AuLock_FLUSH);
28451+ while (nent-- > 0) {
9dbd164d 28452+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 28453+ err = copy_from_user(&ent, u->e, sizeof(ent));
4a4d8108
AM
28454+ if (!err)
28455+ err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino));
1308ab2a 28456+ if (unlikely(err)) {
28457+ err = -EFAULT;
28458+ AuTraceErr(err);
28459+ break;
28460+ }
28461+
28462+ /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */
28463+ if (!ent.wh)
28464+ err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino);
28465+ else
28466+ err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type,
28467+ &ino);
28468+ if (unlikely(err)) {
28469+ AuTraceErr(err);
28470+ break;
28471+ }
28472+
28473+ err = __put_user(ino, &u->e->ino);
28474+ if (unlikely(err)) {
28475+ err = -EFAULT;
28476+ AuTraceErr(err);
28477+ break;
28478+ }
28479+ u->ul += au_rdu_len(ent.nlen);
28480+ }
28481+ si_read_unlock(sb);
28482+
28483+ return err;
28484+}
28485+
28486+/* ---------------------------------------------------------------------- */
28487+
28488+static int au_rdu_verify(struct aufs_rdu *rdu)
28489+{
b752ccd1 28490+ AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | "
1308ab2a 28491+ "%llu, b%d, 0x%x, g%u}\n",
b752ccd1 28492+ rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ],
1308ab2a 28493+ rdu->blk,
28494+ rdu->rent, rdu->shwh, rdu->full,
28495+ rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags,
28496+ rdu->cookie.generation);
dece6358 28497+
b752ccd1 28498+ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu))
1308ab2a 28499+ return 0;
dece6358 28500+
b752ccd1
AM
28501+ AuDbg("%u:%u\n",
28502+ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu));
1308ab2a 28503+ return -EINVAL;
28504+}
28505+
28506+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
dece6358 28507+{
1308ab2a 28508+ long err, e;
28509+ struct aufs_rdu rdu;
28510+ void __user *p = (void __user *)arg;
dece6358 28511+
1308ab2a 28512+ err = copy_from_user(&rdu, p, sizeof(rdu));
28513+ if (unlikely(err)) {
28514+ err = -EFAULT;
28515+ AuTraceErr(err);
28516+ goto out;
28517+ }
28518+ err = au_rdu_verify(&rdu);
dece6358
AM
28519+ if (unlikely(err))
28520+ goto out;
28521+
1308ab2a 28522+ switch (cmd) {
28523+ case AUFS_CTL_RDU:
28524+ err = au_rdu(file, &rdu);
28525+ if (unlikely(err))
28526+ break;
dece6358 28527+
1308ab2a 28528+ e = copy_to_user(p, &rdu, sizeof(rdu));
28529+ if (unlikely(e)) {
28530+ err = -EFAULT;
28531+ AuTraceErr(err);
28532+ }
28533+ break;
28534+ case AUFS_CTL_RDU_INO:
28535+ err = au_rdu_ino(file, &rdu);
28536+ break;
28537+
28538+ default:
4a4d8108 28539+ /* err = -ENOTTY; */
1308ab2a 28540+ err = -EINVAL;
28541+ }
dece6358 28542+
4f0767ce 28543+out:
1308ab2a 28544+ AuTraceErr(err);
28545+ return err;
1facf9fc 28546+}
b752ccd1
AM
28547+
28548+#ifdef CONFIG_COMPAT
28549+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
28550+{
28551+ long err, e;
28552+ struct aufs_rdu rdu;
28553+ void __user *p = compat_ptr(arg);
28554+
28555+ /* todo: get_user()? */
28556+ err = copy_from_user(&rdu, p, sizeof(rdu));
28557+ if (unlikely(err)) {
28558+ err = -EFAULT;
28559+ AuTraceErr(err);
28560+ goto out;
28561+ }
28562+ rdu.ent.e = compat_ptr(rdu.ent.ul);
28563+ err = au_rdu_verify(&rdu);
28564+ if (unlikely(err))
28565+ goto out;
28566+
28567+ switch (cmd) {
28568+ case AUFS_CTL_RDU:
28569+ err = au_rdu(file, &rdu);
28570+ if (unlikely(err))
28571+ break;
28572+
28573+ rdu.ent.ul = ptr_to_compat(rdu.ent.e);
28574+ rdu.tail.ul = ptr_to_compat(rdu.tail.e);
28575+ e = copy_to_user(p, &rdu, sizeof(rdu));
28576+ if (unlikely(e)) {
28577+ err = -EFAULT;
28578+ AuTraceErr(err);
28579+ }
28580+ break;
28581+ case AUFS_CTL_RDU_INO:
28582+ err = au_rdu_ino(file, &rdu);
28583+ break;
28584+
28585+ default:
28586+ /* err = -ENOTTY; */
28587+ err = -EINVAL;
28588+ }
28589+
4f0767ce 28590+out:
b752ccd1
AM
28591+ AuTraceErr(err);
28592+ return err;
28593+}
28594+#endif
7f207e10
AM
28595diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h
28596--- /usr/share/empty/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 28597+++ linux/fs/aufs/rwsem.h 2018-04-15 08:49:13.404484168 +0200
5afbbe0d 28598@@ -0,0 +1,198 @@
1facf9fc 28599+/*
ae9dfd79 28600+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 28601+ *
28602+ * This program, aufs is free software; you can redistribute it and/or modify
28603+ * it under the terms of the GNU General Public License as published by
28604+ * the Free Software Foundation; either version 2 of the License, or
28605+ * (at your option) any later version.
dece6358
AM
28606+ *
28607+ * This program is distributed in the hope that it will be useful,
28608+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28609+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28610+ * GNU General Public License for more details.
28611+ *
28612+ * You should have received a copy of the GNU General Public License
523b37e3 28613+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28614+ */
28615+
28616+/*
28617+ * simple read-write semaphore wrappers
28618+ */
28619+
28620+#ifndef __AUFS_RWSEM_H__
28621+#define __AUFS_RWSEM_H__
28622+
28623+#ifdef __KERNEL__
28624+
4a4d8108 28625+#include "debug.h"
dece6358
AM
28626+
28627+struct au_rwsem {
28628+ struct rw_semaphore rwsem;
28629+#ifdef CONFIG_AUFS_DEBUG
28630+ /* just for debugging, not almighty counter */
28631+ atomic_t rcnt, wcnt;
28632+#endif
28633+};
28634+
5afbbe0d
AM
28635+#ifdef CONFIG_LOCKDEP
28636+#define au_lockdep_set_name(rw) \
28637+ lockdep_set_class_and_name(&(rw)->rwsem, \
28638+ /*original key*/(rw)->rwsem.dep_map.key, \
28639+ /*name*/#rw)
28640+#else
28641+#define au_lockdep_set_name(rw) do {} while (0)
28642+#endif
28643+
dece6358
AM
28644+#ifdef CONFIG_AUFS_DEBUG
28645+#define AuDbgCntInit(rw) do { \
28646+ atomic_set(&(rw)->rcnt, 0); \
28647+ atomic_set(&(rw)->wcnt, 0); \
28648+ smp_mb(); /* atomic set */ \
28649+} while (0)
28650+
5afbbe0d
AM
28651+#define AuDbgCnt(rw, cnt) atomic_read(&(rw)->cnt)
28652+#define AuDbgCntInc(rw, cnt) atomic_inc(&(rw)->cnt)
28653+#define AuDbgCntDec(rw, cnt) WARN_ON(atomic_dec_return(&(rw)->cnt) < 0)
28654+#define AuDbgRcntInc(rw) AuDbgCntInc(rw, rcnt)
28655+#define AuDbgRcntDec(rw) AuDbgCntDec(rw, rcnt)
28656+#define AuDbgWcntInc(rw) AuDbgCntInc(rw, wcnt)
28657+#define AuDbgWcntDec(rw) AuDbgCntDec(rw, wcnt)
dece6358 28658+#else
5afbbe0d 28659+#define AuDbgCnt(rw, cnt) 0
dece6358
AM
28660+#define AuDbgCntInit(rw) do {} while (0)
28661+#define AuDbgRcntInc(rw) do {} while (0)
28662+#define AuDbgRcntDec(rw) do {} while (0)
28663+#define AuDbgWcntInc(rw) do {} while (0)
28664+#define AuDbgWcntDec(rw) do {} while (0)
28665+#endif /* CONFIG_AUFS_DEBUG */
28666+
28667+/* to debug easier, do not make them inlined functions */
5afbbe0d 28668+#define AuRwMustNoWaiters(rw) AuDebugOn(rwsem_is_contended(&(rw)->rwsem))
dece6358 28669+/* rwsem_is_locked() is unusable */
5afbbe0d
AM
28670+#define AuRwMustReadLock(rw) AuDebugOn(AuDbgCnt(rw, rcnt) <= 0)
28671+#define AuRwMustWriteLock(rw) AuDebugOn(AuDbgCnt(rw, wcnt) <= 0)
28672+#define AuRwMustAnyLock(rw) AuDebugOn(AuDbgCnt(rw, rcnt) <= 0 \
28673+ && AuDbgCnt(rw, wcnt) <= 0)
28674+#define AuRwDestroy(rw) AuDebugOn(AuDbgCnt(rw, rcnt) \
28675+ || AuDbgCnt(rw, wcnt))
28676+
28677+#define au_rw_init(rw) do { \
28678+ AuDbgCntInit(rw); \
28679+ init_rwsem(&(rw)->rwsem); \
28680+ au_lockdep_set_name(rw); \
28681+ } while (0)
dece6358 28682+
5afbbe0d
AM
28683+#define au_rw_init_wlock(rw) do { \
28684+ au_rw_init(rw); \
28685+ down_write(&(rw)->rwsem); \
28686+ AuDbgWcntInc(rw); \
28687+ } while (0)
dece6358 28688+
5afbbe0d
AM
28689+#define au_rw_init_wlock_nested(rw, lsc) do { \
28690+ au_rw_init(rw); \
28691+ down_write_nested(&(rw)->rwsem, lsc); \
28692+ AuDbgWcntInc(rw); \
28693+ } while (0)
dece6358
AM
28694+
28695+static inline void au_rw_read_lock(struct au_rwsem *rw)
28696+{
28697+ down_read(&rw->rwsem);
28698+ AuDbgRcntInc(rw);
28699+}
28700+
28701+static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc)
28702+{
28703+ down_read_nested(&rw->rwsem, lsc);
28704+ AuDbgRcntInc(rw);
28705+}
28706+
28707+static inline void au_rw_read_unlock(struct au_rwsem *rw)
28708+{
28709+ AuRwMustReadLock(rw);
28710+ AuDbgRcntDec(rw);
28711+ up_read(&rw->rwsem);
28712+}
28713+
28714+static inline void au_rw_dgrade_lock(struct au_rwsem *rw)
28715+{
28716+ AuRwMustWriteLock(rw);
28717+ AuDbgRcntInc(rw);
28718+ AuDbgWcntDec(rw);
28719+ downgrade_write(&rw->rwsem);
28720+}
28721+
28722+static inline void au_rw_write_lock(struct au_rwsem *rw)
28723+{
28724+ down_write(&rw->rwsem);
28725+ AuDbgWcntInc(rw);
28726+}
28727+
28728+static inline void au_rw_write_lock_nested(struct au_rwsem *rw,
28729+ unsigned int lsc)
28730+{
28731+ down_write_nested(&rw->rwsem, lsc);
28732+ AuDbgWcntInc(rw);
28733+}
1facf9fc 28734+
dece6358
AM
28735+static inline void au_rw_write_unlock(struct au_rwsem *rw)
28736+{
28737+ AuRwMustWriteLock(rw);
28738+ AuDbgWcntDec(rw);
28739+ up_write(&rw->rwsem);
28740+}
28741+
28742+/* why is not _nested version defined */
28743+static inline int au_rw_read_trylock(struct au_rwsem *rw)
28744+{
076b876e
AM
28745+ int ret;
28746+
28747+ ret = down_read_trylock(&rw->rwsem);
dece6358
AM
28748+ if (ret)
28749+ AuDbgRcntInc(rw);
28750+ return ret;
28751+}
28752+
28753+static inline int au_rw_write_trylock(struct au_rwsem *rw)
28754+{
076b876e
AM
28755+ int ret;
28756+
28757+ ret = down_write_trylock(&rw->rwsem);
dece6358
AM
28758+ if (ret)
28759+ AuDbgWcntInc(rw);
28760+ return ret;
28761+}
28762+
5afbbe0d 28763+#undef AuDbgCntDec
dece6358
AM
28764+#undef AuDbgRcntInc
28765+#undef AuDbgRcntDec
dece6358 28766+#undef AuDbgWcntDec
1facf9fc 28767+
28768+#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
28769+static inline void prefix##_read_lock(param) \
dece6358 28770+{ au_rw_read_lock(rwsem); } \
1facf9fc 28771+static inline void prefix##_write_lock(param) \
dece6358 28772+{ au_rw_write_lock(rwsem); } \
1facf9fc 28773+static inline int prefix##_read_trylock(param) \
dece6358 28774+{ return au_rw_read_trylock(rwsem); } \
1facf9fc 28775+static inline int prefix##_write_trylock(param) \
dece6358 28776+{ return au_rw_write_trylock(rwsem); }
1facf9fc 28777+/* why is not _nested version defined */
28778+/* static inline void prefix##_read_trylock_nested(param, lsc)
dece6358 28779+{ au_rw_read_trylock_nested(rwsem, lsc)); }
1facf9fc 28780+static inline void prefix##_write_trylock_nestd(param, lsc)
dece6358 28781+{ au_rw_write_trylock_nested(rwsem, lsc); } */
1facf9fc 28782+
28783+#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
28784+static inline void prefix##_read_unlock(param) \
dece6358 28785+{ au_rw_read_unlock(rwsem); } \
1facf9fc 28786+static inline void prefix##_write_unlock(param) \
dece6358 28787+{ au_rw_write_unlock(rwsem); } \
1facf9fc 28788+static inline void prefix##_downgrade_lock(param) \
dece6358 28789+{ au_rw_dgrade_lock(rwsem); }
1facf9fc 28790+
28791+#define AuSimpleRwsemFuncs(prefix, param, rwsem) \
28792+ AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
28793+ AuSimpleUnlockRwsemFuncs(prefix, param, rwsem)
28794+
28795+#endif /* __KERNEL__ */
28796+#endif /* __AUFS_RWSEM_H__ */
7f207e10
AM
28797diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
28798--- /usr/share/empty/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
28799+++ linux/fs/aufs/sbinfo.c 2018-04-15 08:49:13.404484168 +0200
28800@@ -0,0 +1,304 @@
1facf9fc 28801+/*
ae9dfd79 28802+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 28803+ *
28804+ * This program, aufs is free software; you can redistribute it and/or modify
28805+ * it under the terms of the GNU General Public License as published by
28806+ * the Free Software Foundation; either version 2 of the License, or
28807+ * (at your option) any later version.
dece6358
AM
28808+ *
28809+ * This program is distributed in the hope that it will be useful,
28810+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28811+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28812+ * GNU General Public License for more details.
28813+ *
28814+ * You should have received a copy of the GNU General Public License
523b37e3 28815+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28816+ */
28817+
28818+/*
28819+ * superblock private data
28820+ */
28821+
28822+#include "aufs.h"
28823+
28824+/*
28825+ * they are necessary regardless sysfs is disabled.
28826+ */
28827+void au_si_free(struct kobject *kobj)
28828+{
86dc4139 28829+ int i;
1facf9fc 28830+ struct au_sbinfo *sbinfo;
b752ccd1 28831+ char *locked __maybe_unused; /* debug only */
1facf9fc 28832+
28833+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
86dc4139 28834+ for (i = 0; i < AuPlink_NHASH; i++)
ae9dfd79 28835+ AuDebugOn(!hlist_bl_empty(sbinfo->si_plink + i));
f0c0a007 28836+ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
5afbbe0d
AM
28837+
28838+ AuDebugOn(percpu_counter_sum(&sbinfo->si_ninodes));
28839+ percpu_counter_destroy(&sbinfo->si_ninodes);
28840+ AuDebugOn(percpu_counter_sum(&sbinfo->si_nfiles));
28841+ percpu_counter_destroy(&sbinfo->si_nfiles);
1facf9fc 28842+
e49829fe 28843+ au_rw_write_lock(&sbinfo->si_rwsem);
1facf9fc 28844+ au_br_free(sbinfo);
e49829fe 28845+ au_rw_write_unlock(&sbinfo->si_rwsem);
b752ccd1 28846+
ae9dfd79 28847+ kfree(sbinfo->si_branch);
1facf9fc 28848+ mutex_destroy(&sbinfo->si_xib_mtx);
dece6358 28849+ AuRwDestroy(&sbinfo->si_rwsem);
1facf9fc 28850+
ae9dfd79 28851+ kfree(sbinfo);
1facf9fc 28852+}
28853+
28854+int au_si_alloc(struct super_block *sb)
28855+{
86dc4139 28856+ int err, i;
1facf9fc 28857+ struct au_sbinfo *sbinfo;
28858+
28859+ err = -ENOMEM;
4a4d8108 28860+ sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS);
1facf9fc 28861+ if (unlikely(!sbinfo))
28862+ goto out;
28863+
28864+ /* will be reallocated separately */
28865+ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
28866+ if (unlikely(!sbinfo->si_branch))
febd17d6 28867+ goto out_sbinfo;
1facf9fc 28868+
1facf9fc 28869+ err = sysaufs_si_init(sbinfo);
28870+ if (unlikely(err))
28871+ goto out_br;
28872+
28873+ au_nwt_init(&sbinfo->si_nowait);
dece6358 28874+ au_rw_init_wlock(&sbinfo->si_rwsem);
b752ccd1 28875+
5afbbe0d
AM
28876+ percpu_counter_init(&sbinfo->si_ninodes, 0, GFP_NOFS);
28877+ percpu_counter_init(&sbinfo->si_nfiles, 0, GFP_NOFS);
7f207e10 28878+
5afbbe0d 28879+ sbinfo->si_bbot = -1;
392086de 28880+ sbinfo->si_last_br_id = AUFS_BRANCH_MAX / 2;
1facf9fc 28881+
28882+ sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
28883+ sbinfo->si_wbr_create = AuWbrCreate_Def;
4a4d8108
AM
28884+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup;
28885+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create;
1facf9fc 28886+
076b876e
AM
28887+ au_fhsm_init(sbinfo);
28888+
e49829fe 28889+ sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
1facf9fc 28890+
392086de
AM
28891+ sbinfo->si_xino_jiffy = jiffies;
28892+ sbinfo->si_xino_expire
28893+ = msecs_to_jiffies(AUFS_XINO_DEF_SEC * MSEC_PER_SEC);
1facf9fc 28894+ mutex_init(&sbinfo->si_xib_mtx);
1facf9fc 28895+ sbinfo->si_xino_brid = -1;
28896+ /* leave si_xib_last_pindex and si_xib_next_bit */
28897+
ae9dfd79 28898+ INIT_HLIST_BL_HEAD(&sbinfo->si_aopen);
b912730e 28899+
e49829fe 28900+ sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
1facf9fc 28901+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
28902+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
28903+ sbinfo->si_dirwh = AUFS_DIRWH_DEF;
28904+
86dc4139 28905+ for (i = 0; i < AuPlink_NHASH; i++)
ae9dfd79 28906+ INIT_HLIST_BL_HEAD(sbinfo->si_plink + i);
1facf9fc 28907+ init_waitqueue_head(&sbinfo->si_plink_wq);
4a4d8108 28908+ spin_lock_init(&sbinfo->si_plink_maint_lock);
1facf9fc 28909+
ae9dfd79 28910+ INIT_HLIST_BL_HEAD(&sbinfo->si_files);
523b37e3 28911+
b95c5147
AM
28912+ /* with getattr by default */
28913+ sbinfo->si_iop_array = aufs_iop;
28914+
1facf9fc 28915+ /* leave other members for sysaufs and si_mnt. */
28916+ sbinfo->si_sb = sb;
28917+ sb->s_fs_info = sbinfo;
b752ccd1 28918+ si_pid_set(sb);
1facf9fc 28919+ return 0; /* success */
28920+
4f0767ce 28921+out_br:
ae9dfd79 28922+ kfree(sbinfo->si_branch);
4f0767ce 28923+out_sbinfo:
ae9dfd79 28924+ kfree(sbinfo);
4f0767ce 28925+out:
1facf9fc 28926+ return err;
28927+}
28928+
e2f27e51 28929+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink)
1facf9fc 28930+{
28931+ int err, sz;
28932+ struct au_branch **brp;
28933+
dece6358
AM
28934+ AuRwMustWriteLock(&sbinfo->si_rwsem);
28935+
1facf9fc 28936+ err = -ENOMEM;
5afbbe0d 28937+ sz = sizeof(*brp) * (sbinfo->si_bbot + 1);
1facf9fc 28938+ if (unlikely(!sz))
28939+ sz = sizeof(*brp);
e2f27e51
AM
28940+ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS,
28941+ may_shrink);
1facf9fc 28942+ if (brp) {
28943+ sbinfo->si_branch = brp;
28944+ err = 0;
28945+ }
28946+
28947+ return err;
28948+}
28949+
28950+/* ---------------------------------------------------------------------- */
28951+
28952+unsigned int au_sigen_inc(struct super_block *sb)
28953+{
28954+ unsigned int gen;
5527c038 28955+ struct inode *inode;
1facf9fc 28956+
dece6358
AM
28957+ SiMustWriteLock(sb);
28958+
1facf9fc 28959+ gen = ++au_sbi(sb)->si_generation;
28960+ au_update_digen(sb->s_root);
5527c038
JR
28961+ inode = d_inode(sb->s_root);
28962+ au_update_iigen(inode, /*half*/0);
28963+ inode->i_version++;
1facf9fc 28964+ return gen;
28965+}
28966+
28967+aufs_bindex_t au_new_br_id(struct super_block *sb)
28968+{
28969+ aufs_bindex_t br_id;
28970+ int i;
28971+ struct au_sbinfo *sbinfo;
28972+
dece6358
AM
28973+ SiMustWriteLock(sb);
28974+
1facf9fc 28975+ sbinfo = au_sbi(sb);
28976+ for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
28977+ br_id = ++sbinfo->si_last_br_id;
7f207e10 28978+ AuDebugOn(br_id < 0);
1facf9fc 28979+ if (br_id && au_br_index(sb, br_id) < 0)
28980+ return br_id;
28981+ }
28982+
28983+ return -1;
28984+}
28985+
28986+/* ---------------------------------------------------------------------- */
28987+
e49829fe
JR
28988+/* it is ok that new 'nwt' tasks are appended while we are sleeping */
28989+int si_read_lock(struct super_block *sb, int flags)
28990+{
28991+ int err;
28992+
28993+ err = 0;
28994+ if (au_ftest_lock(flags, FLUSH))
28995+ au_nwt_flush(&au_sbi(sb)->si_nowait);
28996+
28997+ si_noflush_read_lock(sb);
28998+ err = au_plink_maint(sb, flags);
28999+ if (unlikely(err))
29000+ si_read_unlock(sb);
29001+
29002+ return err;
29003+}
29004+
29005+int si_write_lock(struct super_block *sb, int flags)
29006+{
29007+ int err;
29008+
29009+ if (au_ftest_lock(flags, FLUSH))
29010+ au_nwt_flush(&au_sbi(sb)->si_nowait);
29011+
29012+ si_noflush_write_lock(sb);
29013+ err = au_plink_maint(sb, flags);
29014+ if (unlikely(err))
29015+ si_write_unlock(sb);
29016+
29017+ return err;
29018+}
29019+
1facf9fc 29020+/* dentry and super_block lock. call at entry point */
e49829fe 29021+int aufs_read_lock(struct dentry *dentry, int flags)
1facf9fc 29022+{
e49829fe 29023+ int err;
027c5e7a 29024+ struct super_block *sb;
e49829fe 29025+
027c5e7a
AM
29026+ sb = dentry->d_sb;
29027+ err = si_read_lock(sb, flags);
29028+ if (unlikely(err))
29029+ goto out;
29030+
29031+ if (au_ftest_lock(flags, DW))
29032+ di_write_lock_child(dentry);
29033+ else
29034+ di_read_lock_child(dentry, flags);
29035+
29036+ if (au_ftest_lock(flags, GEN)) {
29037+ err = au_digen_test(dentry, au_sigen(sb));
79b8bda9
AM
29038+ if (!au_opt_test(au_mntflags(sb), UDBA_NONE))
29039+ AuDebugOn(!err && au_dbrange_test(dentry));
29040+ else if (!err)
29041+ err = au_dbrange_test(dentry);
027c5e7a
AM
29042+ if (unlikely(err))
29043+ aufs_read_unlock(dentry, flags);
e49829fe
JR
29044+ }
29045+
027c5e7a 29046+out:
e49829fe 29047+ return err;
1facf9fc 29048+}
29049+
29050+void aufs_read_unlock(struct dentry *dentry, int flags)
29051+{
29052+ if (au_ftest_lock(flags, DW))
29053+ di_write_unlock(dentry);
29054+ else
29055+ di_read_unlock(dentry, flags);
29056+ si_read_unlock(dentry->d_sb);
29057+}
29058+
29059+void aufs_write_lock(struct dentry *dentry)
29060+{
e49829fe 29061+ si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW);
1facf9fc 29062+ di_write_lock_child(dentry);
29063+}
29064+
29065+void aufs_write_unlock(struct dentry *dentry)
29066+{
29067+ di_write_unlock(dentry);
29068+ si_write_unlock(dentry->d_sb);
29069+}
29070+
e49829fe 29071+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
1facf9fc 29072+{
e49829fe 29073+ int err;
027c5e7a
AM
29074+ unsigned int sigen;
29075+ struct super_block *sb;
e49829fe 29076+
027c5e7a
AM
29077+ sb = d1->d_sb;
29078+ err = si_read_lock(sb, flags);
29079+ if (unlikely(err))
29080+ goto out;
29081+
b95c5147 29082+ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIRS));
027c5e7a
AM
29083+
29084+ if (au_ftest_lock(flags, GEN)) {
29085+ sigen = au_sigen(sb);
29086+ err = au_digen_test(d1, sigen);
29087+ AuDebugOn(!err && au_dbrange_test(d1));
29088+ if (!err) {
29089+ err = au_digen_test(d2, sigen);
29090+ AuDebugOn(!err && au_dbrange_test(d2));
29091+ }
29092+ if (unlikely(err))
29093+ aufs_read_and_write_unlock2(d1, d2);
29094+ }
29095+
29096+out:
e49829fe 29097+ return err;
1facf9fc 29098+}
29099+
29100+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
29101+{
29102+ di_write_unlock2(d1, d2);
29103+ si_read_unlock(d1->d_sb);
29104+}
7f207e10
AM
29105diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
29106--- /usr/share/empty/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 29107+++ linux/fs/aufs/super.c 2018-04-15 08:49:13.404484168 +0200
f2c43d5f 29108@@ -0,0 +1,1046 @@
1facf9fc 29109+/*
ae9dfd79 29110+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 29111+ *
29112+ * This program, aufs is free software; you can redistribute it and/or modify
29113+ * it under the terms of the GNU General Public License as published by
29114+ * the Free Software Foundation; either version 2 of the License, or
29115+ * (at your option) any later version.
dece6358
AM
29116+ *
29117+ * This program is distributed in the hope that it will be useful,
29118+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29119+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29120+ * GNU General Public License for more details.
29121+ *
29122+ * You should have received a copy of the GNU General Public License
523b37e3 29123+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 29124+ */
29125+
29126+/*
29127+ * mount and super_block operations
29128+ */
29129+
f6c5ef8b 29130+#include <linux/mm.h>
1facf9fc 29131+#include <linux/seq_file.h>
29132+#include <linux/statfs.h>
7f207e10 29133+#include <linux/vmalloc.h>
1facf9fc 29134+#include "aufs.h"
29135+
29136+/*
29137+ * super_operations
29138+ */
29139+static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
29140+{
29141+ struct au_icntnr *c;
29142+
29143+ c = au_cache_alloc_icntnr();
29144+ if (c) {
027c5e7a 29145+ au_icntnr_init(c);
1facf9fc 29146+ c->vfs_inode.i_version = 1; /* sigen(sb); */
29147+ c->iinfo.ii_hinode = NULL;
29148+ return &c->vfs_inode;
29149+ }
29150+ return NULL;
29151+}
29152+
027c5e7a
AM
29153+static void aufs_destroy_inode_cb(struct rcu_head *head)
29154+{
29155+ struct inode *inode = container_of(head, struct inode, i_rcu);
29156+
ae9dfd79 29157+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
027c5e7a
AM
29158+}
29159+
1facf9fc 29160+static void aufs_destroy_inode(struct inode *inode)
29161+{
5afbbe0d
AM
29162+ if (!au_is_bad_inode(inode))
29163+ au_iinfo_fin(inode);
027c5e7a 29164+ call_rcu(&inode->i_rcu, aufs_destroy_inode_cb);
1facf9fc 29165+}
29166+
29167+struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
29168+{
29169+ struct inode *inode;
29170+ int err;
29171+
29172+ inode = iget_locked(sb, ino);
29173+ if (unlikely(!inode)) {
29174+ inode = ERR_PTR(-ENOMEM);
29175+ goto out;
29176+ }
29177+ if (!(inode->i_state & I_NEW))
29178+ goto out;
29179+
29180+ err = au_xigen_new(inode);
29181+ if (!err)
29182+ err = au_iinfo_init(inode);
29183+ if (!err)
29184+ inode->i_version++;
29185+ else {
29186+ iget_failed(inode);
29187+ inode = ERR_PTR(err);
29188+ }
29189+
4f0767ce 29190+out:
1facf9fc 29191+ /* never return NULL */
29192+ AuDebugOn(!inode);
29193+ AuTraceErrPtr(inode);
29194+ return inode;
29195+}
29196+
29197+/* lock free root dinfo */
29198+static int au_show_brs(struct seq_file *seq, struct super_block *sb)
29199+{
29200+ int err;
5afbbe0d 29201+ aufs_bindex_t bindex, bbot;
1facf9fc 29202+ struct path path;
4a4d8108 29203+ struct au_hdentry *hdp;
1facf9fc 29204+ struct au_branch *br;
076b876e 29205+ au_br_perm_str_t perm;
1facf9fc 29206+
29207+ err = 0;
5afbbe0d
AM
29208+ bbot = au_sbbot(sb);
29209+ bindex = 0;
29210+ hdp = au_hdentry(au_di(sb->s_root), bindex);
29211+ for (; !err && bindex <= bbot; bindex++, hdp++) {
1facf9fc 29212+ br = au_sbr(sb, bindex);
86dc4139 29213+ path.mnt = au_br_mnt(br);
5afbbe0d 29214+ path.dentry = hdp->hd_dentry;
1facf9fc 29215+ err = au_seq_path(seq, &path);
79b8bda9 29216+ if (!err) {
076b876e 29217+ au_optstr_br_perm(&perm, br->br_perm);
79b8bda9 29218+ seq_printf(seq, "=%s", perm.a);
5afbbe0d 29219+ if (bindex != bbot)
79b8bda9 29220+ seq_putc(seq, ':');
1e00d052 29221+ }
1facf9fc 29222+ }
79b8bda9
AM
29223+ if (unlikely(err || seq_has_overflowed(seq)))
29224+ err = -E2BIG;
1facf9fc 29225+
29226+ return err;
29227+}
29228+
f2c43d5f
AM
29229+static void au_gen_fmt(char *fmt, int len __maybe_unused, const char *pat,
29230+ const char *append)
29231+{
29232+ char *p;
29233+
29234+ p = fmt;
29235+ while (*pat != ':')
29236+ *p++ = *pat++;
29237+ *p++ = *pat++;
29238+ strcpy(p, append);
29239+ AuDebugOn(strlen(fmt) >= len);
29240+}
29241+
1facf9fc 29242+static void au_show_wbr_create(struct seq_file *m, int v,
29243+ struct au_sbinfo *sbinfo)
29244+{
29245+ const char *pat;
f2c43d5f
AM
29246+ char fmt[32];
29247+ struct au_wbr_mfs *mfs;
1facf9fc 29248+
dece6358
AM
29249+ AuRwMustAnyLock(&sbinfo->si_rwsem);
29250+
c2b27bf2 29251+ seq_puts(m, ",create=");
1facf9fc 29252+ pat = au_optstr_wbr_create(v);
f2c43d5f 29253+ mfs = &sbinfo->si_wbr_mfs;
1facf9fc 29254+ switch (v) {
29255+ case AuWbrCreate_TDP:
29256+ case AuWbrCreate_RR:
29257+ case AuWbrCreate_MFS:
29258+ case AuWbrCreate_PMFS:
c2b27bf2 29259+ seq_puts(m, pat);
1facf9fc 29260+ break;
f2c43d5f
AM
29261+ case AuWbrCreate_MFSRR:
29262+ case AuWbrCreate_TDMFS:
29263+ case AuWbrCreate_PMFSRR:
29264+ au_gen_fmt(fmt, sizeof(fmt), pat, "%llu");
29265+ seq_printf(m, fmt, mfs->mfsrr_watermark);
1facf9fc 29266+ break;
f2c43d5f 29267+ case AuWbrCreate_MFSV:
1facf9fc 29268+ case AuWbrCreate_PMFSV:
f2c43d5f
AM
29269+ au_gen_fmt(fmt, sizeof(fmt), pat, "%lu");
29270+ seq_printf(m, fmt,
29271+ jiffies_to_msecs(mfs->mfs_expire)
e49829fe 29272+ / MSEC_PER_SEC);
1facf9fc 29273+ break;
1facf9fc 29274+ case AuWbrCreate_MFSRRV:
f2c43d5f 29275+ case AuWbrCreate_TDMFSV:
392086de 29276+ case AuWbrCreate_PMFSRRV:
f2c43d5f
AM
29277+ au_gen_fmt(fmt, sizeof(fmt), pat, "%llu:%lu");
29278+ seq_printf(m, fmt, mfs->mfsrr_watermark,
29279+ jiffies_to_msecs(mfs->mfs_expire) / MSEC_PER_SEC);
392086de 29280+ break;
f2c43d5f
AM
29281+ default:
29282+ BUG();
1facf9fc 29283+ }
29284+}
29285+
7eafdf33 29286+static int au_show_xino(struct seq_file *seq, struct super_block *sb)
1facf9fc 29287+{
29288+#ifdef CONFIG_SYSFS
29289+ return 0;
29290+#else
29291+ int err;
29292+ const int len = sizeof(AUFS_XINO_FNAME) - 1;
29293+ aufs_bindex_t bindex, brid;
1facf9fc 29294+ struct qstr *name;
29295+ struct file *f;
29296+ struct dentry *d, *h_root;
29297+
dece6358
AM
29298+ AuRwMustAnyLock(&sbinfo->si_rwsem);
29299+
1facf9fc 29300+ err = 0;
1facf9fc 29301+ f = au_sbi(sb)->si_xib;
29302+ if (!f)
29303+ goto out;
29304+
29305+ /* stop printing the default xino path on the first writable branch */
29306+ h_root = NULL;
29307+ brid = au_xino_brid(sb);
29308+ if (brid >= 0) {
29309+ bindex = au_br_index(sb, brid);
5afbbe0d 29310+ h_root = au_hdentry(au_di(sb->s_root), bindex)->hd_dentry;
1facf9fc 29311+ }
2000de60 29312+ d = f->f_path.dentry;
1facf9fc 29313+ name = &d->d_name;
29314+ /* safe ->d_parent because the file is unlinked */
29315+ if (d->d_parent == h_root
29316+ && name->len == len
29317+ && !memcmp(name->name, AUFS_XINO_FNAME, len))
29318+ goto out;
29319+
29320+ seq_puts(seq, ",xino=");
29321+ err = au_xino_path(seq, f);
29322+
4f0767ce 29323+out:
1facf9fc 29324+ return err;
29325+#endif
29326+}
29327+
29328+/* seq_file will re-call me in case of too long string */
7eafdf33 29329+static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
1facf9fc 29330+{
027c5e7a 29331+ int err;
1facf9fc 29332+ unsigned int mnt_flags, v;
29333+ struct super_block *sb;
29334+ struct au_sbinfo *sbinfo;
29335+
29336+#define AuBool(name, str) do { \
29337+ v = au_opt_test(mnt_flags, name); \
29338+ if (v != au_opt_test(AuOpt_Def, name)) \
29339+ seq_printf(m, ",%s" #str, v ? "" : "no"); \
29340+} while (0)
29341+
29342+#define AuStr(name, str) do { \
29343+ v = mnt_flags & AuOptMask_##name; \
29344+ if (v != (AuOpt_Def & AuOptMask_##name)) \
29345+ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
29346+} while (0)
29347+
29348+#define AuUInt(name, str, val) do { \
29349+ if (val != AUFS_##name##_DEF) \
29350+ seq_printf(m, "," #str "=%u", val); \
29351+} while (0)
29352+
7eafdf33 29353+ sb = dentry->d_sb;
c1595e42
JR
29354+ if (sb->s_flags & MS_POSIXACL)
29355+ seq_puts(m, ",acl");
29356+
29357+ /* lock free root dinfo */
1facf9fc 29358+ si_noflush_read_lock(sb);
29359+ sbinfo = au_sbi(sb);
29360+ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
29361+
29362+ mnt_flags = au_mntflags(sb);
29363+ if (au_opt_test(mnt_flags, XINO)) {
7eafdf33 29364+ err = au_show_xino(m, sb);
1facf9fc 29365+ if (unlikely(err))
29366+ goto out;
29367+ } else
29368+ seq_puts(m, ",noxino");
29369+
29370+ AuBool(TRUNC_XINO, trunc_xino);
29371+ AuStr(UDBA, udba);
dece6358 29372+ AuBool(SHWH, shwh);
1facf9fc 29373+ AuBool(PLINK, plink);
4a4d8108 29374+ AuBool(DIO, dio);
076b876e 29375+ AuBool(DIRPERM1, dirperm1);
1facf9fc 29376+
29377+ v = sbinfo->si_wbr_create;
29378+ if (v != AuWbrCreate_Def)
29379+ au_show_wbr_create(m, v, sbinfo);
29380+
29381+ v = sbinfo->si_wbr_copyup;
29382+ if (v != AuWbrCopyup_Def)
29383+ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
29384+
29385+ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
29386+ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
29387+ seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
29388+
29389+ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
29390+
027c5e7a
AM
29391+ v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC;
29392+ AuUInt(RDCACHE, rdcache, v);
1facf9fc 29393+
29394+ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
29395+ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
29396+
076b876e
AM
29397+ au_fhsm_show(m, sbinfo);
29398+
ae9dfd79 29399+ AuBool(DIRREN, dirren);
1facf9fc 29400+ AuBool(SUM, sum);
29401+ /* AuBool(SUM_W, wsum); */
29402+ AuBool(WARN_PERM, warn_perm);
29403+ AuBool(VERBOSE, verbose);
29404+
4f0767ce 29405+out:
1facf9fc 29406+ /* be sure to print "br:" last */
29407+ if (!sysaufs_brs) {
29408+ seq_puts(m, ",br:");
29409+ au_show_brs(m, sb);
29410+ }
29411+ si_read_unlock(sb);
29412+ return 0;
29413+
1facf9fc 29414+#undef AuBool
29415+#undef AuStr
4a4d8108 29416+#undef AuUInt
1facf9fc 29417+}
29418+
29419+/* ---------------------------------------------------------------------- */
29420+
29421+/* sum mode which returns the summation for statfs(2) */
29422+
29423+static u64 au_add_till_max(u64 a, u64 b)
29424+{
29425+ u64 old;
29426+
29427+ old = a;
29428+ a += b;
92d182d2
AM
29429+ if (old <= a)
29430+ return a;
29431+ return ULLONG_MAX;
29432+}
29433+
29434+static u64 au_mul_till_max(u64 a, long mul)
29435+{
29436+ u64 old;
29437+
29438+ old = a;
29439+ a *= mul;
29440+ if (old <= a)
1facf9fc 29441+ return a;
29442+ return ULLONG_MAX;
29443+}
29444+
29445+static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
29446+{
29447+ int err;
92d182d2 29448+ long bsize, factor;
1facf9fc 29449+ u64 blocks, bfree, bavail, files, ffree;
5afbbe0d 29450+ aufs_bindex_t bbot, bindex, i;
1facf9fc 29451+ unsigned char shared;
7f207e10 29452+ struct path h_path;
1facf9fc 29453+ struct super_block *h_sb;
29454+
92d182d2
AM
29455+ err = 0;
29456+ bsize = LONG_MAX;
29457+ files = 0;
29458+ ffree = 0;
1facf9fc 29459+ blocks = 0;
29460+ bfree = 0;
29461+ bavail = 0;
5afbbe0d
AM
29462+ bbot = au_sbbot(sb);
29463+ for (bindex = 0; bindex <= bbot; bindex++) {
7f207e10
AM
29464+ h_path.mnt = au_sbr_mnt(sb, bindex);
29465+ h_sb = h_path.mnt->mnt_sb;
1facf9fc 29466+ shared = 0;
92d182d2 29467+ for (i = 0; !shared && i < bindex; i++)
1facf9fc 29468+ shared = (au_sbr_sb(sb, i) == h_sb);
29469+ if (shared)
29470+ continue;
29471+
29472+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
29473+ h_path.dentry = h_path.mnt->mnt_root;
29474+ err = vfs_statfs(&h_path, buf);
1facf9fc 29475+ if (unlikely(err))
29476+ goto out;
29477+
92d182d2
AM
29478+ if (bsize > buf->f_bsize) {
29479+ /*
29480+ * we will reduce bsize, so we have to expand blocks
29481+ * etc. to match them again
29482+ */
29483+ factor = (bsize / buf->f_bsize);
29484+ blocks = au_mul_till_max(blocks, factor);
29485+ bfree = au_mul_till_max(bfree, factor);
29486+ bavail = au_mul_till_max(bavail, factor);
29487+ bsize = buf->f_bsize;
29488+ }
29489+
29490+ factor = (buf->f_bsize / bsize);
29491+ blocks = au_add_till_max(blocks,
29492+ au_mul_till_max(buf->f_blocks, factor));
29493+ bfree = au_add_till_max(bfree,
29494+ au_mul_till_max(buf->f_bfree, factor));
29495+ bavail = au_add_till_max(bavail,
29496+ au_mul_till_max(buf->f_bavail, factor));
1facf9fc 29497+ files = au_add_till_max(files, buf->f_files);
29498+ ffree = au_add_till_max(ffree, buf->f_ffree);
29499+ }
29500+
92d182d2 29501+ buf->f_bsize = bsize;
1facf9fc 29502+ buf->f_blocks = blocks;
29503+ buf->f_bfree = bfree;
29504+ buf->f_bavail = bavail;
29505+ buf->f_files = files;
29506+ buf->f_ffree = ffree;
92d182d2 29507+ buf->f_frsize = 0;
1facf9fc 29508+
4f0767ce 29509+out:
1facf9fc 29510+ return err;
29511+}
29512+
29513+static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
29514+{
29515+ int err;
7f207e10 29516+ struct path h_path;
1facf9fc 29517+ struct super_block *sb;
29518+
29519+ /* lock free root dinfo */
29520+ sb = dentry->d_sb;
29521+ si_noflush_read_lock(sb);
7f207e10 29522+ if (!au_opt_test(au_mntflags(sb), SUM)) {
1facf9fc 29523+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
29524+ h_path.mnt = au_sbr_mnt(sb, 0);
29525+ h_path.dentry = h_path.mnt->mnt_root;
29526+ err = vfs_statfs(&h_path, buf);
29527+ } else
1facf9fc 29528+ err = au_statfs_sum(sb, buf);
29529+ si_read_unlock(sb);
29530+
29531+ if (!err) {
29532+ buf->f_type = AUFS_SUPER_MAGIC;
4a4d8108 29533+ buf->f_namelen = AUFS_MAX_NAMELEN;
1facf9fc 29534+ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
29535+ }
29536+ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
29537+
29538+ return err;
29539+}
29540+
29541+/* ---------------------------------------------------------------------- */
29542+
537831f9
AM
29543+static int aufs_sync_fs(struct super_block *sb, int wait)
29544+{
29545+ int err, e;
5afbbe0d 29546+ aufs_bindex_t bbot, bindex;
537831f9
AM
29547+ struct au_branch *br;
29548+ struct super_block *h_sb;
29549+
29550+ err = 0;
29551+ si_noflush_read_lock(sb);
5afbbe0d
AM
29552+ bbot = au_sbbot(sb);
29553+ for (bindex = 0; bindex <= bbot; bindex++) {
537831f9
AM
29554+ br = au_sbr(sb, bindex);
29555+ if (!au_br_writable(br->br_perm))
29556+ continue;
29557+
29558+ h_sb = au_sbr_sb(sb, bindex);
ae9dfd79
AM
29559+ e = vfsub_sync_filesystem(h_sb, wait);
29560+ if (unlikely(e && !err))
29561+ err = e;
29562+ /* go on even if an error happens */
537831f9
AM
29563+ }
29564+ si_read_unlock(sb);
29565+
29566+ return err;
29567+}
29568+
29569+/* ---------------------------------------------------------------------- */
29570+
1facf9fc 29571+/* final actions when unmounting a file system */
29572+static void aufs_put_super(struct super_block *sb)
29573+{
29574+ struct au_sbinfo *sbinfo;
29575+
29576+ sbinfo = au_sbi(sb);
29577+ if (!sbinfo)
29578+ return;
29579+
1facf9fc 29580+ dbgaufs_si_fin(sbinfo);
29581+ kobject_put(&sbinfo->si_kobj);
29582+}
29583+
29584+/* ---------------------------------------------------------------------- */
29585+
79b8bda9
AM
29586+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb,
29587+ struct super_block *sb, void *arg)
7f207e10
AM
29588+{
29589+ void *array;
076b876e 29590+ unsigned long long n, sz;
7f207e10
AM
29591+
29592+ array = NULL;
29593+ n = 0;
29594+ if (!*hint)
29595+ goto out;
29596+
29597+ if (*hint > ULLONG_MAX / sizeof(array)) {
29598+ array = ERR_PTR(-EMFILE);
29599+ pr_err("hint %llu\n", *hint);
29600+ goto out;
29601+ }
29602+
076b876e
AM
29603+ sz = sizeof(array) * *hint;
29604+ array = kzalloc(sz, GFP_NOFS);
7f207e10 29605+ if (unlikely(!array))
076b876e 29606+ array = vzalloc(sz);
7f207e10
AM
29607+ if (unlikely(!array)) {
29608+ array = ERR_PTR(-ENOMEM);
29609+ goto out;
29610+ }
29611+
79b8bda9 29612+ n = cb(sb, array, *hint, arg);
7f207e10
AM
29613+ AuDebugOn(n > *hint);
29614+
29615+out:
29616+ *hint = n;
29617+ return array;
29618+}
29619+
79b8bda9 29620+static unsigned long long au_iarray_cb(struct super_block *sb, void *a,
7f207e10
AM
29621+ unsigned long long max __maybe_unused,
29622+ void *arg)
29623+{
29624+ unsigned long long n;
29625+ struct inode **p, *inode;
29626+ struct list_head *head;
29627+
29628+ n = 0;
29629+ p = a;
29630+ head = arg;
79b8bda9 29631+ spin_lock(&sb->s_inode_list_lock);
7f207e10 29632+ list_for_each_entry(inode, head, i_sb_list) {
5afbbe0d
AM
29633+ if (!au_is_bad_inode(inode)
29634+ && au_ii(inode)->ii_btop >= 0) {
2cbb1c4b
JR
29635+ spin_lock(&inode->i_lock);
29636+ if (atomic_read(&inode->i_count)) {
29637+ au_igrab(inode);
29638+ *p++ = inode;
29639+ n++;
29640+ AuDebugOn(n > max);
29641+ }
29642+ spin_unlock(&inode->i_lock);
7f207e10
AM
29643+ }
29644+ }
79b8bda9 29645+ spin_unlock(&sb->s_inode_list_lock);
7f207e10
AM
29646+
29647+ return n;
29648+}
29649+
29650+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max)
29651+{
5afbbe0d 29652+ *max = au_ninodes(sb);
79b8bda9 29653+ return au_array_alloc(max, au_iarray_cb, sb, &sb->s_inodes);
7f207e10
AM
29654+}
29655+
29656+void au_iarray_free(struct inode **a, unsigned long long max)
29657+{
29658+ unsigned long long ull;
29659+
29660+ for (ull = 0; ull < max; ull++)
29661+ iput(a[ull]);
be52b249 29662+ kvfree(a);
7f207e10
AM
29663+}
29664+
29665+/* ---------------------------------------------------------------------- */
29666+
1facf9fc 29667+/*
29668+ * refresh dentry and inode at remount time.
29669+ */
027c5e7a
AM
29670+/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */
29671+static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags,
29672+ struct dentry *parent)
1facf9fc 29673+{
29674+ int err;
1facf9fc 29675+
29676+ di_write_lock_child(dentry);
1facf9fc 29677+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
29678+ err = au_refresh_dentry(dentry, parent);
29679+ if (!err && dir_flags)
5527c038 29680+ au_hn_reset(d_inode(dentry), dir_flags);
1facf9fc 29681+ di_read_unlock(parent, AuLock_IR);
1facf9fc 29682+ di_write_unlock(dentry);
29683+
29684+ return err;
29685+}
29686+
027c5e7a
AM
29687+static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
29688+ struct au_sbinfo *sbinfo,
b95c5147 29689+ const unsigned int dir_flags, unsigned int do_idop)
1facf9fc 29690+{
027c5e7a
AM
29691+ int err;
29692+ struct dentry *parent;
027c5e7a
AM
29693+
29694+ err = 0;
29695+ parent = dget_parent(dentry);
29696+ if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
5527c038
JR
29697+ if (d_really_is_positive(dentry)) {
29698+ if (!d_is_dir(dentry))
027c5e7a
AM
29699+ err = au_do_refresh(dentry, /*dir_flags*/0,
29700+ parent);
29701+ else {
29702+ err = au_do_refresh(dentry, dir_flags, parent);
29703+ if (unlikely(err))
29704+ au_fset_si(sbinfo, FAILED_REFRESH_DIR);
29705+ }
29706+ } else
29707+ err = au_do_refresh(dentry, /*dir_flags*/0, parent);
29708+ AuDbgDentry(dentry);
29709+ }
29710+ dput(parent);
29711+
79b8bda9 29712+ if (!err) {
b95c5147 29713+ if (do_idop)
79b8bda9
AM
29714+ au_refresh_dop(dentry, /*force_reval*/0);
29715+ } else
29716+ au_refresh_dop(dentry, /*force_reval*/1);
29717+
027c5e7a
AM
29718+ AuTraceErr(err);
29719+ return err;
1facf9fc 29720+}
29721+
b95c5147 29722+static int au_refresh_d(struct super_block *sb, unsigned int do_idop)
1facf9fc 29723+{
29724+ int err, i, j, ndentry, e;
027c5e7a 29725+ unsigned int sigen;
1facf9fc 29726+ struct au_dcsub_pages dpages;
29727+ struct au_dpage *dpage;
027c5e7a
AM
29728+ struct dentry **dentries, *d;
29729+ struct au_sbinfo *sbinfo;
29730+ struct dentry *root = sb->s_root;
5527c038 29731+ const unsigned int dir_flags = au_hi_flags(d_inode(root), /*isdir*/1);
1facf9fc 29732+
b95c5147 29733+ if (do_idop)
79b8bda9
AM
29734+ au_refresh_dop(root, /*force_reval*/0);
29735+
027c5e7a
AM
29736+ err = au_dpages_init(&dpages, GFP_NOFS);
29737+ if (unlikely(err))
1facf9fc 29738+ goto out;
027c5e7a
AM
29739+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
29740+ if (unlikely(err))
1facf9fc 29741+ goto out_dpages;
1facf9fc 29742+
027c5e7a
AM
29743+ sigen = au_sigen(sb);
29744+ sbinfo = au_sbi(sb);
29745+ for (i = 0; i < dpages.ndpage; i++) {
1facf9fc 29746+ dpage = dpages.dpages + i;
29747+ dentries = dpage->dentries;
29748+ ndentry = dpage->ndentry;
027c5e7a 29749+ for (j = 0; j < ndentry; j++) {
1facf9fc 29750+ d = dentries[j];
79b8bda9 29751+ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags,
b95c5147 29752+ do_idop);
027c5e7a
AM
29753+ if (unlikely(e && !err))
29754+ err = e;
29755+ /* go on even err */
1facf9fc 29756+ }
29757+ }
29758+
4f0767ce 29759+out_dpages:
1facf9fc 29760+ au_dpages_free(&dpages);
4f0767ce 29761+out:
1facf9fc 29762+ return err;
29763+}
29764+
b95c5147 29765+static int au_refresh_i(struct super_block *sb, unsigned int do_idop)
1facf9fc 29766+{
027c5e7a
AM
29767+ int err, e;
29768+ unsigned int sigen;
29769+ unsigned long long max, ull;
29770+ struct inode *inode, **array;
1facf9fc 29771+
027c5e7a
AM
29772+ array = au_iarray_alloc(sb, &max);
29773+ err = PTR_ERR(array);
29774+ if (IS_ERR(array))
29775+ goto out;
1facf9fc 29776+
29777+ err = 0;
027c5e7a
AM
29778+ sigen = au_sigen(sb);
29779+ for (ull = 0; ull < max; ull++) {
29780+ inode = array[ull];
076b876e
AM
29781+ if (unlikely(!inode))
29782+ break;
b95c5147
AM
29783+
29784+ e = 0;
29785+ ii_write_lock_child(inode);
537831f9 29786+ if (au_iigen(inode, NULL) != sigen) {
027c5e7a 29787+ e = au_refresh_hinode_self(inode);
1facf9fc 29788+ if (unlikely(e)) {
b95c5147 29789+ au_refresh_iop(inode, /*force_getattr*/1);
027c5e7a 29790+ pr_err("error %d, i%lu\n", e, inode->i_ino);
1facf9fc 29791+ if (!err)
29792+ err = e;
29793+ /* go on even if err */
29794+ }
29795+ }
b95c5147
AM
29796+ if (!e && do_idop)
29797+ au_refresh_iop(inode, /*force_getattr*/0);
29798+ ii_write_unlock(inode);
1facf9fc 29799+ }
29800+
027c5e7a 29801+ au_iarray_free(array, max);
1facf9fc 29802+
4f0767ce 29803+out:
1facf9fc 29804+ return err;
29805+}
29806+
b95c5147 29807+static void au_remount_refresh(struct super_block *sb, unsigned int do_idop)
1facf9fc 29808+{
027c5e7a
AM
29809+ int err, e;
29810+ unsigned int udba;
5afbbe0d 29811+ aufs_bindex_t bindex, bbot;
1facf9fc 29812+ struct dentry *root;
29813+ struct inode *inode;
027c5e7a 29814+ struct au_branch *br;
79b8bda9 29815+ struct au_sbinfo *sbi;
1facf9fc 29816+
29817+ au_sigen_inc(sb);
79b8bda9
AM
29818+ sbi = au_sbi(sb);
29819+ au_fclr_si(sbi, FAILED_REFRESH_DIR);
1facf9fc 29820+
29821+ root = sb->s_root;
29822+ DiMustNoWaiters(root);
5527c038 29823+ inode = d_inode(root);
1facf9fc 29824+ IiMustNoWaiters(inode);
1facf9fc 29825+
027c5e7a 29826+ udba = au_opt_udba(sb);
5afbbe0d
AM
29827+ bbot = au_sbbot(sb);
29828+ for (bindex = 0; bindex <= bbot; bindex++) {
027c5e7a
AM
29829+ br = au_sbr(sb, bindex);
29830+ err = au_hnotify_reset_br(udba, br, br->br_perm);
1facf9fc 29831+ if (unlikely(err))
027c5e7a
AM
29832+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
29833+ bindex, err);
29834+ /* go on even if err */
1facf9fc 29835+ }
027c5e7a 29836+ au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
1facf9fc 29837+
b95c5147 29838+ if (do_idop) {
79b8bda9
AM
29839+ if (au_ftest_si(sbi, NO_DREVAL)) {
29840+ AuDebugOn(sb->s_d_op == &aufs_dop_noreval);
29841+ sb->s_d_op = &aufs_dop_noreval;
b95c5147
AM
29842+ AuDebugOn(sbi->si_iop_array == aufs_iop_nogetattr);
29843+ sbi->si_iop_array = aufs_iop_nogetattr;
79b8bda9
AM
29844+ } else {
29845+ AuDebugOn(sb->s_d_op == &aufs_dop);
29846+ sb->s_d_op = &aufs_dop;
b95c5147
AM
29847+ AuDebugOn(sbi->si_iop_array == aufs_iop);
29848+ sbi->si_iop_array = aufs_iop;
79b8bda9 29849+ }
b95c5147
AM
29850+ pr_info("reset to %pf and %pf\n",
29851+ sb->s_d_op, sbi->si_iop_array);
79b8bda9
AM
29852+ }
29853+
027c5e7a 29854+ di_write_unlock(root);
b95c5147
AM
29855+ err = au_refresh_d(sb, do_idop);
29856+ e = au_refresh_i(sb, do_idop);
027c5e7a
AM
29857+ if (unlikely(e && !err))
29858+ err = e;
1facf9fc 29859+ /* aufs_write_lock() calls ..._child() */
29860+ di_write_lock_child(root);
027c5e7a
AM
29861+
29862+ au_cpup_attr_all(inode, /*force*/1);
29863+
29864+ if (unlikely(err))
29865+ AuIOErr("refresh failed, ignored, %d\n", err);
1facf9fc 29866+}
29867+
29868+/* stop extra interpretation of errno in mount(8), and strange error messages */
29869+static int cvt_err(int err)
29870+{
29871+ AuTraceErr(err);
29872+
29873+ switch (err) {
29874+ case -ENOENT:
29875+ case -ENOTDIR:
29876+ case -EEXIST:
29877+ case -EIO:
29878+ err = -EINVAL;
29879+ }
29880+ return err;
29881+}
29882+
29883+static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
29884+{
4a4d8108
AM
29885+ int err, do_dx;
29886+ unsigned int mntflags;
be52b249
AM
29887+ struct au_opts opts = {
29888+ .opt = NULL
29889+ };
1facf9fc 29890+ struct dentry *root;
29891+ struct inode *inode;
29892+ struct au_sbinfo *sbinfo;
29893+
29894+ err = 0;
29895+ root = sb->s_root;
29896+ if (!data || !*data) {
e49829fe
JR
29897+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
29898+ if (!err) {
29899+ di_write_lock_child(root);
29900+ err = au_opts_verify(sb, *flags, /*pending*/0);
29901+ aufs_write_unlock(root);
29902+ }
1facf9fc 29903+ goto out;
29904+ }
29905+
29906+ err = -ENOMEM;
1facf9fc 29907+ opts.opt = (void *)__get_free_page(GFP_NOFS);
29908+ if (unlikely(!opts.opt))
29909+ goto out;
29910+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
29911+ opts.flags = AuOpts_REMOUNT;
29912+ opts.sb_flags = *flags;
29913+
29914+ /* parse it before aufs lock */
29915+ err = au_opts_parse(sb, data, &opts);
29916+ if (unlikely(err))
29917+ goto out_opts;
29918+
29919+ sbinfo = au_sbi(sb);
5527c038 29920+ inode = d_inode(root);
febd17d6 29921+ inode_lock(inode);
e49829fe
JR
29922+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
29923+ if (unlikely(err))
29924+ goto out_mtx;
29925+ di_write_lock_child(root);
1facf9fc 29926+
29927+ /* au_opts_remount() may return an error */
29928+ err = au_opts_remount(sb, &opts);
29929+ au_opts_free(&opts);
29930+
027c5e7a 29931+ if (au_ftest_opts(opts.flags, REFRESH))
b95c5147 29932+ au_remount_refresh(sb, au_ftest_opts(opts.flags, REFRESH_IDOP));
1facf9fc 29933+
4a4d8108
AM
29934+ if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
29935+ mntflags = au_mntflags(sb);
29936+ do_dx = !!au_opt_test(mntflags, DIO);
29937+ au_dy_arefresh(do_dx);
29938+ }
29939+
076b876e 29940+ au_fhsm_wrote_all(sb, /*force*/1); /* ?? */
1facf9fc 29941+ aufs_write_unlock(root);
953406b4 29942+
e49829fe 29943+out_mtx:
febd17d6 29944+ inode_unlock(inode);
4f0767ce 29945+out_opts:
ae9dfd79 29946+ free_page((unsigned long)opts.opt);
4f0767ce 29947+out:
1facf9fc 29948+ err = cvt_err(err);
29949+ AuTraceErr(err);
29950+ return err;
29951+}
29952+
4a4d8108 29953+static const struct super_operations aufs_sop = {
1facf9fc 29954+ .alloc_inode = aufs_alloc_inode,
29955+ .destroy_inode = aufs_destroy_inode,
b752ccd1 29956+ /* always deleting, no clearing */
1facf9fc 29957+ .drop_inode = generic_delete_inode,
29958+ .show_options = aufs_show_options,
29959+ .statfs = aufs_statfs,
29960+ .put_super = aufs_put_super,
537831f9 29961+ .sync_fs = aufs_sync_fs,
1facf9fc 29962+ .remount_fs = aufs_remount_fs
29963+};
29964+
29965+/* ---------------------------------------------------------------------- */
29966+
29967+static int alloc_root(struct super_block *sb)
29968+{
29969+ int err;
29970+ struct inode *inode;
29971+ struct dentry *root;
29972+
29973+ err = -ENOMEM;
29974+ inode = au_iget_locked(sb, AUFS_ROOT_INO);
29975+ err = PTR_ERR(inode);
29976+ if (IS_ERR(inode))
29977+ goto out;
29978+
b95c5147 29979+ inode->i_op = aufs_iop + AuIop_DIR; /* with getattr by default */
1facf9fc 29980+ inode->i_fop = &aufs_dir_fop;
29981+ inode->i_mode = S_IFDIR;
9dbd164d 29982+ set_nlink(inode, 2);
1facf9fc 29983+ unlock_new_inode(inode);
29984+
92d182d2 29985+ root = d_make_root(inode);
1facf9fc 29986+ if (unlikely(!root))
92d182d2 29987+ goto out;
1facf9fc 29988+ err = PTR_ERR(root);
29989+ if (IS_ERR(root))
92d182d2 29990+ goto out;
1facf9fc 29991+
4a4d8108 29992+ err = au_di_init(root);
1facf9fc 29993+ if (!err) {
29994+ sb->s_root = root;
29995+ return 0; /* success */
29996+ }
29997+ dput(root);
1facf9fc 29998+
4f0767ce 29999+out:
1facf9fc 30000+ return err;
1facf9fc 30001+}
30002+
30003+static int aufs_fill_super(struct super_block *sb, void *raw_data,
30004+ int silent __maybe_unused)
30005+{
30006+ int err;
be52b249
AM
30007+ struct au_opts opts = {
30008+ .opt = NULL
30009+ };
79b8bda9 30010+ struct au_sbinfo *sbinfo;
1facf9fc 30011+ struct dentry *root;
30012+ struct inode *inode;
30013+ char *arg = raw_data;
30014+
30015+ if (unlikely(!arg || !*arg)) {
30016+ err = -EINVAL;
4a4d8108 30017+ pr_err("no arg\n");
1facf9fc 30018+ goto out;
30019+ }
30020+
30021+ err = -ENOMEM;
1facf9fc 30022+ opts.opt = (void *)__get_free_page(GFP_NOFS);
30023+ if (unlikely(!opts.opt))
30024+ goto out;
30025+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
30026+ opts.sb_flags = sb->s_flags;
30027+
30028+ err = au_si_alloc(sb);
30029+ if (unlikely(err))
30030+ goto out_opts;
79b8bda9 30031+ sbinfo = au_sbi(sb);
1facf9fc 30032+
30033+ /* all timestamps always follow the ones on the branch */
30034+ sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
30035+ sb->s_op = &aufs_sop;
027c5e7a 30036+ sb->s_d_op = &aufs_dop;
1facf9fc 30037+ sb->s_magic = AUFS_SUPER_MAGIC;
30038+ sb->s_maxbytes = 0;
c1595e42 30039+ sb->s_stack_depth = 1;
1facf9fc 30040+ au_export_init(sb);
f2c43d5f 30041+ au_xattr_init(sb);
1facf9fc 30042+
30043+ err = alloc_root(sb);
30044+ if (unlikely(err)) {
30045+ si_write_unlock(sb);
30046+ goto out_info;
30047+ }
30048+ root = sb->s_root;
5527c038 30049+ inode = d_inode(root);
1facf9fc 30050+
30051+ /*
30052+ * actually we can parse options regardless aufs lock here.
30053+ * but at remount time, parsing must be done before aufs lock.
30054+ * so we follow the same rule.
30055+ */
30056+ ii_write_lock_parent(inode);
30057+ aufs_write_unlock(root);
30058+ err = au_opts_parse(sb, arg, &opts);
30059+ if (unlikely(err))
30060+ goto out_root;
30061+
30062+ /* lock vfs_inode first, then aufs. */
febd17d6 30063+ inode_lock(inode);
1facf9fc 30064+ aufs_write_lock(root);
30065+ err = au_opts_mount(sb, &opts);
30066+ au_opts_free(&opts);
79b8bda9
AM
30067+ if (!err && au_ftest_si(sbinfo, NO_DREVAL)) {
30068+ sb->s_d_op = &aufs_dop_noreval;
30069+ pr_info("%pf\n", sb->s_d_op);
30070+ au_refresh_dop(root, /*force_reval*/0);
b95c5147
AM
30071+ sbinfo->si_iop_array = aufs_iop_nogetattr;
30072+ au_refresh_iop(inode, /*force_getattr*/0);
79b8bda9 30073+ }
1facf9fc 30074+ aufs_write_unlock(root);
febd17d6 30075+ inode_unlock(inode);
4a4d8108
AM
30076+ if (!err)
30077+ goto out_opts; /* success */
1facf9fc 30078+
4f0767ce 30079+out_root:
1facf9fc 30080+ dput(root);
30081+ sb->s_root = NULL;
4f0767ce 30082+out_info:
79b8bda9
AM
30083+ dbgaufs_si_fin(sbinfo);
30084+ kobject_put(&sbinfo->si_kobj);
1facf9fc 30085+ sb->s_fs_info = NULL;
4f0767ce 30086+out_opts:
ae9dfd79 30087+ free_page((unsigned long)opts.opt);
4f0767ce 30088+out:
1facf9fc 30089+ AuTraceErr(err);
30090+ err = cvt_err(err);
30091+ AuTraceErr(err);
30092+ return err;
30093+}
30094+
30095+/* ---------------------------------------------------------------------- */
30096+
027c5e7a
AM
30097+static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags,
30098+ const char *dev_name __maybe_unused,
30099+ void *raw_data)
1facf9fc 30100+{
027c5e7a 30101+ struct dentry *root;
1facf9fc 30102+ struct super_block *sb;
30103+
30104+ /* all timestamps always follow the ones on the branch */
30105+ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
027c5e7a
AM
30106+ root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super);
30107+ if (IS_ERR(root))
30108+ goto out;
30109+
30110+ sb = root->d_sb;
30111+ si_write_lock(sb, !AuLock_FLUSH);
30112+ sysaufs_brs_add(sb, 0);
30113+ si_write_unlock(sb);
30114+ au_sbilist_add(sb);
30115+
30116+out:
30117+ return root;
1facf9fc 30118+}
30119+
e49829fe
JR
30120+static void aufs_kill_sb(struct super_block *sb)
30121+{
30122+ struct au_sbinfo *sbinfo;
30123+
30124+ sbinfo = au_sbi(sb);
30125+ if (sbinfo) {
30126+ au_sbilist_del(sb);
30127+ aufs_write_lock(sb->s_root);
076b876e 30128+ au_fhsm_fin(sb);
e49829fe
JR
30129+ if (sbinfo->si_wbr_create_ops->fin)
30130+ sbinfo->si_wbr_create_ops->fin(sb);
30131+ if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
30132+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
b95c5147 30133+ au_remount_refresh(sb, /*do_idop*/0);
e49829fe
JR
30134+ }
30135+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
30136+ au_plink_put(sb, /*verbose*/1);
30137+ au_xino_clr(sb);
ae9dfd79 30138+ au_dr_opt_flush(sb);
1e00d052 30139+ sbinfo->si_sb = NULL;
e49829fe 30140+ aufs_write_unlock(sb->s_root);
e49829fe
JR
30141+ au_nwt_flush(&sbinfo->si_nowait);
30142+ }
98d9a5b1 30143+ kill_anon_super(sb);
e49829fe
JR
30144+}
30145+
1facf9fc 30146+struct file_system_type aufs_fs_type = {
30147+ .name = AUFS_FSTYPE,
c06a8ce3
AM
30148+ /* a race between rename and others */
30149+ .fs_flags = FS_RENAME_DOES_D_MOVE,
027c5e7a 30150+ .mount = aufs_mount,
e49829fe 30151+ .kill_sb = aufs_kill_sb,
1facf9fc 30152+ /* no need to __module_get() and module_put(). */
30153+ .owner = THIS_MODULE,
30154+};
7f207e10
AM
30155diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
30156--- /usr/share/empty/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
30157+++ linux/fs/aufs/super.h 2018-04-15 08:49:13.404484168 +0200
30158@@ -0,0 +1,617 @@
1facf9fc 30159+/*
ae9dfd79 30160+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 30161+ *
30162+ * This program, aufs is free software; you can redistribute it and/or modify
30163+ * it under the terms of the GNU General Public License as published by
30164+ * the Free Software Foundation; either version 2 of the License, or
30165+ * (at your option) any later version.
dece6358
AM
30166+ *
30167+ * This program is distributed in the hope that it will be useful,
30168+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30169+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30170+ * GNU General Public License for more details.
30171+ *
30172+ * You should have received a copy of the GNU General Public License
523b37e3 30173+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30174+ */
30175+
30176+/*
30177+ * super_block operations
30178+ */
30179+
30180+#ifndef __AUFS_SUPER_H__
30181+#define __AUFS_SUPER_H__
30182+
30183+#ifdef __KERNEL__
30184+
30185+#include <linux/fs.h>
5527c038 30186+#include <linux/kobject.h>
ae9dfd79 30187+#include "hbl.h"
1facf9fc 30188+#include "rwsem.h"
1facf9fc 30189+#include "wkq.h"
30190+
1facf9fc 30191+/* policies to select one among multiple writable branches */
30192+struct au_wbr_copyup_operations {
30193+ int (*copyup)(struct dentry *dentry);
30194+};
30195+
392086de
AM
30196+#define AuWbr_DIR 1 /* target is a dir */
30197+#define AuWbr_PARENT (1 << 1) /* always require a parent */
30198+
30199+#define au_ftest_wbr(flags, name) ((flags) & AuWbr_##name)
30200+#define au_fset_wbr(flags, name) { (flags) |= AuWbr_##name; }
30201+#define au_fclr_wbr(flags, name) { (flags) &= ~AuWbr_##name; }
30202+
1facf9fc 30203+struct au_wbr_create_operations {
392086de 30204+ int (*create)(struct dentry *dentry, unsigned int flags);
1facf9fc 30205+ int (*init)(struct super_block *sb);
30206+ int (*fin)(struct super_block *sb);
30207+};
30208+
30209+struct au_wbr_mfs {
30210+ struct mutex mfs_lock; /* protect this structure */
30211+ unsigned long mfs_jiffy;
30212+ unsigned long mfs_expire;
30213+ aufs_bindex_t mfs_bindex;
30214+
30215+ unsigned long long mfsrr_bytes;
30216+ unsigned long long mfsrr_watermark;
30217+};
30218+
86dc4139
AM
30219+#define AuPlink_NHASH 100
30220+static inline int au_plink_hash(ino_t ino)
30221+{
30222+ return ino % AuPlink_NHASH;
30223+}
30224+
076b876e
AM
30225+/* File-based Hierarchical Storage Management */
30226+struct au_fhsm {
30227+#ifdef CONFIG_AUFS_FHSM
30228+ /* allow only one process who can receive the notification */
30229+ spinlock_t fhsm_spin;
30230+ pid_t fhsm_pid;
30231+ wait_queue_head_t fhsm_wqh;
30232+ atomic_t fhsm_readable;
30233+
c1595e42 30234+ /* these are protected by si_rwsem */
076b876e 30235+ unsigned long fhsm_expire;
c1595e42 30236+ aufs_bindex_t fhsm_bottom;
076b876e
AM
30237+#endif
30238+};
30239+
1facf9fc 30240+struct au_branch;
30241+struct au_sbinfo {
30242+ /* nowait tasks in the system-wide workqueue */
30243+ struct au_nowait_tasks si_nowait;
30244+
b752ccd1
AM
30245+ /*
30246+ * tried sb->s_umount, but failed due to the dependecy between i_mutex.
30247+ * rwsem for au_sbinfo is necessary.
30248+ */
dece6358 30249+ struct au_rwsem si_rwsem;
1facf9fc 30250+
7f207e10 30251+ /*
523b37e3
AM
30252+ * dirty approach to protect sb->sb_inodes and ->s_files (gone) from
30253+ * remount.
7f207e10 30254+ */
5afbbe0d 30255+ struct percpu_counter si_ninodes, si_nfiles;
7f207e10 30256+
1facf9fc 30257+ /* branch management */
30258+ unsigned int si_generation;
30259+
2000de60 30260+ /* see AuSi_ flags */
1facf9fc 30261+ unsigned char au_si_status;
30262+
5afbbe0d 30263+ aufs_bindex_t si_bbot;
7f207e10
AM
30264+
30265+ /* dirty trick to keep br_id plus */
30266+ unsigned int si_last_br_id :
30267+ sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1;
1facf9fc 30268+ struct au_branch **si_branch;
30269+
30270+ /* policy to select a writable branch */
30271+ unsigned char si_wbr_copyup;
30272+ unsigned char si_wbr_create;
30273+ struct au_wbr_copyup_operations *si_wbr_copyup_ops;
30274+ struct au_wbr_create_operations *si_wbr_create_ops;
30275+
30276+ /* round robin */
30277+ atomic_t si_wbr_rr_next;
30278+
30279+ /* most free space */
30280+ struct au_wbr_mfs si_wbr_mfs;
30281+
076b876e
AM
30282+ /* File-based Hierarchical Storage Management */
30283+ struct au_fhsm si_fhsm;
30284+
1facf9fc 30285+ /* mount flags */
30286+ /* include/asm-ia64/siginfo.h defines a macro named si_flags */
30287+ unsigned int si_mntflags;
30288+
30289+ /* external inode number (bitmap and translation table) */
5527c038
JR
30290+ vfs_readf_t si_xread;
30291+ vfs_writef_t si_xwrite;
1facf9fc 30292+ struct file *si_xib;
30293+ struct mutex si_xib_mtx; /* protect xib members */
30294+ unsigned long *si_xib_buf;
30295+ unsigned long si_xib_last_pindex;
30296+ int si_xib_next_bit;
30297+ aufs_bindex_t si_xino_brid;
392086de
AM
30298+ unsigned long si_xino_jiffy;
30299+ unsigned long si_xino_expire;
1facf9fc 30300+ /* reserved for future use */
30301+ /* unsigned long long si_xib_limit; */ /* Max xib file size */
30302+
30303+#ifdef CONFIG_AUFS_EXPORT
30304+ /* i_generation */
30305+ struct file *si_xigen;
30306+ atomic_t si_xigen_next;
30307+#endif
30308+
b912730e 30309+ /* dirty trick to suppoer atomic_open */
ae9dfd79 30310+ struct hlist_bl_head si_aopen;
b912730e 30311+
1facf9fc 30312+ /* vdir parameters */
e49829fe 30313+ unsigned long si_rdcache; /* max cache time in jiffies */
1facf9fc 30314+ unsigned int si_rdblk; /* deblk size */
30315+ unsigned int si_rdhash; /* hash size */
30316+
30317+ /*
30318+ * If the number of whiteouts are larger than si_dirwh, leave all of
30319+ * them after au_whtmp_ren to reduce the cost of rmdir(2).
30320+ * future fsck.aufs or kernel thread will remove them later.
30321+ * Otherwise, remove all whiteouts and the dir in rmdir(2).
30322+ */
30323+ unsigned int si_dirwh;
30324+
1facf9fc 30325+ /* pseudo_link list */
ae9dfd79 30326+ struct hlist_bl_head si_plink[AuPlink_NHASH];
1facf9fc 30327+ wait_queue_head_t si_plink_wq;
4a4d8108 30328+ spinlock_t si_plink_maint_lock;
e49829fe 30329+ pid_t si_plink_maint_pid;
1facf9fc 30330+
523b37e3 30331+ /* file list */
ae9dfd79 30332+ struct hlist_bl_head si_files;
523b37e3 30333+
b95c5147
AM
30334+ /* with/without getattr, brother of sb->s_d_op */
30335+ struct inode_operations *si_iop_array;
30336+
1facf9fc 30337+ /*
30338+ * sysfs and lifetime management.
30339+ * this is not a small structure and it may be a waste of memory in case
30340+ * of sysfs is disabled, particulary when many aufs-es are mounted.
30341+ * but using sysfs is majority.
30342+ */
30343+ struct kobject si_kobj;
30344+#ifdef CONFIG_DEBUG_FS
86dc4139
AM
30345+ struct dentry *si_dbgaufs;
30346+ struct dentry *si_dbgaufs_plink;
30347+ struct dentry *si_dbgaufs_xib;
1facf9fc 30348+#ifdef CONFIG_AUFS_EXPORT
30349+ struct dentry *si_dbgaufs_xigen;
30350+#endif
30351+#endif
30352+
e49829fe 30353+#ifdef CONFIG_AUFS_SBILIST
ae9dfd79 30354+ struct hlist_bl_node si_list;
e49829fe
JR
30355+#endif
30356+
1facf9fc 30357+ /* dirty, necessary for unmounting, sysfs and sysrq */
30358+ struct super_block *si_sb;
30359+};
30360+
dece6358
AM
30361+/* sbinfo status flags */
30362+/*
30363+ * set true when refresh_dirs() failed at remount time.
30364+ * then try refreshing dirs at access time again.
30365+ * if it is false, refreshing dirs at access time is unnecesary
30366+ */
027c5e7a 30367+#define AuSi_FAILED_REFRESH_DIR 1
076b876e 30368+#define AuSi_FHSM (1 << 1) /* fhsm is active now */
79b8bda9 30369+#define AuSi_NO_DREVAL (1 << 2) /* disable all d_revalidate */
076b876e
AM
30370+
30371+#ifndef CONFIG_AUFS_FHSM
30372+#undef AuSi_FHSM
30373+#define AuSi_FHSM 0
30374+#endif
30375+
dece6358
AM
30376+static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
30377+ unsigned int flag)
30378+{
30379+ AuRwMustAnyLock(&sbi->si_rwsem);
30380+ return sbi->au_si_status & flag;
30381+}
30382+#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name)
30383+#define au_fset_si(sbinfo, name) do { \
30384+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
30385+ (sbinfo)->au_si_status |= AuSi_##name; \
30386+} while (0)
30387+#define au_fclr_si(sbinfo, name) do { \
30388+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
30389+ (sbinfo)->au_si_status &= ~AuSi_##name; \
30390+} while (0)
30391+
1facf9fc 30392+/* ---------------------------------------------------------------------- */
30393+
30394+/* policy to select one among writable branches */
4a4d8108
AM
30395+#define AuWbrCopyup(sbinfo, ...) \
30396+ ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__))
30397+#define AuWbrCreate(sbinfo, ...) \
30398+ ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__))
1facf9fc 30399+
30400+/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
30401+#define AuLock_DW 1 /* write-lock dentry */
30402+#define AuLock_IR (1 << 1) /* read-lock inode */
30403+#define AuLock_IW (1 << 2) /* write-lock inode */
30404+#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
b95c5147 30405+#define AuLock_DIRS (1 << 4) /* target is a pair of dirs */
f2c43d5f 30406+ /* except RENAME_EXCHANGE */
e49829fe
JR
30407+#define AuLock_NOPLM (1 << 5) /* return err in plm mode */
30408+#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */
027c5e7a 30409+#define AuLock_GEN (1 << 7) /* test digen/iigen */
1facf9fc 30410+#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
7f207e10
AM
30411+#define au_fset_lock(flags, name) \
30412+ do { (flags) |= AuLock_##name; } while (0)
30413+#define au_fclr_lock(flags, name) \
30414+ do { (flags) &= ~AuLock_##name; } while (0)
1facf9fc 30415+
30416+/* ---------------------------------------------------------------------- */
30417+
30418+/* super.c */
30419+extern struct file_system_type aufs_fs_type;
30420+struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
79b8bda9
AM
30421+typedef unsigned long long (*au_arraycb_t)(struct super_block *sb, void *array,
30422+ unsigned long long max, void *arg);
79b8bda9
AM
30423+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb,
30424+ struct super_block *sb, void *arg);
7f207e10
AM
30425+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
30426+void au_iarray_free(struct inode **a, unsigned long long max);
1facf9fc 30427+
30428+/* sbinfo.c */
30429+void au_si_free(struct kobject *kobj);
30430+int au_si_alloc(struct super_block *sb);
e2f27e51 30431+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink);
1facf9fc 30432+
30433+unsigned int au_sigen_inc(struct super_block *sb);
30434+aufs_bindex_t au_new_br_id(struct super_block *sb);
30435+
e49829fe
JR
30436+int si_read_lock(struct super_block *sb, int flags);
30437+int si_write_lock(struct super_block *sb, int flags);
30438+int aufs_read_lock(struct dentry *dentry, int flags);
1facf9fc 30439+void aufs_read_unlock(struct dentry *dentry, int flags);
30440+void aufs_write_lock(struct dentry *dentry);
30441+void aufs_write_unlock(struct dentry *dentry);
e49829fe 30442+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
1facf9fc 30443+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
30444+
30445+/* wbr_policy.c */
30446+extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
30447+extern struct au_wbr_create_operations au_wbr_create_ops[];
30448+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
c2b27bf2 30449+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex);
5afbbe0d 30450+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t btop);
c2b27bf2
AM
30451+
30452+/* mvdown.c */
30453+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *arg);
1facf9fc 30454+
076b876e
AM
30455+#ifdef CONFIG_AUFS_FHSM
30456+/* fhsm.c */
30457+
30458+static inline pid_t au_fhsm_pid(struct au_fhsm *fhsm)
30459+{
30460+ pid_t pid;
30461+
30462+ spin_lock(&fhsm->fhsm_spin);
30463+ pid = fhsm->fhsm_pid;
30464+ spin_unlock(&fhsm->fhsm_spin);
30465+
30466+ return pid;
30467+}
30468+
30469+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force);
30470+void au_fhsm_wrote_all(struct super_block *sb, int force);
30471+int au_fhsm_fd(struct super_block *sb, int oflags);
30472+int au_fhsm_br_alloc(struct au_branch *br);
c1595e42 30473+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex);
076b876e
AM
30474+void au_fhsm_fin(struct super_block *sb);
30475+void au_fhsm_init(struct au_sbinfo *sbinfo);
30476+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec);
30477+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo);
30478+#else
30479+AuStubVoid(au_fhsm_wrote, struct super_block *sb, aufs_bindex_t bindex,
30480+ int force)
30481+AuStubVoid(au_fhsm_wrote_all, struct super_block *sb, int force)
30482+AuStub(int, au_fhsm_fd, return -EOPNOTSUPP, struct super_block *sb, int oflags)
c1595e42
JR
30483+AuStub(pid_t, au_fhsm_pid, return 0, struct au_fhsm *fhsm)
30484+AuStubInt0(au_fhsm_br_alloc, struct au_branch *br)
30485+AuStubVoid(au_fhsm_set_bottom, struct super_block *sb, aufs_bindex_t bindex)
076b876e
AM
30486+AuStubVoid(au_fhsm_fin, struct super_block *sb)
30487+AuStubVoid(au_fhsm_init, struct au_sbinfo *sbinfo)
30488+AuStubVoid(au_fhsm_set, struct au_sbinfo *sbinfo, unsigned int sec)
30489+AuStubVoid(au_fhsm_show, struct seq_file *seq, struct au_sbinfo *sbinfo)
30490+#endif
30491+
1facf9fc 30492+/* ---------------------------------------------------------------------- */
30493+
30494+static inline struct au_sbinfo *au_sbi(struct super_block *sb)
30495+{
30496+ return sb->s_fs_info;
30497+}
30498+
30499+/* ---------------------------------------------------------------------- */
30500+
30501+#ifdef CONFIG_AUFS_EXPORT
a2a7ad62 30502+int au_test_nfsd(void);
1facf9fc 30503+void au_export_init(struct super_block *sb);
b752ccd1 30504+void au_xigen_inc(struct inode *inode);
1facf9fc 30505+int au_xigen_new(struct inode *inode);
30506+int au_xigen_set(struct super_block *sb, struct file *base);
30507+void au_xigen_clr(struct super_block *sb);
30508+
30509+static inline int au_busy_or_stale(void)
30510+{
b752ccd1 30511+ if (!au_test_nfsd())
1facf9fc 30512+ return -EBUSY;
30513+ return -ESTALE;
30514+}
30515+#else
b752ccd1 30516+AuStubInt0(au_test_nfsd, void)
a2a7ad62 30517+AuStubVoid(au_export_init, struct super_block *sb)
b752ccd1 30518+AuStubVoid(au_xigen_inc, struct inode *inode)
4a4d8108
AM
30519+AuStubInt0(au_xigen_new, struct inode *inode)
30520+AuStubInt0(au_xigen_set, struct super_block *sb, struct file *base)
30521+AuStubVoid(au_xigen_clr, struct super_block *sb)
c1595e42 30522+AuStub(int, au_busy_or_stale, return -EBUSY, void)
1facf9fc 30523+#endif /* CONFIG_AUFS_EXPORT */
30524+
30525+/* ---------------------------------------------------------------------- */
30526+
e49829fe
JR
30527+#ifdef CONFIG_AUFS_SBILIST
30528+/* module.c */
ae9dfd79 30529+extern struct hlist_bl_head au_sbilist;
e49829fe
JR
30530+
30531+static inline void au_sbilist_init(void)
30532+{
ae9dfd79 30533+ INIT_HLIST_BL_HEAD(&au_sbilist);
e49829fe
JR
30534+}
30535+
30536+static inline void au_sbilist_add(struct super_block *sb)
30537+{
ae9dfd79 30538+ au_hbl_add(&au_sbi(sb)->si_list, &au_sbilist);
e49829fe
JR
30539+}
30540+
30541+static inline void au_sbilist_del(struct super_block *sb)
30542+{
ae9dfd79 30543+ au_hbl_del(&au_sbi(sb)->si_list, &au_sbilist);
e49829fe 30544+}
53392da6
AM
30545+
30546+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
30547+static inline void au_sbilist_lock(void)
30548+{
ae9dfd79 30549+ hlist_bl_lock(&au_sbilist);
53392da6
AM
30550+}
30551+
30552+static inline void au_sbilist_unlock(void)
30553+{
ae9dfd79 30554+ hlist_bl_unlock(&au_sbilist);
53392da6
AM
30555+}
30556+#define AuGFP_SBILIST GFP_ATOMIC
30557+#else
30558+AuStubVoid(au_sbilist_lock, void)
30559+AuStubVoid(au_sbilist_unlock, void)
30560+#define AuGFP_SBILIST GFP_NOFS
30561+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
e49829fe
JR
30562+#else
30563+AuStubVoid(au_sbilist_init, void)
c1595e42
JR
30564+AuStubVoid(au_sbilist_add, struct super_block *sb)
30565+AuStubVoid(au_sbilist_del, struct super_block *sb)
53392da6
AM
30566+AuStubVoid(au_sbilist_lock, void)
30567+AuStubVoid(au_sbilist_unlock, void)
30568+#define AuGFP_SBILIST GFP_NOFS
e49829fe
JR
30569+#endif
30570+
30571+/* ---------------------------------------------------------------------- */
30572+
1facf9fc 30573+static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
30574+{
dece6358 30575+ /*
c1595e42 30576+ * This function is a dynamic '__init' function actually,
dece6358
AM
30577+ * so the tiny check for si_rwsem is unnecessary.
30578+ */
30579+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
1facf9fc 30580+#ifdef CONFIG_DEBUG_FS
30581+ sbinfo->si_dbgaufs = NULL;
86dc4139 30582+ sbinfo->si_dbgaufs_plink = NULL;
1facf9fc 30583+ sbinfo->si_dbgaufs_xib = NULL;
30584+#ifdef CONFIG_AUFS_EXPORT
30585+ sbinfo->si_dbgaufs_xigen = NULL;
30586+#endif
30587+#endif
30588+}
30589+
30590+/* ---------------------------------------------------------------------- */
30591+
ae9dfd79
AM
30592+/* current->atomic_flags */
30593+/* this value should never corrupt the ones defined in linux/sched.h */
30594+#define PFA_AUFS 7
30595+
30596+TASK_PFA_TEST(AUFS, test_aufs) /* task_test_aufs */
30597+TASK_PFA_SET(AUFS, aufs) /* task_set_aufs */
30598+TASK_PFA_CLEAR(AUFS, aufs) /* task_clear_aufs */
b752ccd1
AM
30599+
30600+static inline int si_pid_test(struct super_block *sb)
30601+{
ae9dfd79 30602+ return !!task_test_aufs(current);
b752ccd1
AM
30603+}
30604+
30605+static inline void si_pid_clr(struct super_block *sb)
30606+{
ae9dfd79
AM
30607+ AuDebugOn(!task_test_aufs(current));
30608+ task_clear_aufs(current);
b752ccd1
AM
30609+}
30610+
ae9dfd79
AM
30611+static inline void si_pid_set(struct super_block *sb)
30612+{
30613+ AuDebugOn(task_test_aufs(current));
30614+ task_set_aufs(current);
30615+}
febd17d6 30616+
b752ccd1
AM
30617+/* ---------------------------------------------------------------------- */
30618+
1facf9fc 30619+/* lock superblock. mainly for entry point functions */
30620+/*
b752ccd1
AM
30621+ * __si_read_lock, __si_write_lock,
30622+ * __si_read_unlock, __si_write_unlock, __si_downgrade_lock
1facf9fc 30623+ */
b752ccd1 30624+AuSimpleRwsemFuncs(__si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
1facf9fc 30625+
dece6358
AM
30626+#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
30627+#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
30628+#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
30629+
b752ccd1
AM
30630+static inline void si_noflush_read_lock(struct super_block *sb)
30631+{
30632+ __si_read_lock(sb);
30633+ si_pid_set(sb);
30634+}
30635+
30636+static inline int si_noflush_read_trylock(struct super_block *sb)
30637+{
076b876e
AM
30638+ int locked;
30639+
30640+ locked = __si_read_trylock(sb);
b752ccd1
AM
30641+ if (locked)
30642+ si_pid_set(sb);
30643+ return locked;
30644+}
30645+
30646+static inline void si_noflush_write_lock(struct super_block *sb)
30647+{
30648+ __si_write_lock(sb);
30649+ si_pid_set(sb);
30650+}
30651+
30652+static inline int si_noflush_write_trylock(struct super_block *sb)
30653+{
076b876e
AM
30654+ int locked;
30655+
30656+ locked = __si_write_trylock(sb);
b752ccd1
AM
30657+ if (locked)
30658+ si_pid_set(sb);
30659+ return locked;
30660+}
30661+
7e9cd9fe 30662+#if 0 /* reserved */
1facf9fc 30663+static inline int si_read_trylock(struct super_block *sb, int flags)
30664+{
30665+ if (au_ftest_lock(flags, FLUSH))
30666+ au_nwt_flush(&au_sbi(sb)->si_nowait);
30667+ return si_noflush_read_trylock(sb);
30668+}
e49829fe 30669+#endif
1facf9fc 30670+
b752ccd1
AM
30671+static inline void si_read_unlock(struct super_block *sb)
30672+{
30673+ si_pid_clr(sb);
30674+ __si_read_unlock(sb);
30675+}
30676+
7e9cd9fe 30677+#if 0 /* reserved */
1facf9fc 30678+static inline int si_write_trylock(struct super_block *sb, int flags)
30679+{
30680+ if (au_ftest_lock(flags, FLUSH))
30681+ au_nwt_flush(&au_sbi(sb)->si_nowait);
30682+ return si_noflush_write_trylock(sb);
30683+}
b752ccd1
AM
30684+#endif
30685+
30686+static inline void si_write_unlock(struct super_block *sb)
30687+{
30688+ si_pid_clr(sb);
30689+ __si_write_unlock(sb);
30690+}
30691+
7e9cd9fe 30692+#if 0 /* reserved */
b752ccd1
AM
30693+static inline void si_downgrade_lock(struct super_block *sb)
30694+{
30695+ __si_downgrade_lock(sb);
30696+}
30697+#endif
1facf9fc 30698+
30699+/* ---------------------------------------------------------------------- */
30700+
5afbbe0d 30701+static inline aufs_bindex_t au_sbbot(struct super_block *sb)
1facf9fc 30702+{
dece6358 30703+ SiMustAnyLock(sb);
5afbbe0d 30704+ return au_sbi(sb)->si_bbot;
1facf9fc 30705+}
30706+
30707+static inline unsigned int au_mntflags(struct super_block *sb)
30708+{
dece6358 30709+ SiMustAnyLock(sb);
1facf9fc 30710+ return au_sbi(sb)->si_mntflags;
30711+}
30712+
30713+static inline unsigned int au_sigen(struct super_block *sb)
30714+{
dece6358 30715+ SiMustAnyLock(sb);
1facf9fc 30716+ return au_sbi(sb)->si_generation;
30717+}
30718+
5afbbe0d
AM
30719+static inline unsigned long long au_ninodes(struct super_block *sb)
30720+{
30721+ s64 n = percpu_counter_sum(&au_sbi(sb)->si_ninodes);
30722+
30723+ BUG_ON(n < 0);
30724+ return n;
30725+}
30726+
7f207e10
AM
30727+static inline void au_ninodes_inc(struct super_block *sb)
30728+{
5afbbe0d 30729+ percpu_counter_inc(&au_sbi(sb)->si_ninodes);
7f207e10
AM
30730+}
30731+
30732+static inline void au_ninodes_dec(struct super_block *sb)
30733+{
5afbbe0d
AM
30734+ percpu_counter_dec(&au_sbi(sb)->si_ninodes);
30735+}
30736+
30737+static inline unsigned long long au_nfiles(struct super_block *sb)
30738+{
30739+ s64 n = percpu_counter_sum(&au_sbi(sb)->si_nfiles);
30740+
30741+ BUG_ON(n < 0);
30742+ return n;
7f207e10
AM
30743+}
30744+
30745+static inline void au_nfiles_inc(struct super_block *sb)
30746+{
5afbbe0d 30747+ percpu_counter_inc(&au_sbi(sb)->si_nfiles);
7f207e10
AM
30748+}
30749+
30750+static inline void au_nfiles_dec(struct super_block *sb)
30751+{
5afbbe0d 30752+ percpu_counter_dec(&au_sbi(sb)->si_nfiles);
7f207e10
AM
30753+}
30754+
1facf9fc 30755+static inline struct au_branch *au_sbr(struct super_block *sb,
30756+ aufs_bindex_t bindex)
30757+{
dece6358 30758+ SiMustAnyLock(sb);
1facf9fc 30759+ return au_sbi(sb)->si_branch[0 + bindex];
30760+}
30761+
30762+static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid)
30763+{
dece6358 30764+ SiMustWriteLock(sb);
1facf9fc 30765+ au_sbi(sb)->si_xino_brid = brid;
30766+}
30767+
30768+static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
30769+{
dece6358 30770+ SiMustAnyLock(sb);
1facf9fc 30771+ return au_sbi(sb)->si_xino_brid;
30772+}
30773+
30774+#endif /* __KERNEL__ */
30775+#endif /* __AUFS_SUPER_H__ */
7f207e10
AM
30776diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c
30777--- /usr/share/empty/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 30778+++ linux/fs/aufs/sysaufs.c 2018-04-15 08:49:13.404484168 +0200
523b37e3 30779@@ -0,0 +1,104 @@
1facf9fc 30780+/*
ae9dfd79 30781+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 30782+ *
30783+ * This program, aufs is free software; you can redistribute it and/or modify
30784+ * it under the terms of the GNU General Public License as published by
30785+ * the Free Software Foundation; either version 2 of the License, or
30786+ * (at your option) any later version.
dece6358
AM
30787+ *
30788+ * This program is distributed in the hope that it will be useful,
30789+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30790+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30791+ * GNU General Public License for more details.
30792+ *
30793+ * You should have received a copy of the GNU General Public License
523b37e3 30794+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30795+ */
30796+
30797+/*
30798+ * sysfs interface and lifetime management
30799+ * they are necessary regardless sysfs is disabled.
30800+ */
30801+
1facf9fc 30802+#include <linux/random.h>
1facf9fc 30803+#include "aufs.h"
30804+
30805+unsigned long sysaufs_si_mask;
e49829fe 30806+struct kset *sysaufs_kset;
1facf9fc 30807+
30808+#define AuSiAttr(_name) { \
30809+ .attr = { .name = __stringify(_name), .mode = 0444 }, \
30810+ .show = sysaufs_si_##_name, \
30811+}
30812+
30813+static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
30814+struct attribute *sysaufs_si_attrs[] = {
30815+ &sysaufs_si_attr_xi_path.attr,
30816+ NULL,
30817+};
30818+
4a4d8108 30819+static const struct sysfs_ops au_sbi_ops = {
1facf9fc 30820+ .show = sysaufs_si_show
30821+};
30822+
30823+static struct kobj_type au_sbi_ktype = {
30824+ .release = au_si_free,
30825+ .sysfs_ops = &au_sbi_ops,
30826+ .default_attrs = sysaufs_si_attrs
30827+};
30828+
30829+/* ---------------------------------------------------------------------- */
30830+
30831+int sysaufs_si_init(struct au_sbinfo *sbinfo)
30832+{
30833+ int err;
30834+
e49829fe 30835+ sbinfo->si_kobj.kset = sysaufs_kset;
1facf9fc 30836+ /* cf. sysaufs_name() */
30837+ err = kobject_init_and_add
e49829fe 30838+ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL,
1facf9fc 30839+ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
30840+
30841+ dbgaufs_si_null(sbinfo);
30842+ if (!err) {
30843+ err = dbgaufs_si_init(sbinfo);
30844+ if (unlikely(err))
30845+ kobject_put(&sbinfo->si_kobj);
30846+ }
30847+ return err;
30848+}
30849+
30850+void sysaufs_fin(void)
30851+{
30852+ dbgaufs_fin();
e49829fe
JR
30853+ sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group);
30854+ kset_unregister(sysaufs_kset);
1facf9fc 30855+}
30856+
30857+int __init sysaufs_init(void)
30858+{
30859+ int err;
30860+
30861+ do {
30862+ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
30863+ } while (!sysaufs_si_mask);
30864+
4a4d8108 30865+ err = -EINVAL;
e49829fe
JR
30866+ sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
30867+ if (unlikely(!sysaufs_kset))
4a4d8108 30868+ goto out;
e49829fe
JR
30869+ err = PTR_ERR(sysaufs_kset);
30870+ if (IS_ERR(sysaufs_kset))
1facf9fc 30871+ goto out;
e49829fe 30872+ err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group);
1facf9fc 30873+ if (unlikely(err)) {
e49829fe 30874+ kset_unregister(sysaufs_kset);
1facf9fc 30875+ goto out;
30876+ }
30877+
30878+ err = dbgaufs_init();
30879+ if (unlikely(err))
30880+ sysaufs_fin();
4f0767ce 30881+out:
1facf9fc 30882+ return err;
30883+}
7f207e10
AM
30884diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h
30885--- /usr/share/empty/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 30886+++ linux/fs/aufs/sysaufs.h 2018-04-15 08:49:13.404484168 +0200
c1595e42 30887@@ -0,0 +1,101 @@
1facf9fc 30888+/*
ae9dfd79 30889+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 30890+ *
30891+ * This program, aufs is free software; you can redistribute it and/or modify
30892+ * it under the terms of the GNU General Public License as published by
30893+ * the Free Software Foundation; either version 2 of the License, or
30894+ * (at your option) any later version.
dece6358
AM
30895+ *
30896+ * This program is distributed in the hope that it will be useful,
30897+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30898+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30899+ * GNU General Public License for more details.
30900+ *
30901+ * You should have received a copy of the GNU General Public License
523b37e3 30902+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30903+ */
30904+
30905+/*
30906+ * sysfs interface and mount lifetime management
30907+ */
30908+
30909+#ifndef __SYSAUFS_H__
30910+#define __SYSAUFS_H__
30911+
30912+#ifdef __KERNEL__
30913+
1facf9fc 30914+#include <linux/sysfs.h>
1facf9fc 30915+#include "module.h"
30916+
dece6358
AM
30917+struct super_block;
30918+struct au_sbinfo;
30919+
1facf9fc 30920+struct sysaufs_si_attr {
30921+ struct attribute attr;
30922+ int (*show)(struct seq_file *seq, struct super_block *sb);
30923+};
30924+
30925+/* ---------------------------------------------------------------------- */
30926+
30927+/* sysaufs.c */
30928+extern unsigned long sysaufs_si_mask;
e49829fe 30929+extern struct kset *sysaufs_kset;
1facf9fc 30930+extern struct attribute *sysaufs_si_attrs[];
30931+int sysaufs_si_init(struct au_sbinfo *sbinfo);
30932+int __init sysaufs_init(void);
30933+void sysaufs_fin(void);
30934+
30935+/* ---------------------------------------------------------------------- */
30936+
30937+/* some people doesn't like to show a pointer in kernel */
30938+static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
30939+{
30940+ return sysaufs_si_mask ^ (unsigned long)sbinfo;
30941+}
30942+
30943+#define SysaufsSiNamePrefix "si_"
30944+#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16)
30945+static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
30946+{
30947+ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
30948+ sysaufs_si_id(sbinfo));
30949+}
30950+
30951+struct au_branch;
30952+#ifdef CONFIG_SYSFS
30953+/* sysfs.c */
30954+extern struct attribute_group *sysaufs_attr_group;
30955+
30956+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
30957+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
30958+ char *buf);
076b876e
AM
30959+long au_brinfo_ioctl(struct file *file, unsigned long arg);
30960+#ifdef CONFIG_COMPAT
30961+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg);
30962+#endif
1facf9fc 30963+
30964+void sysaufs_br_init(struct au_branch *br);
30965+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
30966+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
30967+
30968+#define sysaufs_brs_init() do {} while (0)
30969+
30970+#else
30971+#define sysaufs_attr_group NULL
30972+
4a4d8108 30973+AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb)
c1595e42
JR
30974+AuStub(ssize_t, sysaufs_si_show, return 0, struct kobject *kobj,
30975+ struct attribute *attr, char *buf)
4a4d8108
AM
30976+AuStubVoid(sysaufs_br_init, struct au_branch *br)
30977+AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
30978+AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
1facf9fc 30979+
30980+static inline void sysaufs_brs_init(void)
30981+{
30982+ sysaufs_brs = 0;
30983+}
30984+
30985+#endif /* CONFIG_SYSFS */
30986+
30987+#endif /* __KERNEL__ */
30988+#endif /* __SYSAUFS_H__ */
7f207e10
AM
30989diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
30990--- /usr/share/empty/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 30991+++ linux/fs/aufs/sysfs.c 2018-04-15 08:49:13.404484168 +0200
79b8bda9 30992@@ -0,0 +1,376 @@
1facf9fc 30993+/*
ae9dfd79 30994+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 30995+ *
30996+ * This program, aufs is free software; you can redistribute it and/or modify
30997+ * it under the terms of the GNU General Public License as published by
30998+ * the Free Software Foundation; either version 2 of the License, or
30999+ * (at your option) any later version.
dece6358
AM
31000+ *
31001+ * This program is distributed in the hope that it will be useful,
31002+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31003+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31004+ * GNU General Public License for more details.
31005+ *
31006+ * You should have received a copy of the GNU General Public License
523b37e3 31007+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31008+ */
31009+
31010+/*
31011+ * sysfs interface
31012+ */
31013+
076b876e 31014+#include <linux/compat.h>
1facf9fc 31015+#include <linux/seq_file.h>
1facf9fc 31016+#include "aufs.h"
31017+
4a4d8108
AM
31018+#ifdef CONFIG_AUFS_FS_MODULE
31019+/* this entry violates the "one line per file" policy of sysfs */
31020+static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr,
31021+ char *buf)
31022+{
31023+ ssize_t err;
31024+ static char *conf =
31025+/* this file is generated at compiling */
31026+#include "conf.str"
31027+ ;
31028+
31029+ err = snprintf(buf, PAGE_SIZE, conf);
31030+ if (unlikely(err >= PAGE_SIZE))
31031+ err = -EFBIG;
31032+ return err;
31033+}
31034+
31035+static struct kobj_attribute au_config_attr = __ATTR_RO(config);
31036+#endif
31037+
1facf9fc 31038+static struct attribute *au_attr[] = {
4a4d8108
AM
31039+#ifdef CONFIG_AUFS_FS_MODULE
31040+ &au_config_attr.attr,
31041+#endif
1facf9fc 31042+ NULL, /* need to NULL terminate the list of attributes */
31043+};
31044+
31045+static struct attribute_group sysaufs_attr_group_body = {
31046+ .attrs = au_attr
31047+};
31048+
31049+struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
31050+
31051+/* ---------------------------------------------------------------------- */
31052+
31053+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
31054+{
31055+ int err;
31056+
dece6358
AM
31057+ SiMustAnyLock(sb);
31058+
1facf9fc 31059+ err = 0;
31060+ if (au_opt_test(au_mntflags(sb), XINO)) {
31061+ err = au_xino_path(seq, au_sbi(sb)->si_xib);
31062+ seq_putc(seq, '\n');
31063+ }
31064+ return err;
31065+}
31066+
31067+/*
31068+ * the lifetime of branch is independent from the entry under sysfs.
31069+ * sysfs handles the lifetime of the entry, and never call ->show() after it is
31070+ * unlinked.
31071+ */
31072+static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
392086de 31073+ aufs_bindex_t bindex, int idx)
1facf9fc 31074+{
1e00d052 31075+ int err;
1facf9fc 31076+ struct path path;
31077+ struct dentry *root;
31078+ struct au_branch *br;
076b876e 31079+ au_br_perm_str_t perm;
1facf9fc 31080+
31081+ AuDbg("b%d\n", bindex);
31082+
1e00d052 31083+ err = 0;
1facf9fc 31084+ root = sb->s_root;
31085+ di_read_lock_parent(root, !AuLock_IR);
31086+ br = au_sbr(sb, bindex);
392086de
AM
31087+
31088+ switch (idx) {
31089+ case AuBrSysfs_BR:
31090+ path.mnt = au_br_mnt(br);
31091+ path.dentry = au_h_dptr(root, bindex);
79b8bda9
AM
31092+ err = au_seq_path(seq, &path);
31093+ if (!err) {
31094+ au_optstr_br_perm(&perm, br->br_perm);
31095+ seq_printf(seq, "=%s\n", perm.a);
31096+ }
392086de
AM
31097+ break;
31098+ case AuBrSysfs_BRID:
79b8bda9 31099+ seq_printf(seq, "%d\n", br->br_id);
392086de
AM
31100+ break;
31101+ }
076b876e 31102+ di_read_unlock(root, !AuLock_IR);
79b8bda9 31103+ if (unlikely(err || seq_has_overflowed(seq)))
076b876e 31104+ err = -E2BIG;
392086de 31105+
1e00d052 31106+ return err;
1facf9fc 31107+}
31108+
31109+/* ---------------------------------------------------------------------- */
31110+
31111+static struct seq_file *au_seq(char *p, ssize_t len)
31112+{
31113+ struct seq_file *seq;
31114+
31115+ seq = kzalloc(sizeof(*seq), GFP_NOFS);
31116+ if (seq) {
31117+ /* mutex_init(&seq.lock); */
31118+ seq->buf = p;
31119+ seq->size = len;
31120+ return seq; /* success */
31121+ }
31122+
31123+ seq = ERR_PTR(-ENOMEM);
31124+ return seq;
31125+}
31126+
392086de
AM
31127+#define SysaufsBr_PREFIX "br"
31128+#define SysaufsBrid_PREFIX "brid"
1facf9fc 31129+
31130+/* todo: file size may exceed PAGE_SIZE */
31131+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
1308ab2a 31132+ char *buf)
1facf9fc 31133+{
31134+ ssize_t err;
392086de 31135+ int idx;
1facf9fc 31136+ long l;
5afbbe0d 31137+ aufs_bindex_t bbot;
1facf9fc 31138+ struct au_sbinfo *sbinfo;
31139+ struct super_block *sb;
31140+ struct seq_file *seq;
31141+ char *name;
31142+ struct attribute **cattr;
31143+
31144+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
31145+ sb = sbinfo->si_sb;
1308ab2a 31146+
31147+ /*
31148+ * prevent a race condition between sysfs and aufs.
31149+ * for instance, sysfs_file_read() calls sysfs_get_active_two() which
31150+ * prohibits maintaining the sysfs entries.
31151+ * hew we acquire read lock after sysfs_get_active_two().
31152+ * on the other hand, the remount process may maintain the sysfs/aufs
31153+ * entries after acquiring write lock.
31154+ * it can cause a deadlock.
31155+ * simply we gave up processing read here.
31156+ */
31157+ err = -EBUSY;
31158+ if (unlikely(!si_noflush_read_trylock(sb)))
31159+ goto out;
1facf9fc 31160+
31161+ seq = au_seq(buf, PAGE_SIZE);
31162+ err = PTR_ERR(seq);
31163+ if (IS_ERR(seq))
1308ab2a 31164+ goto out_unlock;
1facf9fc 31165+
31166+ name = (void *)attr->name;
31167+ cattr = sysaufs_si_attrs;
31168+ while (*cattr) {
31169+ if (!strcmp(name, (*cattr)->name)) {
31170+ err = container_of(*cattr, struct sysaufs_si_attr, attr)
31171+ ->show(seq, sb);
31172+ goto out_seq;
31173+ }
31174+ cattr++;
31175+ }
31176+
392086de
AM
31177+ if (!strncmp(name, SysaufsBrid_PREFIX,
31178+ sizeof(SysaufsBrid_PREFIX) - 1)) {
31179+ idx = AuBrSysfs_BRID;
31180+ name += sizeof(SysaufsBrid_PREFIX) - 1;
31181+ } else if (!strncmp(name, SysaufsBr_PREFIX,
31182+ sizeof(SysaufsBr_PREFIX) - 1)) {
31183+ idx = AuBrSysfs_BR;
1facf9fc 31184+ name += sizeof(SysaufsBr_PREFIX) - 1;
392086de
AM
31185+ } else
31186+ BUG();
31187+
31188+ err = kstrtol(name, 10, &l);
31189+ if (!err) {
5afbbe0d
AM
31190+ bbot = au_sbbot(sb);
31191+ if (l <= bbot)
392086de
AM
31192+ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l, idx);
31193+ else
31194+ err = -ENOENT;
1facf9fc 31195+ }
1facf9fc 31196+
4f0767ce 31197+out_seq:
1facf9fc 31198+ if (!err) {
31199+ err = seq->count;
31200+ /* sysfs limit */
31201+ if (unlikely(err == PAGE_SIZE))
31202+ err = -EFBIG;
31203+ }
ae9dfd79 31204+ kfree(seq);
4f0767ce 31205+out_unlock:
1facf9fc 31206+ si_read_unlock(sb);
4f0767ce 31207+out:
1facf9fc 31208+ return err;
31209+}
31210+
31211+/* ---------------------------------------------------------------------- */
31212+
076b876e
AM
31213+static int au_brinfo(struct super_block *sb, union aufs_brinfo __user *arg)
31214+{
31215+ int err;
31216+ int16_t brid;
5afbbe0d 31217+ aufs_bindex_t bindex, bbot;
076b876e
AM
31218+ size_t sz;
31219+ char *buf;
31220+ struct seq_file *seq;
31221+ struct au_branch *br;
31222+
31223+ si_read_lock(sb, AuLock_FLUSH);
5afbbe0d
AM
31224+ bbot = au_sbbot(sb);
31225+ err = bbot + 1;
076b876e
AM
31226+ if (!arg)
31227+ goto out;
31228+
31229+ err = -ENOMEM;
31230+ buf = (void *)__get_free_page(GFP_NOFS);
31231+ if (unlikely(!buf))
31232+ goto out;
31233+
31234+ seq = au_seq(buf, PAGE_SIZE);
31235+ err = PTR_ERR(seq);
31236+ if (IS_ERR(seq))
31237+ goto out_buf;
31238+
31239+ sz = sizeof(*arg) - offsetof(union aufs_brinfo, path);
5afbbe0d 31240+ for (bindex = 0; bindex <= bbot; bindex++, arg++) {
076b876e
AM
31241+ err = !access_ok(VERIFY_WRITE, arg, sizeof(*arg));
31242+ if (unlikely(err))
31243+ break;
31244+
31245+ br = au_sbr(sb, bindex);
31246+ brid = br->br_id;
31247+ BUILD_BUG_ON(sizeof(brid) != sizeof(arg->id));
31248+ err = __put_user(brid, &arg->id);
31249+ if (unlikely(err))
31250+ break;
31251+
31252+ BUILD_BUG_ON(sizeof(br->br_perm) != sizeof(arg->perm));
31253+ err = __put_user(br->br_perm, &arg->perm);
31254+ if (unlikely(err))
31255+ break;
31256+
79b8bda9
AM
31257+ err = au_seq_path(seq, &br->br_path);
31258+ if (unlikely(err))
31259+ break;
31260+ seq_putc(seq, '\0');
31261+ if (!seq_has_overflowed(seq)) {
076b876e
AM
31262+ err = copy_to_user(arg->path, seq->buf, seq->count);
31263+ seq->count = 0;
31264+ if (unlikely(err))
31265+ break;
31266+ } else {
31267+ err = -E2BIG;
31268+ goto out_seq;
31269+ }
31270+ }
31271+ if (unlikely(err))
31272+ err = -EFAULT;
31273+
31274+out_seq:
ae9dfd79 31275+ kfree(seq);
076b876e 31276+out_buf:
ae9dfd79 31277+ free_page((unsigned long)buf);
076b876e
AM
31278+out:
31279+ si_read_unlock(sb);
31280+ return err;
31281+}
31282+
31283+long au_brinfo_ioctl(struct file *file, unsigned long arg)
31284+{
2000de60 31285+ return au_brinfo(file->f_path.dentry->d_sb, (void __user *)arg);
076b876e
AM
31286+}
31287+
31288+#ifdef CONFIG_COMPAT
31289+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg)
31290+{
2000de60 31291+ return au_brinfo(file->f_path.dentry->d_sb, compat_ptr(arg));
076b876e
AM
31292+}
31293+#endif
31294+
31295+/* ---------------------------------------------------------------------- */
31296+
1facf9fc 31297+void sysaufs_br_init(struct au_branch *br)
31298+{
392086de
AM
31299+ int i;
31300+ struct au_brsysfs *br_sysfs;
31301+ struct attribute *attr;
4a4d8108 31302+
392086de
AM
31303+ br_sysfs = br->br_sysfs;
31304+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
31305+ attr = &br_sysfs->attr;
31306+ sysfs_attr_init(attr);
31307+ attr->name = br_sysfs->name;
31308+ attr->mode = S_IRUGO;
31309+ br_sysfs++;
31310+ }
1facf9fc 31311+}
31312+
31313+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
31314+{
31315+ struct au_branch *br;
31316+ struct kobject *kobj;
392086de
AM
31317+ struct au_brsysfs *br_sysfs;
31318+ int i;
5afbbe0d 31319+ aufs_bindex_t bbot;
1facf9fc 31320+
31321+ dbgaufs_brs_del(sb, bindex);
31322+
31323+ if (!sysaufs_brs)
31324+ return;
31325+
31326+ kobj = &au_sbi(sb)->si_kobj;
5afbbe0d
AM
31327+ bbot = au_sbbot(sb);
31328+ for (; bindex <= bbot; bindex++) {
1facf9fc 31329+ br = au_sbr(sb, bindex);
392086de
AM
31330+ br_sysfs = br->br_sysfs;
31331+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
31332+ sysfs_remove_file(kobj, &br_sysfs->attr);
31333+ br_sysfs++;
31334+ }
1facf9fc 31335+ }
31336+}
31337+
31338+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
31339+{
392086de 31340+ int err, i;
5afbbe0d 31341+ aufs_bindex_t bbot;
1facf9fc 31342+ struct kobject *kobj;
31343+ struct au_branch *br;
392086de 31344+ struct au_brsysfs *br_sysfs;
1facf9fc 31345+
31346+ dbgaufs_brs_add(sb, bindex);
31347+
31348+ if (!sysaufs_brs)
31349+ return;
31350+
31351+ kobj = &au_sbi(sb)->si_kobj;
5afbbe0d
AM
31352+ bbot = au_sbbot(sb);
31353+ for (; bindex <= bbot; bindex++) {
1facf9fc 31354+ br = au_sbr(sb, bindex);
392086de
AM
31355+ br_sysfs = br->br_sysfs;
31356+ snprintf(br_sysfs[AuBrSysfs_BR].name, sizeof(br_sysfs->name),
31357+ SysaufsBr_PREFIX "%d", bindex);
31358+ snprintf(br_sysfs[AuBrSysfs_BRID].name, sizeof(br_sysfs->name),
31359+ SysaufsBrid_PREFIX "%d", bindex);
31360+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
31361+ err = sysfs_create_file(kobj, &br_sysfs->attr);
31362+ if (unlikely(err))
31363+ pr_warn("failed %s under sysfs(%d)\n",
31364+ br_sysfs->name, err);
31365+ br_sysfs++;
31366+ }
1facf9fc 31367+ }
31368+}
7f207e10
AM
31369diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
31370--- /usr/share/empty/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
31371+++ linux/fs/aufs/sysrq.c 2018-04-15 08:49:13.404484168 +0200
31372@@ -0,0 +1,159 @@
1facf9fc 31373+/*
ae9dfd79 31374+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 31375+ *
31376+ * This program, aufs is free software; you can redistribute it and/or modify
31377+ * it under the terms of the GNU General Public License as published by
31378+ * the Free Software Foundation; either version 2 of the License, or
31379+ * (at your option) any later version.
dece6358
AM
31380+ *
31381+ * This program is distributed in the hope that it will be useful,
31382+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31383+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31384+ * GNU General Public License for more details.
31385+ *
31386+ * You should have received a copy of the GNU General Public License
523b37e3 31387+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31388+ */
31389+
31390+/*
31391+ * magic sysrq hanlder
31392+ */
31393+
1facf9fc 31394+/* #include <linux/sysrq.h> */
027c5e7a 31395+#include <linux/writeback.h>
1facf9fc 31396+#include "aufs.h"
31397+
31398+/* ---------------------------------------------------------------------- */
31399+
31400+static void sysrq_sb(struct super_block *sb)
31401+{
31402+ char *plevel;
31403+ struct au_sbinfo *sbinfo;
31404+ struct file *file;
ae9dfd79
AM
31405+ struct hlist_bl_head *files;
31406+ struct hlist_bl_node *pos;
523b37e3 31407+ struct au_finfo *finfo;
1facf9fc 31408+
31409+ plevel = au_plevel;
31410+ au_plevel = KERN_WARNING;
1facf9fc 31411+
4a4d8108 31412+ /* since we define pr_fmt, call printk directly */
c06a8ce3
AM
31413+#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str)
31414+
31415+ sbinfo = au_sbi(sb);
4a4d8108 31416+ printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo));
c06a8ce3 31417+ pr("superblock\n");
1facf9fc 31418+ au_dpri_sb(sb);
027c5e7a
AM
31419+
31420+#if 0
c06a8ce3 31421+ pr("root dentry\n");
1facf9fc 31422+ au_dpri_dentry(sb->s_root);
c06a8ce3 31423+ pr("root inode\n");
5527c038 31424+ au_dpri_inode(d_inode(sb->s_root));
027c5e7a
AM
31425+#endif
31426+
1facf9fc 31427+#if 0
027c5e7a
AM
31428+ do {
31429+ int err, i, j, ndentry;
31430+ struct au_dcsub_pages dpages;
31431+ struct au_dpage *dpage;
31432+
31433+ err = au_dpages_init(&dpages, GFP_ATOMIC);
31434+ if (unlikely(err))
31435+ break;
31436+ err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL);
31437+ if (!err)
31438+ for (i = 0; i < dpages.ndpage; i++) {
31439+ dpage = dpages.dpages + i;
31440+ ndentry = dpage->ndentry;
31441+ for (j = 0; j < ndentry; j++)
31442+ au_dpri_dentry(dpage->dentries[j]);
31443+ }
31444+ au_dpages_free(&dpages);
31445+ } while (0);
31446+#endif
31447+
31448+#if 1
31449+ {
31450+ struct inode *i;
076b876e 31451+
c06a8ce3 31452+ pr("isolated inode\n");
79b8bda9 31453+ spin_lock(&sb->s_inode_list_lock);
2cbb1c4b
JR
31454+ list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
31455+ spin_lock(&i->i_lock);
b4510431 31456+ if (1 || hlist_empty(&i->i_dentry))
027c5e7a 31457+ au_dpri_inode(i);
2cbb1c4b
JR
31458+ spin_unlock(&i->i_lock);
31459+ }
79b8bda9 31460+ spin_unlock(&sb->s_inode_list_lock);
027c5e7a 31461+ }
1facf9fc 31462+#endif
c06a8ce3 31463+ pr("files\n");
523b37e3 31464+ files = &au_sbi(sb)->si_files;
ae9dfd79
AM
31465+ hlist_bl_lock(files);
31466+ hlist_bl_for_each_entry(finfo, pos, files, fi_hlist) {
4a4d8108 31467+ umode_t mode;
076b876e 31468+
523b37e3 31469+ file = finfo->fi_file;
c06a8ce3 31470+ mode = file_inode(file)->i_mode;
38d290e6 31471+ if (!special_file(mode))
1facf9fc 31472+ au_dpri_file(file);
523b37e3 31473+ }
ae9dfd79 31474+ hlist_bl_unlock(files);
c06a8ce3 31475+ pr("done\n");
1facf9fc 31476+
c06a8ce3 31477+#undef pr
1facf9fc 31478+ au_plevel = plevel;
1facf9fc 31479+}
31480+
31481+/* ---------------------------------------------------------------------- */
31482+
31483+/* module parameter */
31484+static char *aufs_sysrq_key = "a";
31485+module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO);
31486+MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
31487+
0c5527e5 31488+static void au_sysrq(int key __maybe_unused)
1facf9fc 31489+{
1facf9fc 31490+ struct au_sbinfo *sbinfo;
ae9dfd79 31491+ struct hlist_bl_node *pos;
1facf9fc 31492+
027c5e7a 31493+ lockdep_off();
53392da6 31494+ au_sbilist_lock();
ae9dfd79 31495+ hlist_bl_for_each_entry(sbinfo, pos, &au_sbilist, si_list)
1facf9fc 31496+ sysrq_sb(sbinfo->si_sb);
53392da6 31497+ au_sbilist_unlock();
027c5e7a 31498+ lockdep_on();
1facf9fc 31499+}
31500+
31501+static struct sysrq_key_op au_sysrq_op = {
31502+ .handler = au_sysrq,
31503+ .help_msg = "Aufs",
31504+ .action_msg = "Aufs",
31505+ .enable_mask = SYSRQ_ENABLE_DUMP
31506+};
31507+
31508+/* ---------------------------------------------------------------------- */
31509+
31510+int __init au_sysrq_init(void)
31511+{
31512+ int err;
31513+ char key;
31514+
31515+ err = -1;
31516+ key = *aufs_sysrq_key;
31517+ if ('a' <= key && key <= 'z')
31518+ err = register_sysrq_key(key, &au_sysrq_op);
31519+ if (unlikely(err))
4a4d8108 31520+ pr_err("err %d, sysrq=%c\n", err, key);
1facf9fc 31521+ return err;
31522+}
31523+
31524+void au_sysrq_fin(void)
31525+{
31526+ int err;
076b876e 31527+
1facf9fc 31528+ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
31529+ if (unlikely(err))
4a4d8108 31530+ pr_err("err %d (ignored)\n", err);
1facf9fc 31531+}
7f207e10
AM
31532diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
31533--- /usr/share/empty/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
31534+++ linux/fs/aufs/vdir.c 2018-04-15 08:49:13.404484168 +0200
31535@@ -0,0 +1,893 @@
1facf9fc 31536+/*
ae9dfd79 31537+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 31538+ *
31539+ * This program, aufs is free software; you can redistribute it and/or modify
31540+ * it under the terms of the GNU General Public License as published by
31541+ * the Free Software Foundation; either version 2 of the License, or
31542+ * (at your option) any later version.
dece6358
AM
31543+ *
31544+ * This program is distributed in the hope that it will be useful,
31545+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31546+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31547+ * GNU General Public License for more details.
31548+ *
31549+ * You should have received a copy of the GNU General Public License
523b37e3 31550+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31551+ */
31552+
31553+/*
31554+ * virtual or vertical directory
31555+ */
31556+
31557+#include "aufs.h"
31558+
dece6358 31559+static unsigned int calc_size(int nlen)
1facf9fc 31560+{
dece6358 31561+ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
1facf9fc 31562+}
31563+
31564+static int set_deblk_end(union au_vdir_deblk_p *p,
31565+ union au_vdir_deblk_p *deblk_end)
31566+{
31567+ if (calc_size(0) <= deblk_end->deblk - p->deblk) {
31568+ p->de->de_str.len = 0;
31569+ /* smp_mb(); */
31570+ return 0;
31571+ }
31572+ return -1; /* error */
31573+}
31574+
31575+/* returns true or false */
31576+static int is_deblk_end(union au_vdir_deblk_p *p,
31577+ union au_vdir_deblk_p *deblk_end)
31578+{
31579+ if (calc_size(0) <= deblk_end->deblk - p->deblk)
31580+ return !p->de->de_str.len;
31581+ return 1;
31582+}
31583+
31584+static unsigned char *last_deblk(struct au_vdir *vdir)
31585+{
31586+ return vdir->vd_deblk[vdir->vd_nblk - 1];
31587+}
31588+
31589+/* ---------------------------------------------------------------------- */
31590+
79b8bda9 31591+/* estimate the appropriate size for name hash table */
1308ab2a 31592+unsigned int au_rdhash_est(loff_t sz)
31593+{
31594+ unsigned int n;
31595+
31596+ n = UINT_MAX;
31597+ sz >>= 10;
31598+ if (sz < n)
31599+ n = sz;
31600+ if (sz < AUFS_RDHASH_DEF)
31601+ n = AUFS_RDHASH_DEF;
4a4d8108 31602+ /* pr_info("n %u\n", n); */
1308ab2a 31603+ return n;
31604+}
31605+
1facf9fc 31606+/*
31607+ * the allocated memory has to be freed by
dece6358 31608+ * au_nhash_wh_free() or au_nhash_de_free().
1facf9fc 31609+ */
dece6358 31610+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
1facf9fc 31611+{
1facf9fc 31612+ struct hlist_head *head;
dece6358 31613+ unsigned int u;
076b876e 31614+ size_t sz;
1facf9fc 31615+
076b876e
AM
31616+ sz = sizeof(*nhash->nh_head) * num_hash;
31617+ head = kmalloc(sz, gfp);
dece6358
AM
31618+ if (head) {
31619+ nhash->nh_num = num_hash;
31620+ nhash->nh_head = head;
31621+ for (u = 0; u < num_hash; u++)
1facf9fc 31622+ INIT_HLIST_HEAD(head++);
dece6358 31623+ return 0; /* success */
1facf9fc 31624+ }
1facf9fc 31625+
dece6358 31626+ return -ENOMEM;
1facf9fc 31627+}
31628+
dece6358
AM
31629+static void nhash_count(struct hlist_head *head)
31630+{
31631+#if 0
31632+ unsigned long n;
31633+ struct hlist_node *pos;
31634+
31635+ n = 0;
31636+ hlist_for_each(pos, head)
31637+ n++;
4a4d8108 31638+ pr_info("%lu\n", n);
dece6358
AM
31639+#endif
31640+}
31641+
31642+static void au_nhash_wh_do_free(struct hlist_head *head)
1facf9fc 31643+{
c06a8ce3
AM
31644+ struct au_vdir_wh *pos;
31645+ struct hlist_node *node;
1facf9fc 31646+
c06a8ce3 31647+ hlist_for_each_entry_safe(pos, node, head, wh_hash)
ae9dfd79 31648+ kfree(pos);
1facf9fc 31649+}
31650+
dece6358 31651+static void au_nhash_de_do_free(struct hlist_head *head)
1facf9fc 31652+{
c06a8ce3
AM
31653+ struct au_vdir_dehstr *pos;
31654+ struct hlist_node *node;
1facf9fc 31655+
c06a8ce3 31656+ hlist_for_each_entry_safe(pos, node, head, hash)
ae9dfd79 31657+ au_cache_free_vdir_dehstr(pos);
1facf9fc 31658+}
31659+
dece6358
AM
31660+static void au_nhash_do_free(struct au_nhash *nhash,
31661+ void (*free)(struct hlist_head *head))
1facf9fc 31662+{
1308ab2a 31663+ unsigned int n;
1facf9fc 31664+ struct hlist_head *head;
1facf9fc 31665+
dece6358 31666+ n = nhash->nh_num;
1308ab2a 31667+ if (!n)
31668+ return;
31669+
dece6358 31670+ head = nhash->nh_head;
1308ab2a 31671+ while (n-- > 0) {
dece6358
AM
31672+ nhash_count(head);
31673+ free(head++);
1facf9fc 31674+ }
ae9dfd79 31675+ kfree(nhash->nh_head);
1facf9fc 31676+}
31677+
dece6358 31678+void au_nhash_wh_free(struct au_nhash *whlist)
1facf9fc 31679+{
dece6358
AM
31680+ au_nhash_do_free(whlist, au_nhash_wh_do_free);
31681+}
1facf9fc 31682+
dece6358
AM
31683+static void au_nhash_de_free(struct au_nhash *delist)
31684+{
31685+ au_nhash_do_free(delist, au_nhash_de_do_free);
1facf9fc 31686+}
31687+
31688+/* ---------------------------------------------------------------------- */
31689+
31690+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
31691+ int limit)
31692+{
31693+ int num;
31694+ unsigned int u, n;
31695+ struct hlist_head *head;
c06a8ce3 31696+ struct au_vdir_wh *pos;
1facf9fc 31697+
31698+ num = 0;
31699+ n = whlist->nh_num;
31700+ head = whlist->nh_head;
1308ab2a 31701+ for (u = 0; u < n; u++, head++)
c06a8ce3
AM
31702+ hlist_for_each_entry(pos, head, wh_hash)
31703+ if (pos->wh_bindex == btgt && ++num > limit)
1facf9fc 31704+ return 1;
1facf9fc 31705+ return 0;
31706+}
31707+
31708+static struct hlist_head *au_name_hash(struct au_nhash *nhash,
dece6358 31709+ unsigned char *name,
1facf9fc 31710+ unsigned int len)
31711+{
dece6358
AM
31712+ unsigned int v;
31713+ /* const unsigned int magic_bit = 12; */
31714+
1308ab2a 31715+ AuDebugOn(!nhash->nh_num || !nhash->nh_head);
31716+
dece6358 31717+ v = 0;
f0c0a007
AM
31718+ if (len > 8)
31719+ len = 8;
dece6358
AM
31720+ while (len--)
31721+ v += *name++;
31722+ /* v = hash_long(v, magic_bit); */
31723+ v %= nhash->nh_num;
31724+ return nhash->nh_head + v;
31725+}
31726+
31727+static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
31728+ int nlen)
31729+{
31730+ return str->len == nlen && !memcmp(str->name, name, nlen);
1facf9fc 31731+}
31732+
31733+/* returns found or not */
dece6358 31734+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
1facf9fc 31735+{
31736+ struct hlist_head *head;
c06a8ce3 31737+ struct au_vdir_wh *pos;
1facf9fc 31738+ struct au_vdir_destr *str;
31739+
dece6358 31740+ head = au_name_hash(whlist, name, nlen);
c06a8ce3
AM
31741+ hlist_for_each_entry(pos, head, wh_hash) {
31742+ str = &pos->wh_str;
1facf9fc 31743+ AuDbg("%.*s\n", str->len, str->name);
dece6358
AM
31744+ if (au_nhash_test_name(str, name, nlen))
31745+ return 1;
31746+ }
31747+ return 0;
31748+}
31749+
31750+/* returns found(true) or not */
31751+static int test_known(struct au_nhash *delist, char *name, int nlen)
31752+{
31753+ struct hlist_head *head;
c06a8ce3 31754+ struct au_vdir_dehstr *pos;
dece6358
AM
31755+ struct au_vdir_destr *str;
31756+
31757+ head = au_name_hash(delist, name, nlen);
c06a8ce3
AM
31758+ hlist_for_each_entry(pos, head, hash) {
31759+ str = pos->str;
dece6358
AM
31760+ AuDbg("%.*s\n", str->len, str->name);
31761+ if (au_nhash_test_name(str, name, nlen))
1facf9fc 31762+ return 1;
31763+ }
31764+ return 0;
31765+}
31766+
dece6358
AM
31767+static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
31768+ unsigned char d_type)
31769+{
31770+#ifdef CONFIG_AUFS_SHWH
31771+ wh->wh_ino = ino;
31772+ wh->wh_type = d_type;
31773+#endif
31774+}
31775+
31776+/* ---------------------------------------------------------------------- */
31777+
31778+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
31779+ unsigned int d_type, aufs_bindex_t bindex,
31780+ unsigned char shwh)
1facf9fc 31781+{
31782+ int err;
31783+ struct au_vdir_destr *str;
31784+ struct au_vdir_wh *wh;
31785+
dece6358 31786+ AuDbg("%.*s\n", nlen, name);
1308ab2a 31787+ AuDebugOn(!whlist->nh_num || !whlist->nh_head);
31788+
1facf9fc 31789+ err = -ENOMEM;
dece6358 31790+ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
1facf9fc 31791+ if (unlikely(!wh))
31792+ goto out;
31793+
31794+ err = 0;
31795+ wh->wh_bindex = bindex;
dece6358
AM
31796+ if (shwh)
31797+ au_shwh_init_wh(wh, ino, d_type);
1facf9fc 31798+ str = &wh->wh_str;
dece6358
AM
31799+ str->len = nlen;
31800+ memcpy(str->name, name, nlen);
31801+ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
1facf9fc 31802+ /* smp_mb(); */
31803+
4f0767ce 31804+out:
1facf9fc 31805+ return err;
31806+}
31807+
1facf9fc 31808+static int append_deblk(struct au_vdir *vdir)
31809+{
31810+ int err;
dece6358 31811+ unsigned long ul;
1facf9fc 31812+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
31813+ union au_vdir_deblk_p p, deblk_end;
31814+ unsigned char **o;
31815+
31816+ err = -ENOMEM;
e2f27e51
AM
31817+ o = au_krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
31818+ GFP_NOFS, /*may_shrink*/0);
1facf9fc 31819+ if (unlikely(!o))
31820+ goto out;
31821+
31822+ vdir->vd_deblk = o;
31823+ p.deblk = kmalloc(deblk_sz, GFP_NOFS);
31824+ if (p.deblk) {
31825+ ul = vdir->vd_nblk++;
31826+ vdir->vd_deblk[ul] = p.deblk;
31827+ vdir->vd_last.ul = ul;
31828+ vdir->vd_last.p.deblk = p.deblk;
31829+ deblk_end.deblk = p.deblk + deblk_sz;
31830+ err = set_deblk_end(&p, &deblk_end);
31831+ }
31832+
4f0767ce 31833+out:
1facf9fc 31834+ return err;
31835+}
31836+
dece6358
AM
31837+static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
31838+ unsigned int d_type, struct au_nhash *delist)
31839+{
31840+ int err;
31841+ unsigned int sz;
31842+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
31843+ union au_vdir_deblk_p p, *room, deblk_end;
31844+ struct au_vdir_dehstr *dehstr;
31845+
31846+ p.deblk = last_deblk(vdir);
31847+ deblk_end.deblk = p.deblk + deblk_sz;
31848+ room = &vdir->vd_last.p;
31849+ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
31850+ || !is_deblk_end(room, &deblk_end));
31851+
31852+ sz = calc_size(nlen);
31853+ if (unlikely(sz > deblk_end.deblk - room->deblk)) {
31854+ err = append_deblk(vdir);
31855+ if (unlikely(err))
31856+ goto out;
31857+
31858+ p.deblk = last_deblk(vdir);
31859+ deblk_end.deblk = p.deblk + deblk_sz;
31860+ /* smp_mb(); */
31861+ AuDebugOn(room->deblk != p.deblk);
31862+ }
31863+
31864+ err = -ENOMEM;
4a4d8108 31865+ dehstr = au_cache_alloc_vdir_dehstr();
dece6358
AM
31866+ if (unlikely(!dehstr))
31867+ goto out;
31868+
31869+ dehstr->str = &room->de->de_str;
31870+ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
31871+ room->de->de_ino = ino;
31872+ room->de->de_type = d_type;
31873+ room->de->de_str.len = nlen;
31874+ memcpy(room->de->de_str.name, name, nlen);
31875+
31876+ err = 0;
31877+ room->deblk += sz;
31878+ if (unlikely(set_deblk_end(room, &deblk_end)))
31879+ err = append_deblk(vdir);
31880+ /* smp_mb(); */
31881+
4f0767ce 31882+out:
dece6358
AM
31883+ return err;
31884+}
31885+
31886+/* ---------------------------------------------------------------------- */
31887+
ae9dfd79 31888+void au_vdir_free(struct au_vdir *vdir)
dece6358
AM
31889+{
31890+ unsigned char **deblk;
31891+
31892+ deblk = vdir->vd_deblk;
ae9dfd79
AM
31893+ while (vdir->vd_nblk--)
31894+ kfree(*deblk++);
31895+ kfree(vdir->vd_deblk);
31896+ au_cache_free_vdir(vdir);
dece6358
AM
31897+}
31898+
1308ab2a 31899+static struct au_vdir *alloc_vdir(struct file *file)
1facf9fc 31900+{
31901+ struct au_vdir *vdir;
1308ab2a 31902+ struct super_block *sb;
1facf9fc 31903+ int err;
31904+
2000de60 31905+ sb = file->f_path.dentry->d_sb;
dece6358
AM
31906+ SiMustAnyLock(sb);
31907+
1facf9fc 31908+ err = -ENOMEM;
31909+ vdir = au_cache_alloc_vdir();
31910+ if (unlikely(!vdir))
31911+ goto out;
31912+
31913+ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
31914+ if (unlikely(!vdir->vd_deblk))
31915+ goto out_free;
31916+
31917+ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
1308ab2a 31918+ if (!vdir->vd_deblk_sz) {
79b8bda9 31919+ /* estimate the appropriate size for deblk */
1308ab2a 31920+ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
4a4d8108 31921+ /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
1308ab2a 31922+ }
1facf9fc 31923+ vdir->vd_nblk = 0;
31924+ vdir->vd_version = 0;
31925+ vdir->vd_jiffy = 0;
31926+ err = append_deblk(vdir);
31927+ if (!err)
31928+ return vdir; /* success */
31929+
ae9dfd79 31930+ kfree(vdir->vd_deblk);
1facf9fc 31931+
4f0767ce 31932+out_free:
ae9dfd79 31933+ au_cache_free_vdir(vdir);
4f0767ce 31934+out:
1facf9fc 31935+ vdir = ERR_PTR(err);
31936+ return vdir;
31937+}
31938+
31939+static int reinit_vdir(struct au_vdir *vdir)
31940+{
31941+ int err;
31942+ union au_vdir_deblk_p p, deblk_end;
31943+
31944+ while (vdir->vd_nblk > 1) {
ae9dfd79 31945+ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
1facf9fc 31946+ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
31947+ vdir->vd_nblk--;
31948+ }
31949+ p.deblk = vdir->vd_deblk[0];
31950+ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
31951+ err = set_deblk_end(&p, &deblk_end);
31952+ /* keep vd_dblk_sz */
31953+ vdir->vd_last.ul = 0;
31954+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
31955+ vdir->vd_version = 0;
31956+ vdir->vd_jiffy = 0;
31957+ /* smp_mb(); */
31958+ return err;
31959+}
31960+
31961+/* ---------------------------------------------------------------------- */
31962+
1facf9fc 31963+#define AuFillVdir_CALLED 1
31964+#define AuFillVdir_WHABLE (1 << 1)
dece6358 31965+#define AuFillVdir_SHWH (1 << 2)
1facf9fc 31966+#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
7f207e10
AM
31967+#define au_fset_fillvdir(flags, name) \
31968+ do { (flags) |= AuFillVdir_##name; } while (0)
31969+#define au_fclr_fillvdir(flags, name) \
31970+ do { (flags) &= ~AuFillVdir_##name; } while (0)
1facf9fc 31971+
dece6358
AM
31972+#ifndef CONFIG_AUFS_SHWH
31973+#undef AuFillVdir_SHWH
31974+#define AuFillVdir_SHWH 0
31975+#endif
31976+
1facf9fc 31977+struct fillvdir_arg {
392086de 31978+ struct dir_context ctx;
1facf9fc 31979+ struct file *file;
31980+ struct au_vdir *vdir;
dece6358
AM
31981+ struct au_nhash delist;
31982+ struct au_nhash whlist;
1facf9fc 31983+ aufs_bindex_t bindex;
31984+ unsigned int flags;
31985+ int err;
31986+};
31987+
392086de 31988+static int fillvdir(struct dir_context *ctx, const char *__name, int nlen,
1facf9fc 31989+ loff_t offset __maybe_unused, u64 h_ino,
31990+ unsigned int d_type)
31991+{
392086de 31992+ struct fillvdir_arg *arg = container_of(ctx, struct fillvdir_arg, ctx);
1facf9fc 31993+ char *name = (void *)__name;
31994+ struct super_block *sb;
1facf9fc 31995+ ino_t ino;
dece6358 31996+ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
1facf9fc 31997+
1facf9fc 31998+ arg->err = 0;
2000de60 31999+ sb = arg->file->f_path.dentry->d_sb;
1facf9fc 32000+ au_fset_fillvdir(arg->flags, CALLED);
32001+ /* smp_mb(); */
dece6358 32002+ if (nlen <= AUFS_WH_PFX_LEN
1facf9fc 32003+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
dece6358
AM
32004+ if (test_known(&arg->delist, name, nlen)
32005+ || au_nhash_test_known_wh(&arg->whlist, name, nlen))
32006+ goto out; /* already exists or whiteouted */
1facf9fc 32007+
dece6358 32008+ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
4a4d8108
AM
32009+ if (!arg->err) {
32010+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
32011+ d_type = DT_UNKNOWN;
dece6358
AM
32012+ arg->err = append_de(arg->vdir, name, nlen, ino,
32013+ d_type, &arg->delist);
4a4d8108 32014+ }
1facf9fc 32015+ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
32016+ name += AUFS_WH_PFX_LEN;
dece6358
AM
32017+ nlen -= AUFS_WH_PFX_LEN;
32018+ if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
32019+ goto out; /* already whiteouted */
1facf9fc 32020+
dece6358
AM
32021+ if (shwh)
32022+ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
32023+ &ino);
4a4d8108
AM
32024+ if (!arg->err) {
32025+ if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
32026+ d_type = DT_UNKNOWN;
1facf9fc 32027+ arg->err = au_nhash_append_wh
dece6358
AM
32028+ (&arg->whlist, name, nlen, ino, d_type,
32029+ arg->bindex, shwh);
4a4d8108 32030+ }
1facf9fc 32031+ }
32032+
4f0767ce 32033+out:
1facf9fc 32034+ if (!arg->err)
32035+ arg->vdir->vd_jiffy = jiffies;
32036+ /* smp_mb(); */
32037+ AuTraceErr(arg->err);
32038+ return arg->err;
32039+}
32040+
dece6358
AM
32041+static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
32042+ struct au_nhash *whlist, struct au_nhash *delist)
32043+{
32044+#ifdef CONFIG_AUFS_SHWH
32045+ int err;
32046+ unsigned int nh, u;
32047+ struct hlist_head *head;
c06a8ce3
AM
32048+ struct au_vdir_wh *pos;
32049+ struct hlist_node *n;
dece6358
AM
32050+ char *p, *o;
32051+ struct au_vdir_destr *destr;
32052+
32053+ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
32054+
32055+ err = -ENOMEM;
537831f9 32056+ o = p = (void *)__get_free_page(GFP_NOFS);
dece6358
AM
32057+ if (unlikely(!p))
32058+ goto out;
32059+
32060+ err = 0;
32061+ nh = whlist->nh_num;
32062+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
32063+ p += AUFS_WH_PFX_LEN;
32064+ for (u = 0; u < nh; u++) {
32065+ head = whlist->nh_head + u;
c06a8ce3
AM
32066+ hlist_for_each_entry_safe(pos, n, head, wh_hash) {
32067+ destr = &pos->wh_str;
dece6358
AM
32068+ memcpy(p, destr->name, destr->len);
32069+ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
c06a8ce3 32070+ pos->wh_ino, pos->wh_type, delist);
dece6358
AM
32071+ if (unlikely(err))
32072+ break;
32073+ }
32074+ }
32075+
ae9dfd79 32076+ free_page((unsigned long)o);
dece6358 32077+
4f0767ce 32078+out:
dece6358
AM
32079+ AuTraceErr(err);
32080+ return err;
32081+#else
32082+ return 0;
32083+#endif
32084+}
32085+
1facf9fc 32086+static int au_do_read_vdir(struct fillvdir_arg *arg)
32087+{
32088+ int err;
dece6358 32089+ unsigned int rdhash;
1facf9fc 32090+ loff_t offset;
5afbbe0d 32091+ aufs_bindex_t bbot, bindex, btop;
dece6358 32092+ unsigned char shwh;
1facf9fc 32093+ struct file *hf, *file;
32094+ struct super_block *sb;
32095+
1facf9fc 32096+ file = arg->file;
2000de60 32097+ sb = file->f_path.dentry->d_sb;
dece6358
AM
32098+ SiMustAnyLock(sb);
32099+
32100+ rdhash = au_sbi(sb)->si_rdhash;
1308ab2a 32101+ if (!rdhash)
32102+ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
dece6358
AM
32103+ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
32104+ if (unlikely(err))
1facf9fc 32105+ goto out;
dece6358
AM
32106+ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
32107+ if (unlikely(err))
1facf9fc 32108+ goto out_delist;
32109+
32110+ err = 0;
32111+ arg->flags = 0;
dece6358
AM
32112+ shwh = 0;
32113+ if (au_opt_test(au_mntflags(sb), SHWH)) {
32114+ shwh = 1;
32115+ au_fset_fillvdir(arg->flags, SHWH);
32116+ }
5afbbe0d
AM
32117+ btop = au_fbtop(file);
32118+ bbot = au_fbbot_dir(file);
32119+ for (bindex = btop; !err && bindex <= bbot; bindex++) {
4a4d8108 32120+ hf = au_hf_dir(file, bindex);
1facf9fc 32121+ if (!hf)
32122+ continue;
32123+
32124+ offset = vfsub_llseek(hf, 0, SEEK_SET);
32125+ err = offset;
32126+ if (unlikely(offset))
32127+ break;
32128+
32129+ arg->bindex = bindex;
32130+ au_fclr_fillvdir(arg->flags, WHABLE);
dece6358 32131+ if (shwh
5afbbe0d 32132+ || (bindex != bbot
dece6358 32133+ && au_br_whable(au_sbr_perm(sb, bindex))))
1facf9fc 32134+ au_fset_fillvdir(arg->flags, WHABLE);
32135+ do {
32136+ arg->err = 0;
32137+ au_fclr_fillvdir(arg->flags, CALLED);
32138+ /* smp_mb(); */
392086de 32139+ err = vfsub_iterate_dir(hf, &arg->ctx);
1facf9fc 32140+ if (err >= 0)
32141+ err = arg->err;
32142+ } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
392086de
AM
32143+
32144+ /*
32145+ * dir_relax() may be good for concurrency, but aufs should not
32146+ * use it since it will cause a lockdep problem.
32147+ */
1facf9fc 32148+ }
dece6358
AM
32149+
32150+ if (!err && shwh)
32151+ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
32152+
32153+ au_nhash_wh_free(&arg->whlist);
1facf9fc 32154+
4f0767ce 32155+out_delist:
dece6358 32156+ au_nhash_de_free(&arg->delist);
4f0767ce 32157+out:
1facf9fc 32158+ return err;
32159+}
32160+
32161+static int read_vdir(struct file *file, int may_read)
32162+{
32163+ int err;
32164+ unsigned long expire;
32165+ unsigned char do_read;
392086de
AM
32166+ struct fillvdir_arg arg = {
32167+ .ctx = {
2000de60 32168+ .actor = fillvdir
392086de
AM
32169+ }
32170+ };
1facf9fc 32171+ struct inode *inode;
32172+ struct au_vdir *vdir, *allocated;
32173+
32174+ err = 0;
c06a8ce3 32175+ inode = file_inode(file);
1facf9fc 32176+ IMustLock(inode);
5afbbe0d 32177+ IiMustWriteLock(inode);
dece6358
AM
32178+ SiMustAnyLock(inode->i_sb);
32179+
1facf9fc 32180+ allocated = NULL;
32181+ do_read = 0;
32182+ expire = au_sbi(inode->i_sb)->si_rdcache;
32183+ vdir = au_ivdir(inode);
32184+ if (!vdir) {
32185+ do_read = 1;
1308ab2a 32186+ vdir = alloc_vdir(file);
1facf9fc 32187+ err = PTR_ERR(vdir);
32188+ if (IS_ERR(vdir))
32189+ goto out;
32190+ err = 0;
32191+ allocated = vdir;
32192+ } else if (may_read
32193+ && (inode->i_version != vdir->vd_version
32194+ || time_after(jiffies, vdir->vd_jiffy + expire))) {
32195+ do_read = 1;
32196+ err = reinit_vdir(vdir);
32197+ if (unlikely(err))
32198+ goto out;
32199+ }
32200+
32201+ if (!do_read)
32202+ return 0; /* success */
32203+
32204+ arg.file = file;
32205+ arg.vdir = vdir;
32206+ err = au_do_read_vdir(&arg);
32207+ if (!err) {
392086de 32208+ /* file->f_pos = 0; */ /* todo: ctx->pos? */
1facf9fc 32209+ vdir->vd_version = inode->i_version;
32210+ vdir->vd_last.ul = 0;
32211+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
32212+ if (allocated)
32213+ au_set_ivdir(inode, allocated);
32214+ } else if (allocated)
ae9dfd79 32215+ au_vdir_free(allocated);
1facf9fc 32216+
4f0767ce 32217+out:
1facf9fc 32218+ return err;
32219+}
32220+
32221+static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
32222+{
32223+ int err, rerr;
32224+ unsigned long ul, n;
32225+ const unsigned int deblk_sz = src->vd_deblk_sz;
32226+
32227+ AuDebugOn(tgt->vd_nblk != 1);
32228+
32229+ err = -ENOMEM;
32230+ if (tgt->vd_nblk < src->vd_nblk) {
32231+ unsigned char **p;
32232+
e2f27e51
AM
32233+ p = au_krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
32234+ GFP_NOFS, /*may_shrink*/0);
1facf9fc 32235+ if (unlikely(!p))
32236+ goto out;
32237+ tgt->vd_deblk = p;
32238+ }
32239+
1308ab2a 32240+ if (tgt->vd_deblk_sz != deblk_sz) {
32241+ unsigned char *p;
32242+
32243+ tgt->vd_deblk_sz = deblk_sz;
e2f27e51
AM
32244+ p = au_krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS,
32245+ /*may_shrink*/1);
1308ab2a 32246+ if (unlikely(!p))
32247+ goto out;
32248+ tgt->vd_deblk[0] = p;
32249+ }
1facf9fc 32250+ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
1facf9fc 32251+ tgt->vd_version = src->vd_version;
32252+ tgt->vd_jiffy = src->vd_jiffy;
32253+
32254+ n = src->vd_nblk;
32255+ for (ul = 1; ul < n; ul++) {
dece6358
AM
32256+ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
32257+ GFP_NOFS);
32258+ if (unlikely(!tgt->vd_deblk[ul]))
1facf9fc 32259+ goto out;
1308ab2a 32260+ tgt->vd_nblk++;
1facf9fc 32261+ }
1308ab2a 32262+ tgt->vd_nblk = n;
32263+ tgt->vd_last.ul = tgt->vd_last.ul;
32264+ tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul];
32265+ tgt->vd_last.p.deblk += src->vd_last.p.deblk
32266+ - src->vd_deblk[src->vd_last.ul];
1facf9fc 32267+ /* smp_mb(); */
32268+ return 0; /* success */
32269+
4f0767ce 32270+out:
1facf9fc 32271+ rerr = reinit_vdir(tgt);
32272+ BUG_ON(rerr);
32273+ return err;
32274+}
32275+
32276+int au_vdir_init(struct file *file)
32277+{
32278+ int err;
32279+ struct inode *inode;
32280+ struct au_vdir *vdir_cache, *allocated;
32281+
392086de 32282+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 32283+ err = read_vdir(file, !file->f_pos);
32284+ if (unlikely(err))
32285+ goto out;
32286+
32287+ allocated = NULL;
32288+ vdir_cache = au_fvdir_cache(file);
32289+ if (!vdir_cache) {
1308ab2a 32290+ vdir_cache = alloc_vdir(file);
1facf9fc 32291+ err = PTR_ERR(vdir_cache);
32292+ if (IS_ERR(vdir_cache))
32293+ goto out;
32294+ allocated = vdir_cache;
32295+ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
392086de 32296+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 32297+ err = reinit_vdir(vdir_cache);
32298+ if (unlikely(err))
32299+ goto out;
32300+ } else
32301+ return 0; /* success */
32302+
c06a8ce3 32303+ inode = file_inode(file);
1facf9fc 32304+ err = copy_vdir(vdir_cache, au_ivdir(inode));
32305+ if (!err) {
32306+ file->f_version = inode->i_version;
32307+ if (allocated)
32308+ au_set_fvdir_cache(file, allocated);
32309+ } else if (allocated)
ae9dfd79 32310+ au_vdir_free(allocated);
1facf9fc 32311+
4f0767ce 32312+out:
1facf9fc 32313+ return err;
32314+}
32315+
32316+static loff_t calc_offset(struct au_vdir *vdir)
32317+{
32318+ loff_t offset;
32319+ union au_vdir_deblk_p p;
32320+
32321+ p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
32322+ offset = vdir->vd_last.p.deblk - p.deblk;
32323+ offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
32324+ return offset;
32325+}
32326+
32327+/* returns true or false */
392086de 32328+static int seek_vdir(struct file *file, struct dir_context *ctx)
1facf9fc 32329+{
32330+ int valid;
32331+ unsigned int deblk_sz;
32332+ unsigned long ul, n;
32333+ loff_t offset;
32334+ union au_vdir_deblk_p p, deblk_end;
32335+ struct au_vdir *vdir_cache;
32336+
32337+ valid = 1;
32338+ vdir_cache = au_fvdir_cache(file);
32339+ offset = calc_offset(vdir_cache);
32340+ AuDbg("offset %lld\n", offset);
392086de 32341+ if (ctx->pos == offset)
1facf9fc 32342+ goto out;
32343+
32344+ vdir_cache->vd_last.ul = 0;
32345+ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
392086de 32346+ if (!ctx->pos)
1facf9fc 32347+ goto out;
32348+
32349+ valid = 0;
32350+ deblk_sz = vdir_cache->vd_deblk_sz;
392086de 32351+ ul = div64_u64(ctx->pos, deblk_sz);
1facf9fc 32352+ AuDbg("ul %lu\n", ul);
32353+ if (ul >= vdir_cache->vd_nblk)
32354+ goto out;
32355+
32356+ n = vdir_cache->vd_nblk;
32357+ for (; ul < n; ul++) {
32358+ p.deblk = vdir_cache->vd_deblk[ul];
32359+ deblk_end.deblk = p.deblk + deblk_sz;
32360+ offset = ul;
32361+ offset *= deblk_sz;
392086de 32362+ while (!is_deblk_end(&p, &deblk_end) && offset < ctx->pos) {
1facf9fc 32363+ unsigned int l;
32364+
32365+ l = calc_size(p.de->de_str.len);
32366+ offset += l;
32367+ p.deblk += l;
32368+ }
32369+ if (!is_deblk_end(&p, &deblk_end)) {
32370+ valid = 1;
32371+ vdir_cache->vd_last.ul = ul;
32372+ vdir_cache->vd_last.p = p;
32373+ break;
32374+ }
32375+ }
32376+
4f0767ce 32377+out:
1facf9fc 32378+ /* smp_mb(); */
ae9dfd79
AM
32379+ if (!valid)
32380+ AuDbg("valid %d\n", !valid);
1facf9fc 32381+ return valid;
32382+}
32383+
392086de 32384+int au_vdir_fill_de(struct file *file, struct dir_context *ctx)
1facf9fc 32385+{
1facf9fc 32386+ unsigned int l, deblk_sz;
32387+ union au_vdir_deblk_p deblk_end;
32388+ struct au_vdir *vdir_cache;
32389+ struct au_vdir_de *de;
32390+
32391+ vdir_cache = au_fvdir_cache(file);
392086de 32392+ if (!seek_vdir(file, ctx))
1facf9fc 32393+ return 0;
32394+
32395+ deblk_sz = vdir_cache->vd_deblk_sz;
32396+ while (1) {
32397+ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
32398+ deblk_end.deblk += deblk_sz;
32399+ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
32400+ de = vdir_cache->vd_last.p.de;
32401+ AuDbg("%.*s, off%lld, i%lu, dt%d\n",
392086de 32402+ de->de_str.len, de->de_str.name, ctx->pos,
1facf9fc 32403+ (unsigned long)de->de_ino, de->de_type);
392086de
AM
32404+ if (unlikely(!dir_emit(ctx, de->de_str.name,
32405+ de->de_str.len, de->de_ino,
32406+ de->de_type))) {
1facf9fc 32407+ /* todo: ignore the error caused by udba? */
32408+ /* return err; */
32409+ return 0;
32410+ }
32411+
32412+ l = calc_size(de->de_str.len);
32413+ vdir_cache->vd_last.p.deblk += l;
392086de 32414+ ctx->pos += l;
1facf9fc 32415+ }
32416+ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
32417+ vdir_cache->vd_last.ul++;
32418+ vdir_cache->vd_last.p.deblk
32419+ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
392086de 32420+ ctx->pos = deblk_sz * vdir_cache->vd_last.ul;
1facf9fc 32421+ continue;
32422+ }
32423+ break;
32424+ }
32425+
32426+ /* smp_mb(); */
32427+ return 0;
32428+}
7f207e10
AM
32429diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
32430--- /usr/share/empty/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
32431+++ linux/fs/aufs/vfsub.c 2018-04-15 08:49:13.404484168 +0200
32432@@ -0,0 +1,894 @@
1facf9fc 32433+/*
ae9dfd79 32434+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 32435+ *
32436+ * This program, aufs is free software; you can redistribute it and/or modify
32437+ * it under the terms of the GNU General Public License as published by
32438+ * the Free Software Foundation; either version 2 of the License, or
32439+ * (at your option) any later version.
dece6358
AM
32440+ *
32441+ * This program is distributed in the hope that it will be useful,
32442+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32443+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32444+ * GNU General Public License for more details.
32445+ *
32446+ * You should have received a copy of the GNU General Public License
523b37e3 32447+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 32448+ */
32449+
32450+/*
32451+ * sub-routines for VFS
32452+ */
32453+
ae9dfd79 32454+#include <linux/mnt_namespace.h>
dece6358 32455+#include <linux/namei.h>
8cdd5066 32456+#include <linux/nsproxy.h>
dece6358
AM
32457+#include <linux/security.h>
32458+#include <linux/splice.h>
1facf9fc 32459+#include "aufs.h"
32460+
8cdd5066
JR
32461+#ifdef CONFIG_AUFS_BR_FUSE
32462+int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb)
32463+{
8cdd5066
JR
32464+ if (!au_test_fuse(h_sb) || !au_userns)
32465+ return 0;
32466+
ae9dfd79 32467+ return is_current_mnt_ns(mnt) ? 0 : -EACCES;
8cdd5066
JR
32468+}
32469+#endif
32470+
ae9dfd79
AM
32471+int vfsub_sync_filesystem(struct super_block *h_sb, int wait)
32472+{
32473+ int err;
32474+
32475+ lockdep_off();
32476+ down_read(&h_sb->s_umount);
32477+ err = __sync_filesystem(h_sb, wait);
32478+ up_read(&h_sb->s_umount);
32479+ lockdep_on();
32480+
32481+ return err;
32482+}
32483+
8cdd5066
JR
32484+/* ---------------------------------------------------------------------- */
32485+
1facf9fc 32486+int vfsub_update_h_iattr(struct path *h_path, int *did)
32487+{
32488+ int err;
32489+ struct kstat st;
32490+ struct super_block *h_sb;
32491+
32492+ /* for remote fs, leave work for its getattr or d_revalidate */
32493+ /* for bad i_attr fs, handle them in aufs_getattr() */
32494+ /* still some fs may acquire i_mutex. we need to skip them */
32495+ err = 0;
32496+ if (!did)
32497+ did = &err;
32498+ h_sb = h_path->dentry->d_sb;
32499+ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
32500+ if (*did)
c06a8ce3 32501+ err = vfs_getattr(h_path, &st);
1facf9fc 32502+
32503+ return err;
32504+}
32505+
32506+/* ---------------------------------------------------------------------- */
32507+
4a4d8108 32508+struct file *vfsub_dentry_open(struct path *path, int flags)
1308ab2a 32509+{
32510+ struct file *file;
32511+
b4510431 32512+ file = dentry_open(path, flags /* | __FMODE_NONOTIFY */,
7f207e10 32513+ current_cred());
2cbb1c4b
JR
32514+ if (!IS_ERR_OR_NULL(file)
32515+ && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
5527c038 32516+ i_readcount_inc(d_inode(path->dentry));
4a4d8108 32517+
1308ab2a 32518+ return file;
32519+}
32520+
1facf9fc 32521+struct file *vfsub_filp_open(const char *path, int oflags, int mode)
32522+{
32523+ struct file *file;
32524+
2cbb1c4b 32525+ lockdep_off();
7f207e10 32526+ file = filp_open(path,
2cbb1c4b 32527+ oflags /* | __FMODE_NONOTIFY */,
7f207e10 32528+ mode);
2cbb1c4b 32529+ lockdep_on();
1facf9fc 32530+ if (IS_ERR(file))
32531+ goto out;
32532+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
32533+
4f0767ce 32534+out:
1facf9fc 32535+ return file;
32536+}
32537+
b912730e
AM
32538+/*
32539+ * Ideally this function should call VFS:do_last() in order to keep all its
32540+ * checkings. But it is very hard for aufs to regenerate several VFS internal
32541+ * structure such as nameidata. This is a second (or third) best approach.
32542+ * cf. linux/fs/namei.c:do_last(), lookup_open() and atomic_open().
32543+ */
32544+int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
32545+ struct vfsub_aopen_args *args, struct au_branch *br)
32546+{
32547+ int err;
32548+ struct file *file = args->file;
32549+ /* copied from linux/fs/namei.c:atomic_open() */
32550+ struct dentry *const DENTRY_NOT_SET = (void *)-1UL;
32551+
32552+ IMustLock(dir);
32553+ AuDebugOn(!dir->i_op->atomic_open);
32554+
32555+ err = au_br_test_oflag(args->open_flag, br);
32556+ if (unlikely(err))
32557+ goto out;
32558+
32559+ args->file->f_path.dentry = DENTRY_NOT_SET;
32560+ args->file->f_path.mnt = au_br_mnt(br);
32561+ err = dir->i_op->atomic_open(dir, dentry, file, args->open_flag,
32562+ args->create_mode, args->opened);
32563+ if (err >= 0) {
32564+ /* some filesystems don't set FILE_CREATED while succeeded? */
32565+ if (*args->opened & FILE_CREATED)
32566+ fsnotify_create(dir, dentry);
32567+ } else
32568+ goto out;
32569+
32570+
32571+ if (!err) {
32572+ /* todo: call VFS:may_open() here */
32573+ err = open_check_o_direct(file);
32574+ /* todo: ima_file_check() too? */
32575+ if (!err && (args->open_flag & __FMODE_EXEC))
32576+ err = deny_write_access(file);
32577+ if (unlikely(err))
32578+ /* note that the file is created and still opened */
32579+ goto out;
32580+ }
32581+
5afbbe0d 32582+ au_br_get(br);
b912730e
AM
32583+ fsnotify_open(file);
32584+
32585+out:
32586+ return err;
32587+}
32588+
1facf9fc 32589+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
32590+{
32591+ int err;
32592+
1facf9fc 32593+ err = kern_path(name, flags, path);
5527c038 32594+ if (!err && d_is_positive(path->dentry))
1facf9fc 32595+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
32596+ return err;
32597+}
32598+
febd17d6
JR
32599+struct dentry *vfsub_lookup_one_len_unlocked(const char *name,
32600+ struct dentry *parent, int len)
32601+{
32602+ struct path path = {
32603+ .mnt = NULL
32604+ };
32605+
32606+ path.dentry = lookup_one_len_unlocked(name, parent, len);
32607+ if (IS_ERR(path.dentry))
32608+ goto out;
32609+ if (d_is_positive(path.dentry))
32610+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
32611+
32612+out:
32613+ AuTraceErrPtr(path.dentry);
32614+ return path.dentry;
32615+}
32616+
1facf9fc 32617+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
32618+ int len)
32619+{
32620+ struct path path = {
32621+ .mnt = NULL
32622+ };
32623+
1308ab2a 32624+ /* VFS checks it too, but by WARN_ON_ONCE() */
5527c038 32625+ IMustLock(d_inode(parent));
1facf9fc 32626+
32627+ path.dentry = lookup_one_len(name, parent, len);
32628+ if (IS_ERR(path.dentry))
32629+ goto out;
5527c038 32630+ if (d_is_positive(path.dentry))
1facf9fc 32631+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
32632+
4f0767ce 32633+out:
4a4d8108 32634+ AuTraceErrPtr(path.dentry);
1facf9fc 32635+ return path.dentry;
32636+}
32637+
b4510431 32638+void vfsub_call_lkup_one(void *args)
2cbb1c4b 32639+{
b4510431
AM
32640+ struct vfsub_lkup_one_args *a = args;
32641+ *a->errp = vfsub_lkup_one(a->name, a->parent);
2cbb1c4b
JR
32642+}
32643+
1facf9fc 32644+/* ---------------------------------------------------------------------- */
32645+
32646+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
32647+ struct dentry *d2, struct au_hinode *hdir2)
32648+{
32649+ struct dentry *d;
32650+
2cbb1c4b 32651+ lockdep_off();
1facf9fc 32652+ d = lock_rename(d1, d2);
2cbb1c4b 32653+ lockdep_on();
4a4d8108 32654+ au_hn_suspend(hdir1);
1facf9fc 32655+ if (hdir1 != hdir2)
4a4d8108 32656+ au_hn_suspend(hdir2);
1facf9fc 32657+
32658+ return d;
32659+}
32660+
32661+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
32662+ struct dentry *d2, struct au_hinode *hdir2)
32663+{
4a4d8108 32664+ au_hn_resume(hdir1);
1facf9fc 32665+ if (hdir1 != hdir2)
4a4d8108 32666+ au_hn_resume(hdir2);
2cbb1c4b 32667+ lockdep_off();
1facf9fc 32668+ unlock_rename(d1, d2);
2cbb1c4b 32669+ lockdep_on();
1facf9fc 32670+}
32671+
32672+/* ---------------------------------------------------------------------- */
32673+
b4510431 32674+int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl)
1facf9fc 32675+{
32676+ int err;
32677+ struct dentry *d;
32678+
32679+ IMustLock(dir);
32680+
32681+ d = path->dentry;
32682+ path->dentry = d->d_parent;
b752ccd1 32683+ err = security_path_mknod(path, d, mode, 0);
1facf9fc 32684+ path->dentry = d;
32685+ if (unlikely(err))
32686+ goto out;
32687+
c1595e42 32688+ lockdep_off();
b4510431 32689+ err = vfs_create(dir, path->dentry, mode, want_excl);
c1595e42 32690+ lockdep_on();
1facf9fc 32691+ if (!err) {
32692+ struct path tmp = *path;
32693+ int did;
32694+
32695+ vfsub_update_h_iattr(&tmp, &did);
32696+ if (did) {
32697+ tmp.dentry = path->dentry->d_parent;
32698+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
32699+ }
32700+ /*ignore*/
32701+ }
32702+
4f0767ce 32703+out:
1facf9fc 32704+ return err;
32705+}
32706+
32707+int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
32708+{
32709+ int err;
32710+ struct dentry *d;
32711+
32712+ IMustLock(dir);
32713+
32714+ d = path->dentry;
32715+ path->dentry = d->d_parent;
b752ccd1 32716+ err = security_path_symlink(path, d, symname);
1facf9fc 32717+ path->dentry = d;
32718+ if (unlikely(err))
32719+ goto out;
32720+
c1595e42 32721+ lockdep_off();
1facf9fc 32722+ err = vfs_symlink(dir, path->dentry, symname);
c1595e42 32723+ lockdep_on();
1facf9fc 32724+ if (!err) {
32725+ struct path tmp = *path;
32726+ int did;
32727+
32728+ vfsub_update_h_iattr(&tmp, &did);
32729+ if (did) {
32730+ tmp.dentry = path->dentry->d_parent;
32731+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
32732+ }
32733+ /*ignore*/
32734+ }
32735+
4f0767ce 32736+out:
1facf9fc 32737+ return err;
32738+}
32739+
32740+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
32741+{
32742+ int err;
32743+ struct dentry *d;
32744+
32745+ IMustLock(dir);
32746+
32747+ d = path->dentry;
32748+ path->dentry = d->d_parent;
027c5e7a 32749+ err = security_path_mknod(path, d, mode, new_encode_dev(dev));
1facf9fc 32750+ path->dentry = d;
32751+ if (unlikely(err))
32752+ goto out;
32753+
c1595e42 32754+ lockdep_off();
1facf9fc 32755+ err = vfs_mknod(dir, path->dentry, mode, dev);
c1595e42 32756+ lockdep_on();
1facf9fc 32757+ if (!err) {
32758+ struct path tmp = *path;
32759+ int did;
32760+
32761+ vfsub_update_h_iattr(&tmp, &did);
32762+ if (did) {
32763+ tmp.dentry = path->dentry->d_parent;
32764+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
32765+ }
32766+ /*ignore*/
32767+ }
32768+
4f0767ce 32769+out:
1facf9fc 32770+ return err;
32771+}
32772+
32773+static int au_test_nlink(struct inode *inode)
32774+{
32775+ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
32776+
32777+ if (!au_test_fs_no_limit_nlink(inode->i_sb)
32778+ || inode->i_nlink < link_max)
32779+ return 0;
32780+ return -EMLINK;
32781+}
32782+
523b37e3
AM
32783+int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path,
32784+ struct inode **delegated_inode)
1facf9fc 32785+{
32786+ int err;
32787+ struct dentry *d;
32788+
32789+ IMustLock(dir);
32790+
5527c038 32791+ err = au_test_nlink(d_inode(src_dentry));
1facf9fc 32792+ if (unlikely(err))
32793+ return err;
32794+
b4510431 32795+ /* we don't call may_linkat() */
1facf9fc 32796+ d = path->dentry;
32797+ path->dentry = d->d_parent;
b752ccd1 32798+ err = security_path_link(src_dentry, path, d);
1facf9fc 32799+ path->dentry = d;
32800+ if (unlikely(err))
32801+ goto out;
32802+
2cbb1c4b 32803+ lockdep_off();
523b37e3 32804+ err = vfs_link(src_dentry, dir, path->dentry, delegated_inode);
2cbb1c4b 32805+ lockdep_on();
1facf9fc 32806+ if (!err) {
32807+ struct path tmp = *path;
32808+ int did;
32809+
32810+ /* fuse has different memory inode for the same inumber */
32811+ vfsub_update_h_iattr(&tmp, &did);
32812+ if (did) {
32813+ tmp.dentry = path->dentry->d_parent;
32814+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
32815+ tmp.dentry = src_dentry;
32816+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
32817+ }
32818+ /*ignore*/
32819+ }
32820+
4f0767ce 32821+out:
1facf9fc 32822+ return err;
32823+}
32824+
32825+int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
523b37e3 32826+ struct inode *dir, struct path *path,
f2c43d5f 32827+ struct inode **delegated_inode, unsigned int flags)
1facf9fc 32828+{
32829+ int err;
32830+ struct path tmp = {
32831+ .mnt = path->mnt
32832+ };
32833+ struct dentry *d;
32834+
32835+ IMustLock(dir);
32836+ IMustLock(src_dir);
32837+
32838+ d = path->dentry;
32839+ path->dentry = d->d_parent;
32840+ tmp.dentry = src_dentry->d_parent;
38d290e6 32841+ err = security_path_rename(&tmp, src_dentry, path, d, /*flags*/0);
1facf9fc 32842+ path->dentry = d;
32843+ if (unlikely(err))
32844+ goto out;
32845+
2cbb1c4b 32846+ lockdep_off();
523b37e3 32847+ err = vfs_rename(src_dir, src_dentry, dir, path->dentry,
f2c43d5f 32848+ delegated_inode, flags);
2cbb1c4b 32849+ lockdep_on();
1facf9fc 32850+ if (!err) {
32851+ int did;
32852+
32853+ tmp.dentry = d->d_parent;
32854+ vfsub_update_h_iattr(&tmp, &did);
32855+ if (did) {
32856+ tmp.dentry = src_dentry;
32857+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
32858+ tmp.dentry = src_dentry->d_parent;
32859+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
32860+ }
32861+ /*ignore*/
32862+ }
32863+
4f0767ce 32864+out:
1facf9fc 32865+ return err;
32866+}
32867+
32868+int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
32869+{
32870+ int err;
32871+ struct dentry *d;
32872+
32873+ IMustLock(dir);
32874+
32875+ d = path->dentry;
32876+ path->dentry = d->d_parent;
b752ccd1 32877+ err = security_path_mkdir(path, d, mode);
1facf9fc 32878+ path->dentry = d;
32879+ if (unlikely(err))
32880+ goto out;
32881+
c1595e42 32882+ lockdep_off();
1facf9fc 32883+ err = vfs_mkdir(dir, path->dentry, mode);
c1595e42 32884+ lockdep_on();
1facf9fc 32885+ if (!err) {
32886+ struct path tmp = *path;
32887+ int did;
32888+
32889+ vfsub_update_h_iattr(&tmp, &did);
32890+ if (did) {
32891+ tmp.dentry = path->dentry->d_parent;
32892+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
32893+ }
32894+ /*ignore*/
32895+ }
32896+
4f0767ce 32897+out:
1facf9fc 32898+ return err;
32899+}
32900+
32901+int vfsub_rmdir(struct inode *dir, struct path *path)
32902+{
32903+ int err;
32904+ struct dentry *d;
32905+
32906+ IMustLock(dir);
32907+
32908+ d = path->dentry;
32909+ path->dentry = d->d_parent;
b752ccd1 32910+ err = security_path_rmdir(path, d);
1facf9fc 32911+ path->dentry = d;
32912+ if (unlikely(err))
32913+ goto out;
32914+
2cbb1c4b 32915+ lockdep_off();
1facf9fc 32916+ err = vfs_rmdir(dir, path->dentry);
2cbb1c4b 32917+ lockdep_on();
1facf9fc 32918+ if (!err) {
32919+ struct path tmp = {
32920+ .dentry = path->dentry->d_parent,
32921+ .mnt = path->mnt
32922+ };
32923+
32924+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
32925+ }
32926+
4f0767ce 32927+out:
1facf9fc 32928+ return err;
32929+}
32930+
32931+/* ---------------------------------------------------------------------- */
32932+
9dbd164d 32933+/* todo: support mmap_sem? */
1facf9fc 32934+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
32935+ loff_t *ppos)
32936+{
32937+ ssize_t err;
32938+
2cbb1c4b 32939+ lockdep_off();
1facf9fc 32940+ err = vfs_read(file, ubuf, count, ppos);
2cbb1c4b 32941+ lockdep_on();
1facf9fc 32942+ if (err >= 0)
32943+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
32944+ return err;
32945+}
32946+
32947+/* todo: kernel_read()? */
32948+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
32949+ loff_t *ppos)
32950+{
32951+ ssize_t err;
32952+ mm_segment_t oldfs;
b752ccd1
AM
32953+ union {
32954+ void *k;
32955+ char __user *u;
32956+ } buf;
1facf9fc 32957+
b752ccd1 32958+ buf.k = kbuf;
1facf9fc 32959+ oldfs = get_fs();
32960+ set_fs(KERNEL_DS);
b752ccd1 32961+ err = vfsub_read_u(file, buf.u, count, ppos);
1facf9fc 32962+ set_fs(oldfs);
32963+ return err;
32964+}
32965+
32966+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
32967+ loff_t *ppos)
32968+{
32969+ ssize_t err;
32970+
2cbb1c4b 32971+ lockdep_off();
1facf9fc 32972+ err = vfs_write(file, ubuf, count, ppos);
2cbb1c4b 32973+ lockdep_on();
1facf9fc 32974+ if (err >= 0)
32975+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
32976+ return err;
32977+}
32978+
32979+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
32980+{
32981+ ssize_t err;
32982+ mm_segment_t oldfs;
b752ccd1
AM
32983+ union {
32984+ void *k;
32985+ const char __user *u;
32986+ } buf;
1facf9fc 32987+
b752ccd1 32988+ buf.k = kbuf;
1facf9fc 32989+ oldfs = get_fs();
32990+ set_fs(KERNEL_DS);
b752ccd1 32991+ err = vfsub_write_u(file, buf.u, count, ppos);
1facf9fc 32992+ set_fs(oldfs);
32993+ return err;
32994+}
32995+
4a4d8108
AM
32996+int vfsub_flush(struct file *file, fl_owner_t id)
32997+{
32998+ int err;
32999+
33000+ err = 0;
523b37e3 33001+ if (file->f_op->flush) {
2000de60 33002+ if (!au_test_nfs(file->f_path.dentry->d_sb))
2cbb1c4b
JR
33003+ err = file->f_op->flush(file, id);
33004+ else {
33005+ lockdep_off();
33006+ err = file->f_op->flush(file, id);
33007+ lockdep_on();
33008+ }
4a4d8108
AM
33009+ if (!err)
33010+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
33011+ /*ignore*/
33012+ }
33013+ return err;
33014+}
33015+
392086de 33016+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx)
1facf9fc 33017+{
33018+ int err;
33019+
523b37e3 33020+ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
392086de 33021+
2cbb1c4b 33022+ lockdep_off();
392086de 33023+ err = iterate_dir(file, ctx);
2cbb1c4b 33024+ lockdep_on();
1facf9fc 33025+ if (err >= 0)
33026+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
ae9dfd79 33027+
1facf9fc 33028+ return err;
33029+}
33030+
33031+long vfsub_splice_to(struct file *in, loff_t *ppos,
33032+ struct pipe_inode_info *pipe, size_t len,
33033+ unsigned int flags)
33034+{
33035+ long err;
33036+
2cbb1c4b 33037+ lockdep_off();
0fc653ad 33038+ err = do_splice_to(in, ppos, pipe, len, flags);
2cbb1c4b 33039+ lockdep_on();
4a4d8108 33040+ file_accessed(in);
1facf9fc 33041+ if (err >= 0)
33042+ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
33043+ return err;
33044+}
33045+
33046+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
33047+ loff_t *ppos, size_t len, unsigned int flags)
33048+{
33049+ long err;
33050+
2cbb1c4b 33051+ lockdep_off();
0fc653ad 33052+ err = do_splice_from(pipe, out, ppos, len, flags);
2cbb1c4b 33053+ lockdep_on();
1facf9fc 33054+ if (err >= 0)
33055+ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
33056+ return err;
33057+}
33058+
53392da6
AM
33059+int vfsub_fsync(struct file *file, struct path *path, int datasync)
33060+{
33061+ int err;
33062+
33063+ /* file can be NULL */
33064+ lockdep_off();
33065+ err = vfs_fsync(file, datasync);
33066+ lockdep_on();
33067+ if (!err) {
33068+ if (!path) {
33069+ AuDebugOn(!file);
33070+ path = &file->f_path;
33071+ }
33072+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
33073+ }
33074+ return err;
33075+}
33076+
1facf9fc 33077+/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
33078+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
33079+ struct file *h_file)
33080+{
33081+ int err;
33082+ struct inode *h_inode;
c06a8ce3 33083+ struct super_block *h_sb;
1facf9fc 33084+
1facf9fc 33085+ if (!h_file) {
c06a8ce3
AM
33086+ err = vfsub_truncate(h_path, length);
33087+ goto out;
1facf9fc 33088+ }
33089+
5527c038 33090+ h_inode = d_inode(h_path->dentry);
c06a8ce3
AM
33091+ h_sb = h_inode->i_sb;
33092+ lockdep_off();
33093+ sb_start_write(h_sb);
33094+ lockdep_on();
1facf9fc 33095+ err = locks_verify_truncate(h_inode, h_file, length);
33096+ if (!err)
953406b4 33097+ err = security_path_truncate(h_path);
2cbb1c4b
JR
33098+ if (!err) {
33099+ lockdep_off();
1facf9fc 33100+ err = do_truncate(h_path->dentry, length, attr, h_file);
2cbb1c4b
JR
33101+ lockdep_on();
33102+ }
c06a8ce3
AM
33103+ lockdep_off();
33104+ sb_end_write(h_sb);
33105+ lockdep_on();
1facf9fc 33106+
4f0767ce 33107+out:
1facf9fc 33108+ return err;
33109+}
33110+
33111+/* ---------------------------------------------------------------------- */
33112+
33113+struct au_vfsub_mkdir_args {
33114+ int *errp;
33115+ struct inode *dir;
33116+ struct path *path;
33117+ int mode;
33118+};
33119+
33120+static void au_call_vfsub_mkdir(void *args)
33121+{
33122+ struct au_vfsub_mkdir_args *a = args;
33123+ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
33124+}
33125+
33126+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
33127+{
33128+ int err, do_sio, wkq_err;
33129+
33130+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
c1595e42
JR
33131+ if (!do_sio) {
33132+ lockdep_off();
1facf9fc 33133+ err = vfsub_mkdir(dir, path, mode);
c1595e42
JR
33134+ lockdep_on();
33135+ } else {
1facf9fc 33136+ struct au_vfsub_mkdir_args args = {
33137+ .errp = &err,
33138+ .dir = dir,
33139+ .path = path,
33140+ .mode = mode
33141+ };
33142+ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
33143+ if (unlikely(wkq_err))
33144+ err = wkq_err;
33145+ }
33146+
33147+ return err;
33148+}
33149+
33150+struct au_vfsub_rmdir_args {
33151+ int *errp;
33152+ struct inode *dir;
33153+ struct path *path;
33154+};
33155+
33156+static void au_call_vfsub_rmdir(void *args)
33157+{
33158+ struct au_vfsub_rmdir_args *a = args;
33159+ *a->errp = vfsub_rmdir(a->dir, a->path);
33160+}
33161+
33162+int vfsub_sio_rmdir(struct inode *dir, struct path *path)
33163+{
33164+ int err, do_sio, wkq_err;
33165+
33166+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
c1595e42
JR
33167+ if (!do_sio) {
33168+ lockdep_off();
1facf9fc 33169+ err = vfsub_rmdir(dir, path);
c1595e42
JR
33170+ lockdep_on();
33171+ } else {
1facf9fc 33172+ struct au_vfsub_rmdir_args args = {
33173+ .errp = &err,
33174+ .dir = dir,
33175+ .path = path
33176+ };
33177+ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
33178+ if (unlikely(wkq_err))
33179+ err = wkq_err;
33180+ }
33181+
33182+ return err;
33183+}
33184+
33185+/* ---------------------------------------------------------------------- */
33186+
33187+struct notify_change_args {
33188+ int *errp;
33189+ struct path *path;
33190+ struct iattr *ia;
523b37e3 33191+ struct inode **delegated_inode;
1facf9fc 33192+};
33193+
33194+static void call_notify_change(void *args)
33195+{
33196+ struct notify_change_args *a = args;
33197+ struct inode *h_inode;
33198+
5527c038 33199+ h_inode = d_inode(a->path->dentry);
1facf9fc 33200+ IMustLock(h_inode);
33201+
33202+ *a->errp = -EPERM;
33203+ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
c1595e42 33204+ lockdep_off();
523b37e3
AM
33205+ *a->errp = notify_change(a->path->dentry, a->ia,
33206+ a->delegated_inode);
c1595e42 33207+ lockdep_on();
1facf9fc 33208+ if (!*a->errp)
33209+ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
33210+ }
33211+ AuTraceErr(*a->errp);
33212+}
33213+
523b37e3
AM
33214+int vfsub_notify_change(struct path *path, struct iattr *ia,
33215+ struct inode **delegated_inode)
1facf9fc 33216+{
33217+ int err;
33218+ struct notify_change_args args = {
523b37e3
AM
33219+ .errp = &err,
33220+ .path = path,
33221+ .ia = ia,
33222+ .delegated_inode = delegated_inode
1facf9fc 33223+ };
33224+
33225+ call_notify_change(&args);
33226+
33227+ return err;
33228+}
33229+
523b37e3
AM
33230+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
33231+ struct inode **delegated_inode)
1facf9fc 33232+{
33233+ int err, wkq_err;
33234+ struct notify_change_args args = {
523b37e3
AM
33235+ .errp = &err,
33236+ .path = path,
33237+ .ia = ia,
33238+ .delegated_inode = delegated_inode
1facf9fc 33239+ };
33240+
33241+ wkq_err = au_wkq_wait(call_notify_change, &args);
33242+ if (unlikely(wkq_err))
33243+ err = wkq_err;
33244+
33245+ return err;
33246+}
33247+
33248+/* ---------------------------------------------------------------------- */
33249+
33250+struct unlink_args {
33251+ int *errp;
33252+ struct inode *dir;
33253+ struct path *path;
523b37e3 33254+ struct inode **delegated_inode;
1facf9fc 33255+};
33256+
33257+static void call_unlink(void *args)
33258+{
33259+ struct unlink_args *a = args;
33260+ struct dentry *d = a->path->dentry;
33261+ struct inode *h_inode;
33262+ const int stop_sillyrename = (au_test_nfs(d->d_sb)
c1595e42 33263+ && au_dcount(d) == 1);
1facf9fc 33264+
33265+ IMustLock(a->dir);
33266+
33267+ a->path->dentry = d->d_parent;
33268+ *a->errp = security_path_unlink(a->path, d);
33269+ a->path->dentry = d;
33270+ if (unlikely(*a->errp))
33271+ return;
33272+
33273+ if (!stop_sillyrename)
33274+ dget(d);
5527c038
JR
33275+ h_inode = NULL;
33276+ if (d_is_positive(d)) {
33277+ h_inode = d_inode(d);
027c5e7a 33278+ ihold(h_inode);
5527c038 33279+ }
1facf9fc 33280+
2cbb1c4b 33281+ lockdep_off();
523b37e3 33282+ *a->errp = vfs_unlink(a->dir, d, a->delegated_inode);
2cbb1c4b 33283+ lockdep_on();
1facf9fc 33284+ if (!*a->errp) {
33285+ struct path tmp = {
33286+ .dentry = d->d_parent,
33287+ .mnt = a->path->mnt
33288+ };
33289+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
33290+ }
33291+
33292+ if (!stop_sillyrename)
33293+ dput(d);
33294+ if (h_inode)
33295+ iput(h_inode);
33296+
33297+ AuTraceErr(*a->errp);
33298+}
33299+
33300+/*
33301+ * @dir: must be locked.
33302+ * @dentry: target dentry.
33303+ */
523b37e3
AM
33304+int vfsub_unlink(struct inode *dir, struct path *path,
33305+ struct inode **delegated_inode, int force)
1facf9fc 33306+{
33307+ int err;
33308+ struct unlink_args args = {
523b37e3
AM
33309+ .errp = &err,
33310+ .dir = dir,
33311+ .path = path,
33312+ .delegated_inode = delegated_inode
1facf9fc 33313+ };
33314+
33315+ if (!force)
33316+ call_unlink(&args);
33317+ else {
33318+ int wkq_err;
33319+
33320+ wkq_err = au_wkq_wait(call_unlink, &args);
33321+ if (unlikely(wkq_err))
33322+ err = wkq_err;
33323+ }
33324+
33325+ return err;
33326+}
7f207e10
AM
33327diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
33328--- /usr/share/empty/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
33329+++ linux/fs/aufs/vfsub.h 2018-04-15 08:49:13.404484168 +0200
33330@@ -0,0 +1,355 @@
1facf9fc 33331+/*
ae9dfd79 33332+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 33333+ *
33334+ * This program, aufs is free software; you can redistribute it and/or modify
33335+ * it under the terms of the GNU General Public License as published by
33336+ * the Free Software Foundation; either version 2 of the License, or
33337+ * (at your option) any later version.
dece6358
AM
33338+ *
33339+ * This program is distributed in the hope that it will be useful,
33340+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
33341+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33342+ * GNU General Public License for more details.
33343+ *
33344+ * You should have received a copy of the GNU General Public License
523b37e3 33345+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 33346+ */
33347+
33348+/*
33349+ * sub-routines for VFS
33350+ */
33351+
33352+#ifndef __AUFS_VFSUB_H__
33353+#define __AUFS_VFSUB_H__
33354+
33355+#ifdef __KERNEL__
33356+
33357+#include <linux/fs.h>
b4510431 33358+#include <linux/mount.h>
8cdd5066 33359+#include <linux/posix_acl.h>
c1595e42 33360+#include <linux/xattr.h>
7f207e10 33361+#include "debug.h"
1facf9fc 33362+
7f207e10 33363+/* copied from linux/fs/internal.h */
2cbb1c4b 33364+/* todo: BAD approach!! */
c06a8ce3 33365+extern void __mnt_drop_write(struct vfsmount *);
b912730e 33366+extern int open_check_o_direct(struct file *f);
7f207e10
AM
33367+
33368+/* ---------------------------------------------------------------------- */
1facf9fc 33369+
33370+/* lock subclass for lower inode */
33371+/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
33372+/* reduce? gave up. */
33373+enum {
c1595e42 33374+ AuLsc_I_Begin = I_MUTEX_PARENT2, /* 5 */
1facf9fc 33375+ AuLsc_I_PARENT, /* lower inode, parent first */
33376+ AuLsc_I_PARENT2, /* copyup dirs */
dece6358 33377+ AuLsc_I_PARENT3, /* copyup wh */
1facf9fc 33378+ AuLsc_I_CHILD,
33379+ AuLsc_I_CHILD2,
33380+ AuLsc_I_End
33381+};
33382+
33383+/* to debug easier, do not make them inlined functions */
33384+#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
febd17d6 33385+#define IMustLock(i) AuDebugOn(!inode_is_locked(i))
1facf9fc 33386+
ae9dfd79
AM
33387+/* why VFS doesn't define it? */
33388+static inline
33389+void vfsub_inode_lock_shared_nested(struct inode *inode, unsigned int sc)
33390+{
33391+ down_read_nested(&inode->i_rwsem, sc);
33392+}
33393+
1facf9fc 33394+/* ---------------------------------------------------------------------- */
33395+
7f207e10
AM
33396+static inline void vfsub_drop_nlink(struct inode *inode)
33397+{
33398+ AuDebugOn(!inode->i_nlink);
33399+ drop_nlink(inode);
33400+}
33401+
027c5e7a
AM
33402+static inline void vfsub_dead_dir(struct inode *inode)
33403+{
33404+ AuDebugOn(!S_ISDIR(inode->i_mode));
33405+ inode->i_flags |= S_DEAD;
33406+ clear_nlink(inode);
33407+}
33408+
392086de
AM
33409+static inline int vfsub_native_ro(struct inode *inode)
33410+{
33411+ return (inode->i_sb->s_flags & MS_RDONLY)
33412+ || IS_RDONLY(inode)
33413+ /* || IS_APPEND(inode) */
33414+ || IS_IMMUTABLE(inode);
33415+}
33416+
8cdd5066
JR
33417+#ifdef CONFIG_AUFS_BR_FUSE
33418+int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb);
33419+#else
33420+AuStubInt0(vfsub_test_mntns, struct vfsmount *mnt, struct super_block *h_sb);
33421+#endif
33422+
ae9dfd79
AM
33423+int vfsub_sync_filesystem(struct super_block *h_sb, int wait);
33424+
7f207e10
AM
33425+/* ---------------------------------------------------------------------- */
33426+
33427+int vfsub_update_h_iattr(struct path *h_path, int *did);
33428+struct file *vfsub_dentry_open(struct path *path, int flags);
33429+struct file *vfsub_filp_open(const char *path, int oflags, int mode);
b912730e
AM
33430+struct vfsub_aopen_args {
33431+ struct file *file;
33432+ unsigned int open_flag;
33433+ umode_t create_mode;
33434+ int *opened;
33435+};
33436+struct au_branch;
33437+int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
33438+ struct vfsub_aopen_args *args, struct au_branch *br);
1facf9fc 33439+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
b4510431 33440+
febd17d6
JR
33441+struct dentry *vfsub_lookup_one_len_unlocked(const char *name,
33442+ struct dentry *parent, int len);
1facf9fc 33443+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
33444+ int len);
b4510431
AM
33445+
33446+struct vfsub_lkup_one_args {
33447+ struct dentry **errp;
33448+ struct qstr *name;
33449+ struct dentry *parent;
33450+};
33451+
33452+static inline struct dentry *vfsub_lkup_one(struct qstr *name,
33453+ struct dentry *parent)
33454+{
33455+ return vfsub_lookup_one_len(name->name, parent, name->len);
33456+}
33457+
33458+void vfsub_call_lkup_one(void *args);
33459+
33460+/* ---------------------------------------------------------------------- */
33461+
33462+static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
33463+{
33464+ int err;
076b876e 33465+
b4510431
AM
33466+ lockdep_off();
33467+ err = mnt_want_write(mnt);
33468+ lockdep_on();
33469+ return err;
33470+}
33471+
33472+static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
33473+{
33474+ lockdep_off();
33475+ mnt_drop_write(mnt);
33476+ lockdep_on();
33477+}
1facf9fc 33478+
7e9cd9fe 33479+#if 0 /* reserved */
c06a8ce3
AM
33480+static inline void vfsub_mnt_drop_write_file(struct file *file)
33481+{
33482+ lockdep_off();
33483+ mnt_drop_write_file(file);
33484+ lockdep_on();
33485+}
7e9cd9fe 33486+#endif
c06a8ce3 33487+
1facf9fc 33488+/* ---------------------------------------------------------------------- */
33489+
33490+struct au_hinode;
33491+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
33492+ struct dentry *d2, struct au_hinode *hdir2);
33493+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
33494+ struct dentry *d2, struct au_hinode *hdir2);
33495+
537831f9
AM
33496+int vfsub_create(struct inode *dir, struct path *path, int mode,
33497+ bool want_excl);
1facf9fc 33498+int vfsub_symlink(struct inode *dir, struct path *path,
33499+ const char *symname);
33500+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
33501+int vfsub_link(struct dentry *src_dentry, struct inode *dir,
523b37e3 33502+ struct path *path, struct inode **delegated_inode);
1facf9fc 33503+int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
523b37e3 33504+ struct inode *hdir, struct path *path,
f2c43d5f 33505+ struct inode **delegated_inode, unsigned int flags);
1facf9fc 33506+int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
33507+int vfsub_rmdir(struct inode *dir, struct path *path);
33508+
33509+/* ---------------------------------------------------------------------- */
33510+
33511+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
33512+ loff_t *ppos);
33513+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
33514+ loff_t *ppos);
33515+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
33516+ loff_t *ppos);
33517+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
33518+ loff_t *ppos);
4a4d8108 33519+int vfsub_flush(struct file *file, fl_owner_t id);
392086de
AM
33520+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx);
33521+
c06a8ce3
AM
33522+static inline loff_t vfsub_f_size_read(struct file *file)
33523+{
33524+ return i_size_read(file_inode(file));
33525+}
33526+
4a4d8108
AM
33527+static inline unsigned int vfsub_file_flags(struct file *file)
33528+{
33529+ unsigned int flags;
33530+
33531+ spin_lock(&file->f_lock);
33532+ flags = file->f_flags;
33533+ spin_unlock(&file->f_lock);
33534+
33535+ return flags;
33536+}
1308ab2a 33537+
f0c0a007
AM
33538+static inline int vfsub_file_execed(struct file *file)
33539+{
33540+ /* todo: direct access f_flags */
33541+ return !!(vfsub_file_flags(file) & __FMODE_EXEC);
33542+}
33543+
7e9cd9fe 33544+#if 0 /* reserved */
1facf9fc 33545+static inline void vfsub_file_accessed(struct file *h_file)
33546+{
33547+ file_accessed(h_file);
33548+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
33549+}
7e9cd9fe 33550+#endif
1facf9fc 33551+
79b8bda9 33552+#if 0 /* reserved */
1facf9fc 33553+static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
33554+ struct dentry *h_dentry)
33555+{
33556+ struct path h_path = {
33557+ .dentry = h_dentry,
33558+ .mnt = h_mnt
33559+ };
92d182d2 33560+ touch_atime(&h_path);
1facf9fc 33561+ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
33562+}
79b8bda9 33563+#endif
1facf9fc 33564+
0c3ec466
AM
33565+static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts,
33566+ int flags)
33567+{
5afbbe0d 33568+ return update_time(h_inode, ts, flags);
0c3ec466
AM
33569+ /* no vfsub_update_h_iattr() since we don't have struct path */
33570+}
33571+
8cdd5066
JR
33572+#ifdef CONFIG_FS_POSIX_ACL
33573+static inline int vfsub_acl_chmod(struct inode *h_inode, umode_t h_mode)
33574+{
33575+ int err;
33576+
33577+ err = posix_acl_chmod(h_inode, h_mode);
33578+ if (err == -EOPNOTSUPP)
33579+ err = 0;
33580+ return err;
33581+}
33582+#else
33583+AuStubInt0(vfsub_acl_chmod, struct inode *h_inode, umode_t h_mode);
33584+#endif
33585+
4a4d8108
AM
33586+long vfsub_splice_to(struct file *in, loff_t *ppos,
33587+ struct pipe_inode_info *pipe, size_t len,
33588+ unsigned int flags);
33589+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
33590+ loff_t *ppos, size_t len, unsigned int flags);
c06a8ce3
AM
33591+
33592+static inline long vfsub_truncate(struct path *path, loff_t length)
33593+{
33594+ long err;
076b876e 33595+
c06a8ce3
AM
33596+ lockdep_off();
33597+ err = vfs_truncate(path, length);
33598+ lockdep_on();
33599+ return err;
33600+}
33601+
4a4d8108
AM
33602+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
33603+ struct file *h_file);
53392da6 33604+int vfsub_fsync(struct file *file, struct path *path, int datasync);
4a4d8108 33605+
ae9dfd79
AM
33606+/*
33607+ * re-use branch fs's ioctl(FICLONE) while aufs itself doesn't support such
33608+ * ioctl.
33609+ */
33610+static inline int vfsub_clone_file_range(struct file *src, struct file *dst,
33611+ u64 len)
33612+{
33613+ int err;
33614+
33615+ lockdep_off();
33616+ err = vfs_clone_file_range(src, 0, dst, 0, len);
33617+ lockdep_on();
33618+
33619+ return err;
33620+}
33621+
33622+/* copy_file_range(2) is a systemcall */
33623+static inline ssize_t vfsub_copy_file_range(struct file *src, loff_t src_pos,
33624+ struct file *dst, loff_t dst_pos,
33625+ size_t len, unsigned int flags)
33626+{
33627+ ssize_t ssz;
33628+
33629+ lockdep_off();
33630+ ssz = vfs_copy_file_range(src, src_pos, dst, dst_pos, len, flags);
33631+ lockdep_on();
33632+
33633+ return ssz;
33634+}
33635+
1facf9fc 33636+/* ---------------------------------------------------------------------- */
33637+
33638+static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
33639+{
33640+ loff_t err;
33641+
2cbb1c4b 33642+ lockdep_off();
1facf9fc 33643+ err = vfs_llseek(file, offset, origin);
2cbb1c4b 33644+ lockdep_on();
1facf9fc 33645+ return err;
33646+}
33647+
33648+/* ---------------------------------------------------------------------- */
33649+
4a4d8108
AM
33650+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
33651+int vfsub_sio_rmdir(struct inode *dir, struct path *path);
523b37e3
AM
33652+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
33653+ struct inode **delegated_inode);
33654+int vfsub_notify_change(struct path *path, struct iattr *ia,
33655+ struct inode **delegated_inode);
33656+int vfsub_unlink(struct inode *dir, struct path *path,
33657+ struct inode **delegated_inode, int force);
4a4d8108 33658+
c1595e42
JR
33659+/* ---------------------------------------------------------------------- */
33660+
33661+static inline int vfsub_setxattr(struct dentry *dentry, const char *name,
33662+ const void *value, size_t size, int flags)
33663+{
33664+ int err;
33665+
33666+ lockdep_off();
33667+ err = vfs_setxattr(dentry, name, value, size, flags);
33668+ lockdep_on();
33669+
33670+ return err;
33671+}
33672+
33673+static inline int vfsub_removexattr(struct dentry *dentry, const char *name)
33674+{
33675+ int err;
33676+
33677+ lockdep_off();
33678+ err = vfs_removexattr(dentry, name);
33679+ lockdep_on();
33680+
33681+ return err;
33682+}
33683+
1facf9fc 33684+#endif /* __KERNEL__ */
33685+#endif /* __AUFS_VFSUB_H__ */
7f207e10
AM
33686diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
33687--- /usr/share/empty/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 33688+++ linux/fs/aufs/wbr_policy.c 2018-04-15 08:49:13.404484168 +0200
f2c43d5f 33689@@ -0,0 +1,830 @@
1facf9fc 33690+/*
ae9dfd79 33691+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 33692+ *
33693+ * This program, aufs is free software; you can redistribute it and/or modify
33694+ * it under the terms of the GNU General Public License as published by
33695+ * the Free Software Foundation; either version 2 of the License, or
33696+ * (at your option) any later version.
dece6358
AM
33697+ *
33698+ * This program is distributed in the hope that it will be useful,
33699+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
33700+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33701+ * GNU General Public License for more details.
33702+ *
33703+ * You should have received a copy of the GNU General Public License
523b37e3 33704+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 33705+ */
33706+
33707+/*
33708+ * policies for selecting one among multiple writable branches
33709+ */
33710+
33711+#include <linux/statfs.h>
33712+#include "aufs.h"
33713+
33714+/* subset of cpup_attr() */
33715+static noinline_for_stack
33716+int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
33717+{
33718+ int err, sbits;
33719+ struct iattr ia;
33720+ struct inode *h_isrc;
33721+
5527c038 33722+ h_isrc = d_inode(h_src);
1facf9fc 33723+ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
33724+ ia.ia_mode = h_isrc->i_mode;
33725+ ia.ia_uid = h_isrc->i_uid;
33726+ ia.ia_gid = h_isrc->i_gid;
33727+ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
5527c038 33728+ au_cpup_attr_flags(d_inode(h_path->dentry), h_isrc->i_flags);
523b37e3
AM
33729+ /* no delegation since it is just created */
33730+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 33731+
33732+ /* is this nfs only? */
33733+ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
33734+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
33735+ ia.ia_mode = h_isrc->i_mode;
523b37e3 33736+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 33737+ }
33738+
33739+ return err;
33740+}
33741+
33742+#define AuCpdown_PARENT_OPQ 1
33743+#define AuCpdown_WHED (1 << 1)
33744+#define AuCpdown_MADE_DIR (1 << 2)
33745+#define AuCpdown_DIROPQ (1 << 3)
33746+#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name)
7f207e10
AM
33747+#define au_fset_cpdown(flags, name) \
33748+ do { (flags) |= AuCpdown_##name; } while (0)
33749+#define au_fclr_cpdown(flags, name) \
33750+ do { (flags) &= ~AuCpdown_##name; } while (0)
1facf9fc 33751+
1facf9fc 33752+static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
c2b27bf2 33753+ unsigned int *flags)
1facf9fc 33754+{
33755+ int err;
33756+ struct dentry *opq_dentry;
33757+
33758+ opq_dentry = au_diropq_create(dentry, bdst);
33759+ err = PTR_ERR(opq_dentry);
33760+ if (IS_ERR(opq_dentry))
33761+ goto out;
33762+ dput(opq_dentry);
c2b27bf2 33763+ au_fset_cpdown(*flags, DIROPQ);
1facf9fc 33764+
4f0767ce 33765+out:
1facf9fc 33766+ return err;
33767+}
33768+
33769+static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
33770+ struct inode *dir, aufs_bindex_t bdst)
33771+{
33772+ int err;
33773+ struct path h_path;
33774+ struct au_branch *br;
33775+
33776+ br = au_sbr(dentry->d_sb, bdst);
33777+ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
33778+ err = PTR_ERR(h_path.dentry);
33779+ if (IS_ERR(h_path.dentry))
33780+ goto out;
33781+
33782+ err = 0;
5527c038 33783+ if (d_is_positive(h_path.dentry)) {
86dc4139 33784+ h_path.mnt = au_br_mnt(br);
1facf9fc 33785+ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
33786+ dentry);
33787+ }
33788+ dput(h_path.dentry);
33789+
4f0767ce 33790+out:
1facf9fc 33791+ return err;
33792+}
33793+
33794+static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 33795+ struct au_pin *pin,
1facf9fc 33796+ struct dentry *h_parent, void *arg)
33797+{
33798+ int err, rerr;
5afbbe0d 33799+ aufs_bindex_t bopq, btop;
1facf9fc 33800+ struct path h_path;
33801+ struct dentry *parent;
33802+ struct inode *h_dir, *h_inode, *inode, *dir;
c2b27bf2 33803+ unsigned int *flags = arg;
1facf9fc 33804+
5afbbe0d 33805+ btop = au_dbtop(dentry);
1facf9fc 33806+ /* dentry is di-locked */
33807+ parent = dget_parent(dentry);
5527c038
JR
33808+ dir = d_inode(parent);
33809+ h_dir = d_inode(h_parent);
1facf9fc 33810+ AuDebugOn(h_dir != au_h_iptr(dir, bdst));
33811+ IMustLock(h_dir);
33812+
86dc4139 33813+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
1facf9fc 33814+ if (unlikely(err < 0))
33815+ goto out;
33816+ h_path.dentry = au_h_dptr(dentry, bdst);
33817+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
33818+ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path,
33819+ S_IRWXU | S_IRUGO | S_IXUGO);
33820+ if (unlikely(err))
33821+ goto out_put;
c2b27bf2 33822+ au_fset_cpdown(*flags, MADE_DIR);
1facf9fc 33823+
1facf9fc 33824+ bopq = au_dbdiropq(dentry);
c2b27bf2
AM
33825+ au_fclr_cpdown(*flags, WHED);
33826+ au_fclr_cpdown(*flags, DIROPQ);
1facf9fc 33827+ if (au_dbwh(dentry) == bdst)
c2b27bf2
AM
33828+ au_fset_cpdown(*flags, WHED);
33829+ if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst)
33830+ au_fset_cpdown(*flags, PARENT_OPQ);
5527c038 33831+ h_inode = d_inode(h_path.dentry);
febd17d6 33832+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
c2b27bf2
AM
33833+ if (au_ftest_cpdown(*flags, WHED)) {
33834+ err = au_cpdown_dir_opq(dentry, bdst, flags);
1facf9fc 33835+ if (unlikely(err)) {
febd17d6 33836+ inode_unlock(h_inode);
1facf9fc 33837+ goto out_dir;
33838+ }
33839+ }
33840+
5afbbe0d 33841+ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, btop));
febd17d6 33842+ inode_unlock(h_inode);
1facf9fc 33843+ if (unlikely(err))
33844+ goto out_opq;
33845+
c2b27bf2 33846+ if (au_ftest_cpdown(*flags, WHED)) {
1facf9fc 33847+ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
33848+ if (unlikely(err))
33849+ goto out_opq;
33850+ }
33851+
5527c038 33852+ inode = d_inode(dentry);
5afbbe0d
AM
33853+ if (au_ibbot(inode) < bdst)
33854+ au_set_ibbot(inode, bdst);
1facf9fc 33855+ au_set_h_iptr(inode, bdst, au_igrab(h_inode),
33856+ au_hi_flags(inode, /*isdir*/1));
076b876e 33857+ au_fhsm_wrote(dentry->d_sb, bdst, /*force*/0);
1facf9fc 33858+ goto out; /* success */
33859+
33860+ /* revert */
4f0767ce 33861+out_opq:
c2b27bf2 33862+ if (au_ftest_cpdown(*flags, DIROPQ)) {
febd17d6 33863+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
1facf9fc 33864+ rerr = au_diropq_remove(dentry, bdst);
febd17d6 33865+ inode_unlock(h_inode);
1facf9fc 33866+ if (unlikely(rerr)) {
523b37e3
AM
33867+ AuIOErr("failed removing diropq for %pd b%d (%d)\n",
33868+ dentry, bdst, rerr);
1facf9fc 33869+ err = -EIO;
33870+ goto out;
33871+ }
33872+ }
4f0767ce 33873+out_dir:
c2b27bf2 33874+ if (au_ftest_cpdown(*flags, MADE_DIR)) {
1facf9fc 33875+ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
33876+ if (unlikely(rerr)) {
523b37e3
AM
33877+ AuIOErr("failed removing %pd b%d (%d)\n",
33878+ dentry, bdst, rerr);
1facf9fc 33879+ err = -EIO;
33880+ }
33881+ }
4f0767ce 33882+out_put:
1facf9fc 33883+ au_set_h_dptr(dentry, bdst, NULL);
5afbbe0d
AM
33884+ if (au_dbbot(dentry) == bdst)
33885+ au_update_dbbot(dentry);
4f0767ce 33886+out:
1facf9fc 33887+ dput(parent);
33888+ return err;
33889+}
33890+
33891+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
33892+{
33893+ int err;
c2b27bf2 33894+ unsigned int flags;
1facf9fc 33895+
c2b27bf2
AM
33896+ flags = 0;
33897+ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &flags);
1facf9fc 33898+
33899+ return err;
33900+}
33901+
33902+/* ---------------------------------------------------------------------- */
33903+
33904+/* policies for create */
33905+
c2b27bf2 33906+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex)
4a4d8108
AM
33907+{
33908+ int err, i, j, ndentry;
33909+ aufs_bindex_t bopq;
33910+ struct au_dcsub_pages dpages;
33911+ struct au_dpage *dpage;
33912+ struct dentry **dentries, *parent, *d;
33913+
33914+ err = au_dpages_init(&dpages, GFP_NOFS);
33915+ if (unlikely(err))
33916+ goto out;
33917+ parent = dget_parent(dentry);
027c5e7a 33918+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0);
4a4d8108
AM
33919+ if (unlikely(err))
33920+ goto out_free;
33921+
33922+ err = bindex;
33923+ for (i = 0; i < dpages.ndpage; i++) {
33924+ dpage = dpages.dpages + i;
33925+ dentries = dpage->dentries;
33926+ ndentry = dpage->ndentry;
33927+ for (j = 0; j < ndentry; j++) {
33928+ d = dentries[j];
33929+ di_read_lock_parent2(d, !AuLock_IR);
33930+ bopq = au_dbdiropq(d);
33931+ di_read_unlock(d, !AuLock_IR);
33932+ if (bopq >= 0 && bopq < err)
33933+ err = bopq;
33934+ }
33935+ }
33936+
33937+out_free:
33938+ dput(parent);
33939+ au_dpages_free(&dpages);
33940+out:
33941+ return err;
33942+}
33943+
1facf9fc 33944+static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
33945+{
33946+ for (; bindex >= 0; bindex--)
33947+ if (!au_br_rdonly(au_sbr(sb, bindex)))
33948+ return bindex;
33949+ return -EROFS;
33950+}
33951+
33952+/* top down parent */
392086de
AM
33953+static int au_wbr_create_tdp(struct dentry *dentry,
33954+ unsigned int flags __maybe_unused)
1facf9fc 33955+{
33956+ int err;
5afbbe0d 33957+ aufs_bindex_t btop, bindex;
1facf9fc 33958+ struct super_block *sb;
33959+ struct dentry *parent, *h_parent;
33960+
33961+ sb = dentry->d_sb;
5afbbe0d
AM
33962+ btop = au_dbtop(dentry);
33963+ err = btop;
33964+ if (!au_br_rdonly(au_sbr(sb, btop)))
1facf9fc 33965+ goto out;
33966+
33967+ err = -EROFS;
33968+ parent = dget_parent(dentry);
5afbbe0d 33969+ for (bindex = au_dbtop(parent); bindex < btop; bindex++) {
1facf9fc 33970+ h_parent = au_h_dptr(parent, bindex);
5527c038 33971+ if (!h_parent || d_is_negative(h_parent))
1facf9fc 33972+ continue;
33973+
33974+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
33975+ err = bindex;
33976+ break;
33977+ }
33978+ }
33979+ dput(parent);
33980+
33981+ /* bottom up here */
4a4d8108 33982+ if (unlikely(err < 0)) {
5afbbe0d 33983+ err = au_wbr_bu(sb, btop - 1);
4a4d8108
AM
33984+ if (err >= 0)
33985+ err = au_wbr_nonopq(dentry, err);
33986+ }
1facf9fc 33987+
4f0767ce 33988+out:
1facf9fc 33989+ AuDbg("b%d\n", err);
33990+ return err;
33991+}
33992+
33993+/* ---------------------------------------------------------------------- */
33994+
33995+/* an exception for the policy other than tdp */
33996+static int au_wbr_create_exp(struct dentry *dentry)
33997+{
33998+ int err;
33999+ aufs_bindex_t bwh, bdiropq;
34000+ struct dentry *parent;
34001+
34002+ err = -1;
34003+ bwh = au_dbwh(dentry);
34004+ parent = dget_parent(dentry);
34005+ bdiropq = au_dbdiropq(parent);
34006+ if (bwh >= 0) {
34007+ if (bdiropq >= 0)
34008+ err = min(bdiropq, bwh);
34009+ else
34010+ err = bwh;
34011+ AuDbg("%d\n", err);
34012+ } else if (bdiropq >= 0) {
34013+ err = bdiropq;
34014+ AuDbg("%d\n", err);
34015+ }
34016+ dput(parent);
34017+
4a4d8108
AM
34018+ if (err >= 0)
34019+ err = au_wbr_nonopq(dentry, err);
34020+
1facf9fc 34021+ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
34022+ err = -1;
34023+
34024+ AuDbg("%d\n", err);
34025+ return err;
34026+}
34027+
34028+/* ---------------------------------------------------------------------- */
34029+
34030+/* round robin */
34031+static int au_wbr_create_init_rr(struct super_block *sb)
34032+{
34033+ int err;
34034+
5afbbe0d 34035+ err = au_wbr_bu(sb, au_sbbot(sb));
1facf9fc 34036+ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
dece6358 34037+ /* smp_mb(); */
1facf9fc 34038+
34039+ AuDbg("b%d\n", err);
34040+ return err;
34041+}
34042+
392086de 34043+static int au_wbr_create_rr(struct dentry *dentry, unsigned int flags)
1facf9fc 34044+{
34045+ int err, nbr;
34046+ unsigned int u;
5afbbe0d 34047+ aufs_bindex_t bindex, bbot;
1facf9fc 34048+ struct super_block *sb;
34049+ atomic_t *next;
34050+
34051+ err = au_wbr_create_exp(dentry);
34052+ if (err >= 0)
34053+ goto out;
34054+
34055+ sb = dentry->d_sb;
34056+ next = &au_sbi(sb)->si_wbr_rr_next;
5afbbe0d
AM
34057+ bbot = au_sbbot(sb);
34058+ nbr = bbot + 1;
34059+ for (bindex = 0; bindex <= bbot; bindex++) {
392086de 34060+ if (!au_ftest_wbr(flags, DIR)) {
1facf9fc 34061+ err = atomic_dec_return(next) + 1;
34062+ /* modulo for 0 is meaningless */
34063+ if (unlikely(!err))
34064+ err = atomic_dec_return(next) + 1;
34065+ } else
34066+ err = atomic_read(next);
34067+ AuDbg("%d\n", err);
34068+ u = err;
34069+ err = u % nbr;
34070+ AuDbg("%d\n", err);
34071+ if (!au_br_rdonly(au_sbr(sb, err)))
34072+ break;
34073+ err = -EROFS;
34074+ }
34075+
4a4d8108
AM
34076+ if (err >= 0)
34077+ err = au_wbr_nonopq(dentry, err);
34078+
4f0767ce 34079+out:
1facf9fc 34080+ AuDbg("%d\n", err);
34081+ return err;
34082+}
34083+
34084+/* ---------------------------------------------------------------------- */
34085+
34086+/* most free space */
392086de 34087+static void au_mfs(struct dentry *dentry, struct dentry *parent)
1facf9fc 34088+{
34089+ struct super_block *sb;
34090+ struct au_branch *br;
34091+ struct au_wbr_mfs *mfs;
392086de 34092+ struct dentry *h_parent;
5afbbe0d 34093+ aufs_bindex_t bindex, bbot;
1facf9fc 34094+ int err;
34095+ unsigned long long b, bavail;
7f207e10 34096+ struct path h_path;
1facf9fc 34097+ /* reduce the stack usage */
34098+ struct kstatfs *st;
34099+
34100+ st = kmalloc(sizeof(*st), GFP_NOFS);
34101+ if (unlikely(!st)) {
34102+ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
34103+ return;
34104+ }
34105+
34106+ bavail = 0;
34107+ sb = dentry->d_sb;
34108+ mfs = &au_sbi(sb)->si_wbr_mfs;
dece6358 34109+ MtxMustLock(&mfs->mfs_lock);
1facf9fc 34110+ mfs->mfs_bindex = -EROFS;
34111+ mfs->mfsrr_bytes = 0;
392086de
AM
34112+ if (!parent) {
34113+ bindex = 0;
5afbbe0d 34114+ bbot = au_sbbot(sb);
392086de 34115+ } else {
5afbbe0d
AM
34116+ bindex = au_dbtop(parent);
34117+ bbot = au_dbtaildir(parent);
392086de
AM
34118+ }
34119+
5afbbe0d 34120+ for (; bindex <= bbot; bindex++) {
392086de
AM
34121+ if (parent) {
34122+ h_parent = au_h_dptr(parent, bindex);
5527c038 34123+ if (!h_parent || d_is_negative(h_parent))
392086de
AM
34124+ continue;
34125+ }
1facf9fc 34126+ br = au_sbr(sb, bindex);
34127+ if (au_br_rdonly(br))
34128+ continue;
34129+
34130+ /* sb->s_root for NFS is unreliable */
86dc4139 34131+ h_path.mnt = au_br_mnt(br);
7f207e10
AM
34132+ h_path.dentry = h_path.mnt->mnt_root;
34133+ err = vfs_statfs(&h_path, st);
1facf9fc 34134+ if (unlikely(err)) {
34135+ AuWarn1("failed statfs, b%d, %d\n", bindex, err);
34136+ continue;
34137+ }
34138+
34139+ /* when the available size is equal, select the lower one */
34140+ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
34141+ || sizeof(b) < sizeof(st->f_bsize));
34142+ b = st->f_bavail * st->f_bsize;
34143+ br->br_wbr->wbr_bytes = b;
34144+ if (b >= bavail) {
34145+ bavail = b;
34146+ mfs->mfs_bindex = bindex;
34147+ mfs->mfs_jiffy = jiffies;
34148+ }
34149+ }
34150+
34151+ mfs->mfsrr_bytes = bavail;
34152+ AuDbg("b%d\n", mfs->mfs_bindex);
ae9dfd79 34153+ kfree(st);
1facf9fc 34154+}
34155+
392086de 34156+static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags)
1facf9fc 34157+{
34158+ int err;
392086de 34159+ struct dentry *parent;
1facf9fc 34160+ struct super_block *sb;
34161+ struct au_wbr_mfs *mfs;
34162+
34163+ err = au_wbr_create_exp(dentry);
34164+ if (err >= 0)
34165+ goto out;
34166+
34167+ sb = dentry->d_sb;
392086de
AM
34168+ parent = NULL;
34169+ if (au_ftest_wbr(flags, PARENT))
34170+ parent = dget_parent(dentry);
1facf9fc 34171+ mfs = &au_sbi(sb)->si_wbr_mfs;
34172+ mutex_lock(&mfs->mfs_lock);
34173+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
34174+ || mfs->mfs_bindex < 0
34175+ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
392086de 34176+ au_mfs(dentry, parent);
1facf9fc 34177+ mutex_unlock(&mfs->mfs_lock);
34178+ err = mfs->mfs_bindex;
392086de 34179+ dput(parent);
1facf9fc 34180+
4a4d8108
AM
34181+ if (err >= 0)
34182+ err = au_wbr_nonopq(dentry, err);
34183+
4f0767ce 34184+out:
1facf9fc 34185+ AuDbg("b%d\n", err);
34186+ return err;
34187+}
34188+
34189+static int au_wbr_create_init_mfs(struct super_block *sb)
34190+{
34191+ struct au_wbr_mfs *mfs;
34192+
34193+ mfs = &au_sbi(sb)->si_wbr_mfs;
34194+ mutex_init(&mfs->mfs_lock);
34195+ mfs->mfs_jiffy = 0;
34196+ mfs->mfs_bindex = -EROFS;
34197+
34198+ return 0;
34199+}
34200+
34201+static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
34202+{
34203+ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
34204+ return 0;
34205+}
34206+
34207+/* ---------------------------------------------------------------------- */
34208+
f2c43d5f
AM
34209+/* top down regardless parent, and then mfs */
34210+static int au_wbr_create_tdmfs(struct dentry *dentry,
34211+ unsigned int flags __maybe_unused)
34212+{
34213+ int err;
34214+ aufs_bindex_t bwh, btail, bindex, bfound, bmfs;
34215+ unsigned long long watermark;
34216+ struct super_block *sb;
34217+ struct au_wbr_mfs *mfs;
34218+ struct au_branch *br;
34219+ struct dentry *parent;
34220+
34221+ sb = dentry->d_sb;
34222+ mfs = &au_sbi(sb)->si_wbr_mfs;
34223+ mutex_lock(&mfs->mfs_lock);
34224+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
34225+ || mfs->mfs_bindex < 0)
34226+ au_mfs(dentry, /*parent*/NULL);
34227+ watermark = mfs->mfsrr_watermark;
34228+ bmfs = mfs->mfs_bindex;
34229+ mutex_unlock(&mfs->mfs_lock);
34230+
34231+ /* another style of au_wbr_create_exp() */
34232+ bwh = au_dbwh(dentry);
34233+ parent = dget_parent(dentry);
34234+ btail = au_dbtaildir(parent);
34235+ if (bwh >= 0 && bwh < btail)
34236+ btail = bwh;
34237+
34238+ err = au_wbr_nonopq(dentry, btail);
34239+ if (unlikely(err < 0))
34240+ goto out;
34241+ btail = err;
34242+ bfound = -1;
34243+ for (bindex = 0; bindex <= btail; bindex++) {
34244+ br = au_sbr(sb, bindex);
34245+ if (au_br_rdonly(br))
34246+ continue;
34247+ if (br->br_wbr->wbr_bytes > watermark) {
34248+ bfound = bindex;
34249+ break;
34250+ }
34251+ }
34252+ err = bfound;
34253+ if (err < 0)
34254+ err = bmfs;
34255+
34256+out:
34257+ dput(parent);
34258+ AuDbg("b%d\n", err);
34259+ return err;
34260+}
34261+
34262+/* ---------------------------------------------------------------------- */
34263+
1facf9fc 34264+/* most free space and then round robin */
392086de 34265+static int au_wbr_create_mfsrr(struct dentry *dentry, unsigned int flags)
1facf9fc 34266+{
34267+ int err;
34268+ struct au_wbr_mfs *mfs;
34269+
392086de 34270+ err = au_wbr_create_mfs(dentry, flags);
1facf9fc 34271+ if (err >= 0) {
34272+ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
dece6358 34273+ mutex_lock(&mfs->mfs_lock);
1facf9fc 34274+ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
392086de 34275+ err = au_wbr_create_rr(dentry, flags);
dece6358 34276+ mutex_unlock(&mfs->mfs_lock);
1facf9fc 34277+ }
34278+
34279+ AuDbg("b%d\n", err);
34280+ return err;
34281+}
34282+
34283+static int au_wbr_create_init_mfsrr(struct super_block *sb)
34284+{
34285+ int err;
34286+
34287+ au_wbr_create_init_mfs(sb); /* ignore */
34288+ err = au_wbr_create_init_rr(sb);
34289+
34290+ return err;
34291+}
34292+
34293+/* ---------------------------------------------------------------------- */
34294+
34295+/* top down parent and most free space */
392086de 34296+static int au_wbr_create_pmfs(struct dentry *dentry, unsigned int flags)
1facf9fc 34297+{
34298+ int err, e2;
34299+ unsigned long long b;
5afbbe0d 34300+ aufs_bindex_t bindex, btop, bbot;
1facf9fc 34301+ struct super_block *sb;
34302+ struct dentry *parent, *h_parent;
34303+ struct au_branch *br;
34304+
392086de 34305+ err = au_wbr_create_tdp(dentry, flags);
1facf9fc 34306+ if (unlikely(err < 0))
34307+ goto out;
34308+ parent = dget_parent(dentry);
5afbbe0d
AM
34309+ btop = au_dbtop(parent);
34310+ bbot = au_dbtaildir(parent);
34311+ if (btop == bbot)
1facf9fc 34312+ goto out_parent; /* success */
34313+
392086de 34314+ e2 = au_wbr_create_mfs(dentry, flags);
1facf9fc 34315+ if (e2 < 0)
34316+ goto out_parent; /* success */
34317+
34318+ /* when the available size is equal, select upper one */
34319+ sb = dentry->d_sb;
34320+ br = au_sbr(sb, err);
34321+ b = br->br_wbr->wbr_bytes;
34322+ AuDbg("b%d, %llu\n", err, b);
34323+
5afbbe0d 34324+ for (bindex = btop; bindex <= bbot; bindex++) {
1facf9fc 34325+ h_parent = au_h_dptr(parent, bindex);
5527c038 34326+ if (!h_parent || d_is_negative(h_parent))
1facf9fc 34327+ continue;
34328+
34329+ br = au_sbr(sb, bindex);
34330+ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
34331+ b = br->br_wbr->wbr_bytes;
34332+ err = bindex;
34333+ AuDbg("b%d, %llu\n", err, b);
34334+ }
34335+ }
34336+
4a4d8108
AM
34337+ if (err >= 0)
34338+ err = au_wbr_nonopq(dentry, err);
34339+
4f0767ce 34340+out_parent:
1facf9fc 34341+ dput(parent);
4f0767ce 34342+out:
1facf9fc 34343+ AuDbg("b%d\n", err);
34344+ return err;
34345+}
34346+
34347+/* ---------------------------------------------------------------------- */
34348+
392086de
AM
34349+/*
34350+ * - top down parent
34351+ * - most free space with parent
34352+ * - most free space round-robin regardless parent
34353+ */
34354+static int au_wbr_create_pmfsrr(struct dentry *dentry, unsigned int flags)
34355+{
34356+ int err;
34357+ unsigned long long watermark;
34358+ struct super_block *sb;
34359+ struct au_branch *br;
34360+ struct au_wbr_mfs *mfs;
34361+
34362+ err = au_wbr_create_pmfs(dentry, flags | AuWbr_PARENT);
34363+ if (unlikely(err < 0))
34364+ goto out;
34365+
34366+ sb = dentry->d_sb;
34367+ br = au_sbr(sb, err);
34368+ mfs = &au_sbi(sb)->si_wbr_mfs;
34369+ mutex_lock(&mfs->mfs_lock);
34370+ watermark = mfs->mfsrr_watermark;
34371+ mutex_unlock(&mfs->mfs_lock);
34372+ if (br->br_wbr->wbr_bytes < watermark)
34373+ /* regardless the parent dir */
34374+ err = au_wbr_create_mfsrr(dentry, flags);
34375+
34376+out:
34377+ AuDbg("b%d\n", err);
34378+ return err;
34379+}
34380+
34381+/* ---------------------------------------------------------------------- */
34382+
1facf9fc 34383+/* policies for copyup */
34384+
34385+/* top down parent */
34386+static int au_wbr_copyup_tdp(struct dentry *dentry)
34387+{
392086de 34388+ return au_wbr_create_tdp(dentry, /*flags, anything is ok*/0);
1facf9fc 34389+}
34390+
34391+/* bottom up parent */
34392+static int au_wbr_copyup_bup(struct dentry *dentry)
34393+{
34394+ int err;
5afbbe0d 34395+ aufs_bindex_t bindex, btop;
1facf9fc 34396+ struct dentry *parent, *h_parent;
34397+ struct super_block *sb;
34398+
34399+ err = -EROFS;
34400+ sb = dentry->d_sb;
34401+ parent = dget_parent(dentry);
5afbbe0d
AM
34402+ btop = au_dbtop(parent);
34403+ for (bindex = au_dbtop(dentry); bindex >= btop; bindex--) {
1facf9fc 34404+ h_parent = au_h_dptr(parent, bindex);
5527c038 34405+ if (!h_parent || d_is_negative(h_parent))
1facf9fc 34406+ continue;
34407+
34408+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
34409+ err = bindex;
34410+ break;
34411+ }
34412+ }
34413+ dput(parent);
34414+
34415+ /* bottom up here */
34416+ if (unlikely(err < 0))
5afbbe0d 34417+ err = au_wbr_bu(sb, btop - 1);
1facf9fc 34418+
34419+ AuDbg("b%d\n", err);
34420+ return err;
34421+}
34422+
34423+/* bottom up */
5afbbe0d 34424+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t btop)
1facf9fc 34425+{
34426+ int err;
34427+
5afbbe0d 34428+ err = au_wbr_bu(dentry->d_sb, btop);
4a4d8108 34429+ AuDbg("b%d\n", err);
5afbbe0d 34430+ if (err > btop)
4a4d8108 34431+ err = au_wbr_nonopq(dentry, err);
1facf9fc 34432+
34433+ AuDbg("b%d\n", err);
34434+ return err;
34435+}
34436+
076b876e
AM
34437+static int au_wbr_copyup_bu(struct dentry *dentry)
34438+{
34439+ int err;
5afbbe0d 34440+ aufs_bindex_t btop;
076b876e 34441+
5afbbe0d
AM
34442+ btop = au_dbtop(dentry);
34443+ err = au_wbr_do_copyup_bu(dentry, btop);
076b876e
AM
34444+ return err;
34445+}
34446+
1facf9fc 34447+/* ---------------------------------------------------------------------- */
34448+
34449+struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
34450+ [AuWbrCopyup_TDP] = {
34451+ .copyup = au_wbr_copyup_tdp
34452+ },
34453+ [AuWbrCopyup_BUP] = {
34454+ .copyup = au_wbr_copyup_bup
34455+ },
34456+ [AuWbrCopyup_BU] = {
34457+ .copyup = au_wbr_copyup_bu
34458+ }
34459+};
34460+
34461+struct au_wbr_create_operations au_wbr_create_ops[] = {
34462+ [AuWbrCreate_TDP] = {
34463+ .create = au_wbr_create_tdp
34464+ },
34465+ [AuWbrCreate_RR] = {
34466+ .create = au_wbr_create_rr,
34467+ .init = au_wbr_create_init_rr
34468+ },
34469+ [AuWbrCreate_MFS] = {
34470+ .create = au_wbr_create_mfs,
34471+ .init = au_wbr_create_init_mfs,
34472+ .fin = au_wbr_create_fin_mfs
34473+ },
34474+ [AuWbrCreate_MFSV] = {
34475+ .create = au_wbr_create_mfs,
34476+ .init = au_wbr_create_init_mfs,
34477+ .fin = au_wbr_create_fin_mfs
34478+ },
34479+ [AuWbrCreate_MFSRR] = {
34480+ .create = au_wbr_create_mfsrr,
34481+ .init = au_wbr_create_init_mfsrr,
34482+ .fin = au_wbr_create_fin_mfs
34483+ },
34484+ [AuWbrCreate_MFSRRV] = {
34485+ .create = au_wbr_create_mfsrr,
34486+ .init = au_wbr_create_init_mfsrr,
34487+ .fin = au_wbr_create_fin_mfs
34488+ },
f2c43d5f
AM
34489+ [AuWbrCreate_TDMFS] = {
34490+ .create = au_wbr_create_tdmfs,
34491+ .init = au_wbr_create_init_mfs,
34492+ .fin = au_wbr_create_fin_mfs
34493+ },
34494+ [AuWbrCreate_TDMFSV] = {
34495+ .create = au_wbr_create_tdmfs,
34496+ .init = au_wbr_create_init_mfs,
34497+ .fin = au_wbr_create_fin_mfs
34498+ },
1facf9fc 34499+ [AuWbrCreate_PMFS] = {
34500+ .create = au_wbr_create_pmfs,
34501+ .init = au_wbr_create_init_mfs,
34502+ .fin = au_wbr_create_fin_mfs
34503+ },
34504+ [AuWbrCreate_PMFSV] = {
34505+ .create = au_wbr_create_pmfs,
34506+ .init = au_wbr_create_init_mfs,
34507+ .fin = au_wbr_create_fin_mfs
392086de
AM
34508+ },
34509+ [AuWbrCreate_PMFSRR] = {
34510+ .create = au_wbr_create_pmfsrr,
34511+ .init = au_wbr_create_init_mfsrr,
34512+ .fin = au_wbr_create_fin_mfs
34513+ },
34514+ [AuWbrCreate_PMFSRRV] = {
34515+ .create = au_wbr_create_pmfsrr,
34516+ .init = au_wbr_create_init_mfsrr,
34517+ .fin = au_wbr_create_fin_mfs
1facf9fc 34518+ }
34519+};
7f207e10
AM
34520diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
34521--- /usr/share/empty/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 34522+++ linux/fs/aufs/whout.c 2018-04-15 08:49:13.404484168 +0200
f2c43d5f 34523@@ -0,0 +1,1061 @@
1facf9fc 34524+/*
ae9dfd79 34525+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 34526+ *
34527+ * This program, aufs is free software; you can redistribute it and/or modify
34528+ * it under the terms of the GNU General Public License as published by
34529+ * the Free Software Foundation; either version 2 of the License, or
34530+ * (at your option) any later version.
dece6358
AM
34531+ *
34532+ * This program is distributed in the hope that it will be useful,
34533+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
34534+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34535+ * GNU General Public License for more details.
34536+ *
34537+ * You should have received a copy of the GNU General Public License
523b37e3 34538+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 34539+ */
34540+
34541+/*
34542+ * whiteout for logical deletion and opaque directory
34543+ */
34544+
1facf9fc 34545+#include "aufs.h"
34546+
34547+#define WH_MASK S_IRUGO
34548+
34549+/*
34550+ * If a directory contains this file, then it is opaque. We start with the
34551+ * .wh. flag so that it is blocked by lookup.
34552+ */
0c3ec466
AM
34553+static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ,
34554+ sizeof(AUFS_WH_DIROPQ) - 1);
1facf9fc 34555+
34556+/*
34557+ * generate whiteout name, which is NOT terminated by NULL.
34558+ * @name: original d_name.name
34559+ * @len: original d_name.len
34560+ * @wh: whiteout qstr
34561+ * returns zero when succeeds, otherwise error.
34562+ * succeeded value as wh->name should be freed by kfree().
34563+ */
34564+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
34565+{
34566+ char *p;
34567+
34568+ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
34569+ return -ENAMETOOLONG;
34570+
34571+ wh->len = name->len + AUFS_WH_PFX_LEN;
34572+ p = kmalloc(wh->len, GFP_NOFS);
34573+ wh->name = p;
34574+ if (p) {
34575+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
34576+ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
34577+ /* smp_mb(); */
34578+ return 0;
34579+ }
34580+ return -ENOMEM;
34581+}
34582+
34583+/* ---------------------------------------------------------------------- */
34584+
34585+/*
34586+ * test if the @wh_name exists under @h_parent.
34587+ * @try_sio specifies the necessary of super-io.
34588+ */
076b876e 34589+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio)
1facf9fc 34590+{
34591+ int err;
34592+ struct dentry *wh_dentry;
1facf9fc 34593+
1facf9fc 34594+ if (!try_sio)
b4510431 34595+ wh_dentry = vfsub_lkup_one(wh_name, h_parent);
1facf9fc 34596+ else
076b876e 34597+ wh_dentry = au_sio_lkup_one(wh_name, h_parent);
1facf9fc 34598+ err = PTR_ERR(wh_dentry);
2000de60
JR
34599+ if (IS_ERR(wh_dentry)) {
34600+ if (err == -ENAMETOOLONG)
34601+ err = 0;
1facf9fc 34602+ goto out;
2000de60 34603+ }
1facf9fc 34604+
34605+ err = 0;
5527c038 34606+ if (d_is_negative(wh_dentry))
1facf9fc 34607+ goto out_wh; /* success */
34608+
34609+ err = 1;
7e9cd9fe 34610+ if (d_is_reg(wh_dentry))
1facf9fc 34611+ goto out_wh; /* success */
34612+
34613+ err = -EIO;
523b37e3 34614+ AuIOErr("%pd Invalid whiteout entry type 0%o.\n",
5527c038 34615+ wh_dentry, d_inode(wh_dentry)->i_mode);
1facf9fc 34616+
4f0767ce 34617+out_wh:
1facf9fc 34618+ dput(wh_dentry);
4f0767ce 34619+out:
1facf9fc 34620+ return err;
34621+}
34622+
34623+/*
34624+ * test if the @h_dentry sets opaque or not.
34625+ */
076b876e 34626+int au_diropq_test(struct dentry *h_dentry)
1facf9fc 34627+{
34628+ int err;
34629+ struct inode *h_dir;
34630+
5527c038 34631+ h_dir = d_inode(h_dentry);
076b876e 34632+ err = au_wh_test(h_dentry, &diropq_name,
1facf9fc 34633+ au_test_h_perm_sio(h_dir, MAY_EXEC));
34634+ return err;
34635+}
34636+
34637+/*
34638+ * returns a negative dentry whose name is unique and temporary.
34639+ */
34640+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
34641+ struct qstr *prefix)
34642+{
1facf9fc 34643+ struct dentry *dentry;
34644+ int i;
027c5e7a 34645+ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
4a4d8108 34646+ *name, *p;
027c5e7a 34647+ /* strict atomic_t is unnecessary here */
1facf9fc 34648+ static unsigned short cnt;
34649+ struct qstr qs;
34650+
4a4d8108
AM
34651+ BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
34652+
1facf9fc 34653+ name = defname;
027c5e7a
AM
34654+ qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
34655+ if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
1facf9fc 34656+ dentry = ERR_PTR(-ENAMETOOLONG);
4a4d8108 34657+ if (unlikely(qs.len > NAME_MAX))
1facf9fc 34658+ goto out;
34659+ dentry = ERR_PTR(-ENOMEM);
34660+ name = kmalloc(qs.len + 1, GFP_NOFS);
34661+ if (unlikely(!name))
34662+ goto out;
34663+ }
34664+
34665+ /* doubly whiteout-ed */
34666+ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
34667+ p = name + AUFS_WH_PFX_LEN * 2;
34668+ memcpy(p, prefix->name, prefix->len);
34669+ p += prefix->len;
34670+ *p++ = '.';
4a4d8108 34671+ AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
1facf9fc 34672+
34673+ qs.name = name;
34674+ for (i = 0; i < 3; i++) {
b752ccd1 34675+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
076b876e 34676+ dentry = au_sio_lkup_one(&qs, h_parent);
5527c038 34677+ if (IS_ERR(dentry) || d_is_negative(dentry))
1facf9fc 34678+ goto out_name;
34679+ dput(dentry);
34680+ }
0c3ec466 34681+ /* pr_warn("could not get random name\n"); */
1facf9fc 34682+ dentry = ERR_PTR(-EEXIST);
34683+ AuDbg("%.*s\n", AuLNPair(&qs));
34684+ BUG();
34685+
4f0767ce 34686+out_name:
1facf9fc 34687+ if (name != defname)
ae9dfd79 34688+ kfree(name);
4f0767ce 34689+out:
4a4d8108 34690+ AuTraceErrPtr(dentry);
1facf9fc 34691+ return dentry;
1facf9fc 34692+}
34693+
34694+/*
34695+ * rename the @h_dentry on @br to the whiteouted temporary name.
34696+ */
34697+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
34698+{
34699+ int err;
34700+ struct path h_path = {
86dc4139 34701+ .mnt = au_br_mnt(br)
1facf9fc 34702+ };
523b37e3 34703+ struct inode *h_dir, *delegated;
1facf9fc 34704+ struct dentry *h_parent;
34705+
34706+ h_parent = h_dentry->d_parent; /* dir inode is locked */
5527c038 34707+ h_dir = d_inode(h_parent);
1facf9fc 34708+ IMustLock(h_dir);
34709+
34710+ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
34711+ err = PTR_ERR(h_path.dentry);
34712+ if (IS_ERR(h_path.dentry))
34713+ goto out;
34714+
34715+ /* under the same dir, no need to lock_rename() */
523b37e3 34716+ delegated = NULL;
f2c43d5f
AM
34717+ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path, &delegated,
34718+ /*flags*/0);
1facf9fc 34719+ AuTraceErr(err);
523b37e3
AM
34720+ if (unlikely(err == -EWOULDBLOCK)) {
34721+ pr_warn("cannot retry for NFSv4 delegation"
34722+ " for an internal rename\n");
34723+ iput(delegated);
34724+ }
1facf9fc 34725+ dput(h_path.dentry);
34726+
4f0767ce 34727+out:
4a4d8108 34728+ AuTraceErr(err);
1facf9fc 34729+ return err;
34730+}
34731+
34732+/* ---------------------------------------------------------------------- */
34733+/*
34734+ * functions for removing a whiteout
34735+ */
34736+
34737+static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
34738+{
523b37e3
AM
34739+ int err, force;
34740+ struct inode *delegated;
1facf9fc 34741+
34742+ /*
34743+ * forces superio when the dir has a sticky bit.
34744+ * this may be a violation of unix fs semantics.
34745+ */
34746+ force = (h_dir->i_mode & S_ISVTX)
5527c038 34747+ && !uid_eq(current_fsuid(), d_inode(h_path->dentry)->i_uid);
523b37e3
AM
34748+ delegated = NULL;
34749+ err = vfsub_unlink(h_dir, h_path, &delegated, force);
34750+ if (unlikely(err == -EWOULDBLOCK)) {
34751+ pr_warn("cannot retry for NFSv4 delegation"
34752+ " for an internal unlink\n");
34753+ iput(delegated);
34754+ }
34755+ return err;
1facf9fc 34756+}
34757+
34758+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
34759+ struct dentry *dentry)
34760+{
34761+ int err;
34762+
34763+ err = do_unlink_wh(h_dir, h_path);
34764+ if (!err && dentry)
34765+ au_set_dbwh(dentry, -1);
34766+
34767+ return err;
34768+}
34769+
34770+static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
34771+ struct au_branch *br)
34772+{
34773+ int err;
34774+ struct path h_path = {
86dc4139 34775+ .mnt = au_br_mnt(br)
1facf9fc 34776+ };
34777+
34778+ err = 0;
b4510431 34779+ h_path.dentry = vfsub_lkup_one(wh, h_parent);
1facf9fc 34780+ if (IS_ERR(h_path.dentry))
34781+ err = PTR_ERR(h_path.dentry);
34782+ else {
5527c038
JR
34783+ if (d_is_reg(h_path.dentry))
34784+ err = do_unlink_wh(d_inode(h_parent), &h_path);
1facf9fc 34785+ dput(h_path.dentry);
34786+ }
34787+
34788+ return err;
34789+}
34790+
34791+/* ---------------------------------------------------------------------- */
34792+/*
34793+ * initialize/clean whiteout for a branch
34794+ */
34795+
34796+static void au_wh_clean(struct inode *h_dir, struct path *whpath,
34797+ const int isdir)
34798+{
34799+ int err;
523b37e3 34800+ struct inode *delegated;
1facf9fc 34801+
5527c038 34802+ if (d_is_negative(whpath->dentry))
1facf9fc 34803+ return;
34804+
86dc4139
AM
34805+ if (isdir)
34806+ err = vfsub_rmdir(h_dir, whpath);
523b37e3
AM
34807+ else {
34808+ delegated = NULL;
34809+ err = vfsub_unlink(h_dir, whpath, &delegated, /*force*/0);
34810+ if (unlikely(err == -EWOULDBLOCK)) {
34811+ pr_warn("cannot retry for NFSv4 delegation"
34812+ " for an internal unlink\n");
34813+ iput(delegated);
34814+ }
34815+ }
1facf9fc 34816+ if (unlikely(err))
523b37e3
AM
34817+ pr_warn("failed removing %pd (%d), ignored.\n",
34818+ whpath->dentry, err);
1facf9fc 34819+}
34820+
34821+static int test_linkable(struct dentry *h_root)
34822+{
5527c038 34823+ struct inode *h_dir = d_inode(h_root);
1facf9fc 34824+
34825+ if (h_dir->i_op->link)
34826+ return 0;
34827+
523b37e3
AM
34828+ pr_err("%pd (%s) doesn't support link(2), use noplink and rw+nolwh\n",
34829+ h_root, au_sbtype(h_root->d_sb));
1facf9fc 34830+ return -ENOSYS;
34831+}
34832+
34833+/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
34834+static int au_whdir(struct inode *h_dir, struct path *path)
34835+{
34836+ int err;
34837+
34838+ err = -EEXIST;
5527c038 34839+ if (d_is_negative(path->dentry)) {
1facf9fc 34840+ int mode = S_IRWXU;
34841+
34842+ if (au_test_nfs(path->dentry->d_sb))
34843+ mode |= S_IXUGO;
86dc4139 34844+ err = vfsub_mkdir(h_dir, path, mode);
2000de60 34845+ } else if (d_is_dir(path->dentry))
1facf9fc 34846+ err = 0;
34847+ else
523b37e3 34848+ pr_err("unknown %pd exists\n", path->dentry);
1facf9fc 34849+
34850+ return err;
34851+}
34852+
34853+struct au_wh_base {
34854+ const struct qstr *name;
34855+ struct dentry *dentry;
34856+};
34857+
34858+static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
34859+ struct path *h_path)
34860+{
34861+ h_path->dentry = base[AuBrWh_BASE].dentry;
34862+ au_wh_clean(h_dir, h_path, /*isdir*/0);
34863+ h_path->dentry = base[AuBrWh_PLINK].dentry;
34864+ au_wh_clean(h_dir, h_path, /*isdir*/1);
34865+ h_path->dentry = base[AuBrWh_ORPH].dentry;
34866+ au_wh_clean(h_dir, h_path, /*isdir*/1);
34867+}
34868+
34869+/*
34870+ * returns tri-state,
c1595e42 34871+ * minus: error, caller should print the message
1facf9fc 34872+ * zero: succuess
c1595e42 34873+ * plus: error, caller should NOT print the message
1facf9fc 34874+ */
34875+static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
34876+ int do_plink, struct au_wh_base base[],
34877+ struct path *h_path)
34878+{
34879+ int err;
34880+ struct inode *h_dir;
34881+
5527c038 34882+ h_dir = d_inode(h_root);
1facf9fc 34883+ h_path->dentry = base[AuBrWh_BASE].dentry;
34884+ au_wh_clean(h_dir, h_path, /*isdir*/0);
34885+ h_path->dentry = base[AuBrWh_PLINK].dentry;
34886+ if (do_plink) {
34887+ err = test_linkable(h_root);
34888+ if (unlikely(err)) {
34889+ err = 1;
34890+ goto out;
34891+ }
34892+
34893+ err = au_whdir(h_dir, h_path);
34894+ if (unlikely(err))
34895+ goto out;
34896+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
34897+ } else
34898+ au_wh_clean(h_dir, h_path, /*isdir*/1);
34899+ h_path->dentry = base[AuBrWh_ORPH].dentry;
34900+ err = au_whdir(h_dir, h_path);
34901+ if (unlikely(err))
34902+ goto out;
34903+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
34904+
4f0767ce 34905+out:
1facf9fc 34906+ return err;
34907+}
34908+
34909+/*
34910+ * for the moment, aufs supports the branch filesystem which does not support
34911+ * link(2). testing on FAT which does not support i_op->setattr() fully either,
34912+ * copyup failed. finally, such filesystem will not be used as the writable
34913+ * branch.
34914+ *
34915+ * returns tri-state, see above.
34916+ */
34917+static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
34918+ int do_plink, struct au_wh_base base[],
34919+ struct path *h_path)
34920+{
34921+ int err;
34922+ struct inode *h_dir;
34923+
1308ab2a 34924+ WbrWhMustWriteLock(wbr);
34925+
1facf9fc 34926+ err = test_linkable(h_root);
34927+ if (unlikely(err)) {
34928+ err = 1;
34929+ goto out;
34930+ }
34931+
34932+ /*
34933+ * todo: should this create be done in /sbin/mount.aufs helper?
34934+ */
34935+ err = -EEXIST;
5527c038
JR
34936+ h_dir = d_inode(h_root);
34937+ if (d_is_negative(base[AuBrWh_BASE].dentry)) {
86dc4139
AM
34938+ h_path->dentry = base[AuBrWh_BASE].dentry;
34939+ err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true);
7e9cd9fe 34940+ } else if (d_is_reg(base[AuBrWh_BASE].dentry))
1facf9fc 34941+ err = 0;
34942+ else
523b37e3 34943+ pr_err("unknown %pd2 exists\n", base[AuBrWh_BASE].dentry);
1facf9fc 34944+ if (unlikely(err))
34945+ goto out;
34946+
34947+ h_path->dentry = base[AuBrWh_PLINK].dentry;
34948+ if (do_plink) {
34949+ err = au_whdir(h_dir, h_path);
34950+ if (unlikely(err))
34951+ goto out;
34952+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
34953+ } else
34954+ au_wh_clean(h_dir, h_path, /*isdir*/1);
34955+ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
34956+
34957+ h_path->dentry = base[AuBrWh_ORPH].dentry;
34958+ err = au_whdir(h_dir, h_path);
34959+ if (unlikely(err))
34960+ goto out;
34961+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
34962+
4f0767ce 34963+out:
1facf9fc 34964+ return err;
34965+}
34966+
34967+/*
34968+ * initialize the whiteout base file/dir for @br.
34969+ */
86dc4139 34970+int au_wh_init(struct au_branch *br, struct super_block *sb)
1facf9fc 34971+{
34972+ int err, i;
34973+ const unsigned char do_plink
34974+ = !!au_opt_test(au_mntflags(sb), PLINK);
1facf9fc 34975+ struct inode *h_dir;
86dc4139
AM
34976+ struct path path = br->br_path;
34977+ struct dentry *h_root = path.dentry;
1facf9fc 34978+ struct au_wbr *wbr = br->br_wbr;
34979+ static const struct qstr base_name[] = {
0c3ec466
AM
34980+ [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME,
34981+ sizeof(AUFS_BASE_NAME) - 1),
34982+ [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME,
34983+ sizeof(AUFS_PLINKDIR_NAME) - 1),
34984+ [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME,
34985+ sizeof(AUFS_ORPHDIR_NAME) - 1)
1facf9fc 34986+ };
34987+ struct au_wh_base base[] = {
34988+ [AuBrWh_BASE] = {
34989+ .name = base_name + AuBrWh_BASE,
34990+ .dentry = NULL
34991+ },
34992+ [AuBrWh_PLINK] = {
34993+ .name = base_name + AuBrWh_PLINK,
34994+ .dentry = NULL
34995+ },
34996+ [AuBrWh_ORPH] = {
34997+ .name = base_name + AuBrWh_ORPH,
34998+ .dentry = NULL
34999+ }
35000+ };
35001+
1308ab2a 35002+ if (wbr)
35003+ WbrWhMustWriteLock(wbr);
1facf9fc 35004+
1facf9fc 35005+ for (i = 0; i < AuBrWh_Last; i++) {
35006+ /* doubly whiteouted */
35007+ struct dentry *d;
35008+
35009+ d = au_wh_lkup(h_root, (void *)base[i].name, br);
35010+ err = PTR_ERR(d);
35011+ if (IS_ERR(d))
35012+ goto out;
35013+
35014+ base[i].dentry = d;
35015+ AuDebugOn(wbr
35016+ && wbr->wbr_wh[i]
35017+ && wbr->wbr_wh[i] != base[i].dentry);
35018+ }
35019+
35020+ if (wbr)
35021+ for (i = 0; i < AuBrWh_Last; i++) {
35022+ dput(wbr->wbr_wh[i]);
35023+ wbr->wbr_wh[i] = NULL;
35024+ }
35025+
35026+ err = 0;
1e00d052 35027+ if (!au_br_writable(br->br_perm)) {
5527c038 35028+ h_dir = d_inode(h_root);
1facf9fc 35029+ au_wh_init_ro(h_dir, base, &path);
1e00d052 35030+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 35031+ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
35032+ if (err > 0)
35033+ goto out;
35034+ else if (err)
35035+ goto out_err;
1e00d052 35036+ } else {
1facf9fc 35037+ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
35038+ if (err > 0)
35039+ goto out;
35040+ else if (err)
35041+ goto out_err;
1facf9fc 35042+ }
35043+ goto out; /* success */
35044+
4f0767ce 35045+out_err:
523b37e3
AM
35046+ pr_err("an error(%d) on the writable branch %pd(%s)\n",
35047+ err, h_root, au_sbtype(h_root->d_sb));
4f0767ce 35048+out:
1facf9fc 35049+ for (i = 0; i < AuBrWh_Last; i++)
35050+ dput(base[i].dentry);
35051+ return err;
35052+}
35053+
35054+/* ---------------------------------------------------------------------- */
35055+/*
35056+ * whiteouts are all hard-linked usually.
35057+ * when its link count reaches a ceiling, we create a new whiteout base
35058+ * asynchronously.
35059+ */
35060+
35061+struct reinit_br_wh {
35062+ struct super_block *sb;
35063+ struct au_branch *br;
35064+};
35065+
35066+static void reinit_br_wh(void *arg)
35067+{
35068+ int err;
35069+ aufs_bindex_t bindex;
35070+ struct path h_path;
35071+ struct reinit_br_wh *a = arg;
35072+ struct au_wbr *wbr;
523b37e3 35073+ struct inode *dir, *delegated;
1facf9fc 35074+ struct dentry *h_root;
35075+ struct au_hinode *hdir;
35076+
35077+ err = 0;
35078+ wbr = a->br->br_wbr;
35079+ /* big aufs lock */
35080+ si_noflush_write_lock(a->sb);
35081+ if (!au_br_writable(a->br->br_perm))
35082+ goto out;
35083+ bindex = au_br_index(a->sb, a->br->br_id);
35084+ if (unlikely(bindex < 0))
35085+ goto out;
35086+
1308ab2a 35087+ di_read_lock_parent(a->sb->s_root, AuLock_IR);
5527c038 35088+ dir = d_inode(a->sb->s_root);
1facf9fc 35089+ hdir = au_hi(dir, bindex);
35090+ h_root = au_h_dptr(a->sb->s_root, bindex);
86dc4139 35091+ AuDebugOn(h_root != au_br_dentry(a->br));
1facf9fc 35092+
5afbbe0d 35093+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 35094+ wbr_wh_write_lock(wbr);
35095+ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
35096+ h_root, a->br);
35097+ if (!err) {
86dc4139
AM
35098+ h_path.dentry = wbr->wbr_whbase;
35099+ h_path.mnt = au_br_mnt(a->br);
523b37e3
AM
35100+ delegated = NULL;
35101+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated,
35102+ /*force*/0);
35103+ if (unlikely(err == -EWOULDBLOCK)) {
35104+ pr_warn("cannot retry for NFSv4 delegation"
35105+ " for an internal unlink\n");
35106+ iput(delegated);
35107+ }
1facf9fc 35108+ } else {
523b37e3 35109+ pr_warn("%pd is moved, ignored\n", wbr->wbr_whbase);
1facf9fc 35110+ err = 0;
35111+ }
35112+ dput(wbr->wbr_whbase);
35113+ wbr->wbr_whbase = NULL;
35114+ if (!err)
86dc4139 35115+ err = au_wh_init(a->br, a->sb);
1facf9fc 35116+ wbr_wh_write_unlock(wbr);
5afbbe0d 35117+ au_hn_inode_unlock(hdir);
1308ab2a 35118+ di_read_unlock(a->sb->s_root, AuLock_IR);
076b876e
AM
35119+ if (!err)
35120+ au_fhsm_wrote(a->sb, bindex, /*force*/0);
1facf9fc 35121+
4f0767ce 35122+out:
1facf9fc 35123+ if (wbr)
35124+ atomic_dec(&wbr->wbr_wh_running);
5afbbe0d 35125+ au_br_put(a->br);
1facf9fc 35126+ si_write_unlock(a->sb);
027c5e7a 35127+ au_nwt_done(&au_sbi(a->sb)->si_nowait);
ae9dfd79 35128+ kfree(arg);
1facf9fc 35129+ if (unlikely(err))
35130+ AuIOErr("err %d\n", err);
35131+}
35132+
35133+static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
35134+{
35135+ int do_dec, wkq_err;
35136+ struct reinit_br_wh *arg;
35137+
35138+ do_dec = 1;
35139+ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
35140+ goto out;
35141+
35142+ /* ignore ENOMEM */
35143+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
35144+ if (arg) {
35145+ /*
35146+ * dec(wh_running), kfree(arg) and dec(br_count)
35147+ * in reinit function
35148+ */
35149+ arg->sb = sb;
35150+ arg->br = br;
5afbbe0d 35151+ au_br_get(br);
53392da6 35152+ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0);
1facf9fc 35153+ if (unlikely(wkq_err)) {
35154+ atomic_dec(&br->br_wbr->wbr_wh_running);
5afbbe0d 35155+ au_br_put(br);
ae9dfd79 35156+ kfree(arg);
1facf9fc 35157+ }
35158+ do_dec = 0;
35159+ }
35160+
4f0767ce 35161+out:
1facf9fc 35162+ if (do_dec)
35163+ atomic_dec(&br->br_wbr->wbr_wh_running);
35164+}
35165+
35166+/* ---------------------------------------------------------------------- */
35167+
35168+/*
35169+ * create the whiteout @wh.
35170+ */
35171+static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
35172+ struct dentry *wh)
35173+{
35174+ int err;
35175+ struct path h_path = {
35176+ .dentry = wh
35177+ };
35178+ struct au_branch *br;
35179+ struct au_wbr *wbr;
35180+ struct dentry *h_parent;
523b37e3 35181+ struct inode *h_dir, *delegated;
1facf9fc 35182+
35183+ h_parent = wh->d_parent; /* dir inode is locked */
5527c038 35184+ h_dir = d_inode(h_parent);
1facf9fc 35185+ IMustLock(h_dir);
35186+
35187+ br = au_sbr(sb, bindex);
86dc4139 35188+ h_path.mnt = au_br_mnt(br);
1facf9fc 35189+ wbr = br->br_wbr;
35190+ wbr_wh_read_lock(wbr);
35191+ if (wbr->wbr_whbase) {
523b37e3
AM
35192+ delegated = NULL;
35193+ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path, &delegated);
35194+ if (unlikely(err == -EWOULDBLOCK)) {
35195+ pr_warn("cannot retry for NFSv4 delegation"
35196+ " for an internal link\n");
35197+ iput(delegated);
35198+ }
1facf9fc 35199+ if (!err || err != -EMLINK)
35200+ goto out;
35201+
35202+ /* link count full. re-initialize br_whbase. */
35203+ kick_reinit_br_wh(sb, br);
35204+ }
35205+
35206+ /* return this error in this context */
b4510431 35207+ err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true);
076b876e
AM
35208+ if (!err)
35209+ au_fhsm_wrote(sb, bindex, /*force*/0);
1facf9fc 35210+
4f0767ce 35211+out:
1facf9fc 35212+ wbr_wh_read_unlock(wbr);
35213+ return err;
35214+}
35215+
35216+/* ---------------------------------------------------------------------- */
35217+
35218+/*
35219+ * create or remove the diropq.
35220+ */
35221+static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
35222+ unsigned int flags)
35223+{
35224+ struct dentry *opq_dentry, *h_dentry;
35225+ struct super_block *sb;
35226+ struct au_branch *br;
35227+ int err;
35228+
35229+ sb = dentry->d_sb;
35230+ br = au_sbr(sb, bindex);
35231+ h_dentry = au_h_dptr(dentry, bindex);
b4510431 35232+ opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry);
1facf9fc 35233+ if (IS_ERR(opq_dentry))
35234+ goto out;
35235+
35236+ if (au_ftest_diropq(flags, CREATE)) {
35237+ err = link_or_create_wh(sb, bindex, opq_dentry);
35238+ if (!err) {
35239+ au_set_dbdiropq(dentry, bindex);
35240+ goto out; /* success */
35241+ }
35242+ } else {
35243+ struct path tmp = {
35244+ .dentry = opq_dentry,
86dc4139 35245+ .mnt = au_br_mnt(br)
1facf9fc 35246+ };
5527c038 35247+ err = do_unlink_wh(au_h_iptr(d_inode(dentry), bindex), &tmp);
1facf9fc 35248+ if (!err)
35249+ au_set_dbdiropq(dentry, -1);
35250+ }
35251+ dput(opq_dentry);
35252+ opq_dentry = ERR_PTR(err);
35253+
4f0767ce 35254+out:
1facf9fc 35255+ return opq_dentry;
35256+}
35257+
35258+struct do_diropq_args {
35259+ struct dentry **errp;
35260+ struct dentry *dentry;
35261+ aufs_bindex_t bindex;
35262+ unsigned int flags;
35263+};
35264+
35265+static void call_do_diropq(void *args)
35266+{
35267+ struct do_diropq_args *a = args;
35268+ *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
35269+}
35270+
35271+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
35272+ unsigned int flags)
35273+{
35274+ struct dentry *diropq, *h_dentry;
35275+
35276+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 35277+ if (!au_test_h_perm_sio(d_inode(h_dentry), MAY_EXEC | MAY_WRITE))
1facf9fc 35278+ diropq = do_diropq(dentry, bindex, flags);
35279+ else {
35280+ int wkq_err;
35281+ struct do_diropq_args args = {
35282+ .errp = &diropq,
35283+ .dentry = dentry,
35284+ .bindex = bindex,
35285+ .flags = flags
35286+ };
35287+
35288+ wkq_err = au_wkq_wait(call_do_diropq, &args);
35289+ if (unlikely(wkq_err))
35290+ diropq = ERR_PTR(wkq_err);
35291+ }
35292+
35293+ return diropq;
35294+}
35295+
35296+/* ---------------------------------------------------------------------- */
35297+
35298+/*
35299+ * lookup whiteout dentry.
35300+ * @h_parent: lower parent dentry which must exist and be locked
35301+ * @base_name: name of dentry which will be whiteouted
35302+ * returns dentry for whiteout.
35303+ */
35304+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
35305+ struct au_branch *br)
35306+{
35307+ int err;
35308+ struct qstr wh_name;
35309+ struct dentry *wh_dentry;
35310+
35311+ err = au_wh_name_alloc(&wh_name, base_name);
35312+ wh_dentry = ERR_PTR(err);
35313+ if (!err) {
b4510431 35314+ wh_dentry = vfsub_lkup_one(&wh_name, h_parent);
ae9dfd79 35315+ kfree(wh_name.name);
1facf9fc 35316+ }
35317+ return wh_dentry;
35318+}
35319+
35320+/*
35321+ * link/create a whiteout for @dentry on @bindex.
35322+ */
35323+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
35324+ struct dentry *h_parent)
35325+{
35326+ struct dentry *wh_dentry;
35327+ struct super_block *sb;
35328+ int err;
35329+
35330+ sb = dentry->d_sb;
35331+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
5527c038 35332+ if (!IS_ERR(wh_dentry) && d_is_negative(wh_dentry)) {
1facf9fc 35333+ err = link_or_create_wh(sb, bindex, wh_dentry);
076b876e 35334+ if (!err) {
1facf9fc 35335+ au_set_dbwh(dentry, bindex);
076b876e
AM
35336+ au_fhsm_wrote(sb, bindex, /*force*/0);
35337+ } else {
1facf9fc 35338+ dput(wh_dentry);
35339+ wh_dentry = ERR_PTR(err);
35340+ }
35341+ }
35342+
35343+ return wh_dentry;
35344+}
35345+
35346+/* ---------------------------------------------------------------------- */
35347+
35348+/* Delete all whiteouts in this directory on branch bindex. */
35349+static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
35350+ aufs_bindex_t bindex, struct au_branch *br)
35351+{
35352+ int err;
35353+ unsigned long ul, n;
35354+ struct qstr wh_name;
35355+ char *p;
35356+ struct hlist_head *head;
c06a8ce3 35357+ struct au_vdir_wh *pos;
1facf9fc 35358+ struct au_vdir_destr *str;
35359+
35360+ err = -ENOMEM;
537831f9 35361+ p = (void *)__get_free_page(GFP_NOFS);
1facf9fc 35362+ wh_name.name = p;
35363+ if (unlikely(!wh_name.name))
35364+ goto out;
35365+
35366+ err = 0;
35367+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
35368+ p += AUFS_WH_PFX_LEN;
35369+ n = whlist->nh_num;
35370+ head = whlist->nh_head;
35371+ for (ul = 0; !err && ul < n; ul++, head++) {
c06a8ce3
AM
35372+ hlist_for_each_entry(pos, head, wh_hash) {
35373+ if (pos->wh_bindex != bindex)
1facf9fc 35374+ continue;
35375+
c06a8ce3 35376+ str = &pos->wh_str;
1facf9fc 35377+ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
35378+ memcpy(p, str->name, str->len);
35379+ wh_name.len = AUFS_WH_PFX_LEN + str->len;
35380+ err = unlink_wh_name(h_dentry, &wh_name, br);
35381+ if (!err)
35382+ continue;
35383+ break;
35384+ }
35385+ AuIOErr("whiteout name too long %.*s\n",
35386+ str->len, str->name);
35387+ err = -EIO;
35388+ break;
35389+ }
35390+ }
ae9dfd79 35391+ free_page((unsigned long)wh_name.name);
1facf9fc 35392+
4f0767ce 35393+out:
1facf9fc 35394+ return err;
35395+}
35396+
35397+struct del_wh_children_args {
35398+ int *errp;
35399+ struct dentry *h_dentry;
1308ab2a 35400+ struct au_nhash *whlist;
1facf9fc 35401+ aufs_bindex_t bindex;
35402+ struct au_branch *br;
35403+};
35404+
35405+static void call_del_wh_children(void *args)
35406+{
35407+ struct del_wh_children_args *a = args;
1308ab2a 35408+ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
1facf9fc 35409+}
35410+
35411+/* ---------------------------------------------------------------------- */
35412+
35413+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
35414+{
35415+ struct au_whtmp_rmdir *whtmp;
dece6358 35416+ int err;
1308ab2a 35417+ unsigned int rdhash;
dece6358
AM
35418+
35419+ SiMustAnyLock(sb);
1facf9fc 35420+
be52b249 35421+ whtmp = kzalloc(sizeof(*whtmp), gfp);
dece6358
AM
35422+ if (unlikely(!whtmp)) {
35423+ whtmp = ERR_PTR(-ENOMEM);
1facf9fc 35424+ goto out;
dece6358 35425+ }
1facf9fc 35426+
1308ab2a 35427+ /* no estimation for dir size */
35428+ rdhash = au_sbi(sb)->si_rdhash;
35429+ if (!rdhash)
35430+ rdhash = AUFS_RDHASH_DEF;
35431+ err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
35432+ if (unlikely(err)) {
ae9dfd79 35433+ kfree(whtmp);
1308ab2a 35434+ whtmp = ERR_PTR(err);
35435+ }
dece6358 35436+
4f0767ce 35437+out:
dece6358 35438+ return whtmp;
1facf9fc 35439+}
35440+
35441+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
35442+{
027c5e7a 35443+ if (whtmp->br)
5afbbe0d 35444+ au_br_put(whtmp->br);
1facf9fc 35445+ dput(whtmp->wh_dentry);
35446+ iput(whtmp->dir);
dece6358 35447+ au_nhash_wh_free(&whtmp->whlist);
ae9dfd79 35448+ kfree(whtmp);
1facf9fc 35449+}
35450+
35451+/*
35452+ * rmdir the whiteouted temporary named dir @h_dentry.
35453+ * @whlist: whiteouted children.
35454+ */
35455+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
35456+ struct dentry *wh_dentry, struct au_nhash *whlist)
35457+{
35458+ int err;
2000de60 35459+ unsigned int h_nlink;
1facf9fc 35460+ struct path h_tmp;
35461+ struct inode *wh_inode, *h_dir;
35462+ struct au_branch *br;
35463+
5527c038 35464+ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */
1facf9fc 35465+ IMustLock(h_dir);
35466+
35467+ br = au_sbr(dir->i_sb, bindex);
5527c038 35468+ wh_inode = d_inode(wh_dentry);
febd17d6 35469+ inode_lock_nested(wh_inode, AuLsc_I_CHILD);
1facf9fc 35470+
35471+ /*
35472+ * someone else might change some whiteouts while we were sleeping.
35473+ * it means this whlist may have an obsoleted entry.
35474+ */
35475+ if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
35476+ err = del_wh_children(wh_dentry, whlist, bindex, br);
35477+ else {
35478+ int wkq_err;
35479+ struct del_wh_children_args args = {
35480+ .errp = &err,
35481+ .h_dentry = wh_dentry,
1308ab2a 35482+ .whlist = whlist,
1facf9fc 35483+ .bindex = bindex,
35484+ .br = br
35485+ };
35486+
35487+ wkq_err = au_wkq_wait(call_del_wh_children, &args);
35488+ if (unlikely(wkq_err))
35489+ err = wkq_err;
35490+ }
febd17d6 35491+ inode_unlock(wh_inode);
1facf9fc 35492+
35493+ if (!err) {
35494+ h_tmp.dentry = wh_dentry;
86dc4139 35495+ h_tmp.mnt = au_br_mnt(br);
2000de60 35496+ h_nlink = h_dir->i_nlink;
1facf9fc 35497+ err = vfsub_rmdir(h_dir, &h_tmp);
2000de60
JR
35498+ /* some fs doesn't change the parent nlink in some cases */
35499+ h_nlink -= h_dir->i_nlink;
1facf9fc 35500+ }
35501+
35502+ if (!err) {
5afbbe0d 35503+ if (au_ibtop(dir) == bindex) {
7f207e10 35504+ /* todo: dir->i_mutex is necessary */
1facf9fc 35505+ au_cpup_attr_timesizes(dir);
2000de60
JR
35506+ if (h_nlink)
35507+ vfsub_drop_nlink(dir);
1facf9fc 35508+ }
35509+ return 0; /* success */
35510+ }
35511+
523b37e3 35512+ pr_warn("failed removing %pd(%d), ignored\n", wh_dentry, err);
1facf9fc 35513+ return err;
35514+}
35515+
35516+static void call_rmdir_whtmp(void *args)
35517+{
35518+ int err;
e49829fe 35519+ aufs_bindex_t bindex;
1facf9fc 35520+ struct au_whtmp_rmdir *a = args;
35521+ struct super_block *sb;
35522+ struct dentry *h_parent;
35523+ struct inode *h_dir;
1facf9fc 35524+ struct au_hinode *hdir;
35525+
35526+ /* rmdir by nfsd may cause deadlock with this i_mutex */
febd17d6 35527+ /* inode_lock(a->dir); */
e49829fe 35528+ err = -EROFS;
1facf9fc 35529+ sb = a->dir->i_sb;
e49829fe
JR
35530+ si_read_lock(sb, !AuLock_FLUSH);
35531+ if (!au_br_writable(a->br->br_perm))
35532+ goto out;
35533+ bindex = au_br_index(sb, a->br->br_id);
35534+ if (unlikely(bindex < 0))
1facf9fc 35535+ goto out;
35536+
35537+ err = -EIO;
1facf9fc 35538+ ii_write_lock_parent(a->dir);
35539+ h_parent = dget_parent(a->wh_dentry);
5527c038 35540+ h_dir = d_inode(h_parent);
e49829fe 35541+ hdir = au_hi(a->dir, bindex);
86dc4139
AM
35542+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
35543+ if (unlikely(err))
35544+ goto out_mnt;
5afbbe0d 35545+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
e49829fe
JR
35546+ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
35547+ a->br);
86dc4139
AM
35548+ if (!err)
35549+ err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist);
5afbbe0d 35550+ au_hn_inode_unlock(hdir);
86dc4139
AM
35551+ vfsub_mnt_drop_write(au_br_mnt(a->br));
35552+
35553+out_mnt:
1facf9fc 35554+ dput(h_parent);
35555+ ii_write_unlock(a->dir);
4f0767ce 35556+out:
febd17d6 35557+ /* inode_unlock(a->dir); */
1facf9fc 35558+ au_whtmp_rmdir_free(a);
027c5e7a
AM
35559+ si_read_unlock(sb);
35560+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 35561+ if (unlikely(err))
35562+ AuIOErr("err %d\n", err);
35563+}
35564+
35565+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
35566+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
35567+{
35568+ int wkq_err;
e49829fe 35569+ struct super_block *sb;
1facf9fc 35570+
35571+ IMustLock(dir);
35572+
35573+ /* all post-process will be done in do_rmdir_whtmp(). */
e49829fe 35574+ sb = dir->i_sb;
1facf9fc 35575+ args->dir = au_igrab(dir);
e49829fe 35576+ args->br = au_sbr(sb, bindex);
5afbbe0d 35577+ au_br_get(args->br);
1facf9fc 35578+ args->wh_dentry = dget(wh_dentry);
53392da6 35579+ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0);
1facf9fc 35580+ if (unlikely(wkq_err)) {
523b37e3 35581+ pr_warn("rmdir error %pd (%d), ignored\n", wh_dentry, wkq_err);
1facf9fc 35582+ au_whtmp_rmdir_free(args);
35583+ }
35584+}
7f207e10
AM
35585diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h
35586--- /usr/share/empty/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 35587+++ linux/fs/aufs/whout.h 2018-04-15 08:49:13.404484168 +0200
076b876e 35588@@ -0,0 +1,85 @@
1facf9fc 35589+/*
ae9dfd79 35590+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 35591+ *
35592+ * This program, aufs is free software; you can redistribute it and/or modify
35593+ * it under the terms of the GNU General Public License as published by
35594+ * the Free Software Foundation; either version 2 of the License, or
35595+ * (at your option) any later version.
dece6358
AM
35596+ *
35597+ * This program is distributed in the hope that it will be useful,
35598+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
35599+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35600+ * GNU General Public License for more details.
35601+ *
35602+ * You should have received a copy of the GNU General Public License
523b37e3 35603+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 35604+ */
35605+
35606+/*
35607+ * whiteout for logical deletion and opaque directory
35608+ */
35609+
35610+#ifndef __AUFS_WHOUT_H__
35611+#define __AUFS_WHOUT_H__
35612+
35613+#ifdef __KERNEL__
35614+
1facf9fc 35615+#include "dir.h"
35616+
35617+/* whout.c */
35618+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
076b876e
AM
35619+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio);
35620+int au_diropq_test(struct dentry *h_dentry);
7e9cd9fe 35621+struct au_branch;
1facf9fc 35622+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
35623+ struct qstr *prefix);
35624+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
35625+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
35626+ struct dentry *dentry);
86dc4139 35627+int au_wh_init(struct au_branch *br, struct super_block *sb);
1facf9fc 35628+
35629+/* diropq flags */
35630+#define AuDiropq_CREATE 1
35631+#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name)
7f207e10
AM
35632+#define au_fset_diropq(flags, name) \
35633+ do { (flags) |= AuDiropq_##name; } while (0)
35634+#define au_fclr_diropq(flags, name) \
35635+ do { (flags) &= ~AuDiropq_##name; } while (0)
1facf9fc 35636+
35637+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
35638+ unsigned int flags);
35639+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
35640+ struct au_branch *br);
35641+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
35642+ struct dentry *h_parent);
35643+
35644+/* real rmdir for the whiteout-ed dir */
35645+struct au_whtmp_rmdir {
35646+ struct inode *dir;
e49829fe 35647+ struct au_branch *br;
1facf9fc 35648+ struct dentry *wh_dentry;
dece6358 35649+ struct au_nhash whlist;
1facf9fc 35650+};
35651+
35652+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
35653+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
35654+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
35655+ struct dentry *wh_dentry, struct au_nhash *whlist);
35656+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
35657+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
35658+
35659+/* ---------------------------------------------------------------------- */
35660+
35661+static inline struct dentry *au_diropq_create(struct dentry *dentry,
35662+ aufs_bindex_t bindex)
35663+{
35664+ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
35665+}
35666+
35667+static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
35668+{
35669+ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
35670+}
35671+
35672+#endif /* __KERNEL__ */
35673+#endif /* __AUFS_WHOUT_H__ */
7f207e10
AM
35674diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
35675--- /usr/share/empty/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
35676+++ linux/fs/aufs/wkq.c 2018-04-15 08:49:13.404484168 +0200
35677@@ -0,0 +1,212 @@
1facf9fc 35678+/*
ae9dfd79 35679+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 35680+ *
35681+ * This program, aufs is free software; you can redistribute it and/or modify
35682+ * it under the terms of the GNU General Public License as published by
35683+ * the Free Software Foundation; either version 2 of the License, or
35684+ * (at your option) any later version.
dece6358
AM
35685+ *
35686+ * This program is distributed in the hope that it will be useful,
35687+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
35688+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35689+ * GNU General Public License for more details.
35690+ *
35691+ * You should have received a copy of the GNU General Public License
523b37e3 35692+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 35693+ */
35694+
35695+/*
35696+ * workqueue for asynchronous/super-io operations
35697+ * todo: try new dredential scheme
35698+ */
35699+
dece6358 35700+#include <linux/module.h>
1facf9fc 35701+#include "aufs.h"
35702+
9dbd164d 35703+/* internal workqueue named AUFS_WKQ_NAME */
b752ccd1 35704+
9dbd164d 35705+static struct workqueue_struct *au_wkq;
1facf9fc 35706+
35707+struct au_wkinfo {
35708+ struct work_struct wk;
7f207e10 35709+ struct kobject *kobj;
1facf9fc 35710+
35711+ unsigned int flags; /* see wkq.h */
35712+
35713+ au_wkq_func_t func;
35714+ void *args;
35715+
1facf9fc 35716+ struct completion *comp;
35717+};
35718+
35719+/* ---------------------------------------------------------------------- */
35720+
1facf9fc 35721+static void wkq_func(struct work_struct *wk)
35722+{
35723+ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
35724+
2dfbb274 35725+ AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID));
7f207e10
AM
35726+ AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY);
35727+
1facf9fc 35728+ wkinfo->func(wkinfo->args);
1facf9fc 35729+ if (au_ftest_wkq(wkinfo->flags, WAIT))
35730+ complete(wkinfo->comp);
35731+ else {
7f207e10 35732+ kobject_put(wkinfo->kobj);
9dbd164d 35733+ module_put(THIS_MODULE); /* todo: ?? */
ae9dfd79 35734+ kfree(wkinfo);
1facf9fc 35735+ }
35736+}
35737+
35738+/*
35739+ * Since struct completion is large, try allocating it dynamically.
35740+ */
c2b27bf2 35741+#if 1 /* defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) */
1facf9fc 35742+#define AuWkqCompDeclare(name) struct completion *comp = NULL
35743+
35744+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
35745+{
35746+ *comp = kmalloc(sizeof(**comp), GFP_NOFS);
35747+ if (*comp) {
35748+ init_completion(*comp);
35749+ wkinfo->comp = *comp;
35750+ return 0;
35751+ }
35752+ return -ENOMEM;
35753+}
35754+
35755+static void au_wkq_comp_free(struct completion *comp)
35756+{
ae9dfd79 35757+ kfree(comp);
1facf9fc 35758+}
35759+
35760+#else
35761+
35762+/* no braces */
35763+#define AuWkqCompDeclare(name) \
35764+ DECLARE_COMPLETION_ONSTACK(_ ## name); \
35765+ struct completion *comp = &_ ## name
35766+
35767+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
35768+{
35769+ wkinfo->comp = *comp;
35770+ return 0;
35771+}
35772+
35773+static void au_wkq_comp_free(struct completion *comp __maybe_unused)
35774+{
35775+ /* empty */
35776+}
35777+#endif /* 4KSTACKS */
35778+
53392da6 35779+static void au_wkq_run(struct au_wkinfo *wkinfo)
1facf9fc 35780+{
53392da6
AM
35781+ if (au_ftest_wkq(wkinfo->flags, NEST)) {
35782+ if (au_wkq_test()) {
38d290e6
JR
35783+ AuWarn1("wkq from wkq, unless silly-rename on NFS,"
35784+ " due to a dead dir by UDBA?\n");
53392da6
AM
35785+ AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT));
35786+ }
35787+ } else
35788+ au_dbg_verify_kthread();
35789+
35790+ if (au_ftest_wkq(wkinfo->flags, WAIT)) {
a1f66529 35791+ INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func);
9dbd164d 35792+ queue_work(au_wkq, &wkinfo->wk);
4a4d8108
AM
35793+ } else {
35794+ INIT_WORK(&wkinfo->wk, wkq_func);
35795+ schedule_work(&wkinfo->wk);
35796+ }
1facf9fc 35797+}
35798+
7f207e10
AM
35799+/*
35800+ * Be careful. It is easy to make deadlock happen.
35801+ * processA: lock, wkq and wait
35802+ * processB: wkq and wait, lock in wkq
35803+ * --> deadlock
35804+ */
b752ccd1 35805+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args)
1facf9fc 35806+{
35807+ int err;
35808+ AuWkqCompDeclare(comp);
35809+ struct au_wkinfo wkinfo = {
b752ccd1 35810+ .flags = flags,
1facf9fc 35811+ .func = func,
35812+ .args = args
35813+ };
35814+
35815+ err = au_wkq_comp_alloc(&wkinfo, &comp);
35816+ if (!err) {
53392da6 35817+ au_wkq_run(&wkinfo);
1facf9fc 35818+ /* no timeout, no interrupt */
35819+ wait_for_completion(wkinfo.comp);
35820+ au_wkq_comp_free(comp);
35821+ }
35822+
ae9dfd79 35823+ destroy_work_on_stack(&wkinfo.wk);
1facf9fc 35824+ return err;
1facf9fc 35825+}
35826+
027c5e7a
AM
35827+/*
35828+ * Note: dget/dput() in func for aufs dentries are not supported. It will be a
35829+ * problem in a concurrent umounting.
35830+ */
53392da6
AM
35831+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
35832+ unsigned int flags)
1facf9fc 35833+{
35834+ int err;
35835+ struct au_wkinfo *wkinfo;
35836+
f0c0a007 35837+ atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
1facf9fc 35838+
35839+ /*
35840+ * wkq_func() must free this wkinfo.
35841+ * it highly depends upon the implementation of workqueue.
35842+ */
35843+ err = 0;
35844+ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
35845+ if (wkinfo) {
7f207e10 35846+ wkinfo->kobj = &au_sbi(sb)->si_kobj;
53392da6 35847+ wkinfo->flags = flags & ~AuWkq_WAIT;
1facf9fc 35848+ wkinfo->func = func;
35849+ wkinfo->args = args;
35850+ wkinfo->comp = NULL;
7f207e10 35851+ kobject_get(wkinfo->kobj);
9dbd164d 35852+ __module_get(THIS_MODULE); /* todo: ?? */
1facf9fc 35853+
53392da6 35854+ au_wkq_run(wkinfo);
1facf9fc 35855+ } else {
35856+ err = -ENOMEM;
e49829fe 35857+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 35858+ }
35859+
35860+ return err;
35861+}
35862+
35863+/* ---------------------------------------------------------------------- */
35864+
35865+void au_nwt_init(struct au_nowait_tasks *nwt)
35866+{
f0c0a007
AM
35867+ atomic_set(&nwt->nw_len, 0);
35868+ /* smp_mb(); */ /* atomic_set */
1facf9fc 35869+ init_waitqueue_head(&nwt->nw_wq);
35870+}
35871+
35872+void au_wkq_fin(void)
35873+{
9dbd164d 35874+ destroy_workqueue(au_wkq);
1facf9fc 35875+}
35876+
35877+int __init au_wkq_init(void)
35878+{
9dbd164d 35879+ int err;
b752ccd1
AM
35880+
35881+ err = 0;
86dc4139 35882+ au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE);
9dbd164d
AM
35883+ if (IS_ERR(au_wkq))
35884+ err = PTR_ERR(au_wkq);
35885+ else if (!au_wkq)
35886+ err = -ENOMEM;
b752ccd1
AM
35887+
35888+ return err;
1facf9fc 35889+}
7f207e10
AM
35890diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
35891--- /usr/share/empty/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79 35892+++ linux/fs/aufs/wkq.h 2018-04-15 08:49:13.404484168 +0200
f0c0a007 35893@@ -0,0 +1,93 @@
1facf9fc 35894+/*
ae9dfd79 35895+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 35896+ *
35897+ * This program, aufs is free software; you can redistribute it and/or modify
35898+ * it under the terms of the GNU General Public License as published by
35899+ * the Free Software Foundation; either version 2 of the License, or
35900+ * (at your option) any later version.
dece6358
AM
35901+ *
35902+ * This program is distributed in the hope that it will be useful,
35903+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
35904+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35905+ * GNU General Public License for more details.
35906+ *
35907+ * You should have received a copy of the GNU General Public License
523b37e3 35908+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 35909+ */
35910+
35911+/*
35912+ * workqueue for asynchronous/super-io operations
35913+ * todo: try new credentials management scheme
35914+ */
35915+
35916+#ifndef __AUFS_WKQ_H__
35917+#define __AUFS_WKQ_H__
35918+
35919+#ifdef __KERNEL__
35920+
ae9dfd79 35921+#include <linux/wait.h>
5afbbe0d 35922+
dece6358
AM
35923+struct super_block;
35924+
1facf9fc 35925+/* ---------------------------------------------------------------------- */
35926+
35927+/*
35928+ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
35929+ */
35930+struct au_nowait_tasks {
f0c0a007 35931+ atomic_t nw_len;
1facf9fc 35932+ wait_queue_head_t nw_wq;
35933+};
35934+
35935+/* ---------------------------------------------------------------------- */
35936+
35937+typedef void (*au_wkq_func_t)(void *args);
35938+
35939+/* wkq flags */
35940+#define AuWkq_WAIT 1
9dbd164d 35941+#define AuWkq_NEST (1 << 1)
1facf9fc 35942+#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name)
7f207e10
AM
35943+#define au_fset_wkq(flags, name) \
35944+ do { (flags) |= AuWkq_##name; } while (0)
35945+#define au_fclr_wkq(flags, name) \
35946+ do { (flags) &= ~AuWkq_##name; } while (0)
1facf9fc 35947+
9dbd164d
AM
35948+#ifndef CONFIG_AUFS_HNOTIFY
35949+#undef AuWkq_NEST
35950+#define AuWkq_NEST 0
35951+#endif
35952+
1facf9fc 35953+/* wkq.c */
b752ccd1 35954+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args);
53392da6
AM
35955+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
35956+ unsigned int flags);
1facf9fc 35957+void au_nwt_init(struct au_nowait_tasks *nwt);
35958+int __init au_wkq_init(void);
35959+void au_wkq_fin(void);
35960+
35961+/* ---------------------------------------------------------------------- */
35962+
53392da6
AM
35963+static inline int au_wkq_test(void)
35964+{
35965+ return current->flags & PF_WQ_WORKER;
35966+}
35967+
b752ccd1 35968+static inline int au_wkq_wait(au_wkq_func_t func, void *args)
1facf9fc 35969+{
b752ccd1 35970+ return au_wkq_do_wait(AuWkq_WAIT, func, args);
1facf9fc 35971+}
35972+
35973+static inline void au_nwt_done(struct au_nowait_tasks *nwt)
35974+{
f0c0a007 35975+ if (atomic_dec_and_test(&nwt->nw_len))
1facf9fc 35976+ wake_up_all(&nwt->nw_wq);
35977+}
35978+
35979+static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
35980+{
f0c0a007 35981+ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
1facf9fc 35982+ return 0;
35983+}
35984+
35985+#endif /* __KERNEL__ */
35986+#endif /* __AUFS_WKQ_H__ */
c1595e42
JR
35987diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
35988--- /usr/share/empty/fs/aufs/xattr.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
35989+++ linux/fs/aufs/xattr.c 2018-04-15 08:49:13.404484168 +0200
35990@@ -0,0 +1,355 @@
c1595e42 35991+/*
ae9dfd79 35992+ * Copyright (C) 2014-2018 Junjiro R. Okajima
c1595e42
JR
35993+ *
35994+ * This program, aufs is free software; you can redistribute it and/or modify
35995+ * it under the terms of the GNU General Public License as published by
35996+ * the Free Software Foundation; either version 2 of the License, or
35997+ * (at your option) any later version.
35998+ *
35999+ * This program is distributed in the hope that it will be useful,
36000+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
36001+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36002+ * GNU General Public License for more details.
36003+ *
36004+ * You should have received a copy of the GNU General Public License
36005+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
36006+ */
36007+
36008+/*
36009+ * handling xattr functions
36010+ */
36011+
ae9dfd79
AM
36012+#include <linux/fs.h>
36013+#include <linux/posix_acl_xattr.h>
c1595e42
JR
36014+#include <linux/xattr.h>
36015+#include "aufs.h"
36016+
36017+static int au_xattr_ignore(int err, char *name, unsigned int ignore_flags)
36018+{
36019+ if (!ignore_flags)
36020+ goto out;
36021+ switch (err) {
36022+ case -ENOMEM:
36023+ case -EDQUOT:
36024+ goto out;
36025+ }
36026+
36027+ if ((ignore_flags & AuBrAttr_ICEX) == AuBrAttr_ICEX) {
36028+ err = 0;
36029+ goto out;
36030+ }
36031+
36032+#define cmp(brattr, prefix) do { \
36033+ if (!strncmp(name, XATTR_##prefix##_PREFIX, \
36034+ XATTR_##prefix##_PREFIX_LEN)) { \
36035+ if (ignore_flags & AuBrAttr_ICEX_##brattr) \
36036+ err = 0; \
36037+ goto out; \
36038+ } \
36039+ } while (0)
36040+
36041+ cmp(SEC, SECURITY);
36042+ cmp(SYS, SYSTEM);
36043+ cmp(TR, TRUSTED);
36044+ cmp(USR, USER);
36045+#undef cmp
36046+
36047+ if (ignore_flags & AuBrAttr_ICEX_OTH)
36048+ err = 0;
36049+
36050+out:
36051+ return err;
36052+}
36053+
36054+static const int au_xattr_out_of_list = AuBrAttr_ICEX_OTH << 1;
36055+
36056+static int au_do_cpup_xattr(struct dentry *h_dst, struct dentry *h_src,
7e9cd9fe
AM
36057+ char *name, char **buf, unsigned int ignore_flags,
36058+ unsigned int verbose)
c1595e42
JR
36059+{
36060+ int err;
36061+ ssize_t ssz;
36062+ struct inode *h_idst;
36063+
36064+ ssz = vfs_getxattr_alloc(h_src, name, buf, 0, GFP_NOFS);
36065+ err = ssz;
36066+ if (unlikely(err <= 0)) {
c1595e42
JR
36067+ if (err == -ENODATA
36068+ || (err == -EOPNOTSUPP
b912730e 36069+ && ((ignore_flags & au_xattr_out_of_list)
5527c038 36070+ || (au_test_nfs_noacl(d_inode(h_src))
b912730e
AM
36071+ && (!strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS)
36072+ || !strcmp(name,
36073+ XATTR_NAME_POSIX_ACL_DEFAULT))))
36074+ ))
c1595e42 36075+ err = 0;
b912730e
AM
36076+ if (err && (verbose || au_debug_test()))
36077+ pr_err("%s, err %d\n", name, err);
c1595e42
JR
36078+ goto out;
36079+ }
36080+
36081+ /* unlock it temporary */
5527c038 36082+ h_idst = d_inode(h_dst);
febd17d6 36083+ inode_unlock(h_idst);
c1595e42 36084+ err = vfsub_setxattr(h_dst, name, *buf, ssz, /*flags*/0);
febd17d6 36085+ inode_lock_nested(h_idst, AuLsc_I_CHILD2);
c1595e42 36086+ if (unlikely(err)) {
7e9cd9fe
AM
36087+ if (verbose || au_debug_test())
36088+ pr_err("%s, err %d\n", name, err);
c1595e42
JR
36089+ err = au_xattr_ignore(err, name, ignore_flags);
36090+ }
36091+
36092+out:
36093+ return err;
36094+}
36095+
7e9cd9fe
AM
36096+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags,
36097+ unsigned int verbose)
c1595e42
JR
36098+{
36099+ int err, unlocked, acl_access, acl_default;
36100+ ssize_t ssz;
36101+ struct inode *h_isrc, *h_idst;
36102+ char *value, *p, *o, *e;
36103+
36104+ /* try stopping to update the source inode while we are referencing */
7e9cd9fe 36105+ /* there should not be the parent-child relationship between them */
5527c038
JR
36106+ h_isrc = d_inode(h_src);
36107+ h_idst = d_inode(h_dst);
febd17d6 36108+ inode_unlock(h_idst);
ae9dfd79 36109+ vfsub_inode_lock_shared_nested(h_isrc, AuLsc_I_CHILD);
febd17d6 36110+ inode_lock_nested(h_idst, AuLsc_I_CHILD2);
c1595e42
JR
36111+ unlocked = 0;
36112+
36113+ /* some filesystems don't list POSIX ACL, for example tmpfs */
36114+ ssz = vfs_listxattr(h_src, NULL, 0);
36115+ err = ssz;
36116+ if (unlikely(err < 0)) {
36117+ AuTraceErr(err);
36118+ if (err == -ENODATA
36119+ || err == -EOPNOTSUPP)
36120+ err = 0; /* ignore */
36121+ goto out;
36122+ }
36123+
36124+ err = 0;
36125+ p = NULL;
36126+ o = NULL;
36127+ if (ssz) {
36128+ err = -ENOMEM;
36129+ p = kmalloc(ssz, GFP_NOFS);
36130+ o = p;
36131+ if (unlikely(!p))
36132+ goto out;
36133+ err = vfs_listxattr(h_src, p, ssz);
36134+ }
ae9dfd79 36135+ inode_unlock_shared(h_isrc);
c1595e42
JR
36136+ unlocked = 1;
36137+ AuDbg("err %d, ssz %zd\n", err, ssz);
36138+ if (unlikely(err < 0))
36139+ goto out_free;
36140+
36141+ err = 0;
36142+ e = p + ssz;
36143+ value = NULL;
36144+ acl_access = 0;
36145+ acl_default = 0;
36146+ while (!err && p < e) {
36147+ acl_access |= !strncmp(p, XATTR_NAME_POSIX_ACL_ACCESS,
36148+ sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1);
36149+ acl_default |= !strncmp(p, XATTR_NAME_POSIX_ACL_DEFAULT,
36150+ sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)
36151+ - 1);
7e9cd9fe
AM
36152+ err = au_do_cpup_xattr(h_dst, h_src, p, &value, ignore_flags,
36153+ verbose);
c1595e42
JR
36154+ p += strlen(p) + 1;
36155+ }
36156+ AuTraceErr(err);
36157+ ignore_flags |= au_xattr_out_of_list;
36158+ if (!err && !acl_access) {
36159+ err = au_do_cpup_xattr(h_dst, h_src,
36160+ XATTR_NAME_POSIX_ACL_ACCESS, &value,
7e9cd9fe 36161+ ignore_flags, verbose);
c1595e42
JR
36162+ AuTraceErr(err);
36163+ }
36164+ if (!err && !acl_default) {
36165+ err = au_do_cpup_xattr(h_dst, h_src,
36166+ XATTR_NAME_POSIX_ACL_DEFAULT, &value,
7e9cd9fe 36167+ ignore_flags, verbose);
c1595e42
JR
36168+ AuTraceErr(err);
36169+ }
36170+
ae9dfd79 36171+ kfree(value);
c1595e42
JR
36172+
36173+out_free:
ae9dfd79 36174+ kfree(o);
c1595e42
JR
36175+out:
36176+ if (!unlocked)
ae9dfd79 36177+ inode_unlock_shared(h_isrc);
c1595e42
JR
36178+ AuTraceErr(err);
36179+ return err;
36180+}
36181+
36182+/* ---------------------------------------------------------------------- */
36183+
ae9dfd79
AM
36184+static int au_smack_reentering(struct super_block *sb)
36185+{
36186+#if IS_ENABLED(CONFIG_SECURITY_SMACK)
36187+ /*
36188+ * as a part of lookup, smack_d_instantiate() is called, and it calls
36189+ * i_op->getxattr(). ouch.
36190+ */
36191+ return si_pid_test(sb);
36192+#else
36193+ return 0;
36194+#endif
36195+}
36196+
c1595e42
JR
36197+enum {
36198+ AU_XATTR_LIST,
36199+ AU_XATTR_GET
36200+};
36201+
36202+struct au_lgxattr {
36203+ int type;
36204+ union {
36205+ struct {
36206+ char *list;
36207+ size_t size;
36208+ } list;
36209+ struct {
36210+ const char *name;
36211+ void *value;
36212+ size_t size;
36213+ } get;
36214+ } u;
36215+};
36216+
36217+static ssize_t au_lgxattr(struct dentry *dentry, struct au_lgxattr *arg)
36218+{
36219+ ssize_t err;
ae9dfd79 36220+ int reenter;
c1595e42
JR
36221+ struct path h_path;
36222+ struct super_block *sb;
36223+
36224+ sb = dentry->d_sb;
ae9dfd79
AM
36225+ reenter = au_smack_reentering(sb);
36226+ if (!reenter) {
36227+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
36228+ if (unlikely(err))
36229+ goto out;
36230+ }
36231+ err = au_h_path_getattr(dentry, /*force*/1, &h_path, reenter);
c1595e42
JR
36232+ if (unlikely(err))
36233+ goto out_si;
36234+ if (unlikely(!h_path.dentry))
36235+ /* illegally overlapped or something */
36236+ goto out_di; /* pretending success */
36237+
36238+ /* always topmost entry only */
36239+ switch (arg->type) {
36240+ case AU_XATTR_LIST:
36241+ err = vfs_listxattr(h_path.dentry,
36242+ arg->u.list.list, arg->u.list.size);
36243+ break;
36244+ case AU_XATTR_GET:
5afbbe0d 36245+ AuDebugOn(d_is_negative(h_path.dentry));
c1595e42
JR
36246+ err = vfs_getxattr(h_path.dentry,
36247+ arg->u.get.name, arg->u.get.value,
36248+ arg->u.get.size);
36249+ break;
36250+ }
36251+
36252+out_di:
ae9dfd79
AM
36253+ if (!reenter)
36254+ di_read_unlock(dentry, AuLock_IR);
c1595e42 36255+out_si:
ae9dfd79
AM
36256+ if (!reenter)
36257+ si_read_unlock(sb);
c1595e42
JR
36258+out:
36259+ AuTraceErr(err);
36260+ return err;
36261+}
36262+
36263+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size)
36264+{
36265+ struct au_lgxattr arg = {
36266+ .type = AU_XATTR_LIST,
36267+ .u.list = {
36268+ .list = list,
36269+ .size = size
36270+ },
36271+ };
36272+
36273+ return au_lgxattr(dentry, &arg);
36274+}
36275+
f2c43d5f
AM
36276+static ssize_t au_getxattr(struct dentry *dentry,
36277+ struct inode *inode __maybe_unused,
36278+ const char *name, void *value, size_t size)
c1595e42
JR
36279+{
36280+ struct au_lgxattr arg = {
36281+ .type = AU_XATTR_GET,
36282+ .u.get = {
36283+ .name = name,
36284+ .value = value,
36285+ .size = size
36286+ },
36287+ };
36288+
36289+ return au_lgxattr(dentry, &arg);
36290+}
36291+
f2c43d5f
AM
36292+static int au_setxattr(struct dentry *dentry, struct inode *inode,
36293+ const char *name, const void *value, size_t size,
36294+ int flags)
c1595e42 36295+{
f2c43d5f 36296+ struct au_sxattr arg = {
c1595e42
JR
36297+ .type = AU_XATTR_SET,
36298+ .u.set = {
36299+ .name = name,
36300+ .value = value,
36301+ .size = size,
36302+ .flags = flags
36303+ },
36304+ };
36305+
f2c43d5f 36306+ return au_sxattr(dentry, inode, &arg);
c1595e42
JR
36307+}
36308+
36309+/* ---------------------------------------------------------------------- */
36310+
f2c43d5f
AM
36311+static int au_xattr_get(const struct xattr_handler *handler,
36312+ struct dentry *dentry, struct inode *inode,
36313+ const char *name, void *buffer, size_t size)
c1595e42 36314+{
f2c43d5f 36315+ return au_getxattr(dentry, inode, name, buffer, size);
c1595e42
JR
36316+}
36317+
f2c43d5f
AM
36318+static int au_xattr_set(const struct xattr_handler *handler,
36319+ struct dentry *dentry, struct inode *inode,
36320+ const char *name, const void *value, size_t size,
36321+ int flags)
c1595e42 36322+{
f2c43d5f 36323+ return au_setxattr(dentry, inode, name, value, size, flags);
c1595e42
JR
36324+}
36325+
36326+static const struct xattr_handler au_xattr_handler = {
f2c43d5f
AM
36327+ .name = "",
36328+ .prefix = "",
c1595e42
JR
36329+ .get = au_xattr_get,
36330+ .set = au_xattr_set
c1595e42
JR
36331+};
36332+
36333+static const struct xattr_handler *au_xattr_handlers[] = {
ae9dfd79
AM
36334+#ifdef CONFIG_FS_POSIX_ACL
36335+ &posix_acl_access_xattr_handler,
36336+ &posix_acl_default_xattr_handler,
36337+#endif
36338+ &au_xattr_handler, /* must be last */
f2c43d5f 36339+ NULL
c1595e42
JR
36340+};
36341+
36342+void au_xattr_init(struct super_block *sb)
36343+{
f2c43d5f 36344+ sb->s_xattr = au_xattr_handlers;
c1595e42 36345+}
7f207e10
AM
36346diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
36347--- /usr/share/empty/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
36348+++ linux/fs/aufs/xino.c 2018-04-15 08:49:13.404484168 +0200
36349@@ -0,0 +1,1415 @@
1facf9fc 36350+/*
ae9dfd79 36351+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 36352+ *
36353+ * This program, aufs is free software; you can redistribute it and/or modify
36354+ * it under the terms of the GNU General Public License as published by
36355+ * the Free Software Foundation; either version 2 of the License, or
36356+ * (at your option) any later version.
dece6358
AM
36357+ *
36358+ * This program is distributed in the hope that it will be useful,
36359+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
36360+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36361+ * GNU General Public License for more details.
36362+ *
36363+ * You should have received a copy of the GNU General Public License
523b37e3 36364+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 36365+ */
36366+
36367+/*
36368+ * external inode number translation table and bitmap
36369+ */
36370+
36371+#include <linux/seq_file.h>
392086de 36372+#include <linux/statfs.h>
1facf9fc 36373+#include "aufs.h"
36374+
9dbd164d 36375+/* todo: unnecessary to support mmap_sem since kernel-space? */
5527c038 36376+ssize_t xino_fread(vfs_readf_t func, struct file *file, void *kbuf, size_t size,
1facf9fc 36377+ loff_t *pos)
36378+{
36379+ ssize_t err;
36380+ mm_segment_t oldfs;
b752ccd1
AM
36381+ union {
36382+ void *k;
36383+ char __user *u;
36384+ } buf;
1facf9fc 36385+
b752ccd1 36386+ buf.k = kbuf;
1facf9fc 36387+ oldfs = get_fs();
36388+ set_fs(KERNEL_DS);
36389+ do {
36390+ /* todo: signal_pending? */
b752ccd1 36391+ err = func(file, buf.u, size, pos);
1facf9fc 36392+ } while (err == -EAGAIN || err == -EINTR);
36393+ set_fs(oldfs);
36394+
36395+#if 0 /* reserved for future use */
36396+ if (err > 0)
2000de60 36397+ fsnotify_access(file->f_path.dentry);
1facf9fc 36398+#endif
36399+
36400+ return err;
36401+}
36402+
36403+/* ---------------------------------------------------------------------- */
36404+
be52b249
AM
36405+static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf,
36406+ size_t size, loff_t *pos);
36407+
5527c038 36408+static ssize_t do_xino_fwrite(vfs_writef_t func, struct file *file, void *kbuf,
1facf9fc 36409+ size_t size, loff_t *pos)
36410+{
36411+ ssize_t err;
36412+ mm_segment_t oldfs;
b752ccd1
AM
36413+ union {
36414+ void *k;
36415+ const char __user *u;
36416+ } buf;
be52b249
AM
36417+ int i;
36418+ const int prevent_endless = 10;
1facf9fc 36419+
be52b249 36420+ i = 0;
b752ccd1 36421+ buf.k = kbuf;
1facf9fc 36422+ oldfs = get_fs();
36423+ set_fs(KERNEL_DS);
1facf9fc 36424+ do {
b752ccd1 36425+ err = func(file, buf.u, size, pos);
be52b249
AM
36426+ if (err == -EINTR
36427+ && !au_wkq_test()
36428+ && fatal_signal_pending(current)) {
36429+ set_fs(oldfs);
36430+ err = xino_fwrite_wkq(func, file, kbuf, size, pos);
36431+ BUG_ON(err == -EINTR);
36432+ oldfs = get_fs();
36433+ set_fs(KERNEL_DS);
36434+ }
36435+ } while (i++ < prevent_endless
36436+ && (err == -EAGAIN || err == -EINTR));
1facf9fc 36437+ set_fs(oldfs);
36438+
36439+#if 0 /* reserved for future use */
36440+ if (err > 0)
2000de60 36441+ fsnotify_modify(file->f_path.dentry);
1facf9fc 36442+#endif
36443+
36444+ return err;
36445+}
36446+
36447+struct do_xino_fwrite_args {
36448+ ssize_t *errp;
5527c038 36449+ vfs_writef_t func;
1facf9fc 36450+ struct file *file;
36451+ void *buf;
36452+ size_t size;
36453+ loff_t *pos;
36454+};
36455+
36456+static void call_do_xino_fwrite(void *args)
36457+{
36458+ struct do_xino_fwrite_args *a = args;
36459+ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
36460+}
36461+
be52b249
AM
36462+static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf,
36463+ size_t size, loff_t *pos)
36464+{
36465+ ssize_t err;
36466+ int wkq_err;
36467+ struct do_xino_fwrite_args args = {
36468+ .errp = &err,
36469+ .func = func,
36470+ .file = file,
36471+ .buf = buf,
36472+ .size = size,
36473+ .pos = pos
36474+ };
36475+
36476+ /*
36477+ * it breaks RLIMIT_FSIZE and normal user's limit,
36478+ * users should care about quota and real 'filesystem full.'
36479+ */
36480+ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
36481+ if (unlikely(wkq_err))
36482+ err = wkq_err;
36483+
36484+ return err;
36485+}
36486+
5527c038
JR
36487+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf,
36488+ size_t size, loff_t *pos)
1facf9fc 36489+{
36490+ ssize_t err;
36491+
b752ccd1
AM
36492+ if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
36493+ lockdep_off();
36494+ err = do_xino_fwrite(func, file, buf, size, pos);
36495+ lockdep_on();
be52b249
AM
36496+ } else
36497+ err = xino_fwrite_wkq(func, file, buf, size, pos);
1facf9fc 36498+
36499+ return err;
36500+}
36501+
36502+/* ---------------------------------------------------------------------- */
36503+
36504+/*
36505+ * create a new xinofile at the same place/path as @base_file.
36506+ */
36507+struct file *au_xino_create2(struct file *base_file, struct file *copy_src)
36508+{
36509+ struct file *file;
4a4d8108 36510+ struct dentry *base, *parent;
523b37e3 36511+ struct inode *dir, *delegated;
1facf9fc 36512+ struct qstr *name;
1308ab2a 36513+ struct path path;
4a4d8108 36514+ int err;
1facf9fc 36515+
2000de60 36516+ base = base_file->f_path.dentry;
1facf9fc 36517+ parent = base->d_parent; /* dir inode is locked */
5527c038 36518+ dir = d_inode(parent);
1facf9fc 36519+ IMustLock(dir);
36520+
36521+ file = ERR_PTR(-EINVAL);
36522+ name = &base->d_name;
4a4d8108
AM
36523+ path.dentry = vfsub_lookup_one_len(name->name, parent, name->len);
36524+ if (IS_ERR(path.dentry)) {
36525+ file = (void *)path.dentry;
523b37e3
AM
36526+ pr_err("%pd lookup err %ld\n",
36527+ base, PTR_ERR(path.dentry));
1facf9fc 36528+ goto out;
36529+ }
36530+
36531+ /* no need to mnt_want_write() since we call dentry_open() later */
4a4d8108 36532+ err = vfs_create(dir, path.dentry, S_IRUGO | S_IWUGO, NULL);
1facf9fc 36533+ if (unlikely(err)) {
36534+ file = ERR_PTR(err);
523b37e3 36535+ pr_err("%pd create err %d\n", base, err);
1facf9fc 36536+ goto out_dput;
36537+ }
36538+
c06a8ce3 36539+ path.mnt = base_file->f_path.mnt;
4a4d8108 36540+ file = vfsub_dentry_open(&path,
7f207e10 36541+ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 36542+ /* | __FMODE_NONOTIFY */);
1facf9fc 36543+ if (IS_ERR(file)) {
523b37e3 36544+ pr_err("%pd open err %ld\n", base, PTR_ERR(file));
1facf9fc 36545+ goto out_dput;
36546+ }
36547+
523b37e3
AM
36548+ delegated = NULL;
36549+ err = vfsub_unlink(dir, &file->f_path, &delegated, /*force*/0);
36550+ if (unlikely(err == -EWOULDBLOCK)) {
36551+ pr_warn("cannot retry for NFSv4 delegation"
36552+ " for an internal unlink\n");
36553+ iput(delegated);
36554+ }
1facf9fc 36555+ if (unlikely(err)) {
523b37e3 36556+ pr_err("%pd unlink err %d\n", base, err);
1facf9fc 36557+ goto out_fput;
36558+ }
36559+
36560+ if (copy_src) {
36561+ /* no one can touch copy_src xino */
c06a8ce3 36562+ err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src));
1facf9fc 36563+ if (unlikely(err)) {
523b37e3 36564+ pr_err("%pd copy err %d\n", base, err);
1facf9fc 36565+ goto out_fput;
36566+ }
36567+ }
36568+ goto out_dput; /* success */
36569+
4f0767ce 36570+out_fput:
1facf9fc 36571+ fput(file);
36572+ file = ERR_PTR(err);
4f0767ce 36573+out_dput:
4a4d8108 36574+ dput(path.dentry);
4f0767ce 36575+out:
1facf9fc 36576+ return file;
36577+}
36578+
36579+struct au_xino_lock_dir {
36580+ struct au_hinode *hdir;
36581+ struct dentry *parent;
febd17d6 36582+ struct inode *dir;
1facf9fc 36583+};
36584+
36585+static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
36586+ struct au_xino_lock_dir *ldir)
36587+{
36588+ aufs_bindex_t brid, bindex;
36589+
36590+ ldir->hdir = NULL;
36591+ bindex = -1;
36592+ brid = au_xino_brid(sb);
36593+ if (brid >= 0)
36594+ bindex = au_br_index(sb, brid);
36595+ if (bindex >= 0) {
5527c038 36596+ ldir->hdir = au_hi(d_inode(sb->s_root), bindex);
5afbbe0d 36597+ au_hn_inode_lock_nested(ldir->hdir, AuLsc_I_PARENT);
1facf9fc 36598+ } else {
2000de60 36599+ ldir->parent = dget_parent(xino->f_path.dentry);
febd17d6
JR
36600+ ldir->dir = d_inode(ldir->parent);
36601+ inode_lock_nested(ldir->dir, AuLsc_I_PARENT);
1facf9fc 36602+ }
36603+}
36604+
36605+static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
36606+{
36607+ if (ldir->hdir)
5afbbe0d 36608+ au_hn_inode_unlock(ldir->hdir);
1facf9fc 36609+ else {
febd17d6 36610+ inode_unlock(ldir->dir);
1facf9fc 36611+ dput(ldir->parent);
36612+ }
36613+}
36614+
36615+/* ---------------------------------------------------------------------- */
36616+
36617+/* trucate xino files asynchronously */
36618+
36619+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex)
36620+{
36621+ int err;
392086de
AM
36622+ unsigned long jiffy;
36623+ blkcnt_t blocks;
5afbbe0d 36624+ aufs_bindex_t bi, bbot;
392086de 36625+ struct kstatfs *st;
1facf9fc 36626+ struct au_branch *br;
36627+ struct file *new_xino, *file;
36628+ struct super_block *h_sb;
36629+ struct au_xino_lock_dir ldir;
36630+
392086de 36631+ err = -ENOMEM;
be52b249 36632+ st = kmalloc(sizeof(*st), GFP_NOFS);
392086de
AM
36633+ if (unlikely(!st))
36634+ goto out;
36635+
1facf9fc 36636+ err = -EINVAL;
5afbbe0d
AM
36637+ bbot = au_sbbot(sb);
36638+ if (unlikely(bindex < 0 || bbot < bindex))
392086de 36639+ goto out_st;
1facf9fc 36640+ br = au_sbr(sb, bindex);
36641+ file = br->br_xino.xi_file;
36642+ if (!file)
392086de
AM
36643+ goto out_st;
36644+
36645+ err = vfs_statfs(&file->f_path, st);
36646+ if (unlikely(err))
36647+ AuErr1("statfs err %d, ignored\n", err);
36648+ jiffy = jiffies;
36649+ blocks = file_inode(file)->i_blocks;
36650+ pr_info("begin truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
36651+ bindex, (u64)blocks, st->f_bfree, st->f_blocks);
1facf9fc 36652+
36653+ au_xino_lock_dir(sb, file, &ldir);
36654+ /* mnt_want_write() is unnecessary here */
36655+ new_xino = au_xino_create2(file, file);
36656+ au_xino_unlock_dir(&ldir);
36657+ err = PTR_ERR(new_xino);
392086de
AM
36658+ if (IS_ERR(new_xino)) {
36659+ pr_err("err %d, ignored\n", err);
36660+ goto out_st;
36661+ }
1facf9fc 36662+ err = 0;
36663+ fput(file);
36664+ br->br_xino.xi_file = new_xino;
36665+
86dc4139 36666+ h_sb = au_br_sb(br);
5afbbe0d 36667+ for (bi = 0; bi <= bbot; bi++) {
1facf9fc 36668+ if (unlikely(bi == bindex))
36669+ continue;
36670+ br = au_sbr(sb, bi);
86dc4139 36671+ if (au_br_sb(br) != h_sb)
1facf9fc 36672+ continue;
36673+
36674+ fput(br->br_xino.xi_file);
36675+ br->br_xino.xi_file = new_xino;
36676+ get_file(new_xino);
36677+ }
36678+
392086de
AM
36679+ err = vfs_statfs(&new_xino->f_path, st);
36680+ if (!err) {
36681+ pr_info("end truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
36682+ bindex, (u64)file_inode(new_xino)->i_blocks,
36683+ st->f_bfree, st->f_blocks);
36684+ if (file_inode(new_xino)->i_blocks < blocks)
36685+ au_sbi(sb)->si_xino_jiffy = jiffy;
36686+ } else
36687+ AuErr1("statfs err %d, ignored\n", err);
36688+
36689+out_st:
ae9dfd79 36690+ kfree(st);
4f0767ce 36691+out:
1facf9fc 36692+ return err;
36693+}
36694+
36695+struct xino_do_trunc_args {
36696+ struct super_block *sb;
36697+ struct au_branch *br;
36698+};
36699+
36700+static void xino_do_trunc(void *_args)
36701+{
36702+ struct xino_do_trunc_args *args = _args;
36703+ struct super_block *sb;
36704+ struct au_branch *br;
36705+ struct inode *dir;
36706+ int err;
36707+ aufs_bindex_t bindex;
36708+
36709+ err = 0;
36710+ sb = args->sb;
5527c038 36711+ dir = d_inode(sb->s_root);
1facf9fc 36712+ br = args->br;
36713+
36714+ si_noflush_write_lock(sb);
36715+ ii_read_lock_parent(dir);
36716+ bindex = au_br_index(sb, br->br_id);
36717+ err = au_xino_trunc(sb, bindex);
1facf9fc 36718+ ii_read_unlock(dir);
36719+ if (unlikely(err))
392086de 36720+ pr_warn("err b%d, (%d)\n", bindex, err);
1facf9fc 36721+ atomic_dec(&br->br_xino_running);
5afbbe0d 36722+ au_br_put(br);
1facf9fc 36723+ si_write_unlock(sb);
027c5e7a 36724+ au_nwt_done(&au_sbi(sb)->si_nowait);
ae9dfd79 36725+ kfree(args);
1facf9fc 36726+}
36727+
392086de
AM
36728+static int xino_trunc_test(struct super_block *sb, struct au_branch *br)
36729+{
36730+ int err;
36731+ struct kstatfs st;
36732+ struct au_sbinfo *sbinfo;
36733+
36734+ /* todo: si_xino_expire and the ratio should be customizable */
36735+ sbinfo = au_sbi(sb);
36736+ if (time_before(jiffies,
36737+ sbinfo->si_xino_jiffy + sbinfo->si_xino_expire))
36738+ return 0;
36739+
36740+ /* truncation border */
36741+ err = vfs_statfs(&br->br_xino.xi_file->f_path, &st);
36742+ if (unlikely(err)) {
36743+ AuErr1("statfs err %d, ignored\n", err);
36744+ return 0;
36745+ }
36746+ if (div64_u64(st.f_bfree * 100, st.f_blocks) >= AUFS_XINO_DEF_TRUNC)
36747+ return 0;
36748+
36749+ return 1;
36750+}
36751+
1facf9fc 36752+static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
36753+{
36754+ struct xino_do_trunc_args *args;
36755+ int wkq_err;
36756+
392086de 36757+ if (!xino_trunc_test(sb, br))
1facf9fc 36758+ return;
36759+
36760+ if (atomic_inc_return(&br->br_xino_running) > 1)
36761+ goto out;
36762+
36763+ /* lock and kfree() will be called in trunc_xino() */
36764+ args = kmalloc(sizeof(*args), GFP_NOFS);
36765+ if (unlikely(!args)) {
36766+ AuErr1("no memory\n");
f0c0a007 36767+ goto out;
1facf9fc 36768+ }
36769+
5afbbe0d 36770+ au_br_get(br);
1facf9fc 36771+ args->sb = sb;
36772+ args->br = br;
53392da6 36773+ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0);
1facf9fc 36774+ if (!wkq_err)
36775+ return; /* success */
36776+
4a4d8108 36777+ pr_err("wkq %d\n", wkq_err);
5afbbe0d 36778+ au_br_put(br);
ae9dfd79 36779+ kfree(args);
1facf9fc 36780+
4f0767ce 36781+out:
e49829fe 36782+ atomic_dec(&br->br_xino_running);
1facf9fc 36783+}
36784+
36785+/* ---------------------------------------------------------------------- */
36786+
5527c038 36787+static int au_xino_do_write(vfs_writef_t write, struct file *file,
1facf9fc 36788+ ino_t h_ino, ino_t ino)
36789+{
36790+ loff_t pos;
36791+ ssize_t sz;
36792+
36793+ pos = h_ino;
36794+ if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) {
36795+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
36796+ return -EFBIG;
36797+ }
36798+ pos *= sizeof(ino);
36799+ sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos);
36800+ if (sz == sizeof(ino))
36801+ return 0; /* success */
36802+
36803+ AuIOErr("write failed (%zd)\n", sz);
36804+ return -EIO;
36805+}
36806+
36807+/*
36808+ * write @ino to the xinofile for the specified branch{@sb, @bindex}
36809+ * at the position of @h_ino.
36810+ * even if @ino is zero, it is written to the xinofile and means no entry.
36811+ * if the size of the xino file on a specific filesystem exceeds the watermark,
36812+ * try truncating it.
36813+ */
36814+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
36815+ ino_t ino)
36816+{
36817+ int err;
36818+ unsigned int mnt_flags;
36819+ struct au_branch *br;
36820+
36821+ BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max)
36822+ || ((loff_t)-1) > 0);
dece6358 36823+ SiMustAnyLock(sb);
1facf9fc 36824+
36825+ mnt_flags = au_mntflags(sb);
36826+ if (!au_opt_test(mnt_flags, XINO))
36827+ return 0;
36828+
36829+ br = au_sbr(sb, bindex);
36830+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
36831+ h_ino, ino);
36832+ if (!err) {
36833+ if (au_opt_test(mnt_flags, TRUNC_XINO)
86dc4139 36834+ && au_test_fs_trunc_xino(au_br_sb(br)))
1facf9fc 36835+ xino_try_trunc(sb, br);
36836+ return 0; /* success */
36837+ }
36838+
36839+ AuIOErr("write failed (%d)\n", err);
36840+ return -EIO;
36841+}
36842+
36843+/* ---------------------------------------------------------------------- */
36844+
36845+/* aufs inode number bitmap */
36846+
36847+static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
36848+static ino_t xib_calc_ino(unsigned long pindex, int bit)
36849+{
36850+ ino_t ino;
36851+
36852+ AuDebugOn(bit < 0 || page_bits <= bit);
36853+ ino = AUFS_FIRST_INO + pindex * page_bits + bit;
36854+ return ino;
36855+}
36856+
36857+static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
36858+{
36859+ AuDebugOn(ino < AUFS_FIRST_INO);
36860+ ino -= AUFS_FIRST_INO;
36861+ *pindex = ino / page_bits;
36862+ *bit = ino % page_bits;
36863+}
36864+
36865+static int xib_pindex(struct super_block *sb, unsigned long pindex)
36866+{
36867+ int err;
36868+ loff_t pos;
36869+ ssize_t sz;
36870+ struct au_sbinfo *sbinfo;
36871+ struct file *xib;
36872+ unsigned long *p;
36873+
36874+ sbinfo = au_sbi(sb);
36875+ MtxMustLock(&sbinfo->si_xib_mtx);
36876+ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
36877+ || !au_opt_test(sbinfo->si_mntflags, XINO));
36878+
36879+ if (pindex == sbinfo->si_xib_last_pindex)
36880+ return 0;
36881+
36882+ xib = sbinfo->si_xib;
36883+ p = sbinfo->si_xib_buf;
36884+ pos = sbinfo->si_xib_last_pindex;
36885+ pos *= PAGE_SIZE;
36886+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
36887+ if (unlikely(sz != PAGE_SIZE))
36888+ goto out;
36889+
36890+ pos = pindex;
36891+ pos *= PAGE_SIZE;
c06a8ce3 36892+ if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE)
1facf9fc 36893+ sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
36894+ else {
36895+ memset(p, 0, PAGE_SIZE);
36896+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
36897+ }
36898+ if (sz == PAGE_SIZE) {
36899+ sbinfo->si_xib_last_pindex = pindex;
36900+ return 0; /* success */
36901+ }
36902+
4f0767ce 36903+out:
b752ccd1
AM
36904+ AuIOErr1("write failed (%zd)\n", sz);
36905+ err = sz;
36906+ if (sz >= 0)
36907+ err = -EIO;
36908+ return err;
36909+}
36910+
36911+/* ---------------------------------------------------------------------- */
36912+
36913+static void au_xib_clear_bit(struct inode *inode)
36914+{
36915+ int err, bit;
36916+ unsigned long pindex;
36917+ struct super_block *sb;
36918+ struct au_sbinfo *sbinfo;
36919+
36920+ AuDebugOn(inode->i_nlink);
36921+
36922+ sb = inode->i_sb;
36923+ xib_calc_bit(inode->i_ino, &pindex, &bit);
36924+ AuDebugOn(page_bits <= bit);
36925+ sbinfo = au_sbi(sb);
36926+ mutex_lock(&sbinfo->si_xib_mtx);
36927+ err = xib_pindex(sb, pindex);
36928+ if (!err) {
36929+ clear_bit(bit, sbinfo->si_xib_buf);
36930+ sbinfo->si_xib_next_bit = bit;
36931+ }
36932+ mutex_unlock(&sbinfo->si_xib_mtx);
36933+}
36934+
36935+/* for s_op->delete_inode() */
36936+void au_xino_delete_inode(struct inode *inode, const int unlinked)
36937+{
36938+ int err;
36939+ unsigned int mnt_flags;
5afbbe0d 36940+ aufs_bindex_t bindex, bbot, bi;
b752ccd1
AM
36941+ unsigned char try_trunc;
36942+ struct au_iinfo *iinfo;
36943+ struct super_block *sb;
36944+ struct au_hinode *hi;
36945+ struct inode *h_inode;
36946+ struct au_branch *br;
5527c038 36947+ vfs_writef_t xwrite;
b752ccd1 36948+
5afbbe0d
AM
36949+ AuDebugOn(au_is_bad_inode(inode));
36950+
b752ccd1
AM
36951+ sb = inode->i_sb;
36952+ mnt_flags = au_mntflags(sb);
36953+ if (!au_opt_test(mnt_flags, XINO)
36954+ || inode->i_ino == AUFS_ROOT_INO)
36955+ return;
36956+
36957+ if (unlinked) {
36958+ au_xigen_inc(inode);
36959+ au_xib_clear_bit(inode);
36960+ }
36961+
36962+ iinfo = au_ii(inode);
5afbbe0d 36963+ bindex = iinfo->ii_btop;
b752ccd1
AM
36964+ if (bindex < 0)
36965+ return;
1facf9fc 36966+
b752ccd1
AM
36967+ xwrite = au_sbi(sb)->si_xwrite;
36968+ try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO);
5afbbe0d
AM
36969+ hi = au_hinode(iinfo, bindex);
36970+ bbot = iinfo->ii_bbot;
36971+ for (; bindex <= bbot; bindex++, hi++) {
b752ccd1
AM
36972+ h_inode = hi->hi_inode;
36973+ if (!h_inode
36974+ || (!unlinked && h_inode->i_nlink))
36975+ continue;
1facf9fc 36976+
b752ccd1
AM
36977+ /* inode may not be revalidated */
36978+ bi = au_br_index(sb, hi->hi_id);
36979+ if (bi < 0)
36980+ continue;
1facf9fc 36981+
b752ccd1
AM
36982+ br = au_sbr(sb, bi);
36983+ err = au_xino_do_write(xwrite, br->br_xino.xi_file,
36984+ h_inode->i_ino, /*ino*/0);
36985+ if (!err && try_trunc
86dc4139 36986+ && au_test_fs_trunc_xino(au_br_sb(br)))
b752ccd1 36987+ xino_try_trunc(sb, br);
1facf9fc 36988+ }
1facf9fc 36989+}
36990+
36991+/* get an unused inode number from bitmap */
36992+ino_t au_xino_new_ino(struct super_block *sb)
36993+{
36994+ ino_t ino;
36995+ unsigned long *p, pindex, ul, pend;
36996+ struct au_sbinfo *sbinfo;
36997+ struct file *file;
36998+ int free_bit, err;
36999+
37000+ if (!au_opt_test(au_mntflags(sb), XINO))
37001+ return iunique(sb, AUFS_FIRST_INO);
37002+
37003+ sbinfo = au_sbi(sb);
37004+ mutex_lock(&sbinfo->si_xib_mtx);
37005+ p = sbinfo->si_xib_buf;
37006+ free_bit = sbinfo->si_xib_next_bit;
37007+ if (free_bit < page_bits && !test_bit(free_bit, p))
37008+ goto out; /* success */
37009+ free_bit = find_first_zero_bit(p, page_bits);
37010+ if (free_bit < page_bits)
37011+ goto out; /* success */
37012+
37013+ pindex = sbinfo->si_xib_last_pindex;
37014+ for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
37015+ err = xib_pindex(sb, ul);
37016+ if (unlikely(err))
37017+ goto out_err;
37018+ free_bit = find_first_zero_bit(p, page_bits);
37019+ if (free_bit < page_bits)
37020+ goto out; /* success */
37021+ }
37022+
37023+ file = sbinfo->si_xib;
c06a8ce3 37024+ pend = vfsub_f_size_read(file) / PAGE_SIZE;
1facf9fc 37025+ for (ul = pindex + 1; ul <= pend; ul++) {
37026+ err = xib_pindex(sb, ul);
37027+ if (unlikely(err))
37028+ goto out_err;
37029+ free_bit = find_first_zero_bit(p, page_bits);
37030+ if (free_bit < page_bits)
37031+ goto out; /* success */
37032+ }
37033+ BUG();
37034+
4f0767ce 37035+out:
1facf9fc 37036+ set_bit(free_bit, p);
7f207e10 37037+ sbinfo->si_xib_next_bit = free_bit + 1;
1facf9fc 37038+ pindex = sbinfo->si_xib_last_pindex;
37039+ mutex_unlock(&sbinfo->si_xib_mtx);
37040+ ino = xib_calc_ino(pindex, free_bit);
37041+ AuDbg("i%lu\n", (unsigned long)ino);
37042+ return ino;
4f0767ce 37043+out_err:
1facf9fc 37044+ mutex_unlock(&sbinfo->si_xib_mtx);
37045+ AuDbg("i0\n");
37046+ return 0;
37047+}
37048+
37049+/*
37050+ * read @ino from xinofile for the specified branch{@sb, @bindex}
37051+ * at the position of @h_ino.
37052+ * if @ino does not exist and @do_new is true, get new one.
37053+ */
37054+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
37055+ ino_t *ino)
37056+{
37057+ int err;
37058+ ssize_t sz;
37059+ loff_t pos;
37060+ struct file *file;
37061+ struct au_sbinfo *sbinfo;
37062+
37063+ *ino = 0;
37064+ if (!au_opt_test(au_mntflags(sb), XINO))
37065+ return 0; /* no xino */
37066+
37067+ err = 0;
37068+ sbinfo = au_sbi(sb);
37069+ pos = h_ino;
37070+ if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) {
37071+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
37072+ return -EFBIG;
37073+ }
37074+ pos *= sizeof(*ino);
37075+
37076+ file = au_sbr(sb, bindex)->br_xino.xi_file;
c06a8ce3 37077+ if (vfsub_f_size_read(file) < pos + sizeof(*ino))
1facf9fc 37078+ return 0; /* no ino */
37079+
37080+ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos);
37081+ if (sz == sizeof(*ino))
37082+ return 0; /* success */
37083+
37084+ err = sz;
37085+ if (unlikely(sz >= 0)) {
37086+ err = -EIO;
37087+ AuIOErr("xino read error (%zd)\n", sz);
37088+ }
37089+
37090+ return err;
37091+}
37092+
37093+/* ---------------------------------------------------------------------- */
37094+
37095+/* create and set a new xino file */
37096+
37097+struct file *au_xino_create(struct super_block *sb, char *fname, int silent)
37098+{
37099+ struct file *file;
37100+ struct dentry *h_parent, *d;
b912730e 37101+ struct inode *h_dir, *inode;
1facf9fc 37102+ int err;
37103+
37104+ /*
37105+ * at mount-time, and the xino file is the default path,
4a4d8108 37106+ * hnotify is disabled so we have no notify events to ignore.
1facf9fc 37107+ * when a user specified the xino, we cannot get au_hdir to be ignored.
37108+ */
7f207e10 37109+ file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 37110+ /* | __FMODE_NONOTIFY */,
1facf9fc 37111+ S_IRUGO | S_IWUGO);
37112+ if (IS_ERR(file)) {
37113+ if (!silent)
4a4d8108 37114+ pr_err("open %s(%ld)\n", fname, PTR_ERR(file));
1facf9fc 37115+ return file;
37116+ }
37117+
37118+ /* keep file count */
b912730e
AM
37119+ err = 0;
37120+ inode = file_inode(file);
2000de60 37121+ h_parent = dget_parent(file->f_path.dentry);
5527c038 37122+ h_dir = d_inode(h_parent);
febd17d6 37123+ inode_lock_nested(h_dir, AuLsc_I_PARENT);
1facf9fc 37124+ /* mnt_want_write() is unnecessary here */
523b37e3 37125+ /* no delegation since it is just created */
b912730e
AM
37126+ if (inode->i_nlink)
37127+ err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL,
37128+ /*force*/0);
febd17d6 37129+ inode_unlock(h_dir);
1facf9fc 37130+ dput(h_parent);
37131+ if (unlikely(err)) {
37132+ if (!silent)
4a4d8108 37133+ pr_err("unlink %s(%d)\n", fname, err);
1facf9fc 37134+ goto out;
37135+ }
37136+
37137+ err = -EINVAL;
2000de60 37138+ d = file->f_path.dentry;
1facf9fc 37139+ if (unlikely(sb == d->d_sb)) {
37140+ if (!silent)
4a4d8108 37141+ pr_err("%s must be outside\n", fname);
1facf9fc 37142+ goto out;
37143+ }
37144+ if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
37145+ if (!silent)
4a4d8108
AM
37146+ pr_err("xino doesn't support %s(%s)\n",
37147+ fname, au_sbtype(d->d_sb));
1facf9fc 37148+ goto out;
37149+ }
37150+ return file; /* success */
37151+
4f0767ce 37152+out:
1facf9fc 37153+ fput(file);
37154+ file = ERR_PTR(err);
37155+ return file;
37156+}
37157+
37158+/*
37159+ * find another branch who is on the same filesystem of the specified
5afbbe0d 37160+ * branch{@btgt}. search until @bbot.
1facf9fc 37161+ */
37162+static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
5afbbe0d 37163+ aufs_bindex_t bbot)
1facf9fc 37164+{
37165+ aufs_bindex_t bindex;
37166+ struct super_block *tgt_sb = au_sbr_sb(sb, btgt);
37167+
37168+ for (bindex = 0; bindex < btgt; bindex++)
37169+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
37170+ return bindex;
5afbbe0d 37171+ for (bindex++; bindex <= bbot; bindex++)
1facf9fc 37172+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
37173+ return bindex;
37174+ return -1;
37175+}
37176+
37177+/* ---------------------------------------------------------------------- */
37178+
37179+/*
37180+ * initialize the xinofile for the specified branch @br
37181+ * at the place/path where @base_file indicates.
37182+ * test whether another branch is on the same filesystem or not,
37183+ * if @do_test is true.
37184+ */
37185+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
37186+ struct file *base_file, int do_test)
37187+{
37188+ int err;
37189+ ino_t ino;
5afbbe0d 37190+ aufs_bindex_t bbot, bindex;
1facf9fc 37191+ struct au_branch *shared_br, *b;
37192+ struct file *file;
37193+ struct super_block *tgt_sb;
37194+
37195+ shared_br = NULL;
5afbbe0d 37196+ bbot = au_sbbot(sb);
1facf9fc 37197+ if (do_test) {
86dc4139 37198+ tgt_sb = au_br_sb(br);
5afbbe0d 37199+ for (bindex = 0; bindex <= bbot; bindex++) {
1facf9fc 37200+ b = au_sbr(sb, bindex);
86dc4139 37201+ if (tgt_sb == au_br_sb(b)) {
1facf9fc 37202+ shared_br = b;
37203+ break;
37204+ }
37205+ }
37206+ }
37207+
37208+ if (!shared_br || !shared_br->br_xino.xi_file) {
37209+ struct au_xino_lock_dir ldir;
37210+
37211+ au_xino_lock_dir(sb, base_file, &ldir);
37212+ /* mnt_want_write() is unnecessary here */
37213+ file = au_xino_create2(base_file, NULL);
37214+ au_xino_unlock_dir(&ldir);
37215+ err = PTR_ERR(file);
37216+ if (IS_ERR(file))
37217+ goto out;
37218+ br->br_xino.xi_file = file;
37219+ } else {
37220+ br->br_xino.xi_file = shared_br->br_xino.xi_file;
37221+ get_file(br->br_xino.xi_file);
37222+ }
37223+
37224+ ino = AUFS_ROOT_INO;
37225+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
37226+ h_ino, ino);
b752ccd1
AM
37227+ if (unlikely(err)) {
37228+ fput(br->br_xino.xi_file);
37229+ br->br_xino.xi_file = NULL;
37230+ }
1facf9fc 37231+
4f0767ce 37232+out:
1facf9fc 37233+ return err;
37234+}
37235+
37236+/* ---------------------------------------------------------------------- */
37237+
37238+/* trucate a xino bitmap file */
37239+
37240+/* todo: slow */
37241+static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
37242+{
37243+ int err, bit;
37244+ ssize_t sz;
37245+ unsigned long pindex;
37246+ loff_t pos, pend;
37247+ struct au_sbinfo *sbinfo;
5527c038 37248+ vfs_readf_t func;
1facf9fc 37249+ ino_t *ino;
37250+ unsigned long *p;
37251+
37252+ err = 0;
37253+ sbinfo = au_sbi(sb);
dece6358 37254+ MtxMustLock(&sbinfo->si_xib_mtx);
1facf9fc 37255+ p = sbinfo->si_xib_buf;
37256+ func = sbinfo->si_xread;
c06a8ce3 37257+ pend = vfsub_f_size_read(file);
1facf9fc 37258+ pos = 0;
37259+ while (pos < pend) {
37260+ sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
37261+ err = sz;
37262+ if (unlikely(sz <= 0))
37263+ goto out;
37264+
37265+ err = 0;
37266+ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
37267+ if (unlikely(*ino < AUFS_FIRST_INO))
37268+ continue;
37269+
37270+ xib_calc_bit(*ino, &pindex, &bit);
37271+ AuDebugOn(page_bits <= bit);
37272+ err = xib_pindex(sb, pindex);
37273+ if (!err)
37274+ set_bit(bit, p);
37275+ else
37276+ goto out;
37277+ }
37278+ }
37279+
4f0767ce 37280+out:
1facf9fc 37281+ return err;
37282+}
37283+
37284+static int xib_restore(struct super_block *sb)
37285+{
37286+ int err;
5afbbe0d 37287+ aufs_bindex_t bindex, bbot;
1facf9fc 37288+ void *page;
37289+
37290+ err = -ENOMEM;
37291+ page = (void *)__get_free_page(GFP_NOFS);
37292+ if (unlikely(!page))
37293+ goto out;
37294+
37295+ err = 0;
5afbbe0d
AM
37296+ bbot = au_sbbot(sb);
37297+ for (bindex = 0; !err && bindex <= bbot; bindex++)
1facf9fc 37298+ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0)
37299+ err = do_xib_restore
37300+ (sb, au_sbr(sb, bindex)->br_xino.xi_file, page);
37301+ else
37302+ AuDbg("b%d\n", bindex);
ae9dfd79 37303+ free_page((unsigned long)page);
1facf9fc 37304+
4f0767ce 37305+out:
1facf9fc 37306+ return err;
37307+}
37308+
37309+int au_xib_trunc(struct super_block *sb)
37310+{
37311+ int err;
37312+ ssize_t sz;
37313+ loff_t pos;
37314+ struct au_xino_lock_dir ldir;
37315+ struct au_sbinfo *sbinfo;
37316+ unsigned long *p;
37317+ struct file *file;
37318+
dece6358
AM
37319+ SiMustWriteLock(sb);
37320+
1facf9fc 37321+ err = 0;
37322+ sbinfo = au_sbi(sb);
37323+ if (!au_opt_test(sbinfo->si_mntflags, XINO))
37324+ goto out;
37325+
37326+ file = sbinfo->si_xib;
c06a8ce3 37327+ if (vfsub_f_size_read(file) <= PAGE_SIZE)
1facf9fc 37328+ goto out;
37329+
37330+ au_xino_lock_dir(sb, file, &ldir);
37331+ /* mnt_want_write() is unnecessary here */
37332+ file = au_xino_create2(sbinfo->si_xib, NULL);
37333+ au_xino_unlock_dir(&ldir);
37334+ err = PTR_ERR(file);
37335+ if (IS_ERR(file))
37336+ goto out;
37337+ fput(sbinfo->si_xib);
37338+ sbinfo->si_xib = file;
37339+
37340+ p = sbinfo->si_xib_buf;
37341+ memset(p, 0, PAGE_SIZE);
37342+ pos = 0;
37343+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
37344+ if (unlikely(sz != PAGE_SIZE)) {
37345+ err = sz;
37346+ AuIOErr("err %d\n", err);
37347+ if (sz >= 0)
37348+ err = -EIO;
37349+ goto out;
37350+ }
37351+
37352+ mutex_lock(&sbinfo->si_xib_mtx);
37353+ /* mnt_want_write() is unnecessary here */
37354+ err = xib_restore(sb);
37355+ mutex_unlock(&sbinfo->si_xib_mtx);
37356+
37357+out:
37358+ return err;
37359+}
37360+
37361+/* ---------------------------------------------------------------------- */
37362+
37363+/*
37364+ * xino mount option handlers
37365+ */
1facf9fc 37366+
37367+/* xino bitmap */
37368+static void xino_clear_xib(struct super_block *sb)
37369+{
37370+ struct au_sbinfo *sbinfo;
37371+
dece6358
AM
37372+ SiMustWriteLock(sb);
37373+
1facf9fc 37374+ sbinfo = au_sbi(sb);
37375+ sbinfo->si_xread = NULL;
37376+ sbinfo->si_xwrite = NULL;
37377+ if (sbinfo->si_xib)
37378+ fput(sbinfo->si_xib);
37379+ sbinfo->si_xib = NULL;
f0c0a007 37380+ if (sbinfo->si_xib_buf)
ae9dfd79 37381+ free_page((unsigned long)sbinfo->si_xib_buf);
1facf9fc 37382+ sbinfo->si_xib_buf = NULL;
37383+}
37384+
37385+static int au_xino_set_xib(struct super_block *sb, struct file *base)
37386+{
37387+ int err;
37388+ loff_t pos;
37389+ struct au_sbinfo *sbinfo;
37390+ struct file *file;
37391+
dece6358
AM
37392+ SiMustWriteLock(sb);
37393+
1facf9fc 37394+ sbinfo = au_sbi(sb);
37395+ file = au_xino_create2(base, sbinfo->si_xib);
37396+ err = PTR_ERR(file);
37397+ if (IS_ERR(file))
37398+ goto out;
37399+ if (sbinfo->si_xib)
37400+ fput(sbinfo->si_xib);
37401+ sbinfo->si_xib = file;
5527c038
JR
37402+ sbinfo->si_xread = vfs_readf(file);
37403+ sbinfo->si_xwrite = vfs_writef(file);
1facf9fc 37404+
37405+ err = -ENOMEM;
37406+ if (!sbinfo->si_xib_buf)
37407+ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
37408+ if (unlikely(!sbinfo->si_xib_buf))
37409+ goto out_unset;
37410+
37411+ sbinfo->si_xib_last_pindex = 0;
37412+ sbinfo->si_xib_next_bit = 0;
c06a8ce3 37413+ if (vfsub_f_size_read(file) < PAGE_SIZE) {
1facf9fc 37414+ pos = 0;
37415+ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
37416+ PAGE_SIZE, &pos);
37417+ if (unlikely(err != PAGE_SIZE))
37418+ goto out_free;
37419+ }
37420+ err = 0;
37421+ goto out; /* success */
37422+
4f0767ce 37423+out_free:
f0c0a007 37424+ if (sbinfo->si_xib_buf)
ae9dfd79 37425+ free_page((unsigned long)sbinfo->si_xib_buf);
b752ccd1
AM
37426+ sbinfo->si_xib_buf = NULL;
37427+ if (err >= 0)
37428+ err = -EIO;
4f0767ce 37429+out_unset:
b752ccd1
AM
37430+ fput(sbinfo->si_xib);
37431+ sbinfo->si_xib = NULL;
37432+ sbinfo->si_xread = NULL;
37433+ sbinfo->si_xwrite = NULL;
4f0767ce 37434+out:
b752ccd1 37435+ return err;
1facf9fc 37436+}
37437+
b752ccd1
AM
37438+/* xino for each branch */
37439+static void xino_clear_br(struct super_block *sb)
37440+{
5afbbe0d 37441+ aufs_bindex_t bindex, bbot;
b752ccd1 37442+ struct au_branch *br;
1facf9fc 37443+
5afbbe0d
AM
37444+ bbot = au_sbbot(sb);
37445+ for (bindex = 0; bindex <= bbot; bindex++) {
b752ccd1
AM
37446+ br = au_sbr(sb, bindex);
37447+ if (!br || !br->br_xino.xi_file)
37448+ continue;
37449+
37450+ fput(br->br_xino.xi_file);
37451+ br->br_xino.xi_file = NULL;
37452+ }
37453+}
37454+
37455+static int au_xino_set_br(struct super_block *sb, struct file *base)
1facf9fc 37456+{
37457+ int err;
b752ccd1 37458+ ino_t ino;
5afbbe0d 37459+ aufs_bindex_t bindex, bbot, bshared;
b752ccd1
AM
37460+ struct {
37461+ struct file *old, *new;
37462+ } *fpair, *p;
37463+ struct au_branch *br;
37464+ struct inode *inode;
5527c038 37465+ vfs_writef_t writef;
1facf9fc 37466+
b752ccd1
AM
37467+ SiMustWriteLock(sb);
37468+
37469+ err = -ENOMEM;
5afbbe0d
AM
37470+ bbot = au_sbbot(sb);
37471+ fpair = kcalloc(bbot + 1, sizeof(*fpair), GFP_NOFS);
b752ccd1 37472+ if (unlikely(!fpair))
1facf9fc 37473+ goto out;
37474+
5527c038 37475+ inode = d_inode(sb->s_root);
b752ccd1
AM
37476+ ino = AUFS_ROOT_INO;
37477+ writef = au_sbi(sb)->si_xwrite;
5afbbe0d 37478+ for (bindex = 0, p = fpair; bindex <= bbot; bindex++, p++) {
b752ccd1
AM
37479+ bshared = is_sb_shared(sb, bindex, bindex - 1);
37480+ if (bshared >= 0) {
37481+ /* shared xino */
37482+ *p = fpair[bshared];
37483+ get_file(p->new);
37484+ }
37485+
37486+ if (!p->new) {
37487+ /* new xino */
5afbbe0d 37488+ br = au_sbr(sb, bindex);
b752ccd1
AM
37489+ p->old = br->br_xino.xi_file;
37490+ p->new = au_xino_create2(base, br->br_xino.xi_file);
37491+ err = PTR_ERR(p->new);
37492+ if (IS_ERR(p->new)) {
37493+ p->new = NULL;
37494+ goto out_pair;
37495+ }
37496+ }
37497+
37498+ err = au_xino_do_write(writef, p->new,
37499+ au_h_iptr(inode, bindex)->i_ino, ino);
37500+ if (unlikely(err))
37501+ goto out_pair;
37502+ }
37503+
5afbbe0d 37504+ for (bindex = 0, p = fpair; bindex <= bbot; bindex++, p++) {
b752ccd1
AM
37505+ br = au_sbr(sb, bindex);
37506+ if (br->br_xino.xi_file)
37507+ fput(br->br_xino.xi_file);
37508+ get_file(p->new);
37509+ br->br_xino.xi_file = p->new;
37510+ }
1facf9fc 37511+
4f0767ce 37512+out_pair:
5afbbe0d 37513+ for (bindex = 0, p = fpair; bindex <= bbot; bindex++, p++)
b752ccd1
AM
37514+ if (p->new)
37515+ fput(p->new);
37516+ else
37517+ break;
ae9dfd79 37518+ kfree(fpair);
4f0767ce 37519+out:
1facf9fc 37520+ return err;
37521+}
b752ccd1
AM
37522+
37523+void au_xino_clr(struct super_block *sb)
37524+{
37525+ struct au_sbinfo *sbinfo;
37526+
37527+ au_xigen_clr(sb);
37528+ xino_clear_xib(sb);
37529+ xino_clear_br(sb);
37530+ sbinfo = au_sbi(sb);
37531+ /* lvalue, do not call au_mntflags() */
37532+ au_opt_clr(sbinfo->si_mntflags, XINO);
37533+}
37534+
37535+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount)
37536+{
37537+ int err, skip;
37538+ struct dentry *parent, *cur_parent;
37539+ struct qstr *dname, *cur_name;
37540+ struct file *cur_xino;
37541+ struct inode *dir;
37542+ struct au_sbinfo *sbinfo;
37543+
37544+ SiMustWriteLock(sb);
37545+
37546+ err = 0;
37547+ sbinfo = au_sbi(sb);
2000de60 37548+ parent = dget_parent(xino->file->f_path.dentry);
b752ccd1
AM
37549+ if (remount) {
37550+ skip = 0;
2000de60 37551+ dname = &xino->file->f_path.dentry->d_name;
b752ccd1
AM
37552+ cur_xino = sbinfo->si_xib;
37553+ if (cur_xino) {
2000de60
JR
37554+ cur_parent = dget_parent(cur_xino->f_path.dentry);
37555+ cur_name = &cur_xino->f_path.dentry->d_name;
b752ccd1 37556+ skip = (cur_parent == parent
38d290e6 37557+ && au_qstreq(dname, cur_name));
b752ccd1
AM
37558+ dput(cur_parent);
37559+ }
37560+ if (skip)
37561+ goto out;
37562+ }
37563+
37564+ au_opt_set(sbinfo->si_mntflags, XINO);
5527c038 37565+ dir = d_inode(parent);
febd17d6 37566+ inode_lock_nested(dir, AuLsc_I_PARENT);
b752ccd1
AM
37567+ /* mnt_want_write() is unnecessary here */
37568+ err = au_xino_set_xib(sb, xino->file);
37569+ if (!err)
37570+ err = au_xigen_set(sb, xino->file);
37571+ if (!err)
37572+ err = au_xino_set_br(sb, xino->file);
febd17d6 37573+ inode_unlock(dir);
b752ccd1
AM
37574+ if (!err)
37575+ goto out; /* success */
37576+
37577+ /* reset all */
37578+ AuIOErr("failed creating xino(%d).\n", err);
c1595e42
JR
37579+ au_xigen_clr(sb);
37580+ xino_clear_xib(sb);
b752ccd1 37581+
4f0767ce 37582+out:
b752ccd1
AM
37583+ dput(parent);
37584+ return err;
37585+}
37586+
37587+/* ---------------------------------------------------------------------- */
37588+
37589+/*
37590+ * create a xinofile at the default place/path.
37591+ */
37592+struct file *au_xino_def(struct super_block *sb)
37593+{
37594+ struct file *file;
37595+ char *page, *p;
37596+ struct au_branch *br;
37597+ struct super_block *h_sb;
37598+ struct path path;
5afbbe0d 37599+ aufs_bindex_t bbot, bindex, bwr;
b752ccd1
AM
37600+
37601+ br = NULL;
5afbbe0d 37602+ bbot = au_sbbot(sb);
b752ccd1 37603+ bwr = -1;
5afbbe0d 37604+ for (bindex = 0; bindex <= bbot; bindex++) {
b752ccd1
AM
37605+ br = au_sbr(sb, bindex);
37606+ if (au_br_writable(br->br_perm)
86dc4139 37607+ && !au_test_fs_bad_xino(au_br_sb(br))) {
b752ccd1
AM
37608+ bwr = bindex;
37609+ break;
37610+ }
37611+ }
37612+
7f207e10
AM
37613+ if (bwr >= 0) {
37614+ file = ERR_PTR(-ENOMEM);
537831f9 37615+ page = (void *)__get_free_page(GFP_NOFS);
7f207e10
AM
37616+ if (unlikely(!page))
37617+ goto out;
86dc4139 37618+ path.mnt = au_br_mnt(br);
7f207e10
AM
37619+ path.dentry = au_h_dptr(sb->s_root, bwr);
37620+ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
37621+ file = (void *)p;
37622+ if (!IS_ERR(p)) {
37623+ strcat(p, "/" AUFS_XINO_FNAME);
37624+ AuDbg("%s\n", p);
37625+ file = au_xino_create(sb, p, /*silent*/0);
37626+ if (!IS_ERR(file))
37627+ au_xino_brid_set(sb, br->br_id);
37628+ }
ae9dfd79 37629+ free_page((unsigned long)page);
7f207e10
AM
37630+ } else {
37631+ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
37632+ if (IS_ERR(file))
37633+ goto out;
2000de60 37634+ h_sb = file->f_path.dentry->d_sb;
7f207e10
AM
37635+ if (unlikely(au_test_fs_bad_xino(h_sb))) {
37636+ pr_err("xino doesn't support %s(%s)\n",
37637+ AUFS_XINO_DEFPATH, au_sbtype(h_sb));
37638+ fput(file);
37639+ file = ERR_PTR(-EINVAL);
37640+ }
37641+ if (!IS_ERR(file))
37642+ au_xino_brid_set(sb, -1);
37643+ }
0c5527e5 37644+
7f207e10
AM
37645+out:
37646+ return file;
37647+}
37648+
37649+/* ---------------------------------------------------------------------- */
37650+
37651+int au_xino_path(struct seq_file *seq, struct file *file)
37652+{
37653+ int err;
37654+
37655+ err = au_seq_path(seq, &file->f_path);
79b8bda9 37656+ if (unlikely(err))
7f207e10
AM
37657+ goto out;
37658+
7f207e10
AM
37659+#define Deleted "\\040(deleted)"
37660+ seq->count -= sizeof(Deleted) - 1;
37661+ AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
37662+ sizeof(Deleted) - 1));
37663+#undef Deleted
37664+
37665+out:
37666+ return err;
37667+}
ae9dfd79
AM
37668+
37669+/* ---------------------------------------------------------------------- */
37670+
37671+void au_xinondir_leave(struct super_block *sb, aufs_bindex_t bindex,
37672+ ino_t h_ino, int idx)
37673+{
37674+ struct au_xino_file *xino;
37675+
37676+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
37677+ xino = &au_sbr(sb, bindex)->br_xino;
37678+ AuDebugOn(idx < 0 || xino->xi_nondir.total <= idx);
37679+
37680+ spin_lock(&xino->xi_nondir.spin);
37681+ AuDebugOn(xino->xi_nondir.array[idx] != h_ino);
37682+ xino->xi_nondir.array[idx] = 0;
37683+ spin_unlock(&xino->xi_nondir.spin);
37684+ wake_up_all(&xino->xi_nondir.wqh);
37685+}
37686+
37687+static int au_xinondir_find(struct au_xino_file *xino, ino_t h_ino)
37688+{
37689+ int found, total, i;
37690+
37691+ found = -1;
37692+ total = xino->xi_nondir.total;
37693+ for (i = 0; i < total; i++) {
37694+ if (xino->xi_nondir.array[i] != h_ino)
37695+ continue;
37696+ found = i;
37697+ break;
37698+ }
37699+
37700+ return found;
37701+}
37702+
37703+static int au_xinondir_expand(struct au_xino_file *xino)
37704+{
37705+ int err, sz;
37706+ ino_t *p;
37707+
37708+ BUILD_BUG_ON(KMALLOC_MAX_SIZE > INT_MAX);
37709+
37710+ err = -ENOMEM;
37711+ sz = xino->xi_nondir.total * sizeof(ino_t);
37712+ if (unlikely(sz > KMALLOC_MAX_SIZE / 2))
37713+ goto out;
37714+ p = au_kzrealloc(xino->xi_nondir.array, sz, sz << 1, GFP_ATOMIC,
37715+ /*may_shrink*/0);
37716+ if (p) {
37717+ xino->xi_nondir.array = p;
37718+ xino->xi_nondir.total <<= 1;
37719+ AuDbg("xi_nondir.total %d\n", xino->xi_nondir.total);
37720+ err = 0;
37721+ }
37722+
37723+out:
37724+ return err;
37725+}
37726+
37727+int au_xinondir_enter(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
37728+ int *idx)
37729+{
37730+ int err, found, empty;
37731+ struct au_xino_file *xino;
37732+
37733+ err = 0;
37734+ *idx = -1;
37735+ if (!au_opt_test(au_mntflags(sb), XINO))
37736+ goto out; /* no xino */
37737+
37738+ xino = &au_sbr(sb, bindex)->br_xino;
37739+
37740+again:
37741+ spin_lock(&xino->xi_nondir.spin);
37742+ found = au_xinondir_find(xino, h_ino);
37743+ if (found == -1) {
37744+ empty = au_xinondir_find(xino, /*h_ino*/0);
37745+ if (empty == -1) {
37746+ empty = xino->xi_nondir.total;
37747+ err = au_xinondir_expand(xino);
37748+ if (unlikely(err))
37749+ goto out_unlock;
37750+ }
37751+ xino->xi_nondir.array[empty] = h_ino;
37752+ *idx = empty;
37753+ } else {
37754+ spin_unlock(&xino->xi_nondir.spin);
37755+ wait_event(xino->xi_nondir.wqh,
37756+ xino->xi_nondir.array[found] != h_ino);
37757+ goto again;
37758+ }
37759+
37760+out_unlock:
37761+ spin_unlock(&xino->xi_nondir.spin);
37762+out:
37763+ return err;
37764+}
537831f9
AM
37765diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h
37766--- /usr/share/empty/include/uapi/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
ae9dfd79
AM
37767+++ linux/include/uapi/linux/aufs_type.h 2018-04-15 08:49:13.404484168 +0200
37768@@ -0,0 +1,447 @@
7f207e10 37769+/*
ae9dfd79 37770+ * Copyright (C) 2005-2018 Junjiro R. Okajima
7f207e10
AM
37771+ *
37772+ * This program, aufs is free software; you can redistribute it and/or modify
37773+ * it under the terms of the GNU General Public License as published by
37774+ * the Free Software Foundation; either version 2 of the License, or
37775+ * (at your option) any later version.
37776+ *
37777+ * This program is distributed in the hope that it will be useful,
37778+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
37779+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37780+ * GNU General Public License for more details.
37781+ *
37782+ * You should have received a copy of the GNU General Public License
523b37e3 37783+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
37784+ */
37785+
37786+#ifndef __AUFS_TYPE_H__
37787+#define __AUFS_TYPE_H__
37788+
f6c5ef8b
AM
37789+#define AUFS_NAME "aufs"
37790+
9dbd164d 37791+#ifdef __KERNEL__
f6c5ef8b
AM
37792+/*
37793+ * define it before including all other headers.
37794+ * sched.h may use pr_* macros before defining "current", so define the
37795+ * no-current version first, and re-define later.
37796+ */
37797+#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__
37798+#include <linux/sched.h>
37799+#undef pr_fmt
a2a7ad62
AM
37800+#define pr_fmt(fmt) \
37801+ AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \
37802+ (int)sizeof(current->comm), current->comm, current->pid
9dbd164d
AM
37803+#else
37804+#include <stdint.h>
37805+#include <sys/types.h>
f6c5ef8b 37806+#endif /* __KERNEL__ */
7f207e10 37807+
f6c5ef8b
AM
37808+#include <linux/limits.h>
37809+
ae9dfd79 37810+#define AUFS_VERSION "4.9-20180409"
7f207e10
AM
37811+
37812+/* todo? move this to linux-2.6.19/include/magic.h */
37813+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
37814+
37815+/* ---------------------------------------------------------------------- */
37816+
37817+#ifdef CONFIG_AUFS_BRANCH_MAX_127
9dbd164d 37818+typedef int8_t aufs_bindex_t;
7f207e10
AM
37819+#define AUFS_BRANCH_MAX 127
37820+#else
9dbd164d 37821+typedef int16_t aufs_bindex_t;
7f207e10
AM
37822+#ifdef CONFIG_AUFS_BRANCH_MAX_511
37823+#define AUFS_BRANCH_MAX 511
37824+#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
37825+#define AUFS_BRANCH_MAX 1023
37826+#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
37827+#define AUFS_BRANCH_MAX 32767
37828+#endif
37829+#endif
37830+
37831+#ifdef __KERNEL__
37832+#ifndef AUFS_BRANCH_MAX
37833+#error unknown CONFIG_AUFS_BRANCH_MAX value
37834+#endif
37835+#endif /* __KERNEL__ */
37836+
37837+/* ---------------------------------------------------------------------- */
37838+
7f207e10
AM
37839+#define AUFS_FSTYPE AUFS_NAME
37840+
37841+#define AUFS_ROOT_INO 2
37842+#define AUFS_FIRST_INO 11
37843+
37844+#define AUFS_WH_PFX ".wh."
37845+#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1)
37846+#define AUFS_WH_TMP_LEN 4
86dc4139 37847+/* a limit for rmdir/rename a dir and copyup */
7f207e10
AM
37848+#define AUFS_MAX_NAMELEN (NAME_MAX \
37849+ - AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\
37850+ - 1 /* dot */\
37851+ - AUFS_WH_TMP_LEN) /* hex */
37852+#define AUFS_XINO_FNAME "." AUFS_NAME ".xino"
37853+#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME
392086de
AM
37854+#define AUFS_XINO_DEF_SEC 30 /* seconds */
37855+#define AUFS_XINO_DEF_TRUNC 45 /* percentage */
7f207e10
AM
37856+#define AUFS_DIRWH_DEF 3
37857+#define AUFS_RDCACHE_DEF 10 /* seconds */
027c5e7a 37858+#define AUFS_RDCACHE_MAX 3600 /* seconds */
7f207e10
AM
37859+#define AUFS_RDBLK_DEF 512 /* bytes */
37860+#define AUFS_RDHASH_DEF 32
37861+#define AUFS_WKQ_NAME AUFS_NAME "d"
027c5e7a
AM
37862+#define AUFS_MFS_DEF_SEC 30 /* seconds */
37863+#define AUFS_MFS_MAX_SEC 3600 /* seconds */
076b876e 37864+#define AUFS_FHSM_CACHE_DEF_SEC 30 /* seconds */
86dc4139 37865+#define AUFS_PLINK_WARN 50 /* number of plinks in a single bucket */
7f207e10
AM
37866+
37867+/* pseudo-link maintenace under /proc */
37868+#define AUFS_PLINK_MAINT_NAME "plink_maint"
37869+#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME
37870+#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME
37871+
ae9dfd79
AM
37872+/* dirren, renamed dir */
37873+#define AUFS_DR_INFO_PFX AUFS_WH_PFX ".dr."
37874+#define AUFS_DR_BRHINO_NAME AUFS_WH_PFX "hino"
37875+/* whiteouted doubly */
37876+#define AUFS_WH_DR_INFO_PFX AUFS_WH_PFX AUFS_DR_INFO_PFX
37877+#define AUFS_WH_DR_BRHINO AUFS_WH_PFX AUFS_DR_BRHINO_NAME
37878+
7f207e10
AM
37879+#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */
37880+#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME
37881+
37882+#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME
37883+#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk"
37884+#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph"
37885+
37886+/* doubly whiteouted */
37887+#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME
37888+#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME
37889+#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME
37890+
1e00d052 37891+/* branch permissions and attributes */
7f207e10
AM
37892+#define AUFS_BRPERM_RW "rw"
37893+#define AUFS_BRPERM_RO "ro"
37894+#define AUFS_BRPERM_RR "rr"
076b876e
AM
37895+#define AUFS_BRATTR_COO_REG "coo_reg"
37896+#define AUFS_BRATTR_COO_ALL "coo_all"
37897+#define AUFS_BRATTR_FHSM "fhsm"
37898+#define AUFS_BRATTR_UNPIN "unpin"
c1595e42
JR
37899+#define AUFS_BRATTR_ICEX "icex"
37900+#define AUFS_BRATTR_ICEX_SEC "icexsec"
37901+#define AUFS_BRATTR_ICEX_SYS "icexsys"
37902+#define AUFS_BRATTR_ICEX_TR "icextr"
37903+#define AUFS_BRATTR_ICEX_USR "icexusr"
37904+#define AUFS_BRATTR_ICEX_OTH "icexoth"
1e00d052
AM
37905+#define AUFS_BRRATTR_WH "wh"
37906+#define AUFS_BRWATTR_NLWH "nolwh"
076b876e
AM
37907+#define AUFS_BRWATTR_MOO "moo"
37908+
37909+#define AuBrPerm_RW 1 /* writable, hardlinkable wh */
37910+#define AuBrPerm_RO (1 << 1) /* readonly */
37911+#define AuBrPerm_RR (1 << 2) /* natively readonly */
37912+#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
37913+
37914+#define AuBrAttr_COO_REG (1 << 3) /* copy-up on open */
37915+#define AuBrAttr_COO_ALL (1 << 4)
37916+#define AuBrAttr_COO_Mask (AuBrAttr_COO_REG | AuBrAttr_COO_ALL)
37917+
37918+#define AuBrAttr_FHSM (1 << 5) /* file-based hsm */
37919+#define AuBrAttr_UNPIN (1 << 6) /* rename-able top dir of
c1595e42
JR
37920+ branch. meaningless since
37921+ linux-3.18-rc1 */
37922+
37923+/* ignore error in copying XATTR */
37924+#define AuBrAttr_ICEX_SEC (1 << 7)
37925+#define AuBrAttr_ICEX_SYS (1 << 8)
37926+#define AuBrAttr_ICEX_TR (1 << 9)
37927+#define AuBrAttr_ICEX_USR (1 << 10)
37928+#define AuBrAttr_ICEX_OTH (1 << 11)
37929+#define AuBrAttr_ICEX (AuBrAttr_ICEX_SEC \
37930+ | AuBrAttr_ICEX_SYS \
37931+ | AuBrAttr_ICEX_TR \
37932+ | AuBrAttr_ICEX_USR \
37933+ | AuBrAttr_ICEX_OTH)
37934+
37935+#define AuBrRAttr_WH (1 << 12) /* whiteout-able */
076b876e
AM
37936+#define AuBrRAttr_Mask AuBrRAttr_WH
37937+
c1595e42
JR
37938+#define AuBrWAttr_NoLinkWH (1 << 13) /* un-hardlinkable whiteouts */
37939+#define AuBrWAttr_MOO (1 << 14) /* move-up on open */
076b876e
AM
37940+#define AuBrWAttr_Mask (AuBrWAttr_NoLinkWH | AuBrWAttr_MOO)
37941+
37942+#define AuBrAttr_CMOO_Mask (AuBrAttr_COO_Mask | AuBrWAttr_MOO)
37943+
c1595e42 37944+/* #warning test userspace */
076b876e
AM
37945+#ifdef __KERNEL__
37946+#ifndef CONFIG_AUFS_FHSM
37947+#undef AuBrAttr_FHSM
37948+#define AuBrAttr_FHSM 0
37949+#endif
c1595e42
JR
37950+#ifndef CONFIG_AUFS_XATTR
37951+#undef AuBrAttr_ICEX
37952+#define AuBrAttr_ICEX 0
37953+#undef AuBrAttr_ICEX_SEC
37954+#define AuBrAttr_ICEX_SEC 0
37955+#undef AuBrAttr_ICEX_SYS
37956+#define AuBrAttr_ICEX_SYS 0
37957+#undef AuBrAttr_ICEX_TR
37958+#define AuBrAttr_ICEX_TR 0
37959+#undef AuBrAttr_ICEX_USR
37960+#define AuBrAttr_ICEX_USR 0
37961+#undef AuBrAttr_ICEX_OTH
37962+#define AuBrAttr_ICEX_OTH 0
37963+#endif
076b876e
AM
37964+#endif
37965+
37966+/* the longest combination */
c1595e42
JR
37967+/* AUFS_BRATTR_ICEX and AUFS_BRATTR_ICEX_TR don't affect here */
37968+#define AuBrPermStrSz sizeof(AUFS_BRPERM_RW \
37969+ "+" AUFS_BRATTR_COO_REG \
37970+ "+" AUFS_BRATTR_FHSM \
37971+ "+" AUFS_BRATTR_UNPIN \
7e9cd9fe
AM
37972+ "+" AUFS_BRATTR_ICEX_SEC \
37973+ "+" AUFS_BRATTR_ICEX_SYS \
37974+ "+" AUFS_BRATTR_ICEX_USR \
37975+ "+" AUFS_BRATTR_ICEX_OTH \
076b876e
AM
37976+ "+" AUFS_BRWATTR_NLWH)
37977+
37978+typedef struct {
37979+ char a[AuBrPermStrSz];
37980+} au_br_perm_str_t;
37981+
37982+static inline int au_br_writable(int brperm)
37983+{
37984+ return brperm & AuBrPerm_RW;
37985+}
37986+
37987+static inline int au_br_whable(int brperm)
37988+{
37989+ return brperm & (AuBrPerm_RW | AuBrRAttr_WH);
37990+}
37991+
37992+static inline int au_br_wh_linkable(int brperm)
37993+{
37994+ return !(brperm & AuBrWAttr_NoLinkWH);
37995+}
37996+
37997+static inline int au_br_cmoo(int brperm)
37998+{
37999+ return brperm & AuBrAttr_CMOO_Mask;
38000+}
38001+
38002+static inline int au_br_fhsm(int brperm)
38003+{
38004+ return brperm & AuBrAttr_FHSM;
38005+}
7f207e10
AM
38006+
38007+/* ---------------------------------------------------------------------- */
38008+
38009+/* ioctl */
38010+enum {
38011+ /* readdir in userspace */
38012+ AuCtl_RDU,
38013+ AuCtl_RDU_INO,
38014+
076b876e
AM
38015+ AuCtl_WBR_FD, /* pathconf wrapper */
38016+ AuCtl_IBUSY, /* busy inode */
38017+ AuCtl_MVDOWN, /* move-down */
38018+ AuCtl_BR, /* info about branches */
38019+ AuCtl_FHSM_FD /* connection for fhsm */
7f207e10
AM
38020+};
38021+
38022+/* borrowed from linux/include/linux/kernel.h */
38023+#ifndef ALIGN
38024+#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1)
38025+#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
38026+#endif
38027+
38028+/* borrowed from linux/include/linux/compiler-gcc3.h */
38029+#ifndef __aligned
38030+#define __aligned(x) __attribute__((aligned(x)))
53392da6
AM
38031+#endif
38032+
38033+#ifdef __KERNEL__
38034+#ifndef __packed
7f207e10
AM
38035+#define __packed __attribute__((packed))
38036+#endif
53392da6 38037+#endif
7f207e10
AM
38038+
38039+struct au_rdu_cookie {
9dbd164d
AM
38040+ uint64_t h_pos;
38041+ int16_t bindex;
38042+ uint8_t flags;
38043+ uint8_t pad;
38044+ uint32_t generation;
7f207e10
AM
38045+} __aligned(8);
38046+
38047+struct au_rdu_ent {
9dbd164d
AM
38048+ uint64_t ino;
38049+ int16_t bindex;
38050+ uint8_t type;
38051+ uint8_t nlen;
38052+ uint8_t wh;
7f207e10
AM
38053+ char name[0];
38054+} __aligned(8);
38055+
38056+static inline int au_rdu_len(int nlen)
38057+{
38058+ /* include the terminating NULL */
38059+ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1,
9dbd164d 38060+ sizeof(uint64_t));
7f207e10
AM
38061+}
38062+
38063+union au_rdu_ent_ul {
38064+ struct au_rdu_ent __user *e;
9dbd164d 38065+ uint64_t ul;
7f207e10
AM
38066+};
38067+
38068+enum {
38069+ AufsCtlRduV_SZ,
38070+ AufsCtlRduV_End
38071+};
38072+
38073+struct aufs_rdu {
38074+ /* input */
38075+ union {
9dbd164d
AM
38076+ uint64_t sz; /* AuCtl_RDU */
38077+ uint64_t nent; /* AuCtl_RDU_INO */
7f207e10
AM
38078+ };
38079+ union au_rdu_ent_ul ent;
9dbd164d 38080+ uint16_t verify[AufsCtlRduV_End];
7f207e10
AM
38081+
38082+ /* input/output */
9dbd164d 38083+ uint32_t blk;
7f207e10
AM
38084+
38085+ /* output */
38086+ union au_rdu_ent_ul tail;
38087+ /* number of entries which were added in a single call */
9dbd164d
AM
38088+ uint64_t rent;
38089+ uint8_t full;
38090+ uint8_t shwh;
7f207e10
AM
38091+
38092+ struct au_rdu_cookie cookie;
38093+} __aligned(8);
38094+
1e00d052
AM
38095+/* ---------------------------------------------------------------------- */
38096+
ae9dfd79
AM
38097+/* dirren. the branch is identified by the filename who contains this */
38098+struct au_drinfo {
38099+ uint64_t ino;
38100+ union {
38101+ uint8_t oldnamelen;
38102+ uint64_t _padding;
38103+ };
38104+ uint8_t oldname[0];
38105+} __aligned(8);
38106+
38107+struct au_drinfo_fdata {
38108+ uint32_t magic;
38109+ struct au_drinfo drinfo;
38110+} __aligned(8);
38111+
38112+#define AUFS_DRINFO_MAGIC_V1 ('a' << 24 | 'd' << 16 | 'r' << 8 | 0x01)
38113+/* future */
38114+#define AUFS_DRINFO_MAGIC_V2 ('a' << 24 | 'd' << 16 | 'r' << 8 | 0x02)
38115+
38116+/* ---------------------------------------------------------------------- */
38117+
1e00d052 38118+struct aufs_wbr_fd {
9dbd164d
AM
38119+ uint32_t oflags;
38120+ int16_t brid;
1e00d052
AM
38121+} __aligned(8);
38122+
38123+/* ---------------------------------------------------------------------- */
38124+
027c5e7a 38125+struct aufs_ibusy {
9dbd164d
AM
38126+ uint64_t ino, h_ino;
38127+ int16_t bindex;
027c5e7a
AM
38128+} __aligned(8);
38129+
1e00d052
AM
38130+/* ---------------------------------------------------------------------- */
38131+
392086de
AM
38132+/* error code for move-down */
38133+/* the actual message strings are implemented in aufs-util.git */
38134+enum {
38135+ EAU_MVDOWN_OPAQUE = 1,
38136+ EAU_MVDOWN_WHITEOUT,
38137+ EAU_MVDOWN_UPPER,
38138+ EAU_MVDOWN_BOTTOM,
38139+ EAU_MVDOWN_NOUPPER,
38140+ EAU_MVDOWN_NOLOWERBR,
38141+ EAU_Last
38142+};
38143+
c2b27bf2 38144+/* flags for move-down */
392086de
AM
38145+#define AUFS_MVDOWN_DMSG 1
38146+#define AUFS_MVDOWN_OWLOWER (1 << 1) /* overwrite lower */
38147+#define AUFS_MVDOWN_KUPPER (1 << 2) /* keep upper */
38148+#define AUFS_MVDOWN_ROLOWER (1 << 3) /* do even if lower is RO */
38149+#define AUFS_MVDOWN_ROLOWER_R (1 << 4) /* did on lower RO */
38150+#define AUFS_MVDOWN_ROUPPER (1 << 5) /* do even if upper is RO */
38151+#define AUFS_MVDOWN_ROUPPER_R (1 << 6) /* did on upper RO */
38152+#define AUFS_MVDOWN_BRID_UPPER (1 << 7) /* upper brid */
38153+#define AUFS_MVDOWN_BRID_LOWER (1 << 8) /* lower brid */
076b876e
AM
38154+#define AUFS_MVDOWN_FHSM_LOWER (1 << 9) /* find fhsm attr for lower */
38155+#define AUFS_MVDOWN_STFS (1 << 10) /* req. stfs */
38156+#define AUFS_MVDOWN_STFS_FAILED (1 << 11) /* output: stfs is unusable */
38157+#define AUFS_MVDOWN_BOTTOM (1 << 12) /* output: no more lowers */
c2b27bf2 38158+
076b876e 38159+/* index for move-down */
392086de
AM
38160+enum {
38161+ AUFS_MVDOWN_UPPER,
38162+ AUFS_MVDOWN_LOWER,
38163+ AUFS_MVDOWN_NARRAY
38164+};
38165+
076b876e
AM
38166+/*
38167+ * additional info of move-down
38168+ * number of free blocks and inodes.
38169+ * subset of struct kstatfs, but smaller and always 64bit.
38170+ */
38171+struct aufs_stfs {
38172+ uint64_t f_blocks;
38173+ uint64_t f_bavail;
38174+ uint64_t f_files;
38175+ uint64_t f_ffree;
38176+};
38177+
38178+struct aufs_stbr {
38179+ int16_t brid; /* optional input */
38180+ int16_t bindex; /* output */
38181+ struct aufs_stfs stfs; /* output when AUFS_MVDOWN_STFS set */
38182+} __aligned(8);
38183+
c2b27bf2 38184+struct aufs_mvdown {
076b876e
AM
38185+ uint32_t flags; /* input/output */
38186+ struct aufs_stbr stbr[AUFS_MVDOWN_NARRAY]; /* input/output */
38187+ int8_t au_errno; /* output */
38188+} __aligned(8);
38189+
38190+/* ---------------------------------------------------------------------- */
38191+
38192+union aufs_brinfo {
38193+ /* PATH_MAX may differ between kernel-space and user-space */
38194+ char _spacer[4096];
392086de 38195+ struct {
076b876e
AM
38196+ int16_t id;
38197+ int perm;
38198+ char path[0];
38199+ };
c2b27bf2
AM
38200+} __aligned(8);
38201+
38202+/* ---------------------------------------------------------------------- */
38203+
7f207e10
AM
38204+#define AuCtlType 'A'
38205+#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu)
38206+#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu)
1e00d052
AM
38207+#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \
38208+ struct aufs_wbr_fd)
027c5e7a 38209+#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
392086de
AM
38210+#define AUFS_CTL_MVDOWN _IOWR(AuCtlType, AuCtl_MVDOWN, \
38211+ struct aufs_mvdown)
076b876e
AM
38212+#define AUFS_CTL_BRINFO _IOW(AuCtlType, AuCtl_BR, union aufs_brinfo)
38213+#define AUFS_CTL_FHSM_FD _IOW(AuCtlType, AuCtl_FHSM_FD, int)
7f207e10
AM
38214+
38215+#endif /* __AUFS_TYPE_H__ */
f2c43d5f 38216aufs4.9 loopback patch
5527c038
JR
38217
38218diff --git a/drivers/block/loop.c b/drivers/block/loop.c
f2c43d5f 38219index 6ee9235..f64161f 100644
5527c038
JR
38220--- a/drivers/block/loop.c
38221+++ b/drivers/block/loop.c
e2f27e51 38222@@ -551,7 +551,7 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
5527c038
JR
38223 }
38224
38225 struct switch_request {
38226- struct file *file;
38227+ struct file *file, *virt_file;
38228 struct completion wait;
38229 };
38230
e2f27e51 38231@@ -577,6 +577,7 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
5527c038
JR
38232 mapping = file->f_mapping;
38233 mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
38234 lo->lo_backing_file = file;
38235+ lo->lo_backing_virt_file = p->virt_file;
38236 lo->lo_blocksize = S_ISBLK(mapping->host->i_mode) ?
38237 mapping->host->i_bdev->bd_block_size : PAGE_SIZE;
38238 lo->old_gfp_mask = mapping_gfp_mask(mapping);
e2f27e51 38239@@ -589,11 +590,13 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
5527c038
JR
38240 * First it needs to flush existing IO, it does this by sending a magic
38241 * BIO down the pipe. The completion of this BIO does the actual switch.
38242 */
38243-static int loop_switch(struct loop_device *lo, struct file *file)
38244+static int loop_switch(struct loop_device *lo, struct file *file,
38245+ struct file *virt_file)
38246 {
38247 struct switch_request w;
38248
38249 w.file = file;
38250+ w.virt_file = virt_file;
38251
38252 /* freeze queue and wait for completion of scheduled requests */
38253 blk_mq_freeze_queue(lo->lo_queue);
ae9dfd79
AM
38254@@ -619,7 +619,16 @@ static int loop_flush(struct loop_device
38255 /* loop not yet configured, no running thread, nothing to flush */
38256 if (lo->lo_state != Lo_bound)
38257 return 0;
5527c038
JR
38258- return loop_switch(lo, NULL);
38259+ return loop_switch(lo, NULL, NULL);
38260+}
38261+
38262+static struct file *loop_real_file(struct file *file)
38263+{
38264+ struct file *f = NULL;
38265+
38266+ if (file->f_path.dentry->d_sb->s_op->real_loop)
38267+ f = file->f_path.dentry->d_sb->s_op->real_loop(file);
38268+ return f;
38269 }
38270
c2c0f25c 38271 static void loop_reread_partitions(struct loop_device *lo,
e2f27e51 38272@@ -649,6 +661,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
5527c038
JR
38273 unsigned int arg)
38274 {
38275 struct file *file, *old_file;
38276+ struct file *f, *virt_file = NULL, *old_virt_file;
38277 struct inode *inode;
38278 int error;
38279
50b859bf 38280@@ -665,13 +678,20 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
5527c038
JR
38281 file = fget(arg);
38282 if (!file)
38283 goto out;
38284+ f = loop_real_file(file);
38285+ if (f) {
38286+ virt_file = file;
38287+ file = f;
38288+ get_file(file);
38289+ }
38290
50b859bf
JR
38291 error = loop_validate_file(file, bdev);
38292 if (error)
38293 goto out_putf;
38294
5527c038
JR
38295 inode = file->f_mapping->host;
38296 old_file = lo->lo_backing_file;
38297+ old_virt_file = lo->lo_backing_virt_file;
38298
38299 error = -EINVAL;
38300
e2f27e51 38301@@ -679,17 +699,21 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
5527c038
JR
38302 goto out_putf;
38303
38304 /* and ... switch */
38305- error = loop_switch(lo, file);
38306+ error = loop_switch(lo, file, virt_file);
38307 if (error)
38308 goto out_putf;
38309
38310 fput(old_file);
38311+ if (old_virt_file)
38312+ fput(old_virt_file);
38313 if (lo->lo_flags & LO_FLAGS_PARTSCAN)
c2c0f25c 38314 loop_reread_partitions(lo, bdev);
5527c038
JR
38315 return 0;
38316
38317 out_putf:
38318 fput(file);
38319+ if (virt_file)
38320+ fput(virt_file);
38321 out:
38322 return error;
38323 }
e2f27e51 38324@@ -876,7 +900,7 @@ static int loop_prepare_queue(struct loop_device *lo)
5527c038
JR
38325 static int loop_set_fd(struct loop_device *lo, fmode_t mode,
38326 struct block_device *bdev, unsigned int arg)
38327 {
50b859bf 38328- struct file *file;
5527c038
JR
38329+ struct file *file, *f, *virt_file = NULL;
38330 struct inode *inode;
38331 struct address_space *mapping;
38332 unsigned lo_blocksize;
e2f27e51 38333@@ -891,6 +915,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
5527c038
JR
38334 file = fget(arg);
38335 if (!file)
38336 goto out;
38337+ f = loop_real_file(file);
38338+ if (f) {
38339+ virt_file = file;
38340+ file = f;
38341+ get_file(file);
38342+ }
38343
38344 error = -EBUSY;
38345 if (lo->lo_state != Lo_unbound)
e2f27e51 38346@@ -943,6 +973,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
5527c038
JR
38347 lo->lo_device = bdev;
38348 lo->lo_flags = lo_flags;
38349 lo->lo_backing_file = file;
38350+ lo->lo_backing_virt_file = virt_file;
38351 lo->transfer = NULL;
38352 lo->ioctl = NULL;
38353 lo->lo_sizelimit = 0;
e2f27e51 38354@@ -975,6 +1006,8 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
5527c038
JR
38355
38356 out_putf:
38357 fput(file);
38358+ if (virt_file)
38359+ fput(virt_file);
38360 out:
38361 /* This is safe: open() is still holding a reference. */
38362 module_put(THIS_MODULE);
ae9dfd79 38363@@ -1021,6 +1054,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
5527c038
JR
38364 static int loop_clr_fd(struct loop_device *lo)
38365 {
38366 struct file *filp = lo->lo_backing_file;
38367+ struct file *virt_filp = lo->lo_backing_virt_file;
38368 gfp_t gfp = lo->old_gfp_mask;
38369 struct block_device *bdev = lo->lo_device;
38370
e2f27e51 38371@@ -1052,6 +1086,7 @@ static int loop_clr_fd(struct loop_device *lo)
5527c038
JR
38372 spin_lock_irq(&lo->lo_lock);
38373 lo->lo_state = Lo_rundown;
38374 lo->lo_backing_file = NULL;
38375+ lo->lo_backing_virt_file = NULL;
38376 spin_unlock_irq(&lo->lo_lock);
38377
38378 loop_release_xfer(lo);
e2f27e51 38379@@ -1096,6 +1131,8 @@ static int loop_clr_fd(struct loop_device *lo)
5527c038
JR
38380 * bd_mutex which is usually taken before lo_ctl_mutex.
38381 */
38382 fput(filp);
38383+ if (virt_filp)
38384+ fput(virt_filp);
38385 return 0;
38386 }
38387
38388diff --git a/drivers/block/loop.h b/drivers/block/loop.h
be52b249 38389index fb2237c..c3888c5 100644
5527c038
JR
38390--- a/drivers/block/loop.h
38391+++ b/drivers/block/loop.h
38392@@ -46,7 +46,7 @@ struct loop_device {
38393 int (*ioctl)(struct loop_device *, int cmd,
38394 unsigned long arg);
38395
38396- struct file * lo_backing_file;
38397+ struct file * lo_backing_file, *lo_backing_virt_file;
38398 struct block_device *lo_device;
38399 unsigned lo_blocksize;
38400 void *key_data;
38401diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
ae9dfd79 38402index 22e93ee..4586e8d 100644
5527c038
JR
38403--- a/fs/aufs/f_op.c
38404+++ b/fs/aufs/f_op.c
ae9dfd79 38405@@ -357,7 +357,7 @@ static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter)
5527c038
JR
38406 if (IS_ERR(h_file))
38407 goto out;
38408
38409- if (au_test_loopback_kthread()) {
38410+ if (0 && au_test_loopback_kthread()) {
38411 au_warn_loopback(h_file->f_path.dentry->d_sb);
38412 if (file->f_mapping != h_file->f_mapping) {
38413 file->f_mapping = h_file->f_mapping;
38414diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c
ae9dfd79 38415index c1dbe59..1fc4b49 100644
5527c038
JR
38416--- a/fs/aufs/loop.c
38417+++ b/fs/aufs/loop.c
e2f27e51 38418@@ -132,3 +132,19 @@ void au_loopback_fin(void)
79b8bda9 38419 symbol_put(loop_backing_file);
ae9dfd79 38420 kfree(au_warn_loopback_array);
5527c038
JR
38421 }
38422+
38423+/* ---------------------------------------------------------------------- */
38424+
38425+/* support the loopback block device insude aufs */
38426+
38427+struct file *aufs_real_loop(struct file *file)
38428+{
38429+ struct file *f;
38430+
38431+ BUG_ON(!au_test_aufs(file->f_path.dentry->d_sb));
38432+ fi_read_lock(file);
38433+ f = au_hf_top(file);
38434+ fi_read_unlock(file);
38435+ AuDebugOn(!f);
38436+ return f;
38437+}
38438diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h
ae9dfd79 38439index c08374e..5e05083 100644
5527c038
JR
38440--- a/fs/aufs/loop.h
38441+++ b/fs/aufs/loop.h
ae9dfd79 38442@@ -25,7 +25,11 @@ void au_warn_loopback(struct super_block *h_sb);
5527c038
JR
38443
38444 int au_loopback_init(void);
38445 void au_loopback_fin(void);
38446+
38447+struct file *aufs_real_loop(struct file *file);
38448 #else
38449+AuStub(struct file *, loop_backing_file, return NULL)
38450+
38451 AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
38452 struct dentry *h_adding)
38453 AuStubInt0(au_test_loopback_kthread, void)
ae9dfd79 38454@@ -33,6 +37,8 @@ AuStubVoid(au_warn_loopback, struct super_block *h_sb)
5527c038
JR
38455
38456 AuStubInt0(au_loopback_init, void)
38457 AuStubVoid(au_loopback_fin, void)
38458+
38459+AuStub(struct file *, aufs_real_loop, return NULL, struct file *file)
38460 #endif /* BLK_DEV_LOOP */
38461
38462 #endif /* __KERNEL__ */
38463diff --git a/fs/aufs/super.c b/fs/aufs/super.c
ae9dfd79 38464index dd38e63..2486242 100644
5527c038
JR
38465--- a/fs/aufs/super.c
38466+++ b/fs/aufs/super.c
ae9dfd79 38467@@ -838,7 +838,10 @@ static const struct super_operations aufs_sop = {
5527c038
JR
38468 .statfs = aufs_statfs,
38469 .put_super = aufs_put_super,
38470 .sync_fs = aufs_sync_fs,
38471- .remount_fs = aufs_remount_fs
38472+ .remount_fs = aufs_remount_fs,
38473+#ifdef CONFIG_AUFS_BDEV_LOOP
38474+ .real_loop = aufs_real_loop
38475+#endif
38476 };
38477
38478 /* ---------------------------------------------------------------------- */
38479diff --git a/include/linux/fs.h b/include/linux/fs.h
ae9dfd79 38480index 42c7695..3e4f068 100644
5527c038
JR
38481--- a/include/linux/fs.h
38482+++ b/include/linux/fs.h
f2c43d5f 38483@@ -1823,6 +1823,10 @@ struct super_operations {
5527c038
JR
38484 struct shrink_control *);
38485 long (*free_cached_objects)(struct super_block *,
38486 struct shrink_control *);
38487+#if defined(CONFIG_BLK_DEV_LOOP) || defined(CONFIG_BLK_DEV_LOOP_MODULE)
38488+ /* and aufs */
38489+ struct file *(*real_loop)(struct file *);
38490+#endif
38491 };
38492
38493 /*
This page took 6.6648 seconds and 4 git commands to generate.