]> git.pld-linux.org Git - packages/kernel.git/blame_incremental - kernel-aufs5.patch
- 5.4.188
[packages/kernel.git] / kernel-aufs5.patch
... / ...
CommitLineData
1SPDX-License-Identifier: GPL-2.0
2aufs5.4 kbuild patch
3
4diff --git a/fs/Kconfig b/fs/Kconfig
5index 2501e6f1f965..38a6a5991da9 100644
6--- a/fs/Kconfig
7+++ b/fs/Kconfig
8@@ -264,6 +264,7 @@ source "fs/pstore/Kconfig"
9 source "fs/sysv/Kconfig"
10 source "fs/ufs/Kconfig"
11 source "fs/erofs/Kconfig"
12+source "fs/aufs/Kconfig"
13
14 endif # MISC_FILESYSTEMS
15
16diff --git a/fs/Makefile b/fs/Makefile
17index 14231b4cf383..8765e191ebe0 100644
18--- a/fs/Makefile
19+++ b/fs/Makefile
20@@ -132,3 +132,4 @@ obj-$(CONFIG_CEPH_FS) += ceph/
21 obj-$(CONFIG_PSTORE) += pstore/
22 obj-$(CONFIG_EFIVAR_FS) += efivarfs/
23 obj-$(CONFIG_EROFS_FS) += erofs/
24+obj-$(CONFIG_AUFS_FS) += aufs/
25SPDX-License-Identifier: GPL-2.0
26aufs5.4 base patch
27
28diff --git a/MAINTAINERS b/MAINTAINERS
29index 9d3a5c54a41d..f33398b47c42 100644
30--- a/MAINTAINERS
31+++ b/MAINTAINERS
32@@ -2832,6 +2832,19 @@ F: include/linux/audit.h
33 F: include/uapi/linux/audit.h
34 F: kernel/audit*
35
36+AUFS (advanced multi layered unification filesystem) FILESYSTEM
37+M: "J. R. Okajima" <hooanon05g@gmail.com>
38+L: aufs-users@lists.sourceforge.net (members only)
39+L: linux-unionfs@vger.kernel.org
40+W: http://aufs.sourceforge.net
41+T: git://github.com/sfjro/aufs4-linux.git
42+S: Supported
43+F: Documentation/filesystems/aufs/
44+F: Documentation/ABI/testing/debugfs-aufs
45+F: Documentation/ABI/testing/sysfs-aufs
46+F: fs/aufs/
47+F: include/uapi/linux/aufs_type.h
48+
49 AUXILIARY DISPLAY DRIVERS
50 M: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com>
51 S: Maintained
52diff --git a/drivers/block/loop.c b/drivers/block/loop.c
53index f6f77eaa7217..5e094699215e 100644
54--- a/drivers/block/loop.c
55+++ b/drivers/block/loop.c
56@@ -738,6 +738,24 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
57 return error;
58 }
59
60+/*
61+ * for AUFS
62+ * no get/put for file.
63+ */
64+struct file *loop_backing_file(struct super_block *sb)
65+{
66+ struct file *ret;
67+ struct loop_device *l;
68+
69+ ret = NULL;
70+ if (MAJOR(sb->s_dev) == LOOP_MAJOR) {
71+ l = sb->s_bdev->bd_disk->private_data;
72+ ret = l->lo_backing_file;
73+ }
74+ return ret;
75+}
76+EXPORT_SYMBOL_GPL(loop_backing_file);
77+
78 /* loop sysfs attributes */
79
80 static ssize_t loop_attr_show(struct device *dev, char *page,
81diff --git a/fs/dcache.c b/fs/dcache.c
82index e88cf0554e65..7ce4ccf5a51c 100644
83--- a/fs/dcache.c
84+++ b/fs/dcache.c
85@@ -1264,7 +1264,7 @@ enum d_walk_ret {
86 *
87 * The @enter() callbacks are called with d_lock held.
88 */
89-static void d_walk(struct dentry *parent, void *data,
90+void d_walk(struct dentry *parent, void *data,
91 enum d_walk_ret (*enter)(void *, struct dentry *))
92 {
93 struct dentry *this_parent;
94diff --git a/fs/fcntl.c b/fs/fcntl.c
95index 3d40771e8e7c..12dd73930961 100644
96--- a/fs/fcntl.c
97+++ b/fs/fcntl.c
98@@ -32,7 +32,7 @@
99
100 #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
101
102-static int setfl(int fd, struct file * filp, unsigned long arg)
103+int setfl(int fd, struct file *filp, unsigned long arg)
104 {
105 struct inode * inode = file_inode(filp);
106 int error = 0;
107@@ -63,6 +63,8 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
108
109 if (filp->f_op->check_flags)
110 error = filp->f_op->check_flags(arg);
111+ if (!error && filp->f_op->setfl)
112+ error = filp->f_op->setfl(filp, arg);
113 if (error)
114 return error;
115
116diff --git a/fs/inode.c b/fs/inode.c
117index fef457a42882..aaeacde398ee 100644
118--- a/fs/inode.c
119+++ b/fs/inode.c
120@@ -1673,7 +1673,7 @@ EXPORT_SYMBOL(generic_update_time);
121 * This does the actual work of updating an inodes time or version. Must have
122 * had called mnt_want_write() before calling this.
123 */
124-static int update_time(struct inode *inode, struct timespec64 *time, int flags)
125+int update_time(struct inode *inode, struct timespec64 *time, int flags)
126 {
127 int (*update_time)(struct inode *, struct timespec64 *, int);
128
129diff --git a/fs/namespace.c b/fs/namespace.c
130index 2adfe7b166a3..0f7e57e5f4b7 100644
131--- a/fs/namespace.c
132+++ b/fs/namespace.c
133@@ -776,6 +776,12 @@ static inline int check_mnt(struct mount *mnt)
134 return mnt->mnt_ns == current->nsproxy->mnt_ns;
135 }
136
137+/* for aufs, CONFIG_AUFS_BR_FUSE */
138+int is_current_mnt_ns(struct vfsmount *mnt)
139+{
140+ return check_mnt(real_mount(mnt));
141+}
142+
143 /*
144 * vfsmount lock must be held for write
145 */
146diff --git a/fs/read_write.c b/fs/read_write.c
147index 5bbf587f5bc1..fa9b3994b34c 100644
148--- a/fs/read_write.c
149+++ b/fs/read_write.c
150@@ -498,6 +498,28 @@ static ssize_t __vfs_write(struct file *file, const char __user *p,
151 return -EINVAL;
152 }
153
154+vfs_readf_t vfs_readf(struct file *file)
155+{
156+ const struct file_operations *fop = file->f_op;
157+
158+ if (fop->read)
159+ return fop->read;
160+ if (fop->read_iter)
161+ return new_sync_read;
162+ return ERR_PTR(-ENOSYS); /* doesn't have ->read(|_iter)() op */
163+}
164+
165+vfs_writef_t vfs_writef(struct file *file)
166+{
167+ const struct file_operations *fop = file->f_op;
168+
169+ if (fop->write)
170+ return fop->write;
171+ if (fop->write_iter)
172+ return new_sync_write;
173+ return ERR_PTR(-ENOSYS); /* doesn't have ->write(|_iter)() op */
174+}
175+
176 ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
177 {
178 mm_segment_t old_fs;
179diff --git a/fs/splice.c b/fs/splice.c
180index 98412721f056..75b489fcb66f 100644
181--- a/fs/splice.c
182+++ b/fs/splice.c
183@@ -834,8 +834,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
184 /*
185 * Attempt to initiate a splice from pipe to file.
186 */
187-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
188- loff_t *ppos, size_t len, unsigned int flags)
189+long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
190+ loff_t *ppos, size_t len, unsigned int flags)
191 {
192 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
193 loff_t *, size_t, unsigned int);
194@@ -851,9 +851,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
195 /*
196 * Attempt to initiate a splice from a file to a pipe.
197 */
198-static long do_splice_to(struct file *in, loff_t *ppos,
199- struct pipe_inode_info *pipe, size_t len,
200- unsigned int flags)
201+long do_splice_to(struct file *in, loff_t *ppos,
202+ struct pipe_inode_info *pipe, size_t len,
203+ unsigned int flags)
204 {
205 ssize_t (*splice_read)(struct file *, loff_t *,
206 struct pipe_inode_info *, size_t, unsigned int);
207diff --git a/fs/sync.c b/fs/sync.c
208index 4d1ff010bc5a..457f4e4a5cc1 100644
209--- a/fs/sync.c
210+++ b/fs/sync.c
211@@ -28,7 +28,7 @@
212 * wait == 1 case since in that case write_inode() functions do
213 * sync_dirty_buffer() and thus effectively write one block at a time.
214 */
215-static int __sync_filesystem(struct super_block *sb, int wait)
216+int __sync_filesystem(struct super_block *sb, int wait)
217 {
218 if (wait)
219 sync_inodes_sb(sb);
220diff --git a/include/linux/fs.h b/include/linux/fs.h
221index e0d909d35763..381a13995011 100644
222--- a/include/linux/fs.h
223+++ b/include/linux/fs.h
224@@ -1349,6 +1349,7 @@ extern void fasync_free(struct fasync_struct *);
225 /* can be called from interrupts */
226 extern void kill_fasync(struct fasync_struct **, int, int);
227
228+extern int setfl(int fd, struct file *filp, unsigned long arg);
229 extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
230 extern int f_setown(struct file *filp, unsigned long arg, int force);
231 extern void f_delown(struct file *filp);
232@@ -1835,6 +1836,7 @@ struct file_operations {
233 ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
234 unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
235 int (*check_flags)(int);
236+ int (*setfl)(struct file *, unsigned long);
237 int (*flock) (struct file *, int, struct file_lock *);
238 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
239 ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
240@@ -1905,6 +1907,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
241 struct iovec *fast_pointer,
242 struct iovec **ret_pointer);
243
244+typedef ssize_t (*vfs_readf_t)(struct file *, char __user *, size_t, loff_t *);
245+typedef ssize_t (*vfs_writef_t)(struct file *, const char __user *, size_t,
246+ loff_t *);
247+vfs_readf_t vfs_readf(struct file *file);
248+vfs_writef_t vfs_writef(struct file *file);
249+
250 extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *);
251 extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *);
252 extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *);
253@@ -2325,6 +2333,7 @@ extern int current_umask(void);
254 extern void ihold(struct inode * inode);
255 extern void iput(struct inode *);
256 extern int generic_update_time(struct inode *, struct timespec64 *, int);
257+extern int update_time(struct inode *, struct timespec64 *, int);
258
259 /* /sys/fs */
260 extern struct kobject *fs_kobj;
261@@ -2613,6 +2622,7 @@ static inline bool sb_is_blkdev_sb(struct super_block *sb)
262 return false;
263 }
264 #endif
265+extern int __sync_filesystem(struct super_block *, int);
266 extern int sync_filesystem(struct super_block *);
267 extern const struct file_operations def_blk_fops;
268 extern const struct file_operations def_chr_fops;
269diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
270index b8a835fd611b..f452521f2e05 100644
271--- a/include/linux/lockdep.h
272+++ b/include/linux/lockdep.h
273@@ -331,6 +331,8 @@ static inline int lockdep_match_key(struct lockdep_map *lock,
274 return lock->key == key;
275 }
276
277+struct lock_class *lockdep_hlock_class(struct held_lock *hlock);
278+
279 /*
280 * Acquire a lock.
281 *
282@@ -473,6 +475,7 @@ struct lockdep_map { };
283
284 #define lockdep_depth(tsk) (0)
285
286+#define lockdep_is_held(lock) (1)
287 #define lockdep_is_held_type(l, r) (1)
288
289 #define lockdep_assert_held(l) do { (void)(l); } while (0)
290diff --git a/include/linux/mnt_namespace.h b/include/linux/mnt_namespace.h
291index 35942084cd40..24f5fd1a789d 100644
292--- a/include/linux/mnt_namespace.h
293+++ b/include/linux/mnt_namespace.h
294@@ -6,11 +6,14 @@
295 struct mnt_namespace;
296 struct fs_struct;
297 struct user_namespace;
298+struct vfsmount;
299
300 extern struct mnt_namespace *copy_mnt_ns(unsigned long, struct mnt_namespace *,
301 struct user_namespace *, struct fs_struct *);
302 extern void put_mnt_ns(struct mnt_namespace *ns);
303
304+extern int is_current_mnt_ns(struct vfsmount *mnt);
305+
306 extern const struct file_operations proc_mounts_operations;
307 extern const struct file_operations proc_mountinfo_operations;
308 extern const struct file_operations proc_mountstats_operations;
309diff --git a/include/linux/splice.h b/include/linux/splice.h
310index 74b4911ac16d..19789fbea567 100644
311--- a/include/linux/splice.h
312+++ b/include/linux/splice.h
313@@ -87,4 +87,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *);
314
315 extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
316 extern const struct pipe_buf_operations default_pipe_buf_ops;
317+
318+extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
319+ loff_t *ppos, size_t len, unsigned int flags);
320+extern long do_splice_to(struct file *in, loff_t *ppos,
321+ struct pipe_inode_info *pipe, size_t len,
322+ unsigned int flags);
323 #endif
324diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
325index 233459c03b5a..407c08ac8ac8 100644
326--- a/kernel/locking/lockdep.c
327+++ b/kernel/locking/lockdep.c
328@@ -153,7 +153,7 @@ static
329 struct lock_class lock_classes[MAX_LOCKDEP_KEYS];
330 static DECLARE_BITMAP(lock_classes_in_use, MAX_LOCKDEP_KEYS);
331
332-static inline struct lock_class *hlock_class(struct held_lock *hlock)
333+inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock)
334 {
335 unsigned int class_idx = hlock->class_idx;
336
337@@ -174,6 +174,7 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock)
338 */
339 return lock_classes + class_idx;
340 }
341+#define hlock_class(hlock) lockdep_hlock_class(hlock)
342
343 #ifdef CONFIG_LOCK_STAT
344 static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], cpu_lock_stats);
345SPDX-License-Identifier: GPL-2.0
346aufs5.4 mmap patch
347
348diff --git a/fs/proc/base.c b/fs/proc/base.c
349index ebea9501afb8..dc7edc5f7267 100644
350--- a/fs/proc/base.c
351+++ b/fs/proc/base.c
352@@ -2037,7 +2037,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path)
353 rc = -ENOENT;
354 vma = find_exact_vma(mm, vm_start, vm_end);
355 if (vma && vma->vm_file) {
356- *path = vma->vm_file->f_path;
357+ *path = vma_pr_or_file(vma)->f_path;
358 path_get(path);
359 rc = 0;
360 }
361diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
362index 14c2badb8fd9..65afe5287e43 100644
363--- a/fs/proc/nommu.c
364+++ b/fs/proc/nommu.c
365@@ -41,7 +41,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
366 file = region->vm_file;
367
368 if (file) {
369- struct inode *inode = file_inode(region->vm_file);
370+ struct inode *inode;
371+
372+ file = vmr_pr_or_file(region);
373+ inode = file_inode(file);
374 dev = inode->i_sb->s_dev;
375 ino = inode->i_ino;
376 }
377diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
378index 9442631fd4af..1fa8a5fcdeee 100644
379--- a/fs/proc/task_mmu.c
380+++ b/fs/proc/task_mmu.c
381@@ -309,7 +309,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
382 const char *name = NULL;
383
384 if (file) {
385- struct inode *inode = file_inode(vma->vm_file);
386+ struct inode *inode;
387+
388+ file = vma_pr_or_file(vma);
389+ inode = file_inode(file);
390 dev = inode->i_sb->s_dev;
391 ino = inode->i_ino;
392 pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
393@@ -1819,7 +1822,7 @@ static int show_numa_map(struct seq_file *m, void *v)
394 struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
395 struct vm_area_struct *vma = v;
396 struct numa_maps *md = &numa_priv->md;
397- struct file *file = vma->vm_file;
398+ struct file *file = vma_pr_or_file(vma);
399 struct mm_struct *mm = vma->vm_mm;
400 struct mempolicy *pol;
401 char buffer[64];
402diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
403index 7907e6419e57..d17209cf52bc 100644
404--- a/fs/proc/task_nommu.c
405+++ b/fs/proc/task_nommu.c
406@@ -155,7 +155,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma)
407 file = vma->vm_file;
408
409 if (file) {
410- struct inode *inode = file_inode(vma->vm_file);
411+ struct inode *inode;
412+
413+ file = vma_pr_or_file(vma);
414+ inode = file_inode(file);
415 dev = inode->i_sb->s_dev;
416 ino = inode->i_ino;
417 pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
418diff --git a/include/linux/mm.h b/include/linux/mm.h
419index a2adf95b3f9c..70e1dccc1283 100644
420--- a/include/linux/mm.h
421+++ b/include/linux/mm.h
422@@ -1510,6 +1510,28 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping,
423 unmap_mapping_range(mapping, holebegin, holelen, 0);
424 }
425
426+extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int);
427+extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[],
428+ int);
429+extern void vma_do_get_file(struct vm_area_struct *, const char[], int);
430+extern void vma_do_fput(struct vm_area_struct *, const char[], int);
431+
432+#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \
433+ __LINE__)
434+#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \
435+ __LINE__)
436+#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__)
437+#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__)
438+
439+#ifndef CONFIG_MMU
440+extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int);
441+extern void vmr_do_fput(struct vm_region *, const char[], int);
442+
443+#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \
444+ __LINE__)
445+#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__)
446+#endif /* !CONFIG_MMU */
447+
448 extern int access_process_vm(struct task_struct *tsk, unsigned long addr,
449 void *buf, int len, unsigned int gup_flags);
450 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
451diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
452index 270aa8fd2800..33848c2165e2 100644
453--- a/include/linux/mm_types.h
454+++ b/include/linux/mm_types.h
455@@ -267,6 +267,7 @@ struct vm_region {
456 unsigned long vm_top; /* region allocated to here */
457 unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */
458 struct file *vm_file; /* the backing file or NULL */
459+ struct file *vm_prfile; /* the virtual backing file or NULL */
460
461 int vm_usage; /* region usage count (access under nommu_region_sem) */
462 bool vm_icache_flushed : 1; /* true if the icache has been flushed for
463@@ -341,6 +342,7 @@ struct vm_area_struct {
464 unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
465 units */
466 struct file * vm_file; /* File we map to (can be NULL). */
467+ struct file *vm_prfile; /* shadow of vm_file */
468 void * vm_private_data; /* was vm_pte (shared mem) */
469
470 #ifdef CONFIG_SWAP
471diff --git a/kernel/fork.c b/kernel/fork.c
472index 13b38794efb5..ede7225bae95 100644
473--- a/kernel/fork.c
474+++ b/kernel/fork.c
475@@ -562,7 +562,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
476 struct inode *inode = file_inode(file);
477 struct address_space *mapping = file->f_mapping;
478
479- get_file(file);
480+ vma_get_file(tmp);
481 if (tmp->vm_flags & VM_DENYWRITE)
482 atomic_dec(&inode->i_writecount);
483 i_mmap_lock_write(mapping);
484diff --git a/mm/Makefile b/mm/Makefile
485index d996846697ef..fbadb91df4e4 100644
486--- a/mm/Makefile
487+++ b/mm/Makefile
488@@ -42,7 +42,7 @@ obj-y := filemap.o mempool.o oom_kill.o fadvise.o \
489 mm_init.o mmu_context.o percpu.o slab_common.o \
490 compaction.o vmacache.o \
491 interval_tree.o list_lru.o workingset.o \
492- debug.o gup.o $(mmu-y)
493+ prfile.o debug.o gup.o $(mmu-y)
494
495 # Give 'page_alloc' its own module-parameter namespace
496 page-alloc-y := page_alloc.o
497diff --git a/mm/filemap.c b/mm/filemap.c
498index 85b7d087eb45..115275a4a0e2 100644
499--- a/mm/filemap.c
500+++ b/mm/filemap.c
501@@ -2696,7 +2696,7 @@ vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf)
502 vm_fault_t ret = VM_FAULT_LOCKED;
503
504 sb_start_pagefault(inode->i_sb);
505- file_update_time(vmf->vma->vm_file);
506+ vma_file_update_time(vmf->vma);
507 lock_page(page);
508 if (page->mapping != inode->i_mapping) {
509 unlock_page(page);
510diff --git a/mm/mmap.c b/mm/mmap.c
511index a7d8c84d19b7..9c350dc3f570 100644
512--- a/mm/mmap.c
513+++ b/mm/mmap.c
514@@ -182,7 +182,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
515 if (vma->vm_ops && vma->vm_ops->close)
516 vma->vm_ops->close(vma);
517 if (vma->vm_file)
518- fput(vma->vm_file);
519+ vma_fput(vma);
520 mpol_put(vma_policy(vma));
521 vm_area_free(vma);
522 return next;
523@@ -940,7 +940,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
524 if (remove_next) {
525 if (file) {
526 uprobe_munmap(next, next->vm_start, next->vm_end);
527- fput(file);
528+ vma_fput(vma);
529 }
530 if (next->anon_vma)
531 anon_vma_merge(vma, next);
532@@ -1865,8 +1865,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
533 return addr;
534
535 unmap_and_free_vma:
536+ vma_fput(vma);
537 vma->vm_file = NULL;
538- fput(file);
539
540 /* Undo any partial mapping done by a device driver. */
541 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
542@@ -2695,7 +2695,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
543 goto out_free_mpol;
544
545 if (new->vm_file)
546- get_file(new->vm_file);
547+ vma_get_file(new);
548
549 if (new->vm_ops && new->vm_ops->open)
550 new->vm_ops->open(new);
551@@ -2714,7 +2714,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
552 if (new->vm_ops && new->vm_ops->close)
553 new->vm_ops->close(new);
554 if (new->vm_file)
555- fput(new->vm_file);
556+ vma_fput(new);
557 unlink_anon_vmas(new);
558 out_free_mpol:
559 mpol_put(vma_policy(new));
560@@ -2906,7 +2906,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
561 struct vm_area_struct *vma;
562 unsigned long populate = 0;
563 unsigned long ret = -EINVAL;
564- struct file *file;
565+ struct file *file, *prfile;
566
567 pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.rst.\n",
568 current->comm, current->pid);
569@@ -2981,10 +2981,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
570 }
571 }
572
573- file = get_file(vma->vm_file);
574+ vma_get_file(vma);
575+ file = vma->vm_file;
576+ prfile = vma->vm_prfile;
577 ret = do_mmap_pgoff(vma->vm_file, start, size,
578 prot, flags, pgoff, &populate, NULL);
579+ if (!IS_ERR_VALUE(ret) && file && prfile) {
580+ struct vm_area_struct *new_vma;
581+
582+ new_vma = find_vma(mm, ret);
583+ if (!new_vma->vm_prfile)
584+ new_vma->vm_prfile = prfile;
585+ if (new_vma != vma)
586+ get_file(prfile);
587+ }
588+ /*
589+ * two fput()s instead of vma_fput(vma),
590+ * coz vma may not be available anymore.
591+ */
592 fput(file);
593+ if (prfile)
594+ fput(prfile);
595 out:
596 up_write(&mm->mmap_sem);
597 if (populate)
598@@ -3274,7 +3291,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
599 if (anon_vma_clone(new_vma, vma))
600 goto out_free_mempol;
601 if (new_vma->vm_file)
602- get_file(new_vma->vm_file);
603+ vma_get_file(new_vma);
604 if (new_vma->vm_ops && new_vma->vm_ops->open)
605 new_vma->vm_ops->open(new_vma);
606 vma_link(mm, new_vma, prev, rb_link, rb_parent);
607diff --git a/mm/nommu.c b/mm/nommu.c
608index 99b7ec318824..de5b6cd162fe 100644
609--- a/mm/nommu.c
610+++ b/mm/nommu.c
611@@ -552,7 +552,7 @@ static void __put_nommu_region(struct vm_region *region)
612 up_write(&nommu_region_sem);
613
614 if (region->vm_file)
615- fput(region->vm_file);
616+ vmr_fput(region);
617
618 /* IO memory and memory shared directly out of the pagecache
619 * from ramfs/tmpfs mustn't be released here */
620@@ -690,7 +690,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
621 if (vma->vm_ops && vma->vm_ops->close)
622 vma->vm_ops->close(vma);
623 if (vma->vm_file)
624- fput(vma->vm_file);
625+ vma_fput(vma);
626 put_nommu_region(vma->vm_region);
627 vm_area_free(vma);
628 }
629@@ -1213,7 +1213,7 @@ unsigned long do_mmap(struct file *file,
630 goto error_just_free;
631 }
632 }
633- fput(region->vm_file);
634+ vmr_fput(region);
635 kmem_cache_free(vm_region_jar, region);
636 region = pregion;
637 result = start;
638@@ -1290,10 +1290,10 @@ unsigned long do_mmap(struct file *file,
639 up_write(&nommu_region_sem);
640 error:
641 if (region->vm_file)
642- fput(region->vm_file);
643+ vmr_fput(region);
644 kmem_cache_free(vm_region_jar, region);
645 if (vma->vm_file)
646- fput(vma->vm_file);
647+ vma_fput(vma);
648 vm_area_free(vma);
649 return ret;
650
651diff --git a/mm/prfile.c b/mm/prfile.c
652new file mode 100644
653index 000000000000..00d51187c325
654--- /dev/null
655+++ b/mm/prfile.c
656@@ -0,0 +1,86 @@
657+// SPDX-License-Identifier: GPL-2.0
658+/*
659+ * Mainly for aufs which mmap(2) different file and wants to print different
660+ * path in /proc/PID/maps.
661+ * Call these functions via macros defined in linux/mm.h.
662+ *
663+ * See Documentation/filesystems/aufs/design/06mmap.txt
664+ *
665+ * Copyright (c) 2014-2020 Junjro R. Okajima
666+ * Copyright (c) 2014 Ian Campbell
667+ */
668+
669+#include <linux/mm.h>
670+#include <linux/file.h>
671+#include <linux/fs.h>
672+
673+/* #define PRFILE_TRACE */
674+static inline void prfile_trace(struct file *f, struct file *pr,
675+ const char func[], int line, const char func2[])
676+{
677+#ifdef PRFILE_TRACE
678+ if (pr)
679+ pr_info("%s:%d: %s, %pD2\n", func, line, func2, f);
680+#endif
681+}
682+
683+void vma_do_file_update_time(struct vm_area_struct *vma, const char func[],
684+ int line)
685+{
686+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
687+
688+ prfile_trace(f, pr, func, line, __func__);
689+ file_update_time(f);
690+ if (f && pr)
691+ file_update_time(pr);
692+}
693+
694+struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[],
695+ int line)
696+{
697+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
698+
699+ prfile_trace(f, pr, func, line, __func__);
700+ return (f && pr) ? pr : f;
701+}
702+
703+void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line)
704+{
705+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
706+
707+ prfile_trace(f, pr, func, line, __func__);
708+ get_file(f);
709+ if (f && pr)
710+ get_file(pr);
711+}
712+
713+void vma_do_fput(struct vm_area_struct *vma, const char func[], int line)
714+{
715+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
716+
717+ prfile_trace(f, pr, func, line, __func__);
718+ fput(f);
719+ if (f && pr)
720+ fput(pr);
721+}
722+
723+#ifndef CONFIG_MMU
724+struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[],
725+ int line)
726+{
727+ struct file *f = region->vm_file, *pr = region->vm_prfile;
728+
729+ prfile_trace(f, pr, func, line, __func__);
730+ return (f && pr) ? pr : f;
731+}
732+
733+void vmr_do_fput(struct vm_region *region, const char func[], int line)
734+{
735+ struct file *f = region->vm_file, *pr = region->vm_prfile;
736+
737+ prfile_trace(f, pr, func, line, __func__);
738+ fput(f);
739+ if (f && pr)
740+ fput(pr);
741+}
742+#endif /* !CONFIG_MMU */
743SPDX-License-Identifier: GPL-2.0
744aufs5.4 standalone patch
745
746diff --git a/fs/dcache.c b/fs/dcache.c
747index 7ce4ccf5a51c..00d7e6a08026 100644
748--- a/fs/dcache.c
749+++ b/fs/dcache.c
750@@ -1369,6 +1369,7 @@ void d_walk(struct dentry *parent, void *data,
751 seq = 1;
752 goto again;
753 }
754+EXPORT_SYMBOL_GPL(d_walk);
755
756 struct check_mount {
757 struct vfsmount *mnt;
758@@ -2914,6 +2915,7 @@ void d_exchange(struct dentry *dentry1, struct dentry *dentry2)
759
760 write_sequnlock(&rename_lock);
761 }
762+EXPORT_SYMBOL_GPL(d_exchange);
763
764 /**
765 * d_ancestor - search for an ancestor
766diff --git a/fs/exec.c b/fs/exec.c
767index 555e93c7dec8..dad39c6b3878 100644
768--- a/fs/exec.c
769+++ b/fs/exec.c
770@@ -110,6 +110,7 @@ bool path_noexec(const struct path *path)
771 return (path->mnt->mnt_flags & MNT_NOEXEC) ||
772 (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC);
773 }
774+EXPORT_SYMBOL_GPL(path_noexec);
775
776 #ifdef CONFIG_USELIB
777 /*
778diff --git a/fs/fcntl.c b/fs/fcntl.c
779index 12dd73930961..0468c845190f 100644
780--- a/fs/fcntl.c
781+++ b/fs/fcntl.c
782@@ -85,6 +85,7 @@ int setfl(int fd, struct file *filp, unsigned long arg)
783 out:
784 return error;
785 }
786+EXPORT_SYMBOL_GPL(setfl);
787
788 static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
789 int force)
790diff --git a/fs/file_table.c b/fs/file_table.c
791index 30d55c9a1744..34b9bbf4c556 100644
792--- a/fs/file_table.c
793+++ b/fs/file_table.c
794@@ -162,6 +162,7 @@ struct file *alloc_empty_file(int flags, const struct cred *cred)
795 }
796 return ERR_PTR(-ENFILE);
797 }
798+EXPORT_SYMBOL_GPL(alloc_empty_file);
799
800 /*
801 * Variant of alloc_empty_file() that doesn't check and modify nr_files.
802@@ -375,6 +376,7 @@ void __fput_sync(struct file *file)
803 }
804
805 EXPORT_SYMBOL(fput);
806+EXPORT_SYMBOL_GPL(__fput_sync);
807
808 void __init files_init(void)
809 {
810diff --git a/fs/inode.c b/fs/inode.c
811index aaeacde398ee..5be87f2d3828 100644
812--- a/fs/inode.c
813+++ b/fs/inode.c
814@@ -1682,6 +1682,7 @@ int update_time(struct inode *inode, struct timespec64 *time, int flags)
815
816 return update_time(inode, time, flags);
817 }
818+EXPORT_SYMBOL_GPL(update_time);
819
820 /**
821 * touch_atime - update the access time
822diff --git a/fs/namespace.c b/fs/namespace.c
823index 0f7e57e5f4b7..516c2f397d33 100644
824--- a/fs/namespace.c
825+++ b/fs/namespace.c
826@@ -431,6 +431,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
827 mnt_dec_writers(real_mount(mnt));
828 preempt_enable();
829 }
830+EXPORT_SYMBOL_GPL(__mnt_drop_write);
831
832 /**
833 * mnt_drop_write - give up write access to a mount
834@@ -781,6 +782,7 @@ int is_current_mnt_ns(struct vfsmount *mnt)
835 {
836 return check_mnt(real_mount(mnt));
837 }
838+EXPORT_SYMBOL_GPL(is_current_mnt_ns);
839
840 /*
841 * vfsmount lock must be held for write
842@@ -1903,6 +1905,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
843 }
844 return 0;
845 }
846+EXPORT_SYMBOL_GPL(iterate_mounts);
847
848 static void lock_mnt_tree(struct mount *mnt)
849 {
850diff --git a/fs/notify/group.c b/fs/notify/group.c
851index 133f723aca07..0b9f7f6d8390 100644
852--- a/fs/notify/group.c
853+++ b/fs/notify/group.c
854@@ -99,6 +99,7 @@ void fsnotify_get_group(struct fsnotify_group *group)
855 {
856 refcount_inc(&group->refcnt);
857 }
858+EXPORT_SYMBOL_GPL(fsnotify_get_group);
859
860 /*
861 * Drop a reference to a group. Free it if it's through.
862diff --git a/fs/open.c b/fs/open.c
863index b62f5c0923a8..89af4b9c7319 100644
864--- a/fs/open.c
865+++ b/fs/open.c
866@@ -65,6 +65,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
867 inode_unlock(dentry->d_inode);
868 return ret;
869 }
870+EXPORT_SYMBOL_GPL(do_truncate);
871
872 long vfs_truncate(const struct path *path, loff_t length)
873 {
874diff --git a/fs/read_write.c b/fs/read_write.c
875index fa9b3994b34c..eb0e2c6ebaff 100644
876--- a/fs/read_write.c
877+++ b/fs/read_write.c
878@@ -468,6 +468,7 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
879
880 return ret;
881 }
882+EXPORT_SYMBOL_GPL(vfs_read);
883
884 static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
885 {
886@@ -508,6 +509,7 @@ vfs_readf_t vfs_readf(struct file *file)
887 return new_sync_read;
888 return ERR_PTR(-ENOSYS); /* doesn't have ->read(|_iter)() op */
889 }
890+EXPORT_SYMBOL_GPL(vfs_readf);
891
892 vfs_writef_t vfs_writef(struct file *file)
893 {
894@@ -519,6 +521,7 @@ vfs_writef_t vfs_writef(struct file *file)
895 return new_sync_write;
896 return ERR_PTR(-ENOSYS); /* doesn't have ->write(|_iter)() op */
897 }
898+EXPORT_SYMBOL_GPL(vfs_writef);
899
900 ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
901 {
902@@ -588,6 +591,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_
903
904 return ret;
905 }
906+EXPORT_SYMBOL_GPL(vfs_write);
907
908 /* file_ppos returns &file->f_pos or NULL if file is stream */
909 static inline loff_t *file_ppos(struct file *file)
910diff --git a/fs/splice.c b/fs/splice.c
911index 75b489fcb66f..0a1f7498c22b 100644
912--- a/fs/splice.c
913+++ b/fs/splice.c
914@@ -847,6 +847,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
915
916 return splice_write(pipe, out, ppos, len, flags);
917 }
918+EXPORT_SYMBOL_GPL(do_splice_from);
919
920 /*
921 * Attempt to initiate a splice from a file to a pipe.
922@@ -876,6 +877,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
923
924 return splice_read(in, ppos, pipe, len, flags);
925 }
926+EXPORT_SYMBOL_GPL(do_splice_to);
927
928 /**
929 * splice_direct_to_actor - splices data directly between two non-pipes
930diff --git a/fs/sync.c b/fs/sync.c
931index 457f4e4a5cc1..67c66358f3fe 100644
932--- a/fs/sync.c
933+++ b/fs/sync.c
934@@ -39,6 +39,7 @@ int __sync_filesystem(struct super_block *sb, int wait)
935 sb->s_op->sync_fs(sb, wait);
936 return __sync_blockdev(sb->s_bdev, wait);
937 }
938+EXPORT_SYMBOL_GPL(__sync_filesystem);
939
940 /*
941 * Write out and wait upon all dirty data associated with this
942diff --git a/fs/xattr.c b/fs/xattr.c
943index 90dd78f0eb27..40b01dd1b14a 100644
944--- a/fs/xattr.c
945+++ b/fs/xattr.c
946@@ -296,6 +296,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
947 *xattr_value = value;
948 return error;
949 }
950+EXPORT_SYMBOL_GPL(vfs_getxattr_alloc);
951
952 ssize_t
953 __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name,
954diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
955index 407c08ac8ac8..d7f71842f8a2 100644
956--- a/kernel/locking/lockdep.c
957+++ b/kernel/locking/lockdep.c
958@@ -174,6 +174,7 @@ inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock)
959 */
960 return lock_classes + class_idx;
961 }
962+EXPORT_SYMBOL_GPL(lockdep_hlock_class);
963 #define hlock_class(hlock) lockdep_hlock_class(hlock)
964
965 #ifdef CONFIG_LOCK_STAT
966diff --git a/kernel/task_work.c b/kernel/task_work.c
967index 0fef395662a6..83fb1ecfc33d 100644
968--- a/kernel/task_work.c
969+++ b/kernel/task_work.c
970@@ -116,3 +116,4 @@ void task_work_run(void)
971 } while (work);
972 }
973 }
974+EXPORT_SYMBOL_GPL(task_work_run);
975diff --git a/security/device_cgroup.c b/security/device_cgroup.c
976index 725674f3276d..83f6494c52a2 100644
977--- a/security/device_cgroup.c
978+++ b/security/device_cgroup.c
979@@ -824,3 +824,4 @@ int __devcgroup_check_permission(short type, u32 major, u32 minor,
980
981 return 0;
982 }
983+EXPORT_SYMBOL_GPL(__devcgroup_check_permission);
984diff --git a/security/security.c b/security/security.c
985index 1bc000f834e2..306f2c9f7ee2 100644
986--- a/security/security.c
987+++ b/security/security.c
988@@ -1036,6 +1036,7 @@ int security_path_rmdir(const struct path *dir, struct dentry *dentry)
989 return 0;
990 return call_int_hook(path_rmdir, 0, dir, dentry);
991 }
992+EXPORT_SYMBOL_GPL(security_path_rmdir);
993
994 int security_path_unlink(const struct path *dir, struct dentry *dentry)
995 {
996@@ -1052,6 +1053,7 @@ int security_path_symlink(const struct path *dir, struct dentry *dentry,
997 return 0;
998 return call_int_hook(path_symlink, 0, dir, dentry, old_name);
999 }
1000+EXPORT_SYMBOL_GPL(security_path_symlink);
1001
1002 int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
1003 struct dentry *new_dentry)
1004@@ -1060,6 +1062,7 @@ int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
1005 return 0;
1006 return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry);
1007 }
1008+EXPORT_SYMBOL_GPL(security_path_link);
1009
1010 int security_path_rename(const struct path *old_dir, struct dentry *old_dentry,
1011 const struct path *new_dir, struct dentry *new_dentry,
1012@@ -1087,6 +1090,7 @@ int security_path_truncate(const struct path *path)
1013 return 0;
1014 return call_int_hook(path_truncate, 0, path);
1015 }
1016+EXPORT_SYMBOL_GPL(security_path_truncate);
1017
1018 int security_path_chmod(const struct path *path, umode_t mode)
1019 {
1020@@ -1094,6 +1098,7 @@ int security_path_chmod(const struct path *path, umode_t mode)
1021 return 0;
1022 return call_int_hook(path_chmod, 0, path, mode);
1023 }
1024+EXPORT_SYMBOL_GPL(security_path_chmod);
1025
1026 int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
1027 {
1028@@ -1101,6 +1106,7 @@ int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
1029 return 0;
1030 return call_int_hook(path_chown, 0, path, uid, gid);
1031 }
1032+EXPORT_SYMBOL_GPL(security_path_chown);
1033
1034 int security_path_chroot(const struct path *path)
1035 {
1036@@ -1201,6 +1207,7 @@ int security_inode_permission(struct inode *inode, int mask)
1037 return 0;
1038 return call_int_hook(inode_permission, 0, inode, mask);
1039 }
1040+EXPORT_SYMBOL_GPL(security_inode_permission);
1041
1042 int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
1043 {
1044@@ -1378,6 +1385,7 @@ int security_file_permission(struct file *file, int mask)
1045
1046 return fsnotify_perm(file, mask);
1047 }
1048+EXPORT_SYMBOL_GPL(security_file_permission);
1049
1050 int security_file_alloc(struct file *file)
1051 {
1052diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs
1053--- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100
1054+++ linux/Documentation/ABI/testing/debugfs-aufs 2019-07-11 15:42:14.455570938 +0200
1055@@ -0,0 +1,55 @@
1056+What: /debug/aufs/si_<id>/
1057+Date: March 2009
1058+Contact: J. R. Okajima <hooanon05g@gmail.com>
1059+Description:
1060+ Under /debug/aufs, a directory named si_<id> is created
1061+ per aufs mount, where <id> is a unique id generated
1062+ internally.
1063+
1064+What: /debug/aufs/si_<id>/plink
1065+Date: Apr 2013
1066+Contact: J. R. Okajima <hooanon05g@gmail.com>
1067+Description:
1068+ It has three lines and shows the information about the
1069+ pseudo-link. The first line is a single number
1070+ representing a number of buckets. The second line is a
1071+ number of pseudo-links per buckets (separated by a
1072+ blank). The last line is a single number representing a
1073+ total number of psedo-links.
1074+ When the aufs mount option 'noplink' is specified, it
1075+ will show "1\n0\n0\n".
1076+
1077+What: /debug/aufs/si_<id>/xib
1078+Date: March 2009
1079+Contact: J. R. Okajima <hooanon05g@gmail.com>
1080+Description:
1081+ It shows the consumed blocks by xib (External Inode Number
1082+ Bitmap), its block size and file size.
1083+ When the aufs mount option 'noxino' is specified, it
1084+ will be empty. About XINO files, see the aufs manual.
1085+
1086+What: /debug/aufs/si_<id>/xi0, xi1 ... xiN and xiN-N
1087+Date: March 2009
1088+Contact: J. R. Okajima <hooanon05g@gmail.com>
1089+Description:
1090+ It shows the consumed blocks by xino (External Inode Number
1091+ Translation Table), its link count, block size and file
1092+ size.
1093+ Due to the file size limit, there may exist multiple
1094+ xino files per branch. In this case, "-N" is added to
1095+ the filename and it corresponds to the index of the
1096+ internal xino array. "-0" is omitted.
1097+ When the aufs mount option 'noxino' is specified, Those
1098+ entries won't exist. About XINO files, see the aufs
1099+ manual.
1100+
1101+What: /debug/aufs/si_<id>/xigen
1102+Date: March 2009
1103+Contact: J. R. Okajima <hooanon05g@gmail.com>
1104+Description:
1105+ It shows the consumed blocks by xigen (External Inode
1106+ Generation Table), its block size and file size.
1107+ If CONFIG_AUFS_EXPORT is disabled, this entry will not
1108+ be created.
1109+ When the aufs mount option 'noxino' is specified, it
1110+ will be empty. About XINO files, see the aufs manual.
1111diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs
1112--- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100
1113+++ linux/Documentation/ABI/testing/sysfs-aufs 2019-07-11 15:42:14.455570938 +0200
1114@@ -0,0 +1,31 @@
1115+What: /sys/fs/aufs/si_<id>/
1116+Date: March 2009
1117+Contact: J. R. Okajima <hooanon05g@gmail.com>
1118+Description:
1119+ Under /sys/fs/aufs, a directory named si_<id> is created
1120+ per aufs mount, where <id> is a unique id generated
1121+ internally.
1122+
1123+What: /sys/fs/aufs/si_<id>/br0, br1 ... brN
1124+Date: March 2009
1125+Contact: J. R. Okajima <hooanon05g@gmail.com>
1126+Description:
1127+ It shows the abolute path of a member directory (which
1128+ is called branch) in aufs, and its permission.
1129+
1130+What: /sys/fs/aufs/si_<id>/brid0, brid1 ... bridN
1131+Date: July 2013
1132+Contact: J. R. Okajima <hooanon05g@gmail.com>
1133+Description:
1134+ It shows the id of a member directory (which is called
1135+ branch) in aufs.
1136+
1137+What: /sys/fs/aufs/si_<id>/xi_path
1138+Date: March 2009
1139+Contact: J. R. Okajima <hooanon05g@gmail.com>
1140+Description:
1141+ It shows the abolute path of XINO (External Inode Number
1142+ Bitmap, Translation Table and Generation Table) file
1143+ even if it is the default path.
1144+ When the aufs mount option 'noxino' is specified, it
1145+ will be empty. About XINO files, see the aufs manual.
1146diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt
1147--- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 01:00:00.000000000 +0100
1148+++ linux/Documentation/filesystems/aufs/design/01intro.txt 2020-01-27 10:57:18.162204582 +0100
1149@@ -0,0 +1,171 @@
1150+
1151+# Copyright (C) 2005-2020 Junjiro R. Okajima
1152+#
1153+# This program is free software; you can redistribute it and/or modify
1154+# it under the terms of the GNU General Public License as published by
1155+# the Free Software Foundation; either version 2 of the License, or
1156+# (at your option) any later version.
1157+#
1158+# This program is distributed in the hope that it will be useful,
1159+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1160+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1161+# GNU General Public License for more details.
1162+#
1163+# You should have received a copy of the GNU General Public License
1164+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1165+
1166+Introduction
1167+----------------------------------------
1168+
1169+aufs [ei ju: ef es] | /ey-yoo-ef-es/ | [a u f s]
1170+1. abbrev. for "advanced multi-layered unification filesystem".
1171+2. abbrev. for "another unionfs".
1172+3. abbrev. for "auf das" in German which means "on the" in English.
1173+ Ex. "Butter aufs Brot"(G) means "butter onto bread"(E).
1174+ But "Filesystem aufs Filesystem" is hard to understand.
1175+4. abbrev. for "African Urban Fashion Show".
1176+
1177+AUFS is a filesystem with features:
1178+- multi layered stackable unification filesystem, the member directory
1179+ is called as a branch.
1180+- branch permission and attribute, 'readonly', 'real-readonly',
1181+ 'readwrite', 'whiteout-able', 'link-able whiteout', etc. and their
1182+ combination.
1183+- internal "file copy-on-write".
1184+- logical deletion, whiteout.
1185+- dynamic branch manipulation, adding, deleting and changing permission.
1186+- allow bypassing aufs, user's direct branch access.
1187+- external inode number translation table and bitmap which maintains the
1188+ persistent aufs inode number.
1189+- seekable directory, including NFS readdir.
1190+- file mapping, mmap and sharing pages.
1191+- pseudo-link, hardlink over branches.
1192+- loopback mounted filesystem as a branch.
1193+- several policies to select one among multiple writable branches.
1194+- revert a single systemcall when an error occurs in aufs.
1195+- and more...
1196+
1197+
1198+Multi Layered Stackable Unification Filesystem
1199+----------------------------------------------------------------------
1200+Most people already knows what it is.
1201+It is a filesystem which unifies several directories and provides a
1202+merged single directory. When users access a file, the access will be
1203+passed/re-directed/converted (sorry, I am not sure which English word is
1204+correct) to the real file on the member filesystem. The member
1205+filesystem is called 'lower filesystem' or 'branch' and has a mode
1206+'readonly' and 'readwrite.' And the deletion for a file on the lower
1207+readonly branch is handled by creating 'whiteout' on the upper writable
1208+branch.
1209+
1210+On LKML, there have been discussions about UnionMount (Jan Blunck,
1211+Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took
1212+different approaches to implement the merged-view.
1213+The former tries putting it into VFS, and the latter implements as a
1214+separate filesystem.
1215+(If I misunderstand about these implementations, please let me know and
1216+I shall correct it. Because it is a long time ago when I read their
1217+source files last time).
1218+
1219+UnionMount's approach will be able to small, but may be hard to share
1220+branches between several UnionMount since the whiteout in it is
1221+implemented in the inode on branch filesystem and always
1222+shared. According to Bharata's post, readdir does not seems to be
1223+finished yet.
1224+There are several missing features known in this implementations such as
1225+- for users, the inode number may change silently. eg. copy-up.
1226+- link(2) may break by copy-up.
1227+- read(2) may get an obsoleted filedata (fstat(2) too).
1228+- fcntl(F_SETLK) may be broken by copy-up.
1229+- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
1230+ open(O_RDWR).
1231+
1232+In linux-3.18, "overlay" filesystem (formerly known as "overlayfs") was
1233+merged into mainline. This is another implementation of UnionMount as a
1234+separated filesystem. All the limitations and known problems which
1235+UnionMount are equally inherited to "overlay" filesystem.
1236+
1237+Unionfs has a longer history. When I started implementing a stackable
1238+filesystem (Aug 2005), it already existed. It has virtual super_block,
1239+inode, dentry and file objects and they have an array pointing lower
1240+same kind objects. After contributing many patches for Unionfs, I
1241+re-started my project AUFS (Jun 2006).
1242+
1243+In AUFS, the structure of filesystem resembles to Unionfs, but I
1244+implemented my own ideas, approaches and enhancements and it became
1245+totally different one.
1246+
1247+Comparing DM snapshot and fs based implementation
1248+- the number of bytes to be copied between devices is much smaller.
1249+- the type of filesystem must be one and only.
1250+- the fs must be writable, no readonly fs, even for the lower original
1251+ device. so the compression fs will not be usable. but if we use
1252+ loopback mount, we may address this issue.
1253+ for instance,
1254+ mount /cdrom/squashfs.img /sq
1255+ losetup /sq/ext2.img
1256+ losetup /somewhere/cow
1257+ dmsetup "snapshot /dev/loop0 /dev/loop1 ..."
1258+- it will be difficult (or needs more operations) to extract the
1259+ difference between the original device and COW.
1260+- DM snapshot-merge may help a lot when users try merging. in the
1261+ fs-layer union, users will use rsync(1).
1262+
1263+You may want to read my old paper "Filesystems in LiveCD"
1264+(http://aufs.sourceforge.net/aufs2/report/sq/sq.pdf).
1265+
1266+
1267+Several characters/aspects/persona of aufs
1268+----------------------------------------------------------------------
1269+
1270+Aufs has several characters, aspects or persona.
1271+1. a filesystem, callee of VFS helper
1272+2. sub-VFS, caller of VFS helper for branches
1273+3. a virtual filesystem which maintains persistent inode number
1274+4. reader/writer of files on branches such like an application
1275+
1276+1. Callee of VFS Helper
1277+As an ordinary linux filesystem, aufs is a callee of VFS. For instance,
1278+unlink(2) from an application reaches sys_unlink() kernel function and
1279+then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it
1280+calls filesystem specific unlink operation. Actually aufs implements the
1281+unlink operation but it behaves like a redirector.
1282+
1283+2. Caller of VFS Helper for Branches
1284+aufs_unlink() passes the unlink request to the branch filesystem as if
1285+it were called from VFS. So the called unlink operation of the branch
1286+filesystem acts as usual. As a caller of VFS helper, aufs should handle
1287+every necessary pre/post operation for the branch filesystem.
1288+- acquire the lock for the parent dir on a branch
1289+- lookup in a branch
1290+- revalidate dentry on a branch
1291+- mnt_want_write() for a branch
1292+- vfs_unlink() for a branch
1293+- mnt_drop_write() for a branch
1294+- release the lock on a branch
1295+
1296+3. Persistent Inode Number
1297+One of the most important issue for a filesystem is to maintain inode
1298+numbers. This is particularly important to support exporting a
1299+filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
1300+backend block device for its own. But some storage is necessary to
1301+keep and maintain the inode numbers. It may be a large space and may not
1302+suit to keep in memory. Aufs rents some space from its first writable
1303+branch filesystem (by default) and creates file(s) on it. These files
1304+are created by aufs internally and removed soon (currently) keeping
1305+opened.
1306+Note: Because these files are removed, they are totally gone after
1307+ unmounting aufs. It means the inode numbers are not persistent
1308+ across unmount or reboot. I have a plan to make them really
1309+ persistent which will be important for aufs on NFS server.
1310+
1311+4. Read/Write Files Internally (copy-on-write)
1312+Because a branch can be readonly, when you write a file on it, aufs will
1313+"copy-up" it to the upper writable branch internally. And then write the
1314+originally requested thing to the file. Generally kernel doesn't
1315+open/read/write file actively. In aufs, even a single write may cause a
1316+internal "file copy". This behaviour is very similar to cp(1) command.
1317+
1318+Some people may think it is better to pass such work to user space
1319+helper, instead of doing in kernel space. Actually I am still thinking
1320+about it. But currently I have implemented it in kernel space.
1321diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt linux/Documentation/filesystems/aufs/design/02struct.txt
1322--- /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100
1323+++ linux/Documentation/filesystems/aufs/design/02struct.txt 2020-01-27 10:57:18.162204582 +0100
1324@@ -0,0 +1,258 @@
1325+
1326+# Copyright (C) 2005-2020 Junjiro R. Okajima
1327+#
1328+# This program is free software; you can redistribute it and/or modify
1329+# it under the terms of the GNU General Public License as published by
1330+# the Free Software Foundation; either version 2 of the License, or
1331+# (at your option) any later version.
1332+#
1333+# This program is distributed in the hope that it will be useful,
1334+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1335+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1336+# GNU General Public License for more details.
1337+#
1338+# You should have received a copy of the GNU General Public License
1339+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1340+
1341+Basic Aufs Internal Structure
1342+
1343+Superblock/Inode/Dentry/File Objects
1344+----------------------------------------------------------------------
1345+As like an ordinary filesystem, aufs has its own
1346+superblock/inode/dentry/file objects. All these objects have a
1347+dynamically allocated array and store the same kind of pointers to the
1348+lower filesystem, branch.
1349+For example, when you build a union with one readwrite branch and one
1350+readonly, mounted /au, /rw and /ro respectively.
1351+- /au = /rw + /ro
1352+- /ro/fileA exists but /rw/fileA
1353+
1354+Aufs lookup operation finds /ro/fileA and gets dentry for that. These
1355+pointers are stored in a aufs dentry. The array in aufs dentry will be,
1356+- [0] = NULL (because /rw/fileA doesn't exist)
1357+- [1] = /ro/fileA
1358+
1359+This style of an array is essentially same to the aufs
1360+superblock/inode/dentry/file objects.
1361+
1362+Because aufs supports manipulating branches, ie. add/delete/change
1363+branches dynamically, these objects has its own generation. When
1364+branches are changed, the generation in aufs superblock is
1365+incremented. And a generation in other object are compared when it is
1366+accessed. When a generation in other objects are obsoleted, aufs
1367+refreshes the internal array.
1368+
1369+
1370+Superblock
1371+----------------------------------------------------------------------
1372+Additionally aufs superblock has some data for policies to select one
1373+among multiple writable branches, XIB files, pseudo-links and kobject.
1374+See below in detail.
1375+About the policies which supports copy-down a directory, see
1376+wbr_policy.txt too.
1377+
1378+
1379+Branch and XINO(External Inode Number Translation Table)
1380+----------------------------------------------------------------------
1381+Every branch has its own xino (external inode number translation table)
1382+file. The xino file is created and unlinked by aufs internally. When two
1383+members of a union exist on the same filesystem, they share the single
1384+xino file.
1385+The struct of a xino file is simple, just a sequence of aufs inode
1386+numbers which is indexed by the lower inode number.
1387+In the above sample, assume the inode number of /ro/fileA is i111 and
1388+aufs assigns the inode number i999 for fileA. Then aufs writes 999 as
1389+4(8) bytes at 111 * 4(8) bytes offset in the xino file.
1390+
1391+When the inode numbers are not contiguous, the xino file will be sparse
1392+which has a hole in it and doesn't consume as much disk space as it
1393+might appear. If your branch filesystem consumes disk space for such
1394+holes, then you should specify 'xino=' option at mounting aufs.
1395+
1396+Aufs has a mount option to free the disk blocks for such holes in XINO
1397+files on tmpfs or ramdisk. But it is not so effective actually. If you
1398+meet a problem of disk shortage due to XINO files, then you should try
1399+"tmpfs-ino.patch" (and "vfs-ino.patch" too) in aufs4-standalone.git.
1400+The patch localizes the assignment inumbers per tmpfs-mount and avoid
1401+the holes in XINO files.
1402+
1403+Also a writable branch has three kinds of "whiteout bases". All these
1404+are existed when the branch is joined to aufs, and their names are
1405+whiteout-ed doubly, so that users will never see their names in aufs
1406+hierarchy.
1407+1. a regular file which will be hardlinked to all whiteouts.
1408+2. a directory to store a pseudo-link.
1409+3. a directory to store an "orphan"-ed file temporary.
1410+
1411+1. Whiteout Base
1412+ When you remove a file on a readonly branch, aufs handles it as a
1413+ logical deletion and creates a whiteout on the upper writable branch
1414+ as a hardlink of this file in order not to consume inode on the
1415+ writable branch.
1416+2. Pseudo-link Dir
1417+ See below, Pseudo-link.
1418+3. Step-Parent Dir
1419+ When "fileC" exists on the lower readonly branch only and it is
1420+ opened and removed with its parent dir, and then user writes
1421+ something into it, then aufs copies-up fileC to this
1422+ directory. Because there is no other dir to store fileC. After
1423+ creating a file under this dir, the file is unlinked.
1424+
1425+Because aufs supports manipulating branches, ie. add/delete/change
1426+dynamically, a branch has its own id. When the branch order changes,
1427+aufs finds the new index by searching the branch id.
1428+
1429+
1430+Pseudo-link
1431+----------------------------------------------------------------------
1432+Assume "fileA" exists on the lower readonly branch only and it is
1433+hardlinked to "fileB" on the branch. When you write something to fileA,
1434+aufs copies-up it to the upper writable branch. Additionally aufs
1435+creates a hardlink under the Pseudo-link Directory of the writable
1436+branch. The inode of a pseudo-link is kept in aufs super_block as a
1437+simple list. If fileB is read after unlinking fileA, aufs returns
1438+filedata from the pseudo-link instead of the lower readonly
1439+branch. Because the pseudo-link is based upon the inode, to keep the
1440+inode number by xino (see above) is essentially necessary.
1441+
1442+All the hardlinks under the Pseudo-link Directory of the writable branch
1443+should be restored in a proper location later. Aufs provides a utility
1444+to do this. The userspace helpers executed at remounting and unmounting
1445+aufs by default.
1446+During this utility is running, it puts aufs into the pseudo-link
1447+maintenance mode. In this mode, only the process which began the
1448+maintenance mode (and its child processes) is allowed to operate in
1449+aufs. Some other processes which are not related to the pseudo-link will
1450+be allowed to run too, but the rest have to return an error or wait
1451+until the maintenance mode ends. If a process already acquires an inode
1452+mutex (in VFS), it has to return an error.
1453+
1454+
1455+XIB(external inode number bitmap)
1456+----------------------------------------------------------------------
1457+Addition to the xino file per a branch, aufs has an external inode number
1458+bitmap in a superblock object. It is also an internal file such like a
1459+xino file.
1460+It is a simple bitmap to mark whether the aufs inode number is in-use or
1461+not.
1462+To reduce the file I/O, aufs prepares a single memory page to cache xib.
1463+
1464+As well as XINO files, aufs has a feature to truncate/refresh XIB to
1465+reduce the number of consumed disk blocks for these files.
1466+
1467+
1468+Virtual or Vertical Dir, and Readdir in Userspace
1469+----------------------------------------------------------------------
1470+In order to support multiple layers (branches), aufs readdir operation
1471+constructs a virtual dir block on memory. For readdir, aufs calls
1472+vfs_readdir() internally for each dir on branches, merges their entries
1473+with eliminating the whiteout-ed ones, and sets it to file (dir)
1474+object. So the file object has its entry list until it is closed. The
1475+entry list will be updated when the file position is zero and becomes
1476+obsoleted. This decision is made in aufs automatically.
1477+
1478+The dynamically allocated memory block for the name of entries has a
1479+unit of 512 bytes (by default) and stores the names contiguously (no
1480+padding). Another block for each entry is handled by kmem_cache too.
1481+During building dir blocks, aufs creates hash list and judging whether
1482+the entry is whiteouted by its upper branch or already listed.
1483+The merged result is cached in the corresponding inode object and
1484+maintained by a customizable life-time option.
1485+
1486+Some people may call it can be a security hole or invite DoS attack
1487+since the opened and once readdir-ed dir (file object) holds its entry
1488+list and becomes a pressure for system memory. But I'd say it is similar
1489+to files under /proc or /sys. The virtual files in them also holds a
1490+memory page (generally) while they are opened. When an idea to reduce
1491+memory for them is introduced, it will be applied to aufs too.
1492+For those who really hate this situation, I've developed readdir(3)
1493+library which operates this merging in userspace. You just need to set
1494+LD_PRELOAD environment variable, and aufs will not consume no memory in
1495+kernel space for readdir(3).
1496+
1497+
1498+Workqueue
1499+----------------------------------------------------------------------
1500+Aufs sometimes requires privilege access to a branch. For instance,
1501+in copy-up/down operation. When a user process is going to make changes
1502+to a file which exists in the lower readonly branch only, and the mode
1503+of one of ancestor directories may not be writable by a user
1504+process. Here aufs copy-up the file with its ancestors and they may
1505+require privilege to set its owner/group/mode/etc.
1506+This is a typical case of a application character of aufs (see
1507+Introduction).
1508+
1509+Aufs uses workqueue synchronously for this case. It creates its own
1510+workqueue. The workqueue is a kernel thread and has privilege. Aufs
1511+passes the request to call mkdir or write (for example), and wait for
1512+its completion. This approach solves a problem of a signal handler
1513+simply.
1514+If aufs didn't adopt the workqueue and changed the privilege of the
1515+process, then the process may receive the unexpected SIGXFSZ or other
1516+signals.
1517+
1518+Also aufs uses the system global workqueue ("events" kernel thread) too
1519+for asynchronous tasks, such like handling inotify/fsnotify, re-creating a
1520+whiteout base and etc. This is unrelated to a privilege.
1521+Most of aufs operation tries acquiring a rw_semaphore for aufs
1522+superblock at the beginning, at the same time waits for the completion
1523+of all queued asynchronous tasks.
1524+
1525+
1526+Whiteout
1527+----------------------------------------------------------------------
1528+The whiteout in aufs is very similar to Unionfs's. That is represented
1529+by its filename. UnionMount takes an approach of a file mode, but I am
1530+afraid several utilities (find(1) or something) will have to support it.
1531+
1532+Basically the whiteout represents "logical deletion" which stops aufs to
1533+lookup further, but also it represents "dir is opaque" which also stop
1534+further lookup.
1535+
1536+In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively.
1537+In order to make several functions in a single systemcall to be
1538+revertible, aufs adopts an approach to rename a directory to a temporary
1539+unique whiteouted name.
1540+For example, in rename(2) dir where the target dir already existed, aufs
1541+renames the target dir to a temporary unique whiteouted name before the
1542+actual rename on a branch, and then handles other actions (make it opaque,
1543+update the attributes, etc). If an error happens in these actions, aufs
1544+simply renames the whiteouted name back and returns an error. If all are
1545+succeeded, aufs registers a function to remove the whiteouted unique
1546+temporary name completely and asynchronously to the system global
1547+workqueue.
1548+
1549+
1550+Copy-up
1551+----------------------------------------------------------------------
1552+It is a well-known feature or concept.
1553+When user modifies a file on a readonly branch, aufs operate "copy-up"
1554+internally and makes change to the new file on the upper writable branch.
1555+When the trigger systemcall does not update the timestamps of the parent
1556+dir, aufs reverts it after copy-up.
1557+
1558+
1559+Move-down (aufs3.9 and later)
1560+----------------------------------------------------------------------
1561+"Copy-up" is one of the essential feature in aufs. It copies a file from
1562+the lower readonly branch to the upper writable branch when a user
1563+changes something about the file.
1564+"Move-down" is an opposite action of copy-up. Basically this action is
1565+ran manually instead of automatically and internally.
1566+For desgin and implementation, aufs has to consider these issues.
1567+- whiteout for the file may exist on the lower branch.
1568+- ancestor directories may not exist on the lower branch.
1569+- diropq for the ancestor directories may exist on the upper branch.
1570+- free space on the lower branch will reduce.
1571+- another access to the file may happen during moving-down, including
1572+ UDBA (see "Revalidate Dentry and UDBA").
1573+- the file should not be hard-linked nor pseudo-linked. they should be
1574+ handled by auplink utility later.
1575+
1576+Sometimes users want to move-down a file from the upper writable branch
1577+to the lower readonly or writable branch. For instance,
1578+- the free space of the upper writable branch is going to run out.
1579+- create a new intermediate branch between the upper and lower branch.
1580+- etc.
1581+
1582+For this purpose, use "aumvdown" command in aufs-util.git.
1583diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.txt linux/Documentation/filesystems/aufs/design/03atomic_open.txt
1584--- /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.txt 1970-01-01 01:00:00.000000000 +0100
1585+++ linux/Documentation/filesystems/aufs/design/03atomic_open.txt 2020-01-27 10:57:18.162204582 +0100
1586@@ -0,0 +1,85 @@
1587+
1588+# Copyright (C) 2015-2020 Junjiro R. Okajima
1589+#
1590+# This program is free software; you can redistribute it and/or modify
1591+# it under the terms of the GNU General Public License as published by
1592+# the Free Software Foundation; either version 2 of the License, or
1593+# (at your option) any later version.
1594+#
1595+# This program is distributed in the hope that it will be useful,
1596+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1597+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1598+# GNU General Public License for more details.
1599+#
1600+# You should have received a copy of the GNU General Public License
1601+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1602+
1603+Support for a branch who has its ->atomic_open()
1604+----------------------------------------------------------------------
1605+The filesystems who implement its ->atomic_open() are not majority. For
1606+example NFSv4 does, and aufs should call NFSv4 ->atomic_open,
1607+particularly for open(O_CREAT|O_EXCL, 0400) case. Other than
1608+->atomic_open(), NFSv4 returns an error for this open(2). While I am not
1609+sure whether all filesystems who have ->atomic_open() behave like this,
1610+but NFSv4 surely returns the error.
1611+
1612+In order to support ->atomic_open() for aufs, there are a few
1613+approaches.
1614+
1615+A. Introduce aufs_atomic_open()
1616+ - calls one of VFS:do_last(), lookup_open() or atomic_open() for
1617+ branch fs.
1618+B. Introduce aufs_atomic_open() calling create, open and chmod. this is
1619+ an aufs user Pip Cet's approach
1620+ - calls aufs_create(), VFS finish_open() and notify_change().
1621+ - pass fake-mode to finish_open(), and then correct the mode by
1622+ notify_change().
1623+C. Extend aufs_open() to call branch fs's ->atomic_open()
1624+ - no aufs_atomic_open().
1625+ - aufs_lookup() registers the TID to an aufs internal object.
1626+ - aufs_create() does nothing when the matching TID is registered, but
1627+ registers the mode.
1628+ - aufs_open() calls branch fs's ->atomic_open() when the matching
1629+ TID is registered.
1630+D. Extend aufs_open() to re-try branch fs's ->open() with superuser's
1631+ credential
1632+ - no aufs_atomic_open().
1633+ - aufs_create() registers the TID to an internal object. this info
1634+ represents "this process created this file just now."
1635+ - when aufs gets EACCES from branch fs's ->open(), then confirm the
1636+ registered TID and re-try open() with superuser's credential.
1637+
1638+Pros and cons for each approach.
1639+
1640+A.
1641+ - straightforward but highly depends upon VFS internal.
1642+ - the atomic behavaiour is kept.
1643+ - some of parameters such as nameidata are hard to reproduce for
1644+ branch fs.
1645+ - large overhead.
1646+B.
1647+ - easy to implement.
1648+ - the atomic behavaiour is lost.
1649+C.
1650+ - the atomic behavaiour is kept.
1651+ - dirty and tricky.
1652+ - VFS checks whether the file is created correctly after calling
1653+ ->create(), which means this approach doesn't work.
1654+D.
1655+ - easy to implement.
1656+ - the atomic behavaiour is lost.
1657+ - to open a file with superuser's credential and give it to a user
1658+ process is a bad idea, since the file object keeps the credential
1659+ in it. It may affect LSM or something. This approach doesn't work
1660+ either.
1661+
1662+The approach A is ideal, but it hard to implement. So here is a
1663+variation of A, which is to be implemented.
1664+
1665+A-1. Introduce aufs_atomic_open()
1666+ - calls branch fs ->atomic_open() if exists. otherwise calls
1667+ vfs_create() and finish_open().
1668+ - the demerit is that the several checks after branch fs
1669+ ->atomic_open() are lost. in the ordinary case, the checks are
1670+ done by VFS:do_last(), lookup_open() and atomic_open(). some can
1671+ be implemented in aufs, but not all I am afraid.
1672diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt
1673--- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100
1674+++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2020-01-27 10:57:18.165538015 +0100
1675@@ -0,0 +1,113 @@
1676+
1677+# Copyright (C) 2005-2020 Junjiro R. Okajima
1678+#
1679+# This program is free software; you can redistribute it and/or modify
1680+# it under the terms of the GNU General Public License as published by
1681+# the Free Software Foundation; either version 2 of the License, or
1682+# (at your option) any later version.
1683+#
1684+# This program is distributed in the hope that it will be useful,
1685+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1686+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1687+# GNU General Public License for more details.
1688+#
1689+# You should have received a copy of the GNU General Public License
1690+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1691+
1692+Lookup in a Branch
1693+----------------------------------------------------------------------
1694+Since aufs has a character of sub-VFS (see Introduction), it operates
1695+lookup for branches as VFS does. It may be a heavy work. But almost all
1696+lookup operation in aufs is the simplest case, ie. lookup only an entry
1697+directly connected to its parent. Digging down the directory hierarchy
1698+is unnecessary. VFS has a function lookup_one_len() for that use, and
1699+aufs calls it.
1700+
1701+When a branch is a remote filesystem, aufs basically relies upon its
1702+->d_revalidate(), also aufs forces the hardest revalidate tests for
1703+them.
1704+For d_revalidate, aufs implements three levels of revalidate tests. See
1705+"Revalidate Dentry and UDBA" in detail.
1706+
1707+
1708+Test Only the Highest One for the Directory Permission (dirperm1 option)
1709+----------------------------------------------------------------------
1710+Let's try case study.
1711+- aufs has two branches, upper readwrite and lower readonly.
1712+ /au = /rw + /ro
1713+- "dirA" exists under /ro, but /rw. and its mode is 0700.
1714+- user invoked "chmod a+rx /au/dirA"
1715+- the internal copy-up is activated and "/rw/dirA" is created and its
1716+ permission bits are set to world readable.
1717+- then "/au/dirA" becomes world readable?
1718+
1719+In this case, /ro/dirA is still 0700 since it exists in readonly branch,
1720+or it may be a natively readonly filesystem. If aufs respects the lower
1721+branch, it should not respond readdir request from other users. But user
1722+allowed it by chmod. Should really aufs rejects showing the entries
1723+under /ro/dirA?
1724+
1725+To be honest, I don't have a good solution for this case. So aufs
1726+implements 'dirperm1' and 'nodirperm1' mount options, and leave it to
1727+users.
1728+When dirperm1 is specified, aufs checks only the highest one for the
1729+directory permission, and shows the entries. Otherwise, as usual, checks
1730+every dir existing on all branches and rejects the request.
1731+
1732+As a side effect, dirperm1 option improves the performance of aufs
1733+because the number of permission check is reduced when the number of
1734+branch is many.
1735+
1736+
1737+Revalidate Dentry and UDBA (User's Direct Branch Access)
1738+----------------------------------------------------------------------
1739+Generally VFS helpers re-validate a dentry as a part of lookup.
1740+0. digging down the directory hierarchy.
1741+1. lock the parent dir by its i_mutex.
1742+2. lookup the final (child) entry.
1743+3. revalidate it.
1744+4. call the actual operation (create, unlink, etc.)
1745+5. unlock the parent dir
1746+
1747+If the filesystem implements its ->d_revalidate() (step 3), then it is
1748+called. Actually aufs implements it and checks the dentry on a branch is
1749+still valid.
1750+But it is not enough. Because aufs has to release the lock for the
1751+parent dir on a branch at the end of ->lookup() (step 2) and
1752+->d_revalidate() (step 3) while the i_mutex of the aufs dir is still
1753+held by VFS.
1754+If the file on a branch is changed directly, eg. bypassing aufs, after
1755+aufs released the lock, then the subsequent operation may cause
1756+something unpleasant result.
1757+
1758+This situation is a result of VFS architecture, ->lookup() and
1759+->d_revalidate() is separated. But I never say it is wrong. It is a good
1760+design from VFS's point of view. It is just not suitable for sub-VFS
1761+character in aufs.
1762+
1763+Aufs supports such case by three level of revalidation which is
1764+selectable by user.
1765+1. Simple Revalidate
1766+ Addition to the native flow in VFS's, confirm the child-parent
1767+ relationship on the branch just after locking the parent dir on the
1768+ branch in the "actual operation" (step 4). When this validation
1769+ fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still
1770+ checks the validation of the dentry on branches.
1771+2. Monitor Changes Internally by Inotify/Fsnotify
1772+ Addition to above, in the "actual operation" (step 4) aufs re-lookup
1773+ the dentry on the branch, and returns EBUSY if it finds different
1774+ dentry.
1775+ Additionally, aufs sets the inotify/fsnotify watch for every dir on branches
1776+ during it is in cache. When the event is notified, aufs registers a
1777+ function to kernel 'events' thread by schedule_work(). And the
1778+ function sets some special status to the cached aufs dentry and inode
1779+ private data. If they are not cached, then aufs has nothing to
1780+ do. When the same file is accessed through aufs (step 0-3) later,
1781+ aufs will detect the status and refresh all necessary data.
1782+ In this mode, aufs has to ignore the event which is fired by aufs
1783+ itself.
1784+3. No Extra Validation
1785+ This is the simplest test and doesn't add any additional revalidation
1786+ test, and skip the revalidation in step 4. It is useful and improves
1787+ aufs performance when system surely hide the aufs branches from user,
1788+ by over-mounting something (or another method).
1789diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt linux/Documentation/filesystems/aufs/design/04branch.txt
1790--- /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100
1791+++ linux/Documentation/filesystems/aufs/design/04branch.txt 2020-01-27 10:57:18.165538015 +0100
1792@@ -0,0 +1,74 @@
1793+
1794+# Copyright (C) 2005-2020 Junjiro R. Okajima
1795+#
1796+# This program is free software; you can redistribute it and/or modify
1797+# it under the terms of the GNU General Public License as published by
1798+# the Free Software Foundation; either version 2 of the License, or
1799+# (at your option) any later version.
1800+#
1801+# This program is distributed in the hope that it will be useful,
1802+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1803+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1804+# GNU General Public License for more details.
1805+#
1806+# You should have received a copy of the GNU General Public License
1807+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1808+
1809+Branch Manipulation
1810+
1811+Since aufs supports dynamic branch manipulation, ie. add/remove a branch
1812+and changing its permission/attribute, there are a lot of works to do.
1813+
1814+
1815+Add a Branch
1816+----------------------------------------------------------------------
1817+o Confirm the adding dir exists outside of aufs, including loopback
1818+ mount, and its various attributes.
1819+o Initialize the xino file and whiteout bases if necessary.
1820+ See struct.txt.
1821+
1822+o Check the owner/group/mode of the directory
1823+ When the owner/group/mode of the adding directory differs from the
1824+ existing branch, aufs issues a warning because it may impose a
1825+ security risk.
1826+ For example, when a upper writable branch has a world writable empty
1827+ top directory, a malicious user can create any files on the writable
1828+ branch directly, like copy-up and modify manually. If something like
1829+ /etc/{passwd,shadow} exists on the lower readonly branch but the upper
1830+ writable branch, and the writable branch is world-writable, then a
1831+ malicious guy may create /etc/passwd on the writable branch directly
1832+ and the infected file will be valid in aufs.
1833+ I am afraid it can be a security issue, but aufs can do nothing except
1834+ producing a warning.
1835+
1836+
1837+Delete a Branch
1838+----------------------------------------------------------------------
1839+o Confirm the deleting branch is not busy
1840+ To be general, there is one merit to adopt "remount" interface to
1841+ manipulate branches. It is to discard caches. At deleting a branch,
1842+ aufs checks the still cached (and connected) dentries and inodes. If
1843+ there are any, then they are all in-use. An inode without its
1844+ corresponding dentry can be alive alone (for example, inotify/fsnotify case).
1845+
1846+ For the cached one, aufs checks whether the same named entry exists on
1847+ other branches.
1848+ If the cached one is a directory, because aufs provides a merged view
1849+ to users, as long as one dir is left on any branch aufs can show the
1850+ dir to users. In this case, the branch can be removed from aufs.
1851+ Otherwise aufs rejects deleting the branch.
1852+
1853+ If any file on the deleting branch is opened by aufs, then aufs
1854+ rejects deleting.
1855+
1856+
1857+Modify the Permission of a Branch
1858+----------------------------------------------------------------------
1859+o Re-initialize or remove the xino file and whiteout bases if necessary.
1860+ See struct.txt.
1861+
1862+o rw --> ro: Confirm the modifying branch is not busy
1863+ Aufs rejects the request if any of these conditions are true.
1864+ - a file on the branch is mmap-ed.
1865+ - a regular file on the branch is opened for write and there is no
1866+ same named entry on the upper branch.
1867diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt linux/Documentation/filesystems/aufs/design/05wbr_policy.txt
1868--- /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 01:00:00.000000000 +0100
1869+++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2020-01-27 10:57:18.165538015 +0100
1870@@ -0,0 +1,64 @@
1871+
1872+# Copyright (C) 2005-2020 Junjiro R. Okajima
1873+#
1874+# This program is free software; you can redistribute it and/or modify
1875+# it under the terms of the GNU General Public License as published by
1876+# the Free Software Foundation; either version 2 of the License, or
1877+# (at your option) any later version.
1878+#
1879+# This program is distributed in the hope that it will be useful,
1880+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1881+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1882+# GNU General Public License for more details.
1883+#
1884+# You should have received a copy of the GNU General Public License
1885+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1886+
1887+Policies to Select One among Multiple Writable Branches
1888+----------------------------------------------------------------------
1889+When the number of writable branch is more than one, aufs has to decide
1890+the target branch for file creation or copy-up. By default, the highest
1891+writable branch which has the parent (or ancestor) dir of the target
1892+file is chosen (top-down-parent policy).
1893+By user's request, aufs implements some other policies to select the
1894+writable branch, for file creation several policies, round-robin,
1895+most-free-space, and other policies. For copy-up, top-down-parent,
1896+bottom-up-parent, bottom-up and others.
1897+
1898+As expected, the round-robin policy selects the branch in circular. When
1899+you have two writable branches and creates 10 new files, 5 files will be
1900+created for each branch. mkdir(2) systemcall is an exception. When you
1901+create 10 new directories, all will be created on the same branch.
1902+And the most-free-space policy selects the one which has most free
1903+space among the writable branches. The amount of free space will be
1904+checked by aufs internally, and users can specify its time interval.
1905+
1906+The policies for copy-up is more simple,
1907+top-down-parent is equivalent to the same named on in create policy,
1908+bottom-up-parent selects the writable branch where the parent dir
1909+exists and the nearest upper one from the copyup-source,
1910+bottom-up selects the nearest upper writable branch from the
1911+copyup-source, regardless the existence of the parent dir.
1912+
1913+There are some rules or exceptions to apply these policies.
1914+- If there is a readonly branch above the policy-selected branch and
1915+ the parent dir is marked as opaque (a variation of whiteout), or the
1916+ target (creating) file is whiteout-ed on the upper readonly branch,
1917+ then the result of the policy is ignored and the target file will be
1918+ created on the nearest upper writable branch than the readonly branch.
1919+- If there is a writable branch above the policy-selected branch and
1920+ the parent dir is marked as opaque or the target file is whiteouted
1921+ on the branch, then the result of the policy is ignored and the target
1922+ file will be created on the highest one among the upper writable
1923+ branches who has diropq or whiteout. In case of whiteout, aufs removes
1924+ it as usual.
1925+- link(2) and rename(2) systemcalls are exceptions in every policy.
1926+ They try selecting the branch where the source exists as possible
1927+ since copyup a large file will take long time. If it can't be,
1928+ ie. the branch where the source exists is readonly, then they will
1929+ follow the copyup policy.
1930+- There is an exception for rename(2) when the target exists.
1931+ If the rename target exists, aufs compares the index of the branches
1932+ where the source and the target exists and selects the higher
1933+ one. If the selected branch is readonly, then aufs follows the
1934+ copyup policy.
1935diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.dot linux/Documentation/filesystems/aufs/design/06dirren.dot
1936--- /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.dot 1970-01-01 01:00:00.000000000 +0100
1937+++ linux/Documentation/filesystems/aufs/design/06dirren.dot 2019-07-11 15:42:14.458904362 +0200
1938@@ -0,0 +1,31 @@
1939+
1940+// to view this graph, run dot(1) command in GRAPHVIZ.
1941+
1942+digraph G {
1943+node [shape=box];
1944+whinfo [label="detailed info file\n(lower_brid_root-hinum, h_inum, namelen, old name)"];
1945+
1946+node [shape=oval];
1947+
1948+aufs_rename -> whinfo [label="store/remove"];
1949+
1950+node [shape=oval];
1951+inode_list [label="h_inum list in branch\ncache"];
1952+
1953+node [shape=box];
1954+whinode [label="h_inum list file"];
1955+
1956+node [shape=oval];
1957+brmgmt [label="br_add/del/mod/umount"];
1958+
1959+brmgmt -> inode_list [label="create/remove"];
1960+brmgmt -> whinode [label="load/store"];
1961+
1962+inode_list -> whinode [style=dashed,dir=both];
1963+
1964+aufs_rename -> inode_list [label="add/del"];
1965+
1966+aufs_lookup -> inode_list [label="search"];
1967+
1968+aufs_lookup -> whinfo [label="load/remove"];
1969+}
1970diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.txt linux/Documentation/filesystems/aufs/design/06dirren.txt
1971--- /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.txt 1970-01-01 01:00:00.000000000 +0100
1972+++ linux/Documentation/filesystems/aufs/design/06dirren.txt 2020-01-27 10:57:18.165538015 +0100
1973@@ -0,0 +1,102 @@
1974+
1975+# Copyright (C) 2017-2020 Junjiro R. Okajima
1976+#
1977+# This program is free software; you can redistribute it and/or modify
1978+# it under the terms of the GNU General Public License as published by
1979+# the Free Software Foundation; either version 2 of the License, or
1980+# (at your option) any later version.
1981+#
1982+# This program is distributed in the hope that it will be useful,
1983+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1984+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1985+# GNU General Public License for more details.
1986+#
1987+# You should have received a copy of the GNU General Public License
1988+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1989+
1990+Special handling for renaming a directory (DIRREN)
1991+----------------------------------------------------------------------
1992+First, let's assume we have a simple usecase.
1993+
1994+- /u = /rw + /ro
1995+- /rw/dirA exists
1996+- /ro/dirA and /ro/dirA/file exist too
1997+- there is no dirB on both branches
1998+- a user issues rename("dirA", "dirB")
1999+
2000+Now, what should aufs behave against this rename(2)?
2001+There are a few possible cases.
2002+
2003+A. returns EROFS.
2004+ since dirA exists on a readonly branch which cannot be renamed.
2005+B. returns EXDEV.
2006+ it is possible to copy-up dirA (only the dir itself), but the child
2007+ entries ("file" in this case) should not be. it must be a bad
2008+ approach to copy-up recursively.
2009+C. returns a success.
2010+ even the branch /ro is readonly, aufs tries renaming it. Obviously it
2011+ is a violation of aufs' policy.
2012+D. construct an extra information which indicates that /ro/dirA should
2013+ be handled as the name of dirB.
2014+ overlayfs has a similar feature called REDIRECT.
2015+
2016+Until now, aufs implements the case B only which returns EXDEV, and
2017+expects the userspace application behaves like mv(1) which tries
2018+issueing rename(2) recursively.
2019+
2020+A new aufs feature called DIRREN is introduced which implements the case
2021+D. There are several "extra information" added.
2022+
2023+1. detailed info per renamed directory
2024+ path: /rw/dirB/$AUFS_WH_DR_INFO_PFX.<lower branch-id>
2025+2. the inode-number list of directories on a branch
2026+ path: /rw/dirB/$AUFS_WH_DR_BRHINO
2027+
2028+The filename of "detailed info per directory" represents the lower
2029+branch, and its format is
2030+- a type of the branch id
2031+ one of these.
2032+ + uuid (not implemented yet)
2033+ + fsid
2034+ + dev
2035+- the inode-number of the branch root dir
2036+
2037+And it contains these info in a single regular file.
2038+- magic number
2039+- branch's inode-number of the logically renamed dir
2040+- the name of the before-renamed dir
2041+
2042+The "detailed info per directory" file is created in aufs rename(2), and
2043+loaded in any lookup.
2044+The info is considered in lookup for the matching case only. Here
2045+"matching" means that the root of branch (in the info filename) is same
2046+to the current looking-up branch. After looking-up the before-renamed
2047+name, the inode-number is compared. And the matched dentry is used.
2048+
2049+The "inode-number list of directories" is a regular file which contains
2050+simply the inode-numbers on the branch. The file is created or updated
2051+in removing the branch, and loaded in adding the branch. Its lifetime is
2052+equal to the branch.
2053+The list is refered in lookup, and when the current target inode is
2054+found in the list, the aufs tries loading the "detailed info per
2055+directory" and get the changed and valid name of the dir.
2056+
2057+Theoretically these "extra informaiton" may be able to be put into XATTR
2058+in the dir inode. But aufs doesn't choose this way because
2059+1. XATTR may not be supported by the branch (or its configuration)
2060+2. XATTR may have its size limit.
2061+3. XATTR may be less easy to convert than a regular file, when the
2062+ format of the info is changed in the future.
2063+At the same time, I agree that the regular file approach is much slower
2064+than XATTR approach. So, in the future, aufs may take the XATTR or other
2065+better approach.
2066+
2067+This DIRREN feature is enabled by aufs configuration, and is activated
2068+by a new mount option.
2069+
2070+For the more complicated case, there is a work with UDBA option, which
2071+is to dected the direct access to the branches (by-passing aufs) and to
2072+maintain the cashes in aufs. Since a single cached aufs dentry may
2073+contains two names, before- and after-rename, the name comparision in
2074+UDBA handler may not work correctly. In this case, the behaviour will be
2075+equivalen to udba=reval case.
2076diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt linux/Documentation/filesystems/aufs/design/06fhsm.txt
2077--- /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt 1970-01-01 01:00:00.000000000 +0100
2078+++ linux/Documentation/filesystems/aufs/design/06fhsm.txt 2020-01-27 10:57:18.165538015 +0100
2079@@ -0,0 +1,120 @@
2080+
2081+# Copyright (C) 2011-2020 Junjiro R. Okajima
2082+#
2083+# This program is free software; you can redistribute it and/or modify
2084+# it under the terms of the GNU General Public License as published by
2085+# the Free Software Foundation; either version 2 of the License, or
2086+# (at your option) any later version.
2087+#
2088+# This program is distributed in the hope that it will be useful,
2089+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2090+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2091+# GNU General Public License for more details.
2092+#
2093+# You should have received a copy of the GNU General Public License
2094+# along with this program; if not, write to the Free Software
2095+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2096+
2097+
2098+File-based Hierarchical Storage Management (FHSM)
2099+----------------------------------------------------------------------
2100+Hierarchical Storage Management (or HSM) is a well-known feature in the
2101+storage world. Aufs provides this feature as file-based with multiple
2102+writable branches, based upon the principle of "Colder, the Lower".
2103+Here the word "colder" means that the less used files, and "lower" means
2104+that the position in the order of the stacked branches vertically.
2105+These multiple writable branches are prioritized, ie. the topmost one
2106+should be the fastest drive and be used heavily.
2107+
2108+o Characters in aufs FHSM story
2109+- aufs itself and a new branch attribute.
2110+- a new ioctl interface to move-down and to establish a connection with
2111+ the daemon ("move-down" is a converse of "copy-up").
2112+- userspace tool and daemon.
2113+
2114+The userspace daemon establishes a connection with aufs and waits for
2115+the notification. The notified information is very similar to struct
2116+statfs containing the number of consumed blocks and inodes.
2117+When the consumed blocks/inodes of a branch exceeds the user-specified
2118+upper watermark, the daemon activates its move-down process until the
2119+consumed blocks/inodes reaches the user-specified lower watermark.
2120+
2121+The actual move-down is done by aufs based upon the request from
2122+user-space since we need to maintain the inode number and the internal
2123+pointer arrays in aufs.
2124+
2125+Currently aufs FHSM handles the regular files only. Additionally they
2126+must not be hard-linked nor pseudo-linked.
2127+
2128+
2129+o Cowork of aufs and the user-space daemon
2130+ During the userspace daemon established the connection, aufs sends a
2131+ small notification to it whenever aufs writes something into the
2132+ writable branch. But it may cost high since aufs issues statfs(2)
2133+ internally. So user can specify a new option to cache the
2134+ info. Actually the notification is controlled by these factors.
2135+ + the specified cache time.
2136+ + classified as "force" by aufs internally.
2137+ Until the specified time expires, aufs doesn't send the info
2138+ except the forced cases. When aufs decide forcing, the info is always
2139+ notified to userspace.
2140+ For example, the number of free inodes is generally large enough and
2141+ the shortage of it happens rarely. So aufs doesn't force the
2142+ notification when creating a new file, directory and others. This is
2143+ the typical case which aufs doesn't force.
2144+ When aufs writes the actual filedata and the files consumes any of new
2145+ blocks, the aufs forces notifying.
2146+
2147+
2148+o Interfaces in aufs
2149+- New branch attribute.
2150+ + fhsm
2151+ Specifies that the branch is managed by FHSM feature. In other word,
2152+ participant in the FHSM.
2153+ When nofhsm is set to the branch, it will not be the source/target
2154+ branch of the move-down operation. This attribute is set
2155+ independently from coo and moo attributes, and if you want full
2156+ FHSM, you should specify them as well.
2157+- New mount option.
2158+ + fhsm_sec
2159+ Specifies a second to suppress many less important info to be
2160+ notified.
2161+- New ioctl.
2162+ + AUFS_CTL_FHSM_FD
2163+ create a new file descriptor which userspace can read the notification
2164+ (a subset of struct statfs) from aufs.
2165+- Module parameter 'brs'
2166+ It has to be set to 1. Otherwise the new mount option 'fhsm' will not
2167+ be set.
2168+- mount helpers /sbin/mount.aufs and /sbin/umount.aufs
2169+ When there are two or more branches with fhsm attributes,
2170+ /sbin/mount.aufs invokes the user-space daemon and /sbin/umount.aufs
2171+ terminates it. As a result of remounting and branch-manipulation, the
2172+ number of branches with fhsm attribute can be one. In this case,
2173+ /sbin/mount.aufs will terminate the user-space daemon.
2174+
2175+
2176+Finally the operation is done as these steps in kernel-space.
2177+- make sure that,
2178+ + no one else is using the file.
2179+ + the file is not hard-linked.
2180+ + the file is not pseudo-linked.
2181+ + the file is a regular file.
2182+ + the parent dir is not opaqued.
2183+- find the target writable branch.
2184+- make sure the file is not whiteout-ed by the upper (than the target)
2185+ branch.
2186+- make the parent dir on the target branch.
2187+- mutex lock the inode on the branch.
2188+- unlink the whiteout on the target branch (if exists).
2189+- lookup and create the whiteout-ed temporary name on the target branch.
2190+- copy the file as the whiteout-ed temporary name on the target branch.
2191+- rename the whiteout-ed temporary name to the original name.
2192+- unlink the file on the source branch.
2193+- maintain the internal pointer array and the external inode number
2194+ table (XINO).
2195+- maintain the timestamps and other attributes of the parent dir and the
2196+ file.
2197+
2198+And of course, in every step, an error may happen. So the operation
2199+should restore the original file state after an error happens.
2200diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt
2201--- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 01:00:00.000000000 +0100
2202+++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2020-01-27 10:57:18.165538015 +0100
2203@@ -0,0 +1,72 @@
2204+
2205+# Copyright (C) 2005-2020 Junjiro R. Okajima
2206+#
2207+# This program is free software; you can redistribute it and/or modify
2208+# it under the terms of the GNU General Public License as published by
2209+# the Free Software Foundation; either version 2 of the License, or
2210+# (at your option) any later version.
2211+#
2212+# This program is distributed in the hope that it will be useful,
2213+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2214+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2215+# GNU General Public License for more details.
2216+#
2217+# You should have received a copy of the GNU General Public License
2218+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2219+
2220+mmap(2) -- File Memory Mapping
2221+----------------------------------------------------------------------
2222+In aufs, the file-mapped pages are handled by a branch fs directly, no
2223+interaction with aufs. It means aufs_mmap() calls the branch fs's
2224+->mmap().
2225+This approach is simple and good, but there is one problem.
2226+Under /proc, several entries show the mmapped files by its path (with
2227+device and inode number), and the printed path will be the path on the
2228+branch fs's instead of virtual aufs's.
2229+This is not a problem in most cases, but some utilities lsof(1) (and its
2230+user) may expect the path on aufs.
2231+
2232+To address this issue, aufs adds a new member called vm_prfile in struct
2233+vm_area_struct (and struct vm_region). The original vm_file points to
2234+the file on the branch fs in order to handle everything correctly as
2235+usual. The new vm_prfile points to a virtual file in aufs, and the
2236+show-functions in procfs refers to vm_prfile if it is set.
2237+Also we need to maintain several other places where touching vm_file
2238+such like
2239+- fork()/clone() copies vma and the reference count of vm_file is
2240+ incremented.
2241+- merging vma maintains the ref count too.
2242+
2243+This is not a good approach. It just fakes the printed path. But it
2244+leaves all behaviour around f_mapping unchanged. This is surely an
2245+advantage.
2246+Actually aufs had adopted another complicated approach which calls
2247+generic_file_mmap() and handles struct vm_operations_struct. In this
2248+approach, aufs met a hard problem and I could not solve it without
2249+switching the approach.
2250+
2251+There may be one more another approach which is
2252+- bind-mount the branch-root onto the aufs-root internally
2253+- grab the new vfsmount (ie. struct mount)
2254+- lazy-umount the branch-root internally
2255+- in open(2) the aufs-file, open the branch-file with the hidden
2256+ vfsmount (instead of the original branch's vfsmount)
2257+- ideally this "bind-mount and lazy-umount" should be done atomically,
2258+ but it may be possible from userspace by the mount helper.
2259+
2260+Adding the internal hidden vfsmount and using it in opening a file, the
2261+file path under /proc will be printed correctly. This approach looks
2262+smarter, but is not possible I am afraid.
2263+- aufs-root may be bind-mount later. when it happens, another hidden
2264+ vfsmount will be required.
2265+- it is hard to get the chance to bind-mount and lazy-umount
2266+ + in kernel-space, FS can have vfsmount in open(2) via
2267+ file->f_path, and aufs can know its vfsmount. But several locks are
2268+ already acquired, and if aufs tries to bind-mount and lazy-umount
2269+ here, then it may cause a deadlock.
2270+ + in user-space, bind-mount doesn't invoke the mount helper.
2271+- since /proc shows dev and ino, aufs has to give vma these info. it
2272+ means a new member vm_prinode will be necessary. this is essentially
2273+ equivalent to vm_prfile described above.
2274+
2275+I have to give up this "looks-smater" approach.
2276diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt linux/Documentation/filesystems/aufs/design/06xattr.txt
2277--- /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt 1970-01-01 01:00:00.000000000 +0100
2278+++ linux/Documentation/filesystems/aufs/design/06xattr.txt 2020-01-27 10:57:18.165538015 +0100
2279@@ -0,0 +1,96 @@
2280+
2281+# Copyright (C) 2014-2020 Junjiro R. Okajima
2282+#
2283+# This program is free software; you can redistribute it and/or modify
2284+# it under the terms of the GNU General Public License as published by
2285+# the Free Software Foundation; either version 2 of the License, or
2286+# (at your option) any later version.
2287+#
2288+# This program is distributed in the hope that it will be useful,
2289+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2290+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2291+# GNU General Public License for more details.
2292+#
2293+# You should have received a copy of the GNU General Public License
2294+# along with this program; if not, write to the Free Software
2295+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2296+
2297+
2298+Listing XATTR/EA and getting the value
2299+----------------------------------------------------------------------
2300+For the inode standard attributes (owner, group, timestamps, etc.), aufs
2301+shows the values from the topmost existing file. This behaviour is good
2302+for the non-dir entries since the bahaviour exactly matches the shown
2303+information. But for the directories, aufs considers all the same named
2304+entries on the lower branches. Which means, if one of the lower entry
2305+rejects readdir call, then aufs returns an error even if the topmost
2306+entry allows it. This behaviour is necessary to respect the branch fs's
2307+security, but can make users confused since the user-visible standard
2308+attributes don't match the behaviour.
2309+To address this issue, aufs has a mount option called dirperm1 which
2310+checks the permission for the topmost entry only, and ignores the lower
2311+entry's permission.
2312+
2313+A similar issue can happen around XATTR.
2314+getxattr(2) and listxattr(2) families behave as if dirperm1 option is
2315+always set. Otherwise these very unpleasant situation would happen.
2316+- listxattr(2) may return the duplicated entries.
2317+- users may not be able to remove or reset the XATTR forever,
2318+
2319+
2320+XATTR/EA support in the internal (copy,move)-(up,down)
2321+----------------------------------------------------------------------
2322+Generally the extended attributes of inode are categorized as these.
2323+- "security" for LSM and capability.
2324+- "system" for posix ACL, 'acl' mount option is required for the branch
2325+ fs generally.
2326+- "trusted" for userspace, CAP_SYS_ADMIN is required.
2327+- "user" for userspace, 'user_xattr' mount option is required for the
2328+ branch fs generally.
2329+
2330+Moreover there are some other categories. Aufs handles these rather
2331+unpopular categories as the ordinary ones, ie. there is no special
2332+condition nor exception.
2333+
2334+In copy-up, the support for XATTR on the dst branch may differ from the
2335+src branch. In this case, the copy-up operation will get an error and
2336+the original user operation which triggered the copy-up will fail. It
2337+can happen that even all copy-up will fail.
2338+When both of src and dst branches support XATTR and if an error occurs
2339+during copying XATTR, then the copy-up should fail obviously. That is a
2340+good reason and aufs should return an error to userspace. But when only
2341+the src branch support that XATTR, aufs should not return an error.
2342+For example, the src branch supports ACL but the dst branch doesn't
2343+because the dst branch may natively un-support it or temporary
2344+un-support it due to "noacl" mount option. Of course, the dst branch fs
2345+may NOT return an error even if the XATTR is not supported. It is
2346+totally up to the branch fs.
2347+
2348+Anyway when the aufs internal copy-up gets an error from the dst branch
2349+fs, then aufs tries removing the just copied entry and returns the error
2350+to the userspace. The worst case of this situation will be all copy-up
2351+will fail.
2352+
2353+For the copy-up operation, there two basic approaches.
2354+- copy the specified XATTR only (by category above), and return the
2355+ error unconditionally if it happens.
2356+- copy all XATTR, and ignore the error on the specified category only.
2357+
2358+In order to support XATTR and to implement the correct behaviour, aufs
2359+chooses the latter approach and introduces some new branch attributes,
2360+"icexsec", "icexsys", "icextr", "icexusr", and "icexoth".
2361+They correspond to the XATTR namespaces (see above). Additionally, to be
2362+convenient, "icex" is also provided which means all "icex*" attributes
2363+are set (here the word "icex" stands for "ignore copy-error on XATTR").
2364+
2365+The meaning of these attributes is to ignore the error from setting
2366+XATTR on that branch.
2367+Note that aufs tries copying all XATTR unconditionally, and ignores the
2368+error from the dst branch according to the specified attributes.
2369+
2370+Some XATTR may have its default value. The default value may come from
2371+the parent dir or the environment. If the default value is set at the
2372+file creating-time, it will be overwritten by copy-up.
2373+Some contradiction may happen I am afraid.
2374+Do we need another attribute to stop copying XATTR? I am unsure. For
2375+now, aufs implements the branch attributes to ignore the error.
2376diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt
2377--- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100
2378+++ linux/Documentation/filesystems/aufs/design/07export.txt 2020-01-27 10:57:18.165538015 +0100
2379@@ -0,0 +1,58 @@
2380+
2381+# Copyright (C) 2005-2020 Junjiro R. Okajima
2382+#
2383+# This program is free software; you can redistribute it and/or modify
2384+# it under the terms of the GNU General Public License as published by
2385+# the Free Software Foundation; either version 2 of the License, or
2386+# (at your option) any later version.
2387+#
2388+# This program is distributed in the hope that it will be useful,
2389+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2390+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2391+# GNU General Public License for more details.
2392+#
2393+# You should have received a copy of the GNU General Public License
2394+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2395+
2396+Export Aufs via NFS
2397+----------------------------------------------------------------------
2398+Here is an approach.
2399+- like xino/xib, add a new file 'xigen' which stores aufs inode
2400+ generation.
2401+- iget_locked(): initialize aufs inode generation for a new inode, and
2402+ store it in xigen file.
2403+- destroy_inode(): increment aufs inode generation and store it in xigen
2404+ file. it is necessary even if it is not unlinked, because any data of
2405+ inode may be changed by UDBA.
2406+- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise
2407+ build file handle by
2408+ + branch id (4 bytes)
2409+ + superblock generation (4 bytes)
2410+ + inode number (4 or 8 bytes)
2411+ + parent dir inode number (4 or 8 bytes)
2412+ + inode generation (4 bytes))
2413+ + return value of exportfs_encode_fh() for the parent on a branch (4
2414+ bytes)
2415+ + file handle for a branch (by exportfs_encode_fh())
2416+- fh_to_dentry():
2417+ + find the index of a branch from its id in handle, and check it is
2418+ still exist in aufs.
2419+ + 1st level: get the inode number from handle and search it in cache.
2420+ + 2nd level: if not found in cache, get the parent inode number from
2421+ the handle and search it in cache. and then open the found parent
2422+ dir, find the matching inode number by vfs_readdir() and get its
2423+ name, and call lookup_one_len() for the target dentry.
2424+ + 3rd level: if the parent dir is not cached, call
2425+ exportfs_decode_fh() for a branch and get the parent on a branch,
2426+ build a pathname of it, convert it a pathname in aufs, call
2427+ path_lookup(). now aufs gets a parent dir dentry, then handle it as
2428+ the 2nd level.
2429+ + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount
2430+ for every branch, but not itself. to get this, (currently) aufs
2431+ searches in current->nsproxy->mnt_ns list. it may not be a good
2432+ idea, but I didn't get other approach.
2433+ + test the generation of the gotten inode.
2434+- every inode operation: they may get EBUSY due to UDBA. in this case,
2435+ convert it into ESTALE for NFSD.
2436+- readdir(): call lockdep_on/off() because filldir in NFSD calls
2437+ lookup_one_len(), vfs_getattr(), encode_fh() and others.
2438diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linux/Documentation/filesystems/aufs/design/08shwh.txt
2439--- /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 01:00:00.000000000 +0100
2440+++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2020-01-27 10:57:18.165538015 +0100
2441@@ -0,0 +1,52 @@
2442+
2443+# Copyright (C) 2005-2020 Junjiro R. Okajima
2444+#
2445+# This program is free software; you can redistribute it and/or modify
2446+# it under the terms of the GNU General Public License as published by
2447+# the Free Software Foundation; either version 2 of the License, or
2448+# (at your option) any later version.
2449+#
2450+# This program is distributed in the hope that it will be useful,
2451+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2452+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2453+# GNU General Public License for more details.
2454+#
2455+# You should have received a copy of the GNU General Public License
2456+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2457+
2458+Show Whiteout Mode (shwh)
2459+----------------------------------------------------------------------
2460+Generally aufs hides the name of whiteouts. But in some cases, to show
2461+them is very useful for users. For instance, creating a new middle layer
2462+(branch) by merging existing layers.
2463+
2464+(borrowing aufs1 HOW-TO from a user, Michael Towers)
2465+When you have three branches,
2466+- Bottom: 'system', squashfs (underlying base system), read-only
2467+- Middle: 'mods', squashfs, read-only
2468+- Top: 'overlay', ram (tmpfs), read-write
2469+
2470+The top layer is loaded at boot time and saved at shutdown, to preserve
2471+the changes made to the system during the session.
2472+When larger changes have been made, or smaller changes have accumulated,
2473+the size of the saved top layer data grows. At this point, it would be
2474+nice to be able to merge the two overlay branches ('mods' and 'overlay')
2475+and rewrite the 'mods' squashfs, clearing the top layer and thus
2476+restoring save and load speed.
2477+
2478+This merging is simplified by the use of another aufs mount, of just the
2479+two overlay branches using the 'shwh' option.
2480+# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \
2481+ aufs /livesys/merge_union
2482+
2483+A merged view of these two branches is then available at
2484+/livesys/merge_union, and the new feature is that the whiteouts are
2485+visible!
2486+Note that in 'shwh' mode the aufs mount must be 'ro', which will disable
2487+writing to all branches. Also the default mode for all branches is 'ro'.
2488+It is now possible to save the combined contents of the two overlay
2489+branches to a new squashfs, e.g.:
2490+# mksquashfs /livesys/merge_union /path/to/newmods.squash
2491+
2492+This new squashfs archive can be stored on the boot device and the
2493+initramfs will use it to replace the old one at the next boot.
2494diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt linux/Documentation/filesystems/aufs/design/10dynop.txt
2495--- /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 01:00:00.000000000 +0100
2496+++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2020-01-27 10:57:18.165538015 +0100
2497@@ -0,0 +1,47 @@
2498+
2499+# Copyright (C) 2010-2020 Junjiro R. Okajima
2500+#
2501+# This program is free software; you can redistribute it and/or modify
2502+# it under the terms of the GNU General Public License as published by
2503+# the Free Software Foundation; either version 2 of the License, or
2504+# (at your option) any later version.
2505+#
2506+# This program is distributed in the hope that it will be useful,
2507+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2508+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2509+# GNU General Public License for more details.
2510+#
2511+# You should have received a copy of the GNU General Public License
2512+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2513+
2514+Dynamically customizable FS operations
2515+----------------------------------------------------------------------
2516+Generally FS operations (struct inode_operations, struct
2517+address_space_operations, struct file_operations, etc.) are defined as
2518+"static const", but it never means that FS have only one set of
2519+operation. Some FS have multiple sets of them. For instance, ext2 has
2520+three sets, one for XIP, for NOBH, and for normal.
2521+Since aufs overrides and redirects these operations, sometimes aufs has
2522+to change its behaviour according to the branch FS type. More importantly
2523+VFS acts differently if a function (member in the struct) is set or
2524+not. It means aufs should have several sets of operations and select one
2525+among them according to the branch FS definition.
2526+
2527+In order to solve this problem and not to affect the behaviour of VFS,
2528+aufs defines these operations dynamically. For instance, aufs defines
2529+dummy direct_IO function for struct address_space_operations, but it may
2530+not be set to the address_space_operations actually. When the branch FS
2531+doesn't have it, aufs doesn't set it to its address_space_operations
2532+while the function definition itself is still alive. So the behaviour
2533+itself will not change, and it will return an error when direct_IO is
2534+not set.
2535+
2536+The lifetime of these dynamically generated operation object is
2537+maintained by aufs branch object. When the branch is removed from aufs,
2538+the reference counter of the object is decremented. When it reaches
2539+zero, the dynamically generated operation object will be freed.
2540+
2541+This approach is designed to support AIO (io_submit), Direct I/O and
2542+XIP (DAX) mainly.
2543+Currently this approach is applied to address_space_operations for
2544+regular files only.
2545diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README
2546--- /usr/share/empty/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100
2547+++ linux/Documentation/filesystems/aufs/README 2020-01-23 09:59:36.748660743 +0100
2548@@ -0,0 +1,401 @@
2549+
2550+Aufs5 -- advanced multi layered unification filesystem version 5.x
2551+http://aufs.sf.net
2552+Junjiro R. Okajima
2553+
2554+
2555+0. Introduction
2556+----------------------------------------
2557+In the early days, aufs was entirely re-designed and re-implemented
2558+Unionfs Version 1.x series. Adding many original ideas, approaches,
2559+improvements and implementations, it became totally different from
2560+Unionfs while keeping the basic features.
2561+Later, Unionfs Version 2.x series began taking some of the same
2562+approaches to aufs1's.
2563+Unionfs was being developed by Professor Erez Zadok at Stony Brook
2564+University and his team.
2565+
2566+Aufs5 supports linux-v5.0 and later, If you want older kernel version
2567+support,
2568+- for linux-v4.x series, try aufs4-linux.git or aufs4-standalone.git
2569+- for linux-v3.x series, try aufs3-linux.git or aufs3-standalone.git
2570+- for linux-v2.6.16 and later, try aufs2-2.6.git, aufs2-standalone.git
2571+ or aufs1 from CVS on SourceForge.
2572+
2573+Note: it becomes clear that "Aufs was rejected. Let's give it up."
2574+ According to Christoph Hellwig, linux rejects all union-type
2575+ filesystems but UnionMount.
2576+<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
2577+
2578+PS. Al Viro seems have a plan to merge aufs as well as overlayfs and
2579+ UnionMount, and he pointed out an issue around a directory mutex
2580+ lock and aufs addressed it. But it is still unsure whether aufs will
2581+ be merged (or any other union solution).
2582+<http://marc.info/?l=linux-kernel&m=136312705029295&w=1>
2583+
2584+
2585+1. Features
2586+----------------------------------------
2587+- unite several directories into a single virtual filesystem. The member
2588+ directory is called as a branch.
2589+- you can specify the permission flags to the branch, which are 'readonly',
2590+ 'readwrite' and 'whiteout-able.'
2591+- by upper writable branch, internal copyup and whiteout, files/dirs on
2592+ readonly branch are modifiable logically.
2593+- dynamic branch manipulation, add, del.
2594+- etc...
2595+
2596+Also there are many enhancements in aufs, such as:
2597+- test only the highest one for the directory permission (dirperm1)
2598+- copyup on open (coo=)
2599+- 'move' policy for copy-up between two writable branches, after
2600+ checking free space.
2601+- xattr, acl
2602+- readdir(3) in userspace.
2603+- keep inode number by external inode number table
2604+- keep the timestamps of file/dir in internal copyup operation
2605+- seekable directory, supporting NFS readdir.
2606+- whiteout is hardlinked in order to reduce the consumption of inodes
2607+ on branch
2608+- do not copyup, nor create a whiteout when it is unnecessary
2609+- revert a single systemcall when an error occurs in aufs
2610+- remount interface instead of ioctl
2611+- maintain /etc/mtab by an external command, /sbin/mount.aufs.
2612+- loopback mounted filesystem as a branch
2613+- kernel thread for removing the dir who has a plenty of whiteouts
2614+- support copyup sparse file (a file which has a 'hole' in it)
2615+- default permission flags for branches
2616+- selectable permission flags for ro branch, whether whiteout can
2617+ exist or not
2618+- export via NFS.
2619+- support <sysfs>/fs/aufs and <debugfs>/aufs.
2620+- support multiple writable branches, some policies to select one
2621+ among multiple writable branches.
2622+- a new semantics for link(2) and rename(2) to support multiple
2623+ writable branches.
2624+- no glibc changes are required.
2625+- pseudo hardlink (hardlink over branches)
2626+- allow a direct access manually to a file on branch, e.g. bypassing aufs.
2627+ including NFS or remote filesystem branch.
2628+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
2629+- and more...
2630+
2631+Currently these features are dropped temporary from aufs5.
2632+See design/08plan.txt in detail.
2633+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
2634+ (robr)
2635+- statistics of aufs thread (/sys/fs/aufs/stat)
2636+
2637+Features or just an idea in the future (see also design/*.txt),
2638+- reorder the branch index without del/re-add.
2639+- permanent xino files for NFSD
2640+- an option for refreshing the opened files after add/del branches
2641+- light version, without branch manipulation. (unnecessary?)
2642+- copyup in userspace
2643+- inotify in userspace
2644+- readv/writev
2645+
2646+
2647+2. Download
2648+----------------------------------------
2649+There are three GIT trees for aufs5, aufs5-linux.git,
2650+aufs5-standalone.git, and aufs-util.git. Note that there is no "5" in
2651+"aufs-util.git."
2652+While the aufs-util is always necessary, you need either of aufs5-linux
2653+or aufs5-standalone.
2654+
2655+The aufs5-linux tree includes the whole linux mainline GIT tree,
2656+git://git.kernel.org/.../torvalds/linux.git.
2657+And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
2658+build aufs5 as an external kernel module.
2659+Several extra patches are not included in this tree. Only
2660+aufs5-standalone tree contains them. They are described in the later
2661+section "Configuration and Compilation."
2662+
2663+On the other hand, the aufs5-standalone tree has only aufs source files
2664+and necessary patches, and you can select CONFIG_AUFS_FS=m.
2665+But you need to apply all aufs patches manually.
2666+
2667+You will find GIT branches whose name is in form of "aufs5.x" where "x"
2668+represents the linux kernel version, "linux-5.x". For instance,
2669+"aufs5.0" is for linux-5.0. For latest "linux-5.x-rcN", use
2670+"aufs5.x-rcN" branch.
2671+
2672+o aufs5-linux tree
2673+$ git clone --reference /your/linux/git/tree \
2674+ git://github.com/sfjro/aufs5-linux.git aufs5-linux.git
2675+- if you don't have linux GIT tree, then remove "--reference ..."
2676+$ cd aufs5-linux.git
2677+$ git checkout origin/aufs5.0
2678+
2679+Or You may want to directly git-pull aufs into your linux GIT tree, and
2680+leave the patch-work to GIT.
2681+$ cd /your/linux/git/tree
2682+$ git remote add aufs5 git://github.com/sfjro/aufs5-linux.git
2683+$ git fetch aufs5
2684+$ git checkout -b my5.0 v5.0
2685+$ (add your local change...)
2686+$ git pull aufs5 aufs5.0
2687+- now you have v5.0 + your_changes + aufs5.0 in you my5.0 branch.
2688+- you may need to solve some conflicts between your_changes and
2689+ aufs5.0. in this case, git-rerere is recommended so that you can
2690+ solve the similar conflicts automatically when you upgrade to 5.1 or
2691+ later in the future.
2692+
2693+o aufs5-standalone tree
2694+$ git clone git://github.com/sfjro/aufs5-standalone.git aufs5-standalone.git
2695+$ cd aufs5-standalone.git
2696+$ git checkout origin/aufs5.0
2697+
2698+o aufs-util tree
2699+$ git clone git://git.code.sf.net/p/aufs/aufs-util aufs-util.git
2700+- note that the public aufs-util.git is on SourceForge instead of
2701+ GitHUB.
2702+$ cd aufs-util.git
2703+$ git checkout origin/aufs5.0
2704+
2705+Note: The 5.x-rcN branch is to be used with `rc' kernel versions ONLY.
2706+The minor version number, 'x' in '5.x', of aufs may not always
2707+follow the minor version number of the kernel.
2708+Because changes in the kernel that cause the use of a new
2709+minor version number do not always require changes to aufs-util.
2710+
2711+Since aufs-util has its own minor version number, you may not be
2712+able to find a GIT branch in aufs-util for your kernel's
2713+exact minor version number.
2714+In this case, you should git-checkout the branch for the
2715+nearest lower number.
2716+
2717+For (an unreleased) example:
2718+If you are using "linux-5.10" and the "aufs5.10" branch
2719+does not exist in aufs-util repository, then "aufs5.9", "aufs5.8"
2720+or something numerically smaller is the branch for your kernel.
2721+
2722+Also you can view all branches by
2723+ $ git branch -a
2724+
2725+
2726+3. Configuration and Compilation
2727+----------------------------------------
2728+Make sure you have git-checkout'ed the correct branch.
2729+
2730+For aufs5-linux tree,
2731+- enable CONFIG_AUFS_FS.
2732+- set other aufs configurations if necessary.
2733+
2734+For aufs5-standalone tree,
2735+There are several ways to build.
2736+
2737+1.
2738+- apply ./aufs5-kbuild.patch to your kernel source files.
2739+- apply ./aufs5-base.patch too.
2740+- apply ./aufs5-mmap.patch too.
2741+- apply ./aufs5-standalone.patch too, if you have a plan to set
2742+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs5-standalone.patch.
2743+- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
2744+ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
2745+- enable CONFIG_AUFS_FS, you can select either
2746+ =m or =y.
2747+- and build your kernel as usual.
2748+- install the built kernel.
2749+- install the header files too by "make headers_install" to the
2750+ directory where you specify. By default, it is $PWD/usr.
2751+ "make help" shows a brief note for headers_install.
2752+- and reboot your system.
2753+
2754+2.
2755+- module only (CONFIG_AUFS_FS=m).
2756+- apply ./aufs5-base.patch to your kernel source files.
2757+- apply ./aufs5-mmap.patch too.
2758+- apply ./aufs5-standalone.patch too.
2759+- build your kernel, don't forget "make headers_install", and reboot.
2760+- edit ./config.mk and set other aufs configurations if necessary.
2761+ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
2762+ every aufs configurations.
2763+- build the module by simple "make".
2764+- you can specify ${KDIR} make variable which points to your kernel
2765+ source tree.
2766+- install the files
2767+ + run "make install" to install the aufs module, or copy the built
2768+ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply).
2769+ + run "make install_headers" (instead of headers_install) to install
2770+ the modified aufs header file (you can specify DESTDIR which is
2771+ available in aufs standalone version's Makefile only), or copy
2772+ $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever
2773+ you like manually. By default, the target directory is $PWD/usr.
2774+- no need to apply aufs5-kbuild.patch, nor copying source files to your
2775+ kernel source tree.
2776+
2777+Note: The header file aufs_type.h is necessary to build aufs-util
2778+ as well as "make headers_install" in the kernel source tree.
2779+ headers_install is subject to be forgotten, but it is essentially
2780+ necessary, not only for building aufs-util.
2781+ You may not meet problems without headers_install in some older
2782+ version though.
2783+
2784+And then,
2785+- read README in aufs-util, build and install it
2786+- note that your distribution may contain an obsoleted version of
2787+ aufs_type.h in /usr/include/linux or something. When you build aufs
2788+ utilities, make sure that your compiler refers the correct aufs header
2789+ file which is built by "make headers_install."
2790+- if you want to use readdir(3) in userspace or pathconf(3) wrapper,
2791+ then run "make install_ulib" too. And refer to the aufs manual in
2792+ detail.
2793+
2794+There several other patches in aufs5-standalone.git. They are all
2795+optional. When you meet some problems, they will help you.
2796+- aufs5-loopback.patch
2797+ Supports a nested loopback mount in a branch-fs. This patch is
2798+ unnecessary until aufs produces a message like "you may want to try
2799+ another patch for loopback file".
2800+- proc_mounts.patch
2801+ When there are many mountpoints and many mount(2)/umount(2) are
2802+ running, then /proc/mounts may not show the all mountpoints. This
2803+ patch makes /proc/mounts always show the full mountpoints list.
2804+ If you don't want to apply this patch and meet such problem, then you
2805+ need to increase the value of 'ProcMounts_Times' make-variable in
2806+ aufs-util.git as a second best solution.
2807+- vfs-ino.patch
2808+ Modifies a system global kernel internal function get_next_ino() in
2809+ order to stop assigning 0 for an inode-number. Not directly related to
2810+ aufs, but recommended generally.
2811+- tmpfs-idr.patch
2812+ Keeps the tmpfs inode number as the lowest value. Effective to reduce
2813+ the size of aufs XINO files for tmpfs branch. Also it prevents the
2814+ duplication of inode number, which is important for backup tools and
2815+ other utilities. When you find aufs XINO files for tmpfs branch
2816+ growing too much, try this patch.
2817+- lockdep-debug.patch
2818+ Because aufs is not only an ordinary filesystem (callee of VFS), but
2819+ also a caller of VFS functions for branch filesystems, subclassing of
2820+ the internal locks for LOCKDEP is necessary. LOCKDEP is a debugging
2821+ feature of linux kernel. If you enable CONFIG_LOCKDEP, then you will
2822+ need to apply this debug patch to expand several constant values.
2823+ If you don't know what LOCKDEP is, then you don't have apply this
2824+ patch.
2825+
2826+
2827+4. Usage
2828+----------------------------------------
2829+At first, make sure aufs-util are installed, and please read the aufs
2830+manual, aufs.5 in aufs-util.git tree.
2831+$ man -l aufs.5
2832+
2833+And then,
2834+$ mkdir /tmp/rw /tmp/aufs
2835+# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs
2836+
2837+Here is another example. The result is equivalent.
2838+# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
2839+ Or
2840+# mount -t aufs -o br:/tmp/rw none /tmp/aufs
2841+# mount -o remount,append:${HOME} /tmp/aufs
2842+
2843+Then, you can see whole tree of your home dir through /tmp/aufs. If
2844+you modify a file under /tmp/aufs, the one on your home directory is
2845+not affected, instead the same named file will be newly created under
2846+/tmp/rw. And all of your modification to a file will be applied to
2847+the one under /tmp/rw. This is called the file based Copy on Write
2848+(COW) method.
2849+Aufs mount options are described in aufs.5.
2850+If you run chroot or something and make your aufs as a root directory,
2851+then you need to customize the shutdown script. See the aufs manual in
2852+detail.
2853+
2854+Additionally, there are some sample usages of aufs which are a
2855+diskless system with network booting, and LiveCD over NFS.
2856+See sample dir in CVS tree on SourceForge.
2857+
2858+
2859+5. Contact
2860+----------------------------------------
2861+When you have any problems or strange behaviour in aufs, please let me
2862+know with:
2863+- /proc/mounts (instead of the output of mount(8))
2864+- /sys/module/aufs/*
2865+- /sys/fs/aufs/* (if you have them)
2866+- /debug/aufs/* (if you have them)
2867+- linux kernel version
2868+ if your kernel is not plain, for example modified by distributor,
2869+ the url where i can download its source is necessary too.
2870+- aufs version which was printed at loading the module or booting the
2871+ system, instead of the date you downloaded.
2872+- configuration (define/undefine CONFIG_AUFS_xxx)
2873+- kernel configuration or /proc/config.gz (if you have it)
2874+- LSM (linux security module, if you are using)
2875+- behaviour which you think to be incorrect
2876+- actual operation, reproducible one is better
2877+- mailto: aufs-users at lists.sourceforge.net
2878+
2879+Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches,
2880+and Feature Requests) on SourceForge. Please join and write to
2881+aufs-users ML.
2882+
2883+
2884+6. Acknowledgements
2885+----------------------------------------
2886+Thanks to everyone who have tried and are using aufs, whoever
2887+have reported a bug or any feedback.
2888+
2889+Especially donators:
2890+Tomas Matejicek(slax.org) made a donation (much more than once).
2891+ Since Apr 2010, Tomas M (the author of Slax and Linux Live
2892+ scripts) is making "doubling" donations.
2893+ Unfortunately I cannot list all of the donators, but I really
2894+ appreciate.
2895+ It ends Aug 2010, but the ordinary donation URL is still available.
2896+ <http://sourceforge.net/donate/index.php?group_id=167503>
2897+Dai Itasaka made a donation (2007/8).
2898+Chuck Smith made a donation (2008/4, 10 and 12).
2899+Henk Schoneveld made a donation (2008/9).
2900+Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10).
2901+Francois Dupoux made a donation (2008/11).
2902+Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public
2903+ aufs2 GIT tree (2009/2).
2904+William Grant made a donation (2009/3).
2905+Patrick Lane made a donation (2009/4).
2906+The Mail Archive (mail-archive.com) made donations (2009/5).
2907+Nippy Networks (Ed Wildgoose) made a donation (2009/7).
2908+New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11).
2909+Pavel Pronskiy made a donation (2011/2).
2910+Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy
2911+ Networks (Ed Wildgoose) made a donation for hardware (2011/3).
2912+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
2913+11).
2914+Sam Liddicott made a donation (2011/9).
2915+Era Scarecrow made a donation (2013/4).
2916+Bor Ratajc made a donation (2013/4).
2917+Alessandro Gorreta made a donation (2013/4).
2918+POIRETTE Marc made a donation (2013/4).
2919+Alessandro Gorreta made a donation (2013/4).
2920+lauri kasvandik made a donation (2013/5).
2921+"pemasu from Finland" made a donation (2013/7).
2922+The Parted Magic Project made a donation (2013/9 and 11).
2923+Pavel Barta made a donation (2013/10).
2924+Nikolay Pertsev made a donation (2014/5).
2925+James B made a donation (2014/7 and 2015/7).
2926+Stefano Di Biase made a donation (2014/8).
2927+Daniel Epellei made a donation (2015/1).
2928+OmegaPhil made a donation (2016/1, 2018/4).
2929+Tomasz Szewczyk made a donation (2016/4).
2930+James Burry made a donation (2016/12).
2931+Carsten Rose made a donation (2018/9).
2932+Porteus Kiosk made a donation (2018/10).
2933+
2934+Thank you very much.
2935+Donations are always, including future donations, very important and
2936+helpful for me to keep on developing aufs.
2937+
2938+
2939+7.
2940+----------------------------------------
2941+If you are an experienced user, no explanation is needed. Aufs is
2942+just a linux filesystem.
2943+
2944+
2945+Enjoy!
2946+
2947+# Local variables: ;
2948+# mode: text;
2949+# End: ;
2950diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
2951--- /usr/share/empty/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100
2952+++ linux/fs/aufs/aufs.h 2020-01-27 10:57:18.165538015 +0100
2953@@ -0,0 +1,62 @@
2954+/* SPDX-License-Identifier: GPL-2.0 */
2955+/*
2956+ * Copyright (C) 2005-2020 Junjiro R. Okajima
2957+ *
2958+ * This program, aufs is free software; you can redistribute it and/or modify
2959+ * it under the terms of the GNU General Public License as published by
2960+ * the Free Software Foundation; either version 2 of the License, or
2961+ * (at your option) any later version.
2962+ *
2963+ * This program is distributed in the hope that it will be useful,
2964+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2965+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2966+ * GNU General Public License for more details.
2967+ *
2968+ * You should have received a copy of the GNU General Public License
2969+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2970+ */
2971+
2972+/*
2973+ * all header files
2974+ */
2975+
2976+#ifndef __AUFS_H__
2977+#define __AUFS_H__
2978+
2979+#ifdef __KERNEL__
2980+
2981+#define AuStub(type, name, body, ...) \
2982+ static inline type name(__VA_ARGS__) { body; }
2983+
2984+#define AuStubVoid(name, ...) \
2985+ AuStub(void, name, , __VA_ARGS__)
2986+#define AuStubInt0(name, ...) \
2987+ AuStub(int, name, return 0, __VA_ARGS__)
2988+
2989+#include "debug.h"
2990+
2991+#include "branch.h"
2992+#include "cpup.h"
2993+#include "dcsub.h"
2994+#include "dbgaufs.h"
2995+#include "dentry.h"
2996+#include "dir.h"
2997+#include "dirren.h"
2998+#include "dynop.h"
2999+#include "file.h"
3000+#include "fstype.h"
3001+#include "hbl.h"
3002+#include "inode.h"
3003+#include "lcnt.h"
3004+#include "loop.h"
3005+#include "module.h"
3006+#include "opts.h"
3007+#include "rwsem.h"
3008+#include "super.h"
3009+#include "sysaufs.h"
3010+#include "vfsub.h"
3011+#include "whout.h"
3012+#include "wkq.h"
3013+
3014+#endif /* __KERNEL__ */
3015+#endif /* __AUFS_H__ */
3016diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
3017--- /usr/share/empty/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100
3018+++ linux/fs/aufs/branch.c 2020-01-27 10:57:18.165538015 +0100
3019@@ -0,0 +1,1428 @@
3020+// SPDX-License-Identifier: GPL-2.0
3021+/*
3022+ * Copyright (C) 2005-2020 Junjiro R. Okajima
3023+ *
3024+ * This program, aufs is free software; you can redistribute it and/or modify
3025+ * it under the terms of the GNU General Public License as published by
3026+ * the Free Software Foundation; either version 2 of the License, or
3027+ * (at your option) any later version.
3028+ *
3029+ * This program is distributed in the hope that it will be useful,
3030+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3031+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3032+ * GNU General Public License for more details.
3033+ *
3034+ * You should have received a copy of the GNU General Public License
3035+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3036+ */
3037+
3038+/*
3039+ * branch management
3040+ */
3041+
3042+#include <linux/compat.h>
3043+#include <linux/statfs.h>
3044+#include "aufs.h"
3045+
3046+/*
3047+ * free a single branch
3048+ */
3049+static void au_br_do_free(struct au_branch *br)
3050+{
3051+ int i;
3052+ struct au_wbr *wbr;
3053+ struct au_dykey **key;
3054+
3055+ au_hnotify_fin_br(br);
3056+ /* always, regardless the mount option */
3057+ au_dr_hino_free(&br->br_dirren);
3058+ au_xino_put(br);
3059+
3060+ AuLCntZero(au_lcnt_read(&br->br_nfiles, /*do_rev*/0));
3061+ au_lcnt_fin(&br->br_nfiles, /*do_sync*/0);
3062+ AuLCntZero(au_lcnt_read(&br->br_count, /*do_rev*/0));
3063+ au_lcnt_fin(&br->br_count, /*do_sync*/0);
3064+
3065+ wbr = br->br_wbr;
3066+ if (wbr) {
3067+ for (i = 0; i < AuBrWh_Last; i++)
3068+ dput(wbr->wbr_wh[i]);
3069+ AuDebugOn(atomic_read(&wbr->wbr_wh_running));
3070+ AuRwDestroy(&wbr->wbr_wh_rwsem);
3071+ }
3072+
3073+ if (br->br_fhsm) {
3074+ au_br_fhsm_fin(br->br_fhsm);
3075+ au_kfree_try_rcu(br->br_fhsm);
3076+ }
3077+
3078+ key = br->br_dykey;
3079+ for (i = 0; i < AuBrDynOp; i++, key++)
3080+ if (*key)
3081+ au_dy_put(*key);
3082+ else
3083+ break;
3084+
3085+ /* recursive lock, s_umount of branch's */
3086+ /* synchronize_rcu(); */ /* why? */
3087+ lockdep_off();
3088+ path_put(&br->br_path);
3089+ lockdep_on();
3090+ au_kfree_rcu(wbr);
3091+ au_lcnt_wait_for_fin(&br->br_nfiles);
3092+ au_lcnt_wait_for_fin(&br->br_count);
3093+ /* I don't know why, but percpu_refcount requires this */
3094+ /* synchronize_rcu(); */
3095+ au_kfree_rcu(br);
3096+}
3097+
3098+/*
3099+ * frees all branches
3100+ */
3101+void au_br_free(struct au_sbinfo *sbinfo)
3102+{
3103+ aufs_bindex_t bmax;
3104+ struct au_branch **br;
3105+
3106+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3107+
3108+ bmax = sbinfo->si_bbot + 1;
3109+ br = sbinfo->si_branch;
3110+ while (bmax--)
3111+ au_br_do_free(*br++);
3112+}
3113+
3114+/*
3115+ * find the index of a branch which is specified by @br_id.
3116+ */
3117+int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
3118+{
3119+ aufs_bindex_t bindex, bbot;
3120+
3121+ bbot = au_sbbot(sb);
3122+ for (bindex = 0; bindex <= bbot; bindex++)
3123+ if (au_sbr_id(sb, bindex) == br_id)
3124+ return bindex;
3125+ return -1;
3126+}
3127+
3128+/* ---------------------------------------------------------------------- */
3129+
3130+/*
3131+ * add a branch
3132+ */
3133+
3134+static int test_overlap(struct super_block *sb, struct dentry *h_adding,
3135+ struct dentry *h_root)
3136+{
3137+ if (unlikely(h_adding == h_root
3138+ || au_test_loopback_overlap(sb, h_adding)))
3139+ return 1;
3140+ if (h_adding->d_sb != h_root->d_sb)
3141+ return 0;
3142+ return au_test_subdir(h_adding, h_root)
3143+ || au_test_subdir(h_root, h_adding);
3144+}
3145+
3146+/*
3147+ * returns a newly allocated branch. @new_nbranch is a number of branches
3148+ * after adding a branch.
3149+ */
3150+static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
3151+ int perm)
3152+{
3153+ struct au_branch *add_branch;
3154+ struct dentry *root;
3155+ struct inode *inode;
3156+ int err;
3157+
3158+ err = -ENOMEM;
3159+ add_branch = kzalloc(sizeof(*add_branch), GFP_NOFS);
3160+ if (unlikely(!add_branch))
3161+ goto out;
3162+ add_branch->br_xino = au_xino_alloc(/*nfile*/1);
3163+ if (unlikely(!add_branch->br_xino))
3164+ goto out_br;
3165+ err = au_hnotify_init_br(add_branch, perm);
3166+ if (unlikely(err))
3167+ goto out_xino;
3168+
3169+ if (au_br_writable(perm)) {
3170+ /* may be freed separately at changing the branch permission */
3171+ add_branch->br_wbr = kzalloc(sizeof(*add_branch->br_wbr),
3172+ GFP_NOFS);
3173+ if (unlikely(!add_branch->br_wbr))
3174+ goto out_hnotify;
3175+ }
3176+
3177+ if (au_br_fhsm(perm)) {
3178+ err = au_fhsm_br_alloc(add_branch);
3179+ if (unlikely(err))
3180+ goto out_wbr;
3181+ }
3182+
3183+ root = sb->s_root;
3184+ err = au_sbr_realloc(au_sbi(sb), new_nbranch, /*may_shrink*/0);
3185+ if (!err)
3186+ err = au_di_realloc(au_di(root), new_nbranch, /*may_shrink*/0);
3187+ if (!err) {
3188+ inode = d_inode(root);
3189+ err = au_hinode_realloc(au_ii(inode), new_nbranch,
3190+ /*may_shrink*/0);
3191+ }
3192+ if (!err)
3193+ return add_branch; /* success */
3194+
3195+out_wbr:
3196+ au_kfree_rcu(add_branch->br_wbr);
3197+out_hnotify:
3198+ au_hnotify_fin_br(add_branch);
3199+out_xino:
3200+ au_xino_put(add_branch);
3201+out_br:
3202+ au_kfree_rcu(add_branch);
3203+out:
3204+ return ERR_PTR(err);
3205+}
3206+
3207+/*
3208+ * test if the branch permission is legal or not.
3209+ */
3210+static int test_br(struct inode *inode, int brperm, char *path)
3211+{
3212+ int err;
3213+
3214+ err = (au_br_writable(brperm) && IS_RDONLY(inode));
3215+ if (!err)
3216+ goto out;
3217+
3218+ err = -EINVAL;
3219+ pr_err("write permission for readonly mount or inode, %s\n", path);
3220+
3221+out:
3222+ return err;
3223+}
3224+
3225+/*
3226+ * returns:
3227+ * 0: success, the caller will add it
3228+ * plus: success, it is already unified, the caller should ignore it
3229+ * minus: error
3230+ */
3231+static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
3232+{
3233+ int err;
3234+ aufs_bindex_t bbot, bindex;
3235+ struct dentry *root, *h_dentry;
3236+ struct inode *inode, *h_inode;
3237+
3238+ root = sb->s_root;
3239+ bbot = au_sbbot(sb);
3240+ if (unlikely(bbot >= 0
3241+ && au_find_dbindex(root, add->path.dentry) >= 0)) {
3242+ err = 1;
3243+ if (!remount) {
3244+ err = -EINVAL;
3245+ pr_err("%s duplicated\n", add->pathname);
3246+ }
3247+ goto out;
3248+ }
3249+
3250+ err = -ENOSPC; /* -E2BIG; */
3251+ if (unlikely(AUFS_BRANCH_MAX <= add->bindex
3252+ || AUFS_BRANCH_MAX - 1 <= bbot)) {
3253+ pr_err("number of branches exceeded %s\n", add->pathname);
3254+ goto out;
3255+ }
3256+
3257+ err = -EDOM;
3258+ if (unlikely(add->bindex < 0 || bbot + 1 < add->bindex)) {
3259+ pr_err("bad index %d\n", add->bindex);
3260+ goto out;
3261+ }
3262+
3263+ inode = d_inode(add->path.dentry);
3264+ err = -ENOENT;
3265+ if (unlikely(!inode->i_nlink)) {
3266+ pr_err("no existence %s\n", add->pathname);
3267+ goto out;
3268+ }
3269+
3270+ err = -EINVAL;
3271+ if (unlikely(inode->i_sb == sb)) {
3272+ pr_err("%s must be outside\n", add->pathname);
3273+ goto out;
3274+ }
3275+
3276+ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
3277+ pr_err("unsupported filesystem, %s (%s)\n",
3278+ add->pathname, au_sbtype(inode->i_sb));
3279+ goto out;
3280+ }
3281+
3282+ if (unlikely(inode->i_sb->s_stack_depth)) {
3283+ pr_err("already stacked, %s (%s)\n",
3284+ add->pathname, au_sbtype(inode->i_sb));
3285+ goto out;
3286+ }
3287+
3288+ err = test_br(d_inode(add->path.dentry), add->perm, add->pathname);
3289+ if (unlikely(err))
3290+ goto out;
3291+
3292+ if (bbot < 0)
3293+ return 0; /* success */
3294+
3295+ err = -EINVAL;
3296+ for (bindex = 0; bindex <= bbot; bindex++)
3297+ if (unlikely(test_overlap(sb, add->path.dentry,
3298+ au_h_dptr(root, bindex)))) {
3299+ pr_err("%s is overlapped\n", add->pathname);
3300+ goto out;
3301+ }
3302+
3303+ err = 0;
3304+ if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
3305+ h_dentry = au_h_dptr(root, 0);
3306+ h_inode = d_inode(h_dentry);
3307+ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
3308+ || !uid_eq(h_inode->i_uid, inode->i_uid)
3309+ || !gid_eq(h_inode->i_gid, inode->i_gid))
3310+ pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
3311+ add->pathname,
3312+ i_uid_read(inode), i_gid_read(inode),
3313+ (inode->i_mode & S_IALLUGO),
3314+ i_uid_read(h_inode), i_gid_read(h_inode),
3315+ (h_inode->i_mode & S_IALLUGO));
3316+ }
3317+
3318+out:
3319+ return err;
3320+}
3321+
3322+/*
3323+ * initialize or clean the whiteouts for an adding branch
3324+ */
3325+static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
3326+ int new_perm)
3327+{
3328+ int err, old_perm;
3329+ aufs_bindex_t bindex;
3330+ struct inode *h_inode;
3331+ struct au_wbr *wbr;
3332+ struct au_hinode *hdir;
3333+ struct dentry *h_dentry;
3334+
3335+ err = vfsub_mnt_want_write(au_br_mnt(br));
3336+ if (unlikely(err))
3337+ goto out;
3338+
3339+ wbr = br->br_wbr;
3340+ old_perm = br->br_perm;
3341+ br->br_perm = new_perm;
3342+ hdir = NULL;
3343+ h_inode = NULL;
3344+ bindex = au_br_index(sb, br->br_id);
3345+ if (0 <= bindex) {
3346+ hdir = au_hi(d_inode(sb->s_root), bindex);
3347+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
3348+ } else {
3349+ h_dentry = au_br_dentry(br);
3350+ h_inode = d_inode(h_dentry);
3351+ inode_lock_nested(h_inode, AuLsc_I_PARENT);
3352+ }
3353+ if (!wbr)
3354+ err = au_wh_init(br, sb);
3355+ else {
3356+ wbr_wh_write_lock(wbr);
3357+ err = au_wh_init(br, sb);
3358+ wbr_wh_write_unlock(wbr);
3359+ }
3360+ if (hdir)
3361+ au_hn_inode_unlock(hdir);
3362+ else
3363+ inode_unlock(h_inode);
3364+ vfsub_mnt_drop_write(au_br_mnt(br));
3365+ br->br_perm = old_perm;
3366+
3367+ if (!err && wbr && !au_br_writable(new_perm)) {
3368+ au_kfree_rcu(wbr);
3369+ br->br_wbr = NULL;
3370+ }
3371+
3372+out:
3373+ return err;
3374+}
3375+
3376+static int au_wbr_init(struct au_branch *br, struct super_block *sb,
3377+ int perm)
3378+{
3379+ int err;
3380+ struct kstatfs kst;
3381+ struct au_wbr *wbr;
3382+
3383+ wbr = br->br_wbr;
3384+ au_rw_init(&wbr->wbr_wh_rwsem);
3385+ atomic_set(&wbr->wbr_wh_running, 0);
3386+
3387+ /*
3388+ * a limit for rmdir/rename a dir
3389+ * cf. AUFS_MAX_NAMELEN in include/uapi/linux/aufs_type.h
3390+ */
3391+ err = vfs_statfs(&br->br_path, &kst);
3392+ if (unlikely(err))
3393+ goto out;
3394+ err = -EINVAL;
3395+ if (kst.f_namelen >= NAME_MAX)
3396+ err = au_br_init_wh(sb, br, perm);
3397+ else
3398+ pr_err("%pd(%s), unsupported namelen %ld\n",
3399+ au_br_dentry(br),
3400+ au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen);
3401+
3402+out:
3403+ return err;
3404+}
3405+
3406+/* initialize a new branch */
3407+static int au_br_init(struct au_branch *br, struct super_block *sb,
3408+ struct au_opt_add *add)
3409+{
3410+ int err;
3411+ struct au_branch *brbase;
3412+ struct file *xf;
3413+ struct inode *h_inode;
3414+
3415+ err = 0;
3416+ br->br_perm = add->perm;
3417+ br->br_path = add->path; /* set first, path_get() later */
3418+ spin_lock_init(&br->br_dykey_lock);
3419+ au_lcnt_init(&br->br_nfiles, /*release*/NULL);
3420+ au_lcnt_init(&br->br_count, /*release*/NULL);
3421+ br->br_id = au_new_br_id(sb);
3422+ AuDebugOn(br->br_id < 0);
3423+
3424+ /* always, regardless the given option */
3425+ err = au_dr_br_init(sb, br, &add->path);
3426+ if (unlikely(err))
3427+ goto out_err;
3428+
3429+ if (au_br_writable(add->perm)) {
3430+ err = au_wbr_init(br, sb, add->perm);
3431+ if (unlikely(err))
3432+ goto out_err;
3433+ }
3434+
3435+ if (au_opt_test(au_mntflags(sb), XINO)) {
3436+ brbase = au_sbr(sb, 0);
3437+ xf = au_xino_file(brbase->br_xino, /*idx*/-1);
3438+ AuDebugOn(!xf);
3439+ h_inode = d_inode(add->path.dentry);
3440+ err = au_xino_init_br(sb, br, h_inode->i_ino, &xf->f_path);
3441+ if (unlikely(err)) {
3442+ AuDebugOn(au_xino_file(br->br_xino, /*idx*/-1));
3443+ goto out_err;
3444+ }
3445+ }
3446+
3447+ sysaufs_br_init(br);
3448+ path_get(&br->br_path);
3449+ goto out; /* success */
3450+
3451+out_err:
3452+ memset(&br->br_path, 0, sizeof(br->br_path));
3453+out:
3454+ return err;
3455+}
3456+
3457+static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
3458+ struct au_branch *br, aufs_bindex_t bbot,
3459+ aufs_bindex_t amount)
3460+{
3461+ struct au_branch **brp;
3462+
3463+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3464+
3465+ brp = sbinfo->si_branch + bindex;
3466+ memmove(brp + 1, brp, sizeof(*brp) * amount);
3467+ *brp = br;
3468+ sbinfo->si_bbot++;
3469+ if (unlikely(bbot < 0))
3470+ sbinfo->si_bbot = 0;
3471+}
3472+
3473+static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
3474+ aufs_bindex_t bbot, aufs_bindex_t amount)
3475+{
3476+ struct au_hdentry *hdp;
3477+
3478+ AuRwMustWriteLock(&dinfo->di_rwsem);
3479+
3480+ hdp = au_hdentry(dinfo, bindex);
3481+ memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
3482+ au_h_dentry_init(hdp);
3483+ dinfo->di_bbot++;
3484+ if (unlikely(bbot < 0))
3485+ dinfo->di_btop = 0;
3486+}
3487+
3488+static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
3489+ aufs_bindex_t bbot, aufs_bindex_t amount)
3490+{
3491+ struct au_hinode *hip;
3492+
3493+ AuRwMustWriteLock(&iinfo->ii_rwsem);
3494+
3495+ hip = au_hinode(iinfo, bindex);
3496+ memmove(hip + 1, hip, sizeof(*hip) * amount);
3497+ au_hinode_init(hip);
3498+ iinfo->ii_bbot++;
3499+ if (unlikely(bbot < 0))
3500+ iinfo->ii_btop = 0;
3501+}
3502+
3503+static void au_br_do_add(struct super_block *sb, struct au_branch *br,
3504+ aufs_bindex_t bindex)
3505+{
3506+ struct dentry *root, *h_dentry;
3507+ struct inode *root_inode, *h_inode;
3508+ aufs_bindex_t bbot, amount;
3509+
3510+ root = sb->s_root;
3511+ root_inode = d_inode(root);
3512+ bbot = au_sbbot(sb);
3513+ amount = bbot + 1 - bindex;
3514+ h_dentry = au_br_dentry(br);
3515+ au_sbilist_lock();
3516+ au_br_do_add_brp(au_sbi(sb), bindex, br, bbot, amount);
3517+ au_br_do_add_hdp(au_di(root), bindex, bbot, amount);
3518+ au_br_do_add_hip(au_ii(root_inode), bindex, bbot, amount);
3519+ au_set_h_dptr(root, bindex, dget(h_dentry));
3520+ h_inode = d_inode(h_dentry);
3521+ au_set_h_iptr(root_inode, bindex, au_igrab(h_inode), /*flags*/0);
3522+ au_sbilist_unlock();
3523+}
3524+
3525+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
3526+{
3527+ int err;
3528+ aufs_bindex_t bbot, add_bindex;
3529+ struct dentry *root, *h_dentry;
3530+ struct inode *root_inode;
3531+ struct au_branch *add_branch;
3532+
3533+ root = sb->s_root;
3534+ root_inode = d_inode(root);
3535+ IMustLock(root_inode);
3536+ IiMustWriteLock(root_inode);
3537+ err = test_add(sb, add, remount);
3538+ if (unlikely(err < 0))
3539+ goto out;
3540+ if (err) {
3541+ err = 0;
3542+ goto out; /* success */
3543+ }
3544+
3545+ bbot = au_sbbot(sb);
3546+ add_branch = au_br_alloc(sb, bbot + 2, add->perm);
3547+ err = PTR_ERR(add_branch);
3548+ if (IS_ERR(add_branch))
3549+ goto out;
3550+
3551+ err = au_br_init(add_branch, sb, add);
3552+ if (unlikely(err)) {
3553+ au_br_do_free(add_branch);
3554+ goto out;
3555+ }
3556+
3557+ add_bindex = add->bindex;
3558+ sysaufs_brs_del(sb, add_bindex); /* remove successors */
3559+ au_br_do_add(sb, add_branch, add_bindex);
3560+ sysaufs_brs_add(sb, add_bindex); /* append successors */
3561+ dbgaufs_brs_add(sb, add_bindex, /*topdown*/0); /* rename successors */
3562+
3563+ h_dentry = add->path.dentry;
3564+ if (!add_bindex) {
3565+ au_cpup_attr_all(root_inode, /*force*/1);
3566+ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
3567+ } else
3568+ au_add_nlink(root_inode, d_inode(h_dentry));
3569+
3570+out:
3571+ return err;
3572+}
3573+
3574+/* ---------------------------------------------------------------------- */
3575+
3576+static unsigned long long au_farray_cb(struct super_block *sb, void *a,
3577+ unsigned long long max __maybe_unused,
3578+ void *arg)
3579+{
3580+ unsigned long long n;
3581+ struct file **p, *f;
3582+ struct hlist_bl_head *files;
3583+ struct hlist_bl_node *pos;
3584+ struct au_finfo *finfo;
3585+
3586+ n = 0;
3587+ p = a;
3588+ files = &au_sbi(sb)->si_files;
3589+ hlist_bl_lock(files);
3590+ hlist_bl_for_each_entry(finfo, pos, files, fi_hlist) {
3591+ f = finfo->fi_file;
3592+ if (file_count(f)
3593+ && !special_file(file_inode(f)->i_mode)) {
3594+ get_file(f);
3595+ *p++ = f;
3596+ n++;
3597+ AuDebugOn(n > max);
3598+ }
3599+ }
3600+ hlist_bl_unlock(files);
3601+
3602+ return n;
3603+}
3604+
3605+static struct file **au_farray_alloc(struct super_block *sb,
3606+ unsigned long long *max)
3607+{
3608+ struct au_sbinfo *sbi;
3609+
3610+ sbi = au_sbi(sb);
3611+ *max = au_lcnt_read(&sbi->si_nfiles, /*do_rev*/1);
3612+ return au_array_alloc(max, au_farray_cb, sb, /*arg*/NULL);
3613+}
3614+
3615+static void au_farray_free(struct file **a, unsigned long long max)
3616+{
3617+ unsigned long long ull;
3618+
3619+ for (ull = 0; ull < max; ull++)
3620+ if (a[ull])
3621+ fput(a[ull]);
3622+ kvfree(a);
3623+}
3624+
3625+/* ---------------------------------------------------------------------- */
3626+
3627+/*
3628+ * delete a branch
3629+ */
3630+
3631+/* to show the line number, do not make it inlined function */
3632+#define AuVerbose(do_info, fmt, ...) do { \
3633+ if (do_info) \
3634+ pr_info(fmt, ##__VA_ARGS__); \
3635+} while (0)
3636+
3637+static int au_test_ibusy(struct inode *inode, aufs_bindex_t btop,
3638+ aufs_bindex_t bbot)
3639+{
3640+ return (inode && !S_ISDIR(inode->i_mode)) || btop == bbot;
3641+}
3642+
3643+static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t btop,
3644+ aufs_bindex_t bbot)
3645+{
3646+ return au_test_ibusy(d_inode(dentry), btop, bbot);
3647+}
3648+
3649+/*
3650+ * test if the branch is deletable or not.
3651+ */
3652+static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
3653+ unsigned int sigen, const unsigned int verbose)
3654+{
3655+ int err, i, j, ndentry;
3656+ aufs_bindex_t btop, bbot;
3657+ struct au_dcsub_pages dpages;
3658+ struct au_dpage *dpage;
3659+ struct dentry *d;
3660+
3661+ err = au_dpages_init(&dpages, GFP_NOFS);
3662+ if (unlikely(err))
3663+ goto out;
3664+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
3665+ if (unlikely(err))
3666+ goto out_dpages;
3667+
3668+ for (i = 0; !err && i < dpages.ndpage; i++) {
3669+ dpage = dpages.dpages + i;
3670+ ndentry = dpage->ndentry;
3671+ for (j = 0; !err && j < ndentry; j++) {
3672+ d = dpage->dentries[j];
3673+ AuDebugOn(au_dcount(d) <= 0);
3674+ if (!au_digen_test(d, sigen)) {
3675+ di_read_lock_child(d, AuLock_IR);
3676+ if (unlikely(au_dbrange_test(d))) {
3677+ di_read_unlock(d, AuLock_IR);
3678+ continue;
3679+ }
3680+ } else {
3681+ di_write_lock_child(d);
3682+ if (unlikely(au_dbrange_test(d))) {
3683+ di_write_unlock(d);
3684+ continue;
3685+ }
3686+ err = au_reval_dpath(d, sigen);
3687+ if (!err)
3688+ di_downgrade_lock(d, AuLock_IR);
3689+ else {
3690+ di_write_unlock(d);
3691+ break;
3692+ }
3693+ }
3694+
3695+ /* AuDbgDentry(d); */
3696+ btop = au_dbtop(d);
3697+ bbot = au_dbbot(d);
3698+ if (btop <= bindex
3699+ && bindex <= bbot
3700+ && au_h_dptr(d, bindex)
3701+ && au_test_dbusy(d, btop, bbot)) {
3702+ err = -EBUSY;
3703+ AuVerbose(verbose, "busy %pd\n", d);
3704+ AuDbgDentry(d);
3705+ }
3706+ di_read_unlock(d, AuLock_IR);
3707+ }
3708+ }
3709+
3710+out_dpages:
3711+ au_dpages_free(&dpages);
3712+out:
3713+ return err;
3714+}
3715+
3716+static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
3717+ unsigned int sigen, const unsigned int verbose)
3718+{
3719+ int err;
3720+ unsigned long long max, ull;
3721+ struct inode *i, **array;
3722+ aufs_bindex_t btop, bbot;
3723+
3724+ array = au_iarray_alloc(sb, &max);
3725+ err = PTR_ERR(array);
3726+ if (IS_ERR(array))
3727+ goto out;
3728+
3729+ err = 0;
3730+ AuDbg("b%d\n", bindex);
3731+ for (ull = 0; !err && ull < max; ull++) {
3732+ i = array[ull];
3733+ if (unlikely(!i))
3734+ break;
3735+ if (i->i_ino == AUFS_ROOT_INO)
3736+ continue;
3737+
3738+ /* AuDbgInode(i); */
3739+ if (au_iigen(i, NULL) == sigen)
3740+ ii_read_lock_child(i);
3741+ else {
3742+ ii_write_lock_child(i);
3743+ err = au_refresh_hinode_self(i);
3744+ au_iigen_dec(i);
3745+ if (!err)
3746+ ii_downgrade_lock(i);
3747+ else {
3748+ ii_write_unlock(i);
3749+ break;
3750+ }
3751+ }
3752+
3753+ btop = au_ibtop(i);
3754+ bbot = au_ibbot(i);
3755+ if (btop <= bindex
3756+ && bindex <= bbot
3757+ && au_h_iptr(i, bindex)
3758+ && au_test_ibusy(i, btop, bbot)) {
3759+ err = -EBUSY;
3760+ AuVerbose(verbose, "busy i%lu\n", i->i_ino);
3761+ AuDbgInode(i);
3762+ }
3763+ ii_read_unlock(i);
3764+ }
3765+ au_iarray_free(array, max);
3766+
3767+out:
3768+ return err;
3769+}
3770+
3771+static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
3772+ const unsigned int verbose)
3773+{
3774+ int err;
3775+ unsigned int sigen;
3776+
3777+ sigen = au_sigen(root->d_sb);
3778+ DiMustNoWaiters(root);
3779+ IiMustNoWaiters(d_inode(root));
3780+ di_write_unlock(root);
3781+ err = test_dentry_busy(root, bindex, sigen, verbose);
3782+ if (!err)
3783+ err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
3784+ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
3785+
3786+ return err;
3787+}
3788+
3789+static int test_dir_busy(struct file *file, aufs_bindex_t br_id,
3790+ struct file **to_free, int *idx)
3791+{
3792+ int err;
3793+ unsigned char matched, root;
3794+ aufs_bindex_t bindex, bbot;
3795+ struct au_fidir *fidir;
3796+ struct au_hfile *hfile;
3797+
3798+ err = 0;
3799+ root = IS_ROOT(file->f_path.dentry);
3800+ if (root) {
3801+ get_file(file);
3802+ to_free[*idx] = file;
3803+ (*idx)++;
3804+ goto out;
3805+ }
3806+
3807+ matched = 0;
3808+ fidir = au_fi(file)->fi_hdir;
3809+ AuDebugOn(!fidir);
3810+ bbot = au_fbbot_dir(file);
3811+ for (bindex = au_fbtop(file); bindex <= bbot; bindex++) {
3812+ hfile = fidir->fd_hfile + bindex;
3813+ if (!hfile->hf_file)
3814+ continue;
3815+
3816+ if (hfile->hf_br->br_id == br_id) {
3817+ matched = 1;
3818+ break;
3819+ }
3820+ }
3821+ if (matched)
3822+ err = -EBUSY;
3823+
3824+out:
3825+ return err;
3826+}
3827+
3828+static int test_file_busy(struct super_block *sb, aufs_bindex_t br_id,
3829+ struct file **to_free, int opened)
3830+{
3831+ int err, idx;
3832+ unsigned long long ull, max;
3833+ aufs_bindex_t btop;
3834+ struct file *file, **array;
3835+ struct dentry *root;
3836+ struct au_hfile *hfile;
3837+
3838+ array = au_farray_alloc(sb, &max);
3839+ err = PTR_ERR(array);
3840+ if (IS_ERR(array))
3841+ goto out;
3842+
3843+ err = 0;
3844+ idx = 0;
3845+ root = sb->s_root;
3846+ di_write_unlock(root);
3847+ for (ull = 0; ull < max; ull++) {
3848+ file = array[ull];
3849+ if (unlikely(!file))
3850+ break;
3851+
3852+ /* AuDbg("%pD\n", file); */
3853+ fi_read_lock(file);
3854+ btop = au_fbtop(file);
3855+ if (!d_is_dir(file->f_path.dentry)) {
3856+ hfile = &au_fi(file)->fi_htop;
3857+ if (hfile->hf_br->br_id == br_id)
3858+ err = -EBUSY;
3859+ } else
3860+ err = test_dir_busy(file, br_id, to_free, &idx);
3861+ fi_read_unlock(file);
3862+ if (unlikely(err))
3863+ break;
3864+ }
3865+ di_write_lock_child(root);
3866+ au_farray_free(array, max);
3867+ AuDebugOn(idx > opened);
3868+
3869+out:
3870+ return err;
3871+}
3872+
3873+static void br_del_file(struct file **to_free, unsigned long long opened,
3874+ aufs_bindex_t br_id)
3875+{
3876+ unsigned long long ull;
3877+ aufs_bindex_t bindex, btop, bbot, bfound;
3878+ struct file *file;
3879+ struct au_fidir *fidir;
3880+ struct au_hfile *hfile;
3881+
3882+ for (ull = 0; ull < opened; ull++) {
3883+ file = to_free[ull];
3884+ if (unlikely(!file))
3885+ break;
3886+
3887+ /* AuDbg("%pD\n", file); */
3888+ AuDebugOn(!d_is_dir(file->f_path.dentry));
3889+ bfound = -1;
3890+ fidir = au_fi(file)->fi_hdir;
3891+ AuDebugOn(!fidir);
3892+ fi_write_lock(file);
3893+ btop = au_fbtop(file);
3894+ bbot = au_fbbot_dir(file);
3895+ for (bindex = btop; bindex <= bbot; bindex++) {
3896+ hfile = fidir->fd_hfile + bindex;
3897+ if (!hfile->hf_file)
3898+ continue;
3899+
3900+ if (hfile->hf_br->br_id == br_id) {
3901+ bfound = bindex;
3902+ break;
3903+ }
3904+ }
3905+ AuDebugOn(bfound < 0);
3906+ au_set_h_fptr(file, bfound, NULL);
3907+ if (bfound == btop) {
3908+ for (btop++; btop <= bbot; btop++)
3909+ if (au_hf_dir(file, btop)) {
3910+ au_set_fbtop(file, btop);
3911+ break;
3912+ }
3913+ }
3914+ fi_write_unlock(file);
3915+ }
3916+}
3917+
3918+static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
3919+ const aufs_bindex_t bindex,
3920+ const aufs_bindex_t bbot)
3921+{
3922+ struct au_branch **brp, **p;
3923+
3924+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3925+
3926+ brp = sbinfo->si_branch + bindex;
3927+ if (bindex < bbot)
3928+ memmove(brp, brp + 1, sizeof(*brp) * (bbot - bindex));
3929+ sbinfo->si_branch[0 + bbot] = NULL;
3930+ sbinfo->si_bbot--;
3931+
3932+ p = au_krealloc(sbinfo->si_branch, sizeof(*p) * bbot, AuGFP_SBILIST,
3933+ /*may_shrink*/1);
3934+ if (p)
3935+ sbinfo->si_branch = p;
3936+ /* harmless error */
3937+}
3938+
3939+static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
3940+ const aufs_bindex_t bbot)
3941+{
3942+ struct au_hdentry *hdp, *p;
3943+
3944+ AuRwMustWriteLock(&dinfo->di_rwsem);
3945+
3946+ hdp = au_hdentry(dinfo, bindex);
3947+ if (bindex < bbot)
3948+ memmove(hdp, hdp + 1, sizeof(*hdp) * (bbot - bindex));
3949+ /* au_h_dentry_init(au_hdentry(dinfo, bbot); */
3950+ dinfo->di_bbot--;
3951+
3952+ p = au_krealloc(dinfo->di_hdentry, sizeof(*p) * bbot, AuGFP_SBILIST,
3953+ /*may_shrink*/1);
3954+ if (p)
3955+ dinfo->di_hdentry = p;
3956+ /* harmless error */
3957+}
3958+
3959+static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
3960+ const aufs_bindex_t bbot)
3961+{
3962+ struct au_hinode *hip, *p;
3963+
3964+ AuRwMustWriteLock(&iinfo->ii_rwsem);
3965+
3966+ hip = au_hinode(iinfo, bindex);
3967+ if (bindex < bbot)
3968+ memmove(hip, hip + 1, sizeof(*hip) * (bbot - bindex));
3969+ /* au_hinode_init(au_hinode(iinfo, bbot)); */
3970+ iinfo->ii_bbot--;
3971+
3972+ p = au_krealloc(iinfo->ii_hinode, sizeof(*p) * bbot, AuGFP_SBILIST,
3973+ /*may_shrink*/1);
3974+ if (p)
3975+ iinfo->ii_hinode = p;
3976+ /* harmless error */
3977+}
3978+
3979+static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
3980+ struct au_branch *br)
3981+{
3982+ aufs_bindex_t bbot;
3983+ struct au_sbinfo *sbinfo;
3984+ struct dentry *root, *h_root;
3985+ struct inode *inode, *h_inode;
3986+ struct au_hinode *hinode;
3987+
3988+ SiMustWriteLock(sb);
3989+
3990+ root = sb->s_root;
3991+ inode = d_inode(root);
3992+ sbinfo = au_sbi(sb);
3993+ bbot = sbinfo->si_bbot;
3994+
3995+ h_root = au_h_dptr(root, bindex);
3996+ hinode = au_hi(inode, bindex);
3997+ h_inode = au_igrab(hinode->hi_inode);
3998+ au_hiput(hinode);
3999+
4000+ au_sbilist_lock();
4001+ au_br_do_del_brp(sbinfo, bindex, bbot);
4002+ au_br_do_del_hdp(au_di(root), bindex, bbot);
4003+ au_br_do_del_hip(au_ii(inode), bindex, bbot);
4004+ au_sbilist_unlock();
4005+
4006+ /* ignore an error */
4007+ au_dr_br_fin(sb, br); /* always, regardless the mount option */
4008+
4009+ dput(h_root);
4010+ iput(h_inode);
4011+ au_br_do_free(br);
4012+}
4013+
4014+static unsigned long long empty_cb(struct super_block *sb, void *array,
4015+ unsigned long long max, void *arg)
4016+{
4017+ return max;
4018+}
4019+
4020+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
4021+{
4022+ int err, rerr, i;
4023+ unsigned long long opened;
4024+ unsigned int mnt_flags;
4025+ aufs_bindex_t bindex, bbot, br_id;
4026+ unsigned char do_wh, verbose;
4027+ struct au_branch *br;
4028+ struct au_wbr *wbr;
4029+ struct dentry *root;
4030+ struct file **to_free;
4031+
4032+ err = 0;
4033+ opened = 0;
4034+ to_free = NULL;
4035+ root = sb->s_root;
4036+ bindex = au_find_dbindex(root, del->h_path.dentry);
4037+ if (bindex < 0) {
4038+ if (remount)
4039+ goto out; /* success */
4040+ err = -ENOENT;
4041+ pr_err("%s no such branch\n", del->pathname);
4042+ goto out;
4043+ }
4044+ AuDbg("bindex b%d\n", bindex);
4045+
4046+ err = -EBUSY;
4047+ mnt_flags = au_mntflags(sb);
4048+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
4049+ bbot = au_sbbot(sb);
4050+ if (unlikely(!bbot)) {
4051+ AuVerbose(verbose, "no more branches left\n");
4052+ goto out;
4053+ }
4054+
4055+ br = au_sbr(sb, bindex);
4056+ AuDebugOn(!path_equal(&br->br_path, &del->h_path));
4057+ if (unlikely(au_lcnt_read(&br->br_count, /*do_rev*/1))) {
4058+ AuVerbose(verbose, "br %pd2 is busy now\n", del->h_path.dentry);
4059+ goto out;
4060+ }
4061+
4062+ br_id = br->br_id;
4063+ opened = au_lcnt_read(&br->br_nfiles, /*do_rev*/1);
4064+ if (unlikely(opened)) {
4065+ to_free = au_array_alloc(&opened, empty_cb, sb, NULL);
4066+ err = PTR_ERR(to_free);
4067+ if (IS_ERR(to_free))
4068+ goto out;
4069+
4070+ err = test_file_busy(sb, br_id, to_free, opened);
4071+ if (unlikely(err)) {
4072+ AuVerbose(verbose, "%llu file(s) opened\n", opened);
4073+ goto out;
4074+ }
4075+ }
4076+
4077+ wbr = br->br_wbr;
4078+ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
4079+ if (do_wh) {
4080+ /* instead of WbrWhMustWriteLock(wbr) */
4081+ SiMustWriteLock(sb);
4082+ for (i = 0; i < AuBrWh_Last; i++) {
4083+ dput(wbr->wbr_wh[i]);
4084+ wbr->wbr_wh[i] = NULL;
4085+ }
4086+ }
4087+
4088+ err = test_children_busy(root, bindex, verbose);
4089+ if (unlikely(err)) {
4090+ if (do_wh)
4091+ goto out_wh;
4092+ goto out;
4093+ }
4094+
4095+ err = 0;
4096+ if (to_free) {
4097+ /*
4098+ * now we confirmed the branch is deletable.
4099+ * let's free the remaining opened dirs on the branch.
4100+ */
4101+ di_write_unlock(root);
4102+ br_del_file(to_free, opened, br_id);
4103+ di_write_lock_child(root);
4104+ }
4105+
4106+ sysaufs_brs_del(sb, bindex); /* remove successors */
4107+ dbgaufs_xino_del(br); /* remove one */
4108+ au_br_do_del(sb, bindex, br);
4109+ sysaufs_brs_add(sb, bindex); /* append successors */
4110+ dbgaufs_brs_add(sb, bindex, /*topdown*/1); /* rename successors */
4111+
4112+ if (!bindex) {
4113+ au_cpup_attr_all(d_inode(root), /*force*/1);
4114+ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
4115+ } else
4116+ au_sub_nlink(d_inode(root), d_inode(del->h_path.dentry));
4117+ if (au_opt_test(mnt_flags, PLINK))
4118+ au_plink_half_refresh(sb, br_id);
4119+
4120+ goto out; /* success */
4121+
4122+out_wh:
4123+ /* revert */
4124+ rerr = au_br_init_wh(sb, br, br->br_perm);
4125+ if (rerr)
4126+ pr_warn("failed re-creating base whiteout, %s. (%d)\n",
4127+ del->pathname, rerr);
4128+out:
4129+ if (to_free)
4130+ au_farray_free(to_free, opened);
4131+ return err;
4132+}
4133+
4134+/* ---------------------------------------------------------------------- */
4135+
4136+static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg)
4137+{
4138+ int err;
4139+ aufs_bindex_t btop, bbot;
4140+ struct aufs_ibusy ibusy;
4141+ struct inode *inode, *h_inode;
4142+
4143+ err = -EPERM;
4144+ if (unlikely(!capable(CAP_SYS_ADMIN)))
4145+ goto out;
4146+
4147+ err = copy_from_user(&ibusy, arg, sizeof(ibusy));
4148+ if (!err)
4149+ /* VERIFY_WRITE */
4150+ err = !access_ok(&arg->h_ino, sizeof(arg->h_ino));
4151+ if (unlikely(err)) {
4152+ err = -EFAULT;
4153+ AuTraceErr(err);
4154+ goto out;
4155+ }
4156+
4157+ err = -EINVAL;
4158+ si_read_lock(sb, AuLock_FLUSH);
4159+ if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbbot(sb)))
4160+ goto out_unlock;
4161+
4162+ err = 0;
4163+ ibusy.h_ino = 0; /* invalid */
4164+ inode = ilookup(sb, ibusy.ino);
4165+ if (!inode
4166+ || inode->i_ino == AUFS_ROOT_INO
4167+ || au_is_bad_inode(inode))
4168+ goto out_unlock;
4169+
4170+ ii_read_lock_child(inode);
4171+ btop = au_ibtop(inode);
4172+ bbot = au_ibbot(inode);
4173+ if (btop <= ibusy.bindex && ibusy.bindex <= bbot) {
4174+ h_inode = au_h_iptr(inode, ibusy.bindex);
4175+ if (h_inode && au_test_ibusy(inode, btop, bbot))
4176+ ibusy.h_ino = h_inode->i_ino;
4177+ }
4178+ ii_read_unlock(inode);
4179+ iput(inode);
4180+
4181+out_unlock:
4182+ si_read_unlock(sb);
4183+ if (!err) {
4184+ err = __put_user(ibusy.h_ino, &arg->h_ino);
4185+ if (unlikely(err)) {
4186+ err = -EFAULT;
4187+ AuTraceErr(err);
4188+ }
4189+ }
4190+out:
4191+ return err;
4192+}
4193+
4194+long au_ibusy_ioctl(struct file *file, unsigned long arg)
4195+{
4196+ return au_ibusy(file->f_path.dentry->d_sb, (void __user *)arg);
4197+}
4198+
4199+#ifdef CONFIG_COMPAT
4200+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg)
4201+{
4202+ return au_ibusy(file->f_path.dentry->d_sb, compat_ptr(arg));
4203+}
4204+#endif
4205+
4206+/* ---------------------------------------------------------------------- */
4207+
4208+/*
4209+ * change a branch permission
4210+ */
4211+
4212+static void au_warn_ima(void)
4213+{
4214+#ifdef CONFIG_IMA
4215+ /* since it doesn't support mark_files_ro() */
4216+ AuWarn1("RW -> RO makes IMA to produce wrong message\n");
4217+#endif
4218+}
4219+
4220+static int do_need_sigen_inc(int a, int b)
4221+{
4222+ return au_br_whable(a) && !au_br_whable(b);
4223+}
4224+
4225+static int need_sigen_inc(int old, int new)
4226+{
4227+ return do_need_sigen_inc(old, new)
4228+ || do_need_sigen_inc(new, old);
4229+}
4230+
4231+static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
4232+{
4233+ int err, do_warn;
4234+ unsigned int mnt_flags;
4235+ unsigned long long ull, max;
4236+ aufs_bindex_t br_id;
4237+ unsigned char verbose, writer;
4238+ struct file *file, *hf, **array;
4239+ struct au_hfile *hfile;
4240+ struct inode *h_inode;
4241+
4242+ mnt_flags = au_mntflags(sb);
4243+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
4244+
4245+ array = au_farray_alloc(sb, &max);
4246+ err = PTR_ERR(array);
4247+ if (IS_ERR(array))
4248+ goto out;
4249+
4250+ do_warn = 0;
4251+ br_id = au_sbr_id(sb, bindex);
4252+ for (ull = 0; ull < max; ull++) {
4253+ file = array[ull];
4254+ if (unlikely(!file))
4255+ break;
4256+
4257+ /* AuDbg("%pD\n", file); */
4258+ fi_read_lock(file);
4259+ if (unlikely(au_test_mmapped(file))) {
4260+ err = -EBUSY;
4261+ AuVerbose(verbose, "mmapped %pD\n", file);
4262+ AuDbgFile(file);
4263+ FiMustNoWaiters(file);
4264+ fi_read_unlock(file);
4265+ goto out_array;
4266+ }
4267+
4268+ hfile = &au_fi(file)->fi_htop;
4269+ hf = hfile->hf_file;
4270+ if (!d_is_reg(file->f_path.dentry)
4271+ || !(file->f_mode & FMODE_WRITE)
4272+ || hfile->hf_br->br_id != br_id
4273+ || !(hf->f_mode & FMODE_WRITE))
4274+ array[ull] = NULL;
4275+ else {
4276+ do_warn = 1;
4277+ get_file(file);
4278+ }
4279+
4280+ FiMustNoWaiters(file);
4281+ fi_read_unlock(file);
4282+ fput(file);
4283+ }
4284+
4285+ err = 0;
4286+ if (do_warn)
4287+ au_warn_ima();
4288+
4289+ for (ull = 0; ull < max; ull++) {
4290+ file = array[ull];
4291+ if (!file)
4292+ continue;
4293+
4294+ /* todo: already flushed? */
4295+ /*
4296+ * fs/super.c:mark_files_ro() is gone, but aufs keeps its
4297+ * approach which resets f_mode and calls mnt_drop_write() and
4298+ * file_release_write() for each file, because the branch
4299+ * attribute in aufs world is totally different from the native
4300+ * fs rw/ro mode.
4301+ */
4302+ /* fi_read_lock(file); */
4303+ hfile = &au_fi(file)->fi_htop;
4304+ hf = hfile->hf_file;
4305+ /* fi_read_unlock(file); */
4306+ spin_lock(&hf->f_lock);
4307+ writer = !!(hf->f_mode & FMODE_WRITER);
4308+ hf->f_mode &= ~(FMODE_WRITE | FMODE_WRITER);
4309+ spin_unlock(&hf->f_lock);
4310+ if (writer) {
4311+ h_inode = file_inode(hf);
4312+ put_write_access(h_inode);
4313+ __mnt_drop_write(hf->f_path.mnt);
4314+ if ((hf->f_mode & (FMODE_READ | FMODE_WRITE))
4315+ == FMODE_READ)
4316+ i_readcount_inc(h_inode);
4317+ }
4318+ }
4319+
4320+out_array:
4321+ au_farray_free(array, max);
4322+out:
4323+ AuTraceErr(err);
4324+ return err;
4325+}
4326+
4327+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
4328+ int *do_refresh)
4329+{
4330+ int err, rerr;
4331+ aufs_bindex_t bindex;
4332+ struct dentry *root;
4333+ struct au_branch *br;
4334+ struct au_br_fhsm *bf;
4335+
4336+ root = sb->s_root;
4337+ bindex = au_find_dbindex(root, mod->h_root);
4338+ if (bindex < 0) {
4339+ if (remount)
4340+ return 0; /* success */
4341+ err = -ENOENT;
4342+ pr_err("%s no such branch\n", mod->path);
4343+ goto out;
4344+ }
4345+ AuDbg("bindex b%d\n", bindex);
4346+
4347+ err = test_br(d_inode(mod->h_root), mod->perm, mod->path);
4348+ if (unlikely(err))
4349+ goto out;
4350+
4351+ br = au_sbr(sb, bindex);
4352+ AuDebugOn(mod->h_root != au_br_dentry(br));
4353+ if (br->br_perm == mod->perm)
4354+ return 0; /* success */
4355+
4356+ /* pre-allocate for non-fhsm --> fhsm */
4357+ bf = NULL;
4358+ if (!au_br_fhsm(br->br_perm) && au_br_fhsm(mod->perm)) {
4359+ err = au_fhsm_br_alloc(br);
4360+ if (unlikely(err))
4361+ goto out;
4362+ bf = br->br_fhsm;
4363+ br->br_fhsm = NULL;
4364+ }
4365+
4366+ if (au_br_writable(br->br_perm)) {
4367+ /* remove whiteout base */
4368+ err = au_br_init_wh(sb, br, mod->perm);
4369+ if (unlikely(err))
4370+ goto out_bf;
4371+
4372+ if (!au_br_writable(mod->perm)) {
4373+ /* rw --> ro, file might be mmapped */
4374+ DiMustNoWaiters(root);
4375+ IiMustNoWaiters(d_inode(root));
4376+ di_write_unlock(root);
4377+ err = au_br_mod_files_ro(sb, bindex);
4378+ /* aufs_write_lock() calls ..._child() */
4379+ di_write_lock_child(root);
4380+
4381+ if (unlikely(err)) {
4382+ rerr = -ENOMEM;
4383+ br->br_wbr = kzalloc(sizeof(*br->br_wbr),
4384+ GFP_NOFS);
4385+ if (br->br_wbr)
4386+ rerr = au_wbr_init(br, sb, br->br_perm);
4387+ if (unlikely(rerr)) {
4388+ AuIOErr("nested error %d (%d)\n",
4389+ rerr, err);
4390+ br->br_perm = mod->perm;
4391+ }
4392+ }
4393+ }
4394+ } else if (au_br_writable(mod->perm)) {
4395+ /* ro --> rw */
4396+ err = -ENOMEM;
4397+ br->br_wbr = kzalloc(sizeof(*br->br_wbr), GFP_NOFS);
4398+ if (br->br_wbr) {
4399+ err = au_wbr_init(br, sb, mod->perm);
4400+ if (unlikely(err)) {
4401+ au_kfree_rcu(br->br_wbr);
4402+ br->br_wbr = NULL;
4403+ }
4404+ }
4405+ }
4406+ if (unlikely(err))
4407+ goto out_bf;
4408+
4409+ if (au_br_fhsm(br->br_perm)) {
4410+ if (!au_br_fhsm(mod->perm)) {
4411+ /* fhsm --> non-fhsm */
4412+ au_br_fhsm_fin(br->br_fhsm);
4413+ au_kfree_rcu(br->br_fhsm);
4414+ br->br_fhsm = NULL;
4415+ }
4416+ } else if (au_br_fhsm(mod->perm))
4417+ /* non-fhsm --> fhsm */
4418+ br->br_fhsm = bf;
4419+
4420+ *do_refresh |= need_sigen_inc(br->br_perm, mod->perm);
4421+ br->br_perm = mod->perm;
4422+ goto out; /* success */
4423+
4424+out_bf:
4425+ au_kfree_try_rcu(bf);
4426+out:
4427+ AuTraceErr(err);
4428+ return err;
4429+}
4430+
4431+/* ---------------------------------------------------------------------- */
4432+
4433+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs)
4434+{
4435+ int err;
4436+ struct kstatfs kstfs;
4437+
4438+ err = vfs_statfs(&br->br_path, &kstfs);
4439+ if (!err) {
4440+ stfs->f_blocks = kstfs.f_blocks;
4441+ stfs->f_bavail = kstfs.f_bavail;
4442+ stfs->f_files = kstfs.f_files;
4443+ stfs->f_ffree = kstfs.f_ffree;
4444+ }
4445+
4446+ return err;
4447+}
4448diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
4449--- /usr/share/empty/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100
4450+++ linux/fs/aufs/branch.h 2020-01-27 10:57:18.165538015 +0100
4451@@ -0,0 +1,366 @@
4452+/* SPDX-License-Identifier: GPL-2.0 */
4453+/*
4454+ * Copyright (C) 2005-2020 Junjiro R. Okajima
4455+ *
4456+ * This program, aufs is free software; you can redistribute it and/or modify
4457+ * it under the terms of the GNU General Public License as published by
4458+ * the Free Software Foundation; either version 2 of the License, or
4459+ * (at your option) any later version.
4460+ *
4461+ * This program is distributed in the hope that it will be useful,
4462+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4463+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4464+ * GNU General Public License for more details.
4465+ *
4466+ * You should have received a copy of the GNU General Public License
4467+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4468+ */
4469+
4470+/*
4471+ * branch filesystems and xino for them
4472+ */
4473+
4474+#ifndef __AUFS_BRANCH_H__
4475+#define __AUFS_BRANCH_H__
4476+
4477+#ifdef __KERNEL__
4478+
4479+#include <linux/mount.h>
4480+#include "dirren.h"
4481+#include "dynop.h"
4482+#include "lcnt.h"
4483+#include "rwsem.h"
4484+#include "super.h"
4485+
4486+/* ---------------------------------------------------------------------- */
4487+
4488+/* a xino file */
4489+struct au_xino {
4490+ struct file **xi_file;
4491+ unsigned int xi_nfile;
4492+
4493+ struct {
4494+ spinlock_t spin;
4495+ ino_t *array;
4496+ int total;
4497+ /* reserved for future use */
4498+ /* unsigned long *bitmap; */
4499+ wait_queue_head_t wqh;
4500+ } xi_nondir;
4501+
4502+ struct mutex xi_mtx; /* protects xi_file array */
4503+ struct hlist_bl_head xi_writing;
4504+
4505+ atomic_t xi_truncating;
4506+
4507+ struct kref xi_kref;
4508+};
4509+
4510+/* File-based Hierarchical Storage Management */
4511+struct au_br_fhsm {
4512+#ifdef CONFIG_AUFS_FHSM
4513+ struct mutex bf_lock;
4514+ unsigned long bf_jiffy;
4515+ struct aufs_stfs bf_stfs;
4516+ int bf_readable;
4517+#endif
4518+};
4519+
4520+/* members for writable branch only */
4521+enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
4522+struct au_wbr {
4523+ struct au_rwsem wbr_wh_rwsem;
4524+ struct dentry *wbr_wh[AuBrWh_Last];
4525+ atomic_t wbr_wh_running;
4526+#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
4527+#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
4528+#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
4529+
4530+ /* mfs mode */
4531+ unsigned long long wbr_bytes;
4532+};
4533+
4534+/* ext2 has 3 types of operations at least, ext3 has 4 */
4535+#define AuBrDynOp (AuDyLast * 4)
4536+
4537+#ifdef CONFIG_AUFS_HFSNOTIFY
4538+/* support for asynchronous destruction */
4539+struct au_br_hfsnotify {
4540+ struct fsnotify_group *hfsn_group;
4541+};
4542+#endif
4543+
4544+/* sysfs entries */
4545+struct au_brsysfs {
4546+ char name[16];
4547+ struct attribute attr;
4548+};
4549+
4550+enum {
4551+ AuBrSysfs_BR,
4552+ AuBrSysfs_BRID,
4553+ AuBrSysfs_Last
4554+};
4555+
4556+/* protected by superblock rwsem */
4557+struct au_branch {
4558+ struct au_xino *br_xino;
4559+
4560+ aufs_bindex_t br_id;
4561+
4562+ int br_perm;
4563+ struct path br_path;
4564+ spinlock_t br_dykey_lock;
4565+ struct au_dykey *br_dykey[AuBrDynOp];
4566+ au_lcnt_t br_nfiles; /* opened files */
4567+ au_lcnt_t br_count; /* in-use for other */
4568+
4569+ struct au_wbr *br_wbr;
4570+ struct au_br_fhsm *br_fhsm;
4571+
4572+#ifdef CONFIG_AUFS_HFSNOTIFY
4573+ struct au_br_hfsnotify *br_hfsn;
4574+#endif
4575+
4576+#ifdef CONFIG_SYSFS
4577+ /* entries under sysfs per mount-point */
4578+ struct au_brsysfs br_sysfs[AuBrSysfs_Last];
4579+#endif
4580+
4581+#ifdef CONFIG_DEBUG_FS
4582+ struct dentry *br_dbgaufs; /* xino */
4583+#endif
4584+
4585+ struct au_dr_br br_dirren;
4586+};
4587+
4588+/* ---------------------------------------------------------------------- */
4589+
4590+static inline struct vfsmount *au_br_mnt(struct au_branch *br)
4591+{
4592+ return br->br_path.mnt;
4593+}
4594+
4595+static inline struct dentry *au_br_dentry(struct au_branch *br)
4596+{
4597+ return br->br_path.dentry;
4598+}
4599+
4600+static inline struct super_block *au_br_sb(struct au_branch *br)
4601+{
4602+ return au_br_mnt(br)->mnt_sb;
4603+}
4604+
4605+static inline int au_br_rdonly(struct au_branch *br)
4606+{
4607+ return (sb_rdonly(au_br_sb(br))
4608+ || !au_br_writable(br->br_perm))
4609+ ? -EROFS : 0;
4610+}
4611+
4612+static inline int au_br_hnotifyable(int brperm __maybe_unused)
4613+{
4614+#ifdef CONFIG_AUFS_HNOTIFY
4615+ return !(brperm & AuBrPerm_RR);
4616+#else
4617+ return 0;
4618+#endif
4619+}
4620+
4621+static inline int au_br_test_oflag(int oflag, struct au_branch *br)
4622+{
4623+ int err, exec_flag;
4624+
4625+ err = 0;
4626+ exec_flag = oflag & __FMODE_EXEC;
4627+ if (unlikely(exec_flag && path_noexec(&br->br_path)))
4628+ err = -EACCES;
4629+
4630+ return err;
4631+}
4632+
4633+static inline void au_xino_get(struct au_branch *br)
4634+{
4635+ struct au_xino *xi;
4636+
4637+ xi = br->br_xino;
4638+ if (xi)
4639+ kref_get(&xi->xi_kref);
4640+}
4641+
4642+static inline int au_xino_count(struct au_branch *br)
4643+{
4644+ int v;
4645+ struct au_xino *xi;
4646+
4647+ v = 0;
4648+ xi = br->br_xino;
4649+ if (xi)
4650+ v = kref_read(&xi->xi_kref);
4651+
4652+ return v;
4653+}
4654+
4655+/* ---------------------------------------------------------------------- */
4656+
4657+/* branch.c */
4658+struct au_sbinfo;
4659+void au_br_free(struct au_sbinfo *sinfo);
4660+int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
4661+struct au_opt_add;
4662+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
4663+struct au_opt_del;
4664+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
4665+long au_ibusy_ioctl(struct file *file, unsigned long arg);
4666+#ifdef CONFIG_COMPAT
4667+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
4668+#endif
4669+struct au_opt_mod;
4670+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
4671+ int *do_refresh);
4672+struct aufs_stfs;
4673+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs);
4674+
4675+/* xino.c */
4676+static const loff_t au_loff_max = LLONG_MAX;
4677+
4678+aufs_bindex_t au_xi_root(struct super_block *sb, struct dentry *dentry);
4679+struct file *au_xino_create(struct super_block *sb, char *fpath, int silent,
4680+ int wbrtop);
4681+struct file *au_xino_create2(struct super_block *sb, struct path *base,
4682+ struct file *copy_src);
4683+struct au_xi_new {
4684+ struct au_xino *xi; /* switch between xino and xigen */
4685+ int idx;
4686+ struct path *base;
4687+ struct file *copy_src;
4688+};
4689+struct file *au_xi_new(struct super_block *sb, struct au_xi_new *xinew);
4690+
4691+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4692+ ino_t *ino);
4693+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4694+ ino_t ino);
4695+ssize_t xino_fread(vfs_readf_t func, struct file *file, void *buf, size_t size,
4696+ loff_t *pos);
4697+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf,
4698+ size_t size, loff_t *pos);
4699+
4700+int au_xib_trunc(struct super_block *sb);
4701+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex, int idx_begin);
4702+
4703+struct au_xino *au_xino_alloc(unsigned int nfile);
4704+int au_xino_put(struct au_branch *br);
4705+struct file *au_xino_file1(struct au_xino *xi);
4706+
4707+struct au_opt_xino;
4708+void au_xino_clr(struct super_block *sb);
4709+int au_xino_set(struct super_block *sb, struct au_opt_xino *xiopt, int remount);
4710+struct file *au_xino_def(struct super_block *sb);
4711+int au_xino_init_br(struct super_block *sb, struct au_branch *br, ino_t hino,
4712+ struct path *base);
4713+
4714+ino_t au_xino_new_ino(struct super_block *sb);
4715+void au_xino_delete_inode(struct inode *inode, const int unlinked);
4716+
4717+void au_xinondir_leave(struct super_block *sb, aufs_bindex_t bindex,
4718+ ino_t h_ino, int idx);
4719+int au_xinondir_enter(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4720+ int *idx);
4721+
4722+int au_xino_path(struct seq_file *seq, struct file *file);
4723+
4724+/* ---------------------------------------------------------------------- */
4725+
4726+/* @idx is signed to accept -1 meaning the first file */
4727+static inline struct file *au_xino_file(struct au_xino *xi, int idx)
4728+{
4729+ struct file *file;
4730+
4731+ file = NULL;
4732+ if (!xi)
4733+ goto out;
4734+
4735+ if (idx >= 0) {
4736+ if (idx < xi->xi_nfile)
4737+ file = xi->xi_file[idx];
4738+ } else
4739+ file = au_xino_file1(xi);
4740+
4741+out:
4742+ return file;
4743+}
4744+
4745+/* ---------------------------------------------------------------------- */
4746+
4747+/* Superblock to branch */
4748+static inline
4749+aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
4750+{
4751+ return au_sbr(sb, bindex)->br_id;
4752+}
4753+
4754+static inline
4755+struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
4756+{
4757+ return au_br_mnt(au_sbr(sb, bindex));
4758+}
4759+
4760+static inline
4761+struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
4762+{
4763+ return au_br_sb(au_sbr(sb, bindex));
4764+}
4765+
4766+static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
4767+{
4768+ return au_sbr(sb, bindex)->br_perm;
4769+}
4770+
4771+static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
4772+{
4773+ return au_br_whable(au_sbr_perm(sb, bindex));
4774+}
4775+
4776+/* ---------------------------------------------------------------------- */
4777+
4778+#define wbr_wh_read_lock(wbr) au_rw_read_lock(&(wbr)->wbr_wh_rwsem)
4779+#define wbr_wh_write_lock(wbr) au_rw_write_lock(&(wbr)->wbr_wh_rwsem)
4780+#define wbr_wh_read_trylock(wbr) au_rw_read_trylock(&(wbr)->wbr_wh_rwsem)
4781+#define wbr_wh_write_trylock(wbr) au_rw_write_trylock(&(wbr)->wbr_wh_rwsem)
4782+/*
4783+#define wbr_wh_read_trylock_nested(wbr) \
4784+ au_rw_read_trylock_nested(&(wbr)->wbr_wh_rwsem)
4785+#define wbr_wh_write_trylock_nested(wbr) \
4786+ au_rw_write_trylock_nested(&(wbr)->wbr_wh_rwsem)
4787+*/
4788+
4789+#define wbr_wh_read_unlock(wbr) au_rw_read_unlock(&(wbr)->wbr_wh_rwsem)
4790+#define wbr_wh_write_unlock(wbr) au_rw_write_unlock(&(wbr)->wbr_wh_rwsem)
4791+#define wbr_wh_downgrade_lock(wbr) au_rw_dgrade_lock(&(wbr)->wbr_wh_rwsem)
4792+
4793+#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&(wbr)->wbr_wh_rwsem)
4794+#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&(wbr)->wbr_wh_rwsem)
4795+#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&(wbr)->wbr_wh_rwsem)
4796+
4797+/* ---------------------------------------------------------------------- */
4798+
4799+#ifdef CONFIG_AUFS_FHSM
4800+static inline void au_br_fhsm_init(struct au_br_fhsm *brfhsm)
4801+{
4802+ mutex_init(&brfhsm->bf_lock);
4803+ brfhsm->bf_jiffy = 0;
4804+ brfhsm->bf_readable = 0;
4805+}
4806+
4807+static inline void au_br_fhsm_fin(struct au_br_fhsm *brfhsm)
4808+{
4809+ mutex_destroy(&brfhsm->bf_lock);
4810+}
4811+#else
4812+AuStubVoid(au_br_fhsm_init, struct au_br_fhsm *brfhsm)
4813+AuStubVoid(au_br_fhsm_fin, struct au_br_fhsm *brfhsm)
4814+#endif
4815+
4816+#endif /* __KERNEL__ */
4817+#endif /* __AUFS_BRANCH_H__ */
4818diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
4819--- /usr/share/empty/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100
4820+++ linux/fs/aufs/conf.mk 2019-07-11 15:42:14.462237786 +0200
4821@@ -0,0 +1,40 @@
4822+# SPDX-License-Identifier: GPL-2.0
4823+
4824+AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
4825+
4826+define AuConf
4827+ifdef ${1}
4828+AuConfStr += ${1}=${${1}}
4829+endif
4830+endef
4831+
4832+AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
4833+ SBILIST \
4834+ HNOTIFY HFSNOTIFY \
4835+ EXPORT INO_T_64 \
4836+ XATTR \
4837+ FHSM \
4838+ RDU \
4839+ DIRREN \
4840+ SHWH \
4841+ BR_RAMFS \
4842+ BR_FUSE POLL \
4843+ BR_HFSPLUS \
4844+ BDEV_LOOP \
4845+ DEBUG MAGIC_SYSRQ
4846+$(foreach i, ${AuConfAll}, \
4847+ $(eval $(call AuConf,CONFIG_AUFS_${i})))
4848+
4849+AuConfName = ${obj}/conf.str
4850+${AuConfName}.tmp: FORCE
4851+ @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
4852+${AuConfName}: ${AuConfName}.tmp
4853+ @diff -q $< $@ > /dev/null 2>&1 || { \
4854+ echo ' GEN ' $@; \
4855+ cp -p $< $@; \
4856+ }
4857+FORCE:
4858+clean-files += ${AuConfName} ${AuConfName}.tmp
4859+${obj}/sysfs.o: ${AuConfName}
4860+
4861+-include ${srctree}/${src}/conf_priv.mk
4862diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
4863--- /usr/share/empty/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
4864+++ linux/fs/aufs/cpup.c 2020-01-27 10:57:18.165538015 +0100
4865@@ -0,0 +1,1458 @@
4866+// SPDX-License-Identifier: GPL-2.0
4867+/*
4868+ * Copyright (C) 2005-2020 Junjiro R. Okajima
4869+ *
4870+ * This program, aufs is free software; you can redistribute it and/or modify
4871+ * it under the terms of the GNU General Public License as published by
4872+ * the Free Software Foundation; either version 2 of the License, or
4873+ * (at your option) any later version.
4874+ *
4875+ * This program is distributed in the hope that it will be useful,
4876+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4877+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4878+ * GNU General Public License for more details.
4879+ *
4880+ * You should have received a copy of the GNU General Public License
4881+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4882+ */
4883+
4884+/*
4885+ * copy-up functions, see wbr_policy.c for copy-down
4886+ */
4887+
4888+#include <linux/fs_stack.h>
4889+#include <linux/mm.h>
4890+#include <linux/task_work.h>
4891+#include "aufs.h"
4892+
4893+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags)
4894+{
4895+ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
4896+ | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT;
4897+
4898+ BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags));
4899+
4900+ dst->i_flags |= iflags & ~mask;
4901+ if (au_test_fs_notime(dst->i_sb))
4902+ dst->i_flags |= S_NOATIME | S_NOCMTIME;
4903+}
4904+
4905+void au_cpup_attr_timesizes(struct inode *inode)
4906+{
4907+ struct inode *h_inode;
4908+
4909+ h_inode = au_h_iptr(inode, au_ibtop(inode));
4910+ fsstack_copy_attr_times(inode, h_inode);
4911+ fsstack_copy_inode_size(inode, h_inode);
4912+}
4913+
4914+void au_cpup_attr_nlink(struct inode *inode, int force)
4915+{
4916+ struct inode *h_inode;
4917+ struct super_block *sb;
4918+ aufs_bindex_t bindex, bbot;
4919+
4920+ sb = inode->i_sb;
4921+ bindex = au_ibtop(inode);
4922+ h_inode = au_h_iptr(inode, bindex);
4923+ if (!force
4924+ && !S_ISDIR(h_inode->i_mode)
4925+ && au_opt_test(au_mntflags(sb), PLINK)
4926+ && au_plink_test(inode))
4927+ return;
4928+
4929+ /*
4930+ * 0 can happen in revalidating.
4931+ * h_inode->i_mutex may not be held here, but it is harmless since once
4932+ * i_nlink reaches 0, it will never become positive except O_TMPFILE
4933+ * case.
4934+ * todo: O_TMPFILE+linkat(AT_SYMLINK_FOLLOW) bypassing aufs may cause
4935+ * the incorrect link count.
4936+ */
4937+ set_nlink(inode, h_inode->i_nlink);
4938+
4939+ /*
4940+ * fewer nlink makes find(1) noisy, but larger nlink doesn't.
4941+ * it may includes whplink directory.
4942+ */
4943+ if (S_ISDIR(h_inode->i_mode)) {
4944+ bbot = au_ibbot(inode);
4945+ for (bindex++; bindex <= bbot; bindex++) {
4946+ h_inode = au_h_iptr(inode, bindex);
4947+ if (h_inode)
4948+ au_add_nlink(inode, h_inode);
4949+ }
4950+ }
4951+}
4952+
4953+void au_cpup_attr_changeable(struct inode *inode)
4954+{
4955+ struct inode *h_inode;
4956+
4957+ h_inode = au_h_iptr(inode, au_ibtop(inode));
4958+ inode->i_mode = h_inode->i_mode;
4959+ inode->i_uid = h_inode->i_uid;
4960+ inode->i_gid = h_inode->i_gid;
4961+ au_cpup_attr_timesizes(inode);
4962+ au_cpup_attr_flags(inode, h_inode->i_flags);
4963+}
4964+
4965+void au_cpup_igen(struct inode *inode, struct inode *h_inode)
4966+{
4967+ struct au_iinfo *iinfo = au_ii(inode);
4968+
4969+ IiMustWriteLock(inode);
4970+
4971+ iinfo->ii_higen = h_inode->i_generation;
4972+ iinfo->ii_hsb1 = h_inode->i_sb;
4973+}
4974+
4975+void au_cpup_attr_all(struct inode *inode, int force)
4976+{
4977+ struct inode *h_inode;
4978+
4979+ h_inode = au_h_iptr(inode, au_ibtop(inode));
4980+ au_cpup_attr_changeable(inode);
4981+ if (inode->i_nlink > 0)
4982+ au_cpup_attr_nlink(inode, force);
4983+ inode->i_rdev = h_inode->i_rdev;
4984+ inode->i_blkbits = h_inode->i_blkbits;
4985+ au_cpup_igen(inode, h_inode);
4986+}
4987+
4988+/* ---------------------------------------------------------------------- */
4989+
4990+/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
4991+
4992+/* keep the timestamps of the parent dir when cpup */
4993+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
4994+ struct path *h_path)
4995+{
4996+ struct inode *h_inode;
4997+
4998+ dt->dt_dentry = dentry;
4999+ dt->dt_h_path = *h_path;
5000+ h_inode = d_inode(h_path->dentry);
5001+ dt->dt_atime = h_inode->i_atime;
5002+ dt->dt_mtime = h_inode->i_mtime;
5003+ /* smp_mb(); */
5004+}
5005+
5006+void au_dtime_revert(struct au_dtime *dt)
5007+{
5008+ struct iattr attr;
5009+ int err;
5010+
5011+ attr.ia_atime = dt->dt_atime;
5012+ attr.ia_mtime = dt->dt_mtime;
5013+ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
5014+ | ATTR_ATIME | ATTR_ATIME_SET;
5015+
5016+ /* no delegation since this is a directory */
5017+ err = vfsub_notify_change(&dt->dt_h_path, &attr, /*delegated*/NULL);
5018+ if (unlikely(err))
5019+ pr_warn("restoring timestamps failed(%d). ignored\n", err);
5020+}
5021+
5022+/* ---------------------------------------------------------------------- */
5023+
5024+/* internal use only */
5025+struct au_cpup_reg_attr {
5026+ int valid;
5027+ struct kstat st;
5028+ unsigned int iflags; /* inode->i_flags */
5029+};
5030+
5031+static noinline_for_stack
5032+int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src,
5033+ struct au_cpup_reg_attr *h_src_attr)
5034+{
5035+ int err, sbits, icex;
5036+ unsigned int mnt_flags;
5037+ unsigned char verbose;
5038+ struct iattr ia;
5039+ struct path h_path;
5040+ struct inode *h_isrc, *h_idst;
5041+ struct kstat *h_st;
5042+ struct au_branch *br;
5043+
5044+ h_path.dentry = au_h_dptr(dst, bindex);
5045+ h_idst = d_inode(h_path.dentry);
5046+ br = au_sbr(dst->d_sb, bindex);
5047+ h_path.mnt = au_br_mnt(br);
5048+ h_isrc = d_inode(h_src);
5049+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
5050+ | ATTR_ATIME | ATTR_MTIME
5051+ | ATTR_ATIME_SET | ATTR_MTIME_SET;
5052+ if (h_src_attr && h_src_attr->valid) {
5053+ h_st = &h_src_attr->st;
5054+ ia.ia_uid = h_st->uid;
5055+ ia.ia_gid = h_st->gid;
5056+ ia.ia_atime = h_st->atime;
5057+ ia.ia_mtime = h_st->mtime;
5058+ if (h_idst->i_mode != h_st->mode
5059+ && !S_ISLNK(h_idst->i_mode)) {
5060+ ia.ia_valid |= ATTR_MODE;
5061+ ia.ia_mode = h_st->mode;
5062+ }
5063+ sbits = !!(h_st->mode & (S_ISUID | S_ISGID));
5064+ au_cpup_attr_flags(h_idst, h_src_attr->iflags);
5065+ } else {
5066+ ia.ia_uid = h_isrc->i_uid;
5067+ ia.ia_gid = h_isrc->i_gid;
5068+ ia.ia_atime = h_isrc->i_atime;
5069+ ia.ia_mtime = h_isrc->i_mtime;
5070+ if (h_idst->i_mode != h_isrc->i_mode
5071+ && !S_ISLNK(h_idst->i_mode)) {
5072+ ia.ia_valid |= ATTR_MODE;
5073+ ia.ia_mode = h_isrc->i_mode;
5074+ }
5075+ sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
5076+ au_cpup_attr_flags(h_idst, h_isrc->i_flags);
5077+ }
5078+ /* no delegation since it is just created */
5079+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
5080+
5081+ /* is this nfs only? */
5082+ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
5083+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
5084+ ia.ia_mode = h_isrc->i_mode;
5085+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
5086+ }
5087+
5088+ icex = br->br_perm & AuBrAttr_ICEX;
5089+ if (!err) {
5090+ mnt_flags = au_mntflags(dst->d_sb);
5091+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
5092+ err = au_cpup_xattr(h_path.dentry, h_src, icex, verbose);
5093+ }
5094+
5095+ return err;
5096+}
5097+
5098+/* ---------------------------------------------------------------------- */
5099+
5100+static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
5101+ char *buf, unsigned long blksize)
5102+{
5103+ int err;
5104+ size_t sz, rbytes, wbytes;
5105+ unsigned char all_zero;
5106+ char *p, *zp;
5107+ struct inode *h_inode;
5108+ /* reduce stack usage */
5109+ struct iattr *ia;
5110+
5111+ zp = page_address(ZERO_PAGE(0));
5112+ if (unlikely(!zp))
5113+ return -ENOMEM; /* possible? */
5114+
5115+ err = 0;
5116+ all_zero = 0;
5117+ while (len) {
5118+ AuDbg("len %lld\n", len);
5119+ sz = blksize;
5120+ if (len < blksize)
5121+ sz = len;
5122+
5123+ rbytes = 0;
5124+ /* todo: signal_pending? */
5125+ while (!rbytes || err == -EAGAIN || err == -EINTR) {
5126+ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
5127+ err = rbytes;
5128+ }
5129+ if (unlikely(err < 0))
5130+ break;
5131+
5132+ all_zero = 0;
5133+ if (len >= rbytes && rbytes == blksize)
5134+ all_zero = !memcmp(buf, zp, rbytes);
5135+ if (!all_zero) {
5136+ wbytes = rbytes;
5137+ p = buf;
5138+ while (wbytes) {
5139+ size_t b;
5140+
5141+ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
5142+ err = b;
5143+ /* todo: signal_pending? */
5144+ if (unlikely(err == -EAGAIN || err == -EINTR))
5145+ continue;
5146+ if (unlikely(err < 0))
5147+ break;
5148+ wbytes -= b;
5149+ p += b;
5150+ }
5151+ if (unlikely(err < 0))
5152+ break;
5153+ } else {
5154+ loff_t res;
5155+
5156+ AuLabel(hole);
5157+ res = vfsub_llseek(dst, rbytes, SEEK_CUR);
5158+ err = res;
5159+ if (unlikely(res < 0))
5160+ break;
5161+ }
5162+ len -= rbytes;
5163+ err = 0;
5164+ }
5165+
5166+ /* the last block may be a hole */
5167+ if (!err && all_zero) {
5168+ AuLabel(last hole);
5169+
5170+ err = 1;
5171+ if (au_test_nfs(dst->f_path.dentry->d_sb)) {
5172+ /* nfs requires this step to make last hole */
5173+ /* is this only nfs? */
5174+ do {
5175+ /* todo: signal_pending? */
5176+ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
5177+ } while (err == -EAGAIN || err == -EINTR);
5178+ if (err == 1)
5179+ dst->f_pos--;
5180+ }
5181+
5182+ if (err == 1) {
5183+ ia = (void *)buf;
5184+ ia->ia_size = dst->f_pos;
5185+ ia->ia_valid = ATTR_SIZE | ATTR_FILE;
5186+ ia->ia_file = dst;
5187+ h_inode = file_inode(dst);
5188+ inode_lock_nested(h_inode, AuLsc_I_CHILD2);
5189+ /* no delegation since it is just created */
5190+ err = vfsub_notify_change(&dst->f_path, ia,
5191+ /*delegated*/NULL);
5192+ inode_unlock(h_inode);
5193+ }
5194+ }
5195+
5196+ return err;
5197+}
5198+
5199+int au_copy_file(struct file *dst, struct file *src, loff_t len)
5200+{
5201+ int err;
5202+ unsigned long blksize;
5203+ unsigned char do_kfree;
5204+ char *buf;
5205+ struct super_block *h_sb;
5206+
5207+ err = -ENOMEM;
5208+ h_sb = file_inode(dst)->i_sb;
5209+ blksize = h_sb->s_blocksize;
5210+ if (!blksize || PAGE_SIZE < blksize)
5211+ blksize = PAGE_SIZE;
5212+ AuDbg("blksize %lu\n", blksize);
5213+ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
5214+ if (do_kfree)
5215+ buf = kmalloc(blksize, GFP_NOFS);
5216+ else
5217+ buf = (void *)__get_free_page(GFP_NOFS);
5218+ if (unlikely(!buf))
5219+ goto out;
5220+
5221+ if (len > (1 << 22))
5222+ AuDbg("copying a large file %lld\n", (long long)len);
5223+
5224+ src->f_pos = 0;
5225+ dst->f_pos = 0;
5226+ err = au_do_copy_file(dst, src, len, buf, blksize);
5227+ if (do_kfree) {
5228+ AuDebugOn(!au_kfree_do_sz_test(blksize));
5229+ au_kfree_do_rcu(buf);
5230+ } else
5231+ free_page((unsigned long)buf);
5232+
5233+out:
5234+ return err;
5235+}
5236+
5237+static int au_do_copy(struct file *dst, struct file *src, loff_t len)
5238+{
5239+ int err;
5240+ struct super_block *h_src_sb;
5241+ struct inode *h_src_inode;
5242+
5243+ h_src_inode = file_inode(src);
5244+ h_src_sb = h_src_inode->i_sb;
5245+
5246+ /* XFS acquires inode_lock */
5247+ if (!au_test_xfs(h_src_sb))
5248+ err = au_copy_file(dst, src, len);
5249+ else {
5250+ inode_unlock_shared(h_src_inode);
5251+ err = au_copy_file(dst, src, len);
5252+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD);
5253+ }
5254+
5255+ return err;
5256+}
5257+
5258+static int au_clone_or_copy(struct file *dst, struct file *src, loff_t len)
5259+{
5260+ int err;
5261+ loff_t lo;
5262+ struct super_block *h_src_sb;
5263+ struct inode *h_src_inode;
5264+
5265+ h_src_inode = file_inode(src);
5266+ h_src_sb = h_src_inode->i_sb;
5267+ if (h_src_sb != file_inode(dst)->i_sb
5268+ || !dst->f_op->remap_file_range) {
5269+ err = au_do_copy(dst, src, len);
5270+ goto out;
5271+ }
5272+
5273+ if (!au_test_nfs(h_src_sb)) {
5274+ inode_unlock_shared(h_src_inode);
5275+ lo = vfsub_clone_file_range(src, dst, len);
5276+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD);
5277+ } else
5278+ lo = vfsub_clone_file_range(src, dst, len);
5279+ if (lo == len) {
5280+ err = 0;
5281+ goto out; /* success */
5282+ } else if (lo >= 0)
5283+ /* todo: possible? */
5284+ /* paritially succeeded */
5285+ AuDbg("lo %lld, len %lld. Retrying.\n", lo, len);
5286+ else if (lo != -EOPNOTSUPP) {
5287+ /* older XFS has a condition in cloning */
5288+ err = lo;
5289+ goto out;
5290+ }
5291+
5292+ /* the backend fs on NFS may not support cloning */
5293+ err = au_do_copy(dst, src, len);
5294+
5295+out:
5296+ AuTraceErr(err);
5297+ return err;
5298+}
5299+
5300+/*
5301+ * to support a sparse file which is opened with O_APPEND,
5302+ * we need to close the file.
5303+ */
5304+static int au_cp_regular(struct au_cp_generic *cpg)
5305+{
5306+ int err, i;
5307+ enum { SRC, DST };
5308+ struct {
5309+ aufs_bindex_t bindex;
5310+ unsigned int flags;
5311+ struct dentry *dentry;
5312+ int force_wr;
5313+ struct file *file;
5314+ } *f, file[] = {
5315+ {
5316+ .bindex = cpg->bsrc,
5317+ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
5318+ },
5319+ {
5320+ .bindex = cpg->bdst,
5321+ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
5322+ .force_wr = !!au_ftest_cpup(cpg->flags, RWDST),
5323+ }
5324+ };
5325+ struct au_branch *br;
5326+ struct super_block *sb, *h_src_sb;
5327+ struct inode *h_src_inode;
5328+ struct task_struct *tsk = current;
5329+
5330+ /* bsrc branch can be ro/rw. */
5331+ sb = cpg->dentry->d_sb;
5332+ f = file;
5333+ for (i = 0; i < 2; i++, f++) {
5334+ f->dentry = au_h_dptr(cpg->dentry, f->bindex);
5335+ f->file = au_h_open(cpg->dentry, f->bindex, f->flags,
5336+ /*file*/NULL, f->force_wr);
5337+ if (IS_ERR(f->file)) {
5338+ err = PTR_ERR(f->file);
5339+ if (i == SRC)
5340+ goto out;
5341+ else
5342+ goto out_src;
5343+ }
5344+ }
5345+
5346+ /* try stopping to update while we copyup */
5347+ h_src_inode = d_inode(file[SRC].dentry);
5348+ h_src_sb = h_src_inode->i_sb;
5349+ if (!au_test_nfs(h_src_sb))
5350+ IMustLock(h_src_inode);
5351+ err = au_clone_or_copy(file[DST].file, file[SRC].file, cpg->len);
5352+
5353+ /* i wonder if we had O_NO_DELAY_FPUT flag */
5354+ if (tsk->flags & PF_KTHREAD)
5355+ __fput_sync(file[DST].file);
5356+ else {
5357+ /* it happened actually */
5358+ fput(file[DST].file);
5359+ /*
5360+ * too bad.
5361+ * we have to call both since we don't know which place the file
5362+ * was added to.
5363+ */
5364+ task_work_run();
5365+ flush_delayed_fput();
5366+ }
5367+ br = au_sbr(sb, file[DST].bindex);
5368+ au_lcnt_dec(&br->br_nfiles);
5369+
5370+out_src:
5371+ fput(file[SRC].file);
5372+ br = au_sbr(sb, file[SRC].bindex);
5373+ au_lcnt_dec(&br->br_nfiles);
5374+out:
5375+ return err;
5376+}
5377+
5378+static int au_do_cpup_regular(struct au_cp_generic *cpg,
5379+ struct au_cpup_reg_attr *h_src_attr)
5380+{
5381+ int err, rerr;
5382+ loff_t l;
5383+ struct path h_path;
5384+ struct inode *h_src_inode, *h_dst_inode;
5385+
5386+ err = 0;
5387+ h_src_inode = au_h_iptr(d_inode(cpg->dentry), cpg->bsrc);
5388+ l = i_size_read(h_src_inode);
5389+ if (cpg->len == -1 || l < cpg->len)
5390+ cpg->len = l;
5391+ if (cpg->len) {
5392+ /* try stopping to update while we are referencing */
5393+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD);
5394+ au_pin_hdir_unlock(cpg->pin);
5395+
5396+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
5397+ h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc);
5398+ h_src_attr->iflags = h_src_inode->i_flags;
5399+ if (!au_test_nfs(h_src_inode->i_sb))
5400+ err = vfsub_getattr(&h_path, &h_src_attr->st);
5401+ else {
5402+ inode_unlock_shared(h_src_inode);
5403+ err = vfsub_getattr(&h_path, &h_src_attr->st);
5404+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD);
5405+ }
5406+ if (unlikely(err)) {
5407+ inode_unlock_shared(h_src_inode);
5408+ goto out;
5409+ }
5410+ h_src_attr->valid = 1;
5411+ if (!au_test_nfs(h_src_inode->i_sb)) {
5412+ err = au_cp_regular(cpg);
5413+ inode_unlock_shared(h_src_inode);
5414+ } else {
5415+ inode_unlock_shared(h_src_inode);
5416+ err = au_cp_regular(cpg);
5417+ }
5418+ rerr = au_pin_hdir_relock(cpg->pin);
5419+ if (!err && rerr)
5420+ err = rerr;
5421+ }
5422+ if (!err && (h_src_inode->i_state & I_LINKABLE)) {
5423+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bdst);
5424+ h_dst_inode = d_inode(h_path.dentry);
5425+ spin_lock(&h_dst_inode->i_lock);
5426+ h_dst_inode->i_state |= I_LINKABLE;
5427+ spin_unlock(&h_dst_inode->i_lock);
5428+ }
5429+
5430+out:
5431+ return err;
5432+}
5433+
5434+static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
5435+ struct inode *h_dir)
5436+{
5437+ int err, symlen;
5438+ mm_segment_t old_fs;
5439+ union {
5440+ char *k;
5441+ char __user *u;
5442+ } sym;
5443+
5444+ err = -ENOMEM;
5445+ sym.k = (void *)__get_free_page(GFP_NOFS);
5446+ if (unlikely(!sym.k))
5447+ goto out;
5448+
5449+ /* unnecessary to support mmap_sem since symlink is not mmap-able */
5450+ old_fs = get_fs();
5451+ set_fs(KERNEL_DS);
5452+ symlen = vfs_readlink(h_src, sym.u, PATH_MAX);
5453+ err = symlen;
5454+ set_fs(old_fs);
5455+
5456+ if (symlen > 0) {
5457+ sym.k[symlen] = 0;
5458+ err = vfsub_symlink(h_dir, h_path, sym.k);
5459+ }
5460+ free_page((unsigned long)sym.k);
5461+
5462+out:
5463+ return err;
5464+}
5465+
5466+/*
5467+ * regardless 'acl' option, reset all ACL.
5468+ * All ACL will be copied up later from the original entry on the lower branch.
5469+ */
5470+static int au_reset_acl(struct inode *h_dir, struct path *h_path, umode_t mode)
5471+{
5472+ int err;
5473+ struct dentry *h_dentry;
5474+ struct inode *h_inode;
5475+
5476+ h_dentry = h_path->dentry;
5477+ h_inode = d_inode(h_dentry);
5478+ /* forget_all_cached_acls(h_inode)); */
5479+ err = vfsub_removexattr(h_dentry, XATTR_NAME_POSIX_ACL_ACCESS);
5480+ AuTraceErr(err);
5481+ if (err == -EOPNOTSUPP)
5482+ err = 0;
5483+ if (!err)
5484+ err = vfsub_acl_chmod(h_inode, mode);
5485+
5486+ AuTraceErr(err);
5487+ return err;
5488+}
5489+
5490+static int au_do_cpup_dir(struct au_cp_generic *cpg, struct dentry *dst_parent,
5491+ struct inode *h_dir, struct path *h_path)
5492+{
5493+ int err;
5494+ struct inode *dir, *inode;
5495+
5496+ err = vfsub_removexattr(h_path->dentry, XATTR_NAME_POSIX_ACL_DEFAULT);
5497+ AuTraceErr(err);
5498+ if (err == -EOPNOTSUPP)
5499+ err = 0;
5500+ if (unlikely(err))
5501+ goto out;
5502+
5503+ /*
5504+ * strange behaviour from the users view,
5505+ * particularly setattr case
5506+ */
5507+ dir = d_inode(dst_parent);
5508+ if (au_ibtop(dir) == cpg->bdst)
5509+ au_cpup_attr_nlink(dir, /*force*/1);
5510+ inode = d_inode(cpg->dentry);
5511+ au_cpup_attr_nlink(inode, /*force*/1);
5512+
5513+out:
5514+ return err;
5515+}
5516+
5517+static noinline_for_stack
5518+int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent,
5519+ struct au_cpup_reg_attr *h_src_attr)
5520+{
5521+ int err;
5522+ umode_t mode;
5523+ unsigned int mnt_flags;
5524+ unsigned char isdir, isreg, force;
5525+ const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME);
5526+ struct au_dtime dt;
5527+ struct path h_path;
5528+ struct dentry *h_src, *h_dst, *h_parent;
5529+ struct inode *h_inode, *h_dir;
5530+ struct super_block *sb;
5531+
5532+ /* bsrc branch can be ro/rw. */
5533+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
5534+ h_inode = d_inode(h_src);
5535+ AuDebugOn(h_inode != au_h_iptr(d_inode(cpg->dentry), cpg->bsrc));
5536+
5537+ /* try stopping to be referenced while we are creating */
5538+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
5539+ if (au_ftest_cpup(cpg->flags, RENAME))
5540+ AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX,
5541+ AUFS_WH_PFX_LEN));
5542+ h_parent = h_dst->d_parent; /* dir inode is locked */
5543+ h_dir = d_inode(h_parent);
5544+ IMustLock(h_dir);
5545+ AuDebugOn(h_parent != h_dst->d_parent);
5546+
5547+ sb = cpg->dentry->d_sb;
5548+ h_path.mnt = au_sbr_mnt(sb, cpg->bdst);
5549+ if (do_dt) {
5550+ h_path.dentry = h_parent;
5551+ au_dtime_store(&dt, dst_parent, &h_path);
5552+ }
5553+ h_path.dentry = h_dst;
5554+
5555+ isreg = 0;
5556+ isdir = 0;
5557+ mode = h_inode->i_mode;
5558+ switch (mode & S_IFMT) {
5559+ case S_IFREG:
5560+ isreg = 1;
5561+ err = vfsub_create(h_dir, &h_path, 0600, /*want_excl*/true);
5562+ if (!err)
5563+ err = au_do_cpup_regular(cpg, h_src_attr);
5564+ break;
5565+ case S_IFDIR:
5566+ isdir = 1;
5567+ err = vfsub_mkdir(h_dir, &h_path, mode);
5568+ if (!err)
5569+ err = au_do_cpup_dir(cpg, dst_parent, h_dir, &h_path);
5570+ break;
5571+ case S_IFLNK:
5572+ err = au_do_cpup_symlink(&h_path, h_src, h_dir);
5573+ break;
5574+ case S_IFCHR:
5575+ case S_IFBLK:
5576+ AuDebugOn(!capable(CAP_MKNOD));
5577+ /*FALLTHROUGH*/
5578+ case S_IFIFO:
5579+ case S_IFSOCK:
5580+ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
5581+ break;
5582+ default:
5583+ AuIOErr("Unknown inode type 0%o\n", mode);
5584+ err = -EIO;
5585+ }
5586+ if (!err)
5587+ err = au_reset_acl(h_dir, &h_path, mode);
5588+
5589+ mnt_flags = au_mntflags(sb);
5590+ if (!au_opt_test(mnt_flags, UDBA_NONE)
5591+ && !isdir
5592+ && au_opt_test(mnt_flags, XINO)
5593+ && (h_inode->i_nlink == 1
5594+ || (h_inode->i_state & I_LINKABLE))
5595+ /* todo: unnecessary? */
5596+ /* && d_inode(cpg->dentry)->i_nlink == 1 */
5597+ && cpg->bdst < cpg->bsrc
5598+ && !au_ftest_cpup(cpg->flags, KEEPLINO))
5599+ au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0);
5600+ /* ignore this error */
5601+
5602+ if (!err) {
5603+ force = 0;
5604+ if (isreg) {
5605+ force = !!cpg->len;
5606+ if (cpg->len == -1)
5607+ force = !!i_size_read(h_inode);
5608+ }
5609+ au_fhsm_wrote(sb, cpg->bdst, force);
5610+ }
5611+
5612+ if (do_dt)
5613+ au_dtime_revert(&dt);
5614+ return err;
5615+}
5616+
5617+static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path)
5618+{
5619+ int err;
5620+ struct dentry *dentry, *h_dentry, *h_parent, *parent;
5621+ struct inode *h_dir;
5622+ aufs_bindex_t bdst;
5623+
5624+ dentry = cpg->dentry;
5625+ bdst = cpg->bdst;
5626+ h_dentry = au_h_dptr(dentry, bdst);
5627+ if (!au_ftest_cpup(cpg->flags, OVERWRITE)) {
5628+ dget(h_dentry);
5629+ au_set_h_dptr(dentry, bdst, NULL);
5630+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
5631+ if (!err)
5632+ h_path->dentry = dget(au_h_dptr(dentry, bdst));
5633+ au_set_h_dptr(dentry, bdst, h_dentry);
5634+ } else {
5635+ err = 0;
5636+ parent = dget_parent(dentry);
5637+ h_parent = au_h_dptr(parent, bdst);
5638+ dput(parent);
5639+ h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
5640+ if (IS_ERR(h_path->dentry))
5641+ err = PTR_ERR(h_path->dentry);
5642+ }
5643+ if (unlikely(err))
5644+ goto out;
5645+
5646+ h_parent = h_dentry->d_parent; /* dir inode is locked */
5647+ h_dir = d_inode(h_parent);
5648+ IMustLock(h_dir);
5649+ AuDbg("%pd %pd\n", h_dentry, h_path->dentry);
5650+ /* no delegation since it is just created */
5651+ err = vfsub_rename(h_dir, h_dentry, h_dir, h_path, /*delegated*/NULL,
5652+ /*flags*/0);
5653+ dput(h_path->dentry);
5654+
5655+out:
5656+ return err;
5657+}
5658+
5659+/*
5660+ * copyup the @dentry from @bsrc to @bdst.
5661+ * the caller must set the both of lower dentries.
5662+ * @len is for truncating when it is -1 copyup the entire file.
5663+ * in link/rename cases, @dst_parent may be different from the real one.
5664+ * basic->bsrc can be larger than basic->bdst.
5665+ * aufs doesn't touch the credential so
5666+ * security_inode_copy_up{,_xattr}() are unnecessary.
5667+ */
5668+static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
5669+{
5670+ int err, rerr;
5671+ aufs_bindex_t old_ibtop;
5672+ unsigned char isdir, plink;
5673+ struct dentry *h_src, *h_dst, *h_parent;
5674+ struct inode *dst_inode, *h_dir, *inode, *delegated, *src_inode;
5675+ struct super_block *sb;
5676+ struct au_branch *br;
5677+ /* to reduce stack size */
5678+ struct {
5679+ struct au_dtime dt;
5680+ struct path h_path;
5681+ struct au_cpup_reg_attr h_src_attr;
5682+ } *a;
5683+
5684+ err = -ENOMEM;
5685+ a = kmalloc(sizeof(*a), GFP_NOFS);
5686+ if (unlikely(!a))
5687+ goto out;
5688+ a->h_src_attr.valid = 0;
5689+
5690+ sb = cpg->dentry->d_sb;
5691+ br = au_sbr(sb, cpg->bdst);
5692+ a->h_path.mnt = au_br_mnt(br);
5693+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
5694+ h_parent = h_dst->d_parent; /* dir inode is locked */
5695+ h_dir = d_inode(h_parent);
5696+ IMustLock(h_dir);
5697+
5698+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
5699+ inode = d_inode(cpg->dentry);
5700+
5701+ if (!dst_parent)
5702+ dst_parent = dget_parent(cpg->dentry);
5703+ else
5704+ dget(dst_parent);
5705+
5706+ plink = !!au_opt_test(au_mntflags(sb), PLINK);
5707+ dst_inode = au_h_iptr(inode, cpg->bdst);
5708+ if (dst_inode) {
5709+ if (unlikely(!plink)) {
5710+ err = -EIO;
5711+ AuIOErr("hi%lu(i%lu) exists on b%d "
5712+ "but plink is disabled\n",
5713+ dst_inode->i_ino, inode->i_ino, cpg->bdst);
5714+ goto out_parent;
5715+ }
5716+
5717+ if (dst_inode->i_nlink) {
5718+ const int do_dt = au_ftest_cpup(cpg->flags, DTIME);
5719+
5720+ h_src = au_plink_lkup(inode, cpg->bdst);
5721+ err = PTR_ERR(h_src);
5722+ if (IS_ERR(h_src))
5723+ goto out_parent;
5724+ if (unlikely(d_is_negative(h_src))) {
5725+ err = -EIO;
5726+ AuIOErr("i%lu exists on b%d "
5727+ "but not pseudo-linked\n",
5728+ inode->i_ino, cpg->bdst);
5729+ dput(h_src);
5730+ goto out_parent;
5731+ }
5732+
5733+ if (do_dt) {
5734+ a->h_path.dentry = h_parent;
5735+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
5736+ }
5737+
5738+ a->h_path.dentry = h_dst;
5739+ delegated = NULL;
5740+ err = vfsub_link(h_src, h_dir, &a->h_path, &delegated);
5741+ if (!err && au_ftest_cpup(cpg->flags, RENAME))
5742+ err = au_do_ren_after_cpup(cpg, &a->h_path);
5743+ if (do_dt)
5744+ au_dtime_revert(&a->dt);
5745+ if (unlikely(err == -EWOULDBLOCK)) {
5746+ pr_warn("cannot retry for NFSv4 delegation"
5747+ " for an internal link\n");
5748+ iput(delegated);
5749+ }
5750+ dput(h_src);
5751+ goto out_parent;
5752+ } else
5753+ /* todo: cpup_wh_file? */
5754+ /* udba work */
5755+ au_update_ibrange(inode, /*do_put_zero*/1);
5756+ }
5757+
5758+ isdir = S_ISDIR(inode->i_mode);
5759+ old_ibtop = au_ibtop(inode);
5760+ err = cpup_entry(cpg, dst_parent, &a->h_src_attr);
5761+ if (unlikely(err))
5762+ goto out_rev;
5763+ dst_inode = d_inode(h_dst);
5764+ inode_lock_nested(dst_inode, AuLsc_I_CHILD2);
5765+ /* todo: necessary? */
5766+ /* au_pin_hdir_unlock(cpg->pin); */
5767+
5768+ err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &a->h_src_attr);
5769+ if (unlikely(err)) {
5770+ /* todo: necessary? */
5771+ /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */
5772+ inode_unlock(dst_inode);
5773+ goto out_rev;
5774+ }
5775+
5776+ if (cpg->bdst < old_ibtop) {
5777+ if (S_ISREG(inode->i_mode)) {
5778+ err = au_dy_iaop(inode, cpg->bdst, dst_inode);
5779+ if (unlikely(err)) {
5780+ /* ignore an error */
5781+ /* au_pin_hdir_relock(cpg->pin); */
5782+ inode_unlock(dst_inode);
5783+ goto out_rev;
5784+ }
5785+ }
5786+ au_set_ibtop(inode, cpg->bdst);
5787+ } else
5788+ au_set_ibbot(inode, cpg->bdst);
5789+ au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode),
5790+ au_hi_flags(inode, isdir));
5791+
5792+ /* todo: necessary? */
5793+ /* err = au_pin_hdir_relock(cpg->pin); */
5794+ inode_unlock(dst_inode);
5795+ if (unlikely(err))
5796+ goto out_rev;
5797+
5798+ src_inode = d_inode(h_src);
5799+ if (!isdir
5800+ && (src_inode->i_nlink > 1
5801+ || src_inode->i_state & I_LINKABLE)
5802+ && plink)
5803+ au_plink_append(inode, cpg->bdst, h_dst);
5804+
5805+ if (au_ftest_cpup(cpg->flags, RENAME)) {
5806+ a->h_path.dentry = h_dst;
5807+ err = au_do_ren_after_cpup(cpg, &a->h_path);
5808+ }
5809+ if (!err)
5810+ goto out_parent; /* success */
5811+
5812+ /* revert */
5813+out_rev:
5814+ a->h_path.dentry = h_parent;
5815+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
5816+ a->h_path.dentry = h_dst;
5817+ rerr = 0;
5818+ if (d_is_positive(h_dst)) {
5819+ if (!isdir) {
5820+ /* no delegation since it is just created */
5821+ rerr = vfsub_unlink(h_dir, &a->h_path,
5822+ /*delegated*/NULL, /*force*/0);
5823+ } else
5824+ rerr = vfsub_rmdir(h_dir, &a->h_path);
5825+ }
5826+ au_dtime_revert(&a->dt);
5827+ if (rerr) {
5828+ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
5829+ err = -EIO;
5830+ }
5831+out_parent:
5832+ dput(dst_parent);
5833+ au_kfree_rcu(a);
5834+out:
5835+ return err;
5836+}
5837+
5838+#if 0 /* reserved */
5839+struct au_cpup_single_args {
5840+ int *errp;
5841+ struct au_cp_generic *cpg;
5842+ struct dentry *dst_parent;
5843+};
5844+
5845+static void au_call_cpup_single(void *args)
5846+{
5847+ struct au_cpup_single_args *a = args;
5848+
5849+ au_pin_hdir_acquire_nest(a->cpg->pin);
5850+ *a->errp = au_cpup_single(a->cpg, a->dst_parent);
5851+ au_pin_hdir_release(a->cpg->pin);
5852+}
5853+#endif
5854+
5855+/*
5856+ * prevent SIGXFSZ in copy-up.
5857+ * testing CAP_MKNOD is for generic fs,
5858+ * but CAP_FSETID is for xfs only, currently.
5859+ */
5860+static int au_cpup_sio_test(struct au_pin *pin, umode_t mode)
5861+{
5862+ int do_sio;
5863+ struct super_block *sb;
5864+ struct inode *h_dir;
5865+
5866+ do_sio = 0;
5867+ sb = au_pinned_parent(pin)->d_sb;
5868+ if (!au_wkq_test()
5869+ && (!au_sbi(sb)->si_plink_maint_pid
5870+ || au_plink_maint(sb, AuLock_NOPLM))) {
5871+ switch (mode & S_IFMT) {
5872+ case S_IFREG:
5873+ /* no condition about RLIMIT_FSIZE and the file size */
5874+ do_sio = 1;
5875+ break;
5876+ case S_IFCHR:
5877+ case S_IFBLK:
5878+ do_sio = !capable(CAP_MKNOD);
5879+ break;
5880+ }
5881+ if (!do_sio)
5882+ do_sio = ((mode & (S_ISUID | S_ISGID))
5883+ && !capable(CAP_FSETID));
5884+ /* this workaround may be removed in the future */
5885+ if (!do_sio) {
5886+ h_dir = au_pinned_h_dir(pin);
5887+ do_sio = h_dir->i_mode & S_ISVTX;
5888+ }
5889+ }
5890+
5891+ return do_sio;
5892+}
5893+
5894+#if 0 /* reserved */
5895+int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
5896+{
5897+ int err, wkq_err;
5898+ struct dentry *h_dentry;
5899+
5900+ h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
5901+ if (!au_cpup_sio_test(pin, d_inode(h_dentry)->i_mode))
5902+ err = au_cpup_single(cpg, dst_parent);
5903+ else {
5904+ struct au_cpup_single_args args = {
5905+ .errp = &err,
5906+ .cpg = cpg,
5907+ .dst_parent = dst_parent
5908+ };
5909+ wkq_err = au_wkq_wait(au_call_cpup_single, &args);
5910+ if (unlikely(wkq_err))
5911+ err = wkq_err;
5912+ }
5913+
5914+ return err;
5915+}
5916+#endif
5917+
5918+/*
5919+ * copyup the @dentry from the first active lower branch to @bdst,
5920+ * using au_cpup_single().
5921+ */
5922+static int au_cpup_simple(struct au_cp_generic *cpg)
5923+{
5924+ int err;
5925+ unsigned int flags_orig;
5926+ struct dentry *dentry;
5927+
5928+ AuDebugOn(cpg->bsrc < 0);
5929+
5930+ dentry = cpg->dentry;
5931+ DiMustWriteLock(dentry);
5932+
5933+ err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1);
5934+ if (!err) {
5935+ flags_orig = cpg->flags;
5936+ au_fset_cpup(cpg->flags, RENAME);
5937+ err = au_cpup_single(cpg, NULL);
5938+ cpg->flags = flags_orig;
5939+ if (!err)
5940+ return 0; /* success */
5941+
5942+ /* revert */
5943+ au_set_h_dptr(dentry, cpg->bdst, NULL);
5944+ au_set_dbtop(dentry, cpg->bsrc);
5945+ }
5946+
5947+ return err;
5948+}
5949+
5950+struct au_cpup_simple_args {
5951+ int *errp;
5952+ struct au_cp_generic *cpg;
5953+};
5954+
5955+static void au_call_cpup_simple(void *args)
5956+{
5957+ struct au_cpup_simple_args *a = args;
5958+
5959+ au_pin_hdir_acquire_nest(a->cpg->pin);
5960+ *a->errp = au_cpup_simple(a->cpg);
5961+ au_pin_hdir_release(a->cpg->pin);
5962+}
5963+
5964+static int au_do_sio_cpup_simple(struct au_cp_generic *cpg)
5965+{
5966+ int err, wkq_err;
5967+ struct dentry *dentry, *parent;
5968+ struct file *h_file;
5969+ struct inode *h_dir;
5970+
5971+ dentry = cpg->dentry;
5972+ h_file = NULL;
5973+ if (au_ftest_cpup(cpg->flags, HOPEN)) {
5974+ AuDebugOn(cpg->bsrc < 0);
5975+ h_file = au_h_open_pre(dentry, cpg->bsrc, /*force_wr*/0);
5976+ err = PTR_ERR(h_file);
5977+ if (IS_ERR(h_file))
5978+ goto out;
5979+ }
5980+
5981+ parent = dget_parent(dentry);
5982+ h_dir = au_h_iptr(d_inode(parent), cpg->bdst);
5983+ if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
5984+ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode))
5985+ err = au_cpup_simple(cpg);
5986+ else {
5987+ struct au_cpup_simple_args args = {
5988+ .errp = &err,
5989+ .cpg = cpg
5990+ };
5991+ wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
5992+ if (unlikely(wkq_err))
5993+ err = wkq_err;
5994+ }
5995+
5996+ dput(parent);
5997+ if (h_file)
5998+ au_h_open_post(dentry, cpg->bsrc, h_file);
5999+
6000+out:
6001+ return err;
6002+}
6003+
6004+int au_sio_cpup_simple(struct au_cp_generic *cpg)
6005+{
6006+ aufs_bindex_t bsrc, bbot;
6007+ struct dentry *dentry, *h_dentry;
6008+
6009+ if (cpg->bsrc < 0) {
6010+ dentry = cpg->dentry;
6011+ bbot = au_dbbot(dentry);
6012+ for (bsrc = cpg->bdst + 1; bsrc <= bbot; bsrc++) {
6013+ h_dentry = au_h_dptr(dentry, bsrc);
6014+ if (h_dentry) {
6015+ AuDebugOn(d_is_negative(h_dentry));
6016+ break;
6017+ }
6018+ }
6019+ AuDebugOn(bsrc > bbot);
6020+ cpg->bsrc = bsrc;
6021+ }
6022+ AuDebugOn(cpg->bsrc <= cpg->bdst);
6023+ return au_do_sio_cpup_simple(cpg);
6024+}
6025+
6026+int au_sio_cpdown_simple(struct au_cp_generic *cpg)
6027+{
6028+ AuDebugOn(cpg->bdst <= cpg->bsrc);
6029+ return au_do_sio_cpup_simple(cpg);
6030+}
6031+
6032+/* ---------------------------------------------------------------------- */
6033+
6034+/*
6035+ * copyup the deleted file for writing.
6036+ */
6037+static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry,
6038+ struct file *file)
6039+{
6040+ int err;
6041+ unsigned int flags_orig;
6042+ aufs_bindex_t bsrc_orig;
6043+ struct au_dinfo *dinfo;
6044+ struct {
6045+ struct au_hdentry *hd;
6046+ struct dentry *h_dentry;
6047+ } hdst, hsrc;
6048+
6049+ dinfo = au_di(cpg->dentry);
6050+ AuRwMustWriteLock(&dinfo->di_rwsem);
6051+
6052+ bsrc_orig = cpg->bsrc;
6053+ cpg->bsrc = dinfo->di_btop;
6054+ hdst.hd = au_hdentry(dinfo, cpg->bdst);
6055+ hdst.h_dentry = hdst.hd->hd_dentry;
6056+ hdst.hd->hd_dentry = wh_dentry;
6057+ dinfo->di_btop = cpg->bdst;
6058+
6059+ hsrc.h_dentry = NULL;
6060+ if (file) {
6061+ hsrc.hd = au_hdentry(dinfo, cpg->bsrc);
6062+ hsrc.h_dentry = hsrc.hd->hd_dentry;
6063+ hsrc.hd->hd_dentry = au_hf_top(file)->f_path.dentry;
6064+ }
6065+ flags_orig = cpg->flags;
6066+ cpg->flags = !AuCpup_DTIME;
6067+ err = au_cpup_single(cpg, /*h_parent*/NULL);
6068+ cpg->flags = flags_orig;
6069+ if (file) {
6070+ if (!err)
6071+ err = au_reopen_nondir(file);
6072+ hsrc.hd->hd_dentry = hsrc.h_dentry;
6073+ }
6074+ hdst.hd->hd_dentry = hdst.h_dentry;
6075+ dinfo->di_btop = cpg->bsrc;
6076+ cpg->bsrc = bsrc_orig;
6077+
6078+ return err;
6079+}
6080+
6081+static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file)
6082+{
6083+ int err;
6084+ aufs_bindex_t bdst;
6085+ struct au_dtime dt;
6086+ struct dentry *dentry, *parent, *h_parent, *wh_dentry;
6087+ struct au_branch *br;
6088+ struct path h_path;
6089+
6090+ dentry = cpg->dentry;
6091+ bdst = cpg->bdst;
6092+ br = au_sbr(dentry->d_sb, bdst);
6093+ parent = dget_parent(dentry);
6094+ h_parent = au_h_dptr(parent, bdst);
6095+ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
6096+ err = PTR_ERR(wh_dentry);
6097+ if (IS_ERR(wh_dentry))
6098+ goto out;
6099+
6100+ h_path.dentry = h_parent;
6101+ h_path.mnt = au_br_mnt(br);
6102+ au_dtime_store(&dt, parent, &h_path);
6103+ err = au_do_cpup_wh(cpg, wh_dentry, file);
6104+ if (unlikely(err))
6105+ goto out_wh;
6106+
6107+ dget(wh_dentry);
6108+ h_path.dentry = wh_dentry;
6109+ if (!d_is_dir(wh_dentry)) {
6110+ /* no delegation since it is just created */
6111+ err = vfsub_unlink(d_inode(h_parent), &h_path,
6112+ /*delegated*/NULL, /*force*/0);
6113+ } else
6114+ err = vfsub_rmdir(d_inode(h_parent), &h_path);
6115+ if (unlikely(err)) {
6116+ AuIOErr("failed remove copied-up tmp file %pd(%d)\n",
6117+ wh_dentry, err);
6118+ err = -EIO;
6119+ }
6120+ au_dtime_revert(&dt);
6121+ au_set_hi_wh(d_inode(dentry), bdst, wh_dentry);
6122+
6123+out_wh:
6124+ dput(wh_dentry);
6125+out:
6126+ dput(parent);
6127+ return err;
6128+}
6129+
6130+struct au_cpup_wh_args {
6131+ int *errp;
6132+ struct au_cp_generic *cpg;
6133+ struct file *file;
6134+};
6135+
6136+static void au_call_cpup_wh(void *args)
6137+{
6138+ struct au_cpup_wh_args *a = args;
6139+
6140+ au_pin_hdir_acquire_nest(a->cpg->pin);
6141+ *a->errp = au_cpup_wh(a->cpg, a->file);
6142+ au_pin_hdir_release(a->cpg->pin);
6143+}
6144+
6145+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file)
6146+{
6147+ int err, wkq_err;
6148+ aufs_bindex_t bdst;
6149+ struct dentry *dentry, *parent, *h_orph, *h_parent;
6150+ struct inode *dir, *h_dir, *h_tmpdir;
6151+ struct au_wbr *wbr;
6152+ struct au_pin wh_pin, *pin_orig;
6153+
6154+ dentry = cpg->dentry;
6155+ bdst = cpg->bdst;
6156+ parent = dget_parent(dentry);
6157+ dir = d_inode(parent);
6158+ h_orph = NULL;
6159+ h_parent = NULL;
6160+ h_dir = au_igrab(au_h_iptr(dir, bdst));
6161+ h_tmpdir = h_dir;
6162+ pin_orig = NULL;
6163+ if (!h_dir->i_nlink) {
6164+ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
6165+ h_orph = wbr->wbr_orph;
6166+
6167+ h_parent = dget(au_h_dptr(parent, bdst));
6168+ au_set_h_dptr(parent, bdst, dget(h_orph));
6169+ h_tmpdir = d_inode(h_orph);
6170+ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
6171+
6172+ inode_lock_nested(h_tmpdir, AuLsc_I_PARENT3);
6173+ /* todo: au_h_open_pre()? */
6174+
6175+ pin_orig = cpg->pin;
6176+ au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT,
6177+ AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED);
6178+ cpg->pin = &wh_pin;
6179+ }
6180+
6181+ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
6182+ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode))
6183+ err = au_cpup_wh(cpg, file);
6184+ else {
6185+ struct au_cpup_wh_args args = {
6186+ .errp = &err,
6187+ .cpg = cpg,
6188+ .file = file
6189+ };
6190+ wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
6191+ if (unlikely(wkq_err))
6192+ err = wkq_err;
6193+ }
6194+
6195+ if (h_orph) {
6196+ inode_unlock(h_tmpdir);
6197+ /* todo: au_h_open_post()? */
6198+ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
6199+ au_set_h_dptr(parent, bdst, h_parent);
6200+ AuDebugOn(!pin_orig);
6201+ cpg->pin = pin_orig;
6202+ }
6203+ iput(h_dir);
6204+ dput(parent);
6205+
6206+ return err;
6207+}
6208+
6209+/* ---------------------------------------------------------------------- */
6210+
6211+/*
6212+ * generic routine for both of copy-up and copy-down.
6213+ */
6214+/* cf. revalidate function in file.c */
6215+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
6216+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
6217+ struct au_pin *pin,
6218+ struct dentry *h_parent, void *arg),
6219+ void *arg)
6220+{
6221+ int err;
6222+ struct au_pin pin;
6223+ struct dentry *d, *parent, *h_parent, *real_parent, *h_dentry;
6224+
6225+ err = 0;
6226+ parent = dget_parent(dentry);
6227+ if (IS_ROOT(parent))
6228+ goto out;
6229+
6230+ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
6231+ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
6232+
6233+ /* do not use au_dpage */
6234+ real_parent = parent;
6235+ while (1) {
6236+ dput(parent);
6237+ parent = dget_parent(dentry);
6238+ h_parent = au_h_dptr(parent, bdst);
6239+ if (h_parent)
6240+ goto out; /* success */
6241+
6242+ /* find top dir which is necessary to cpup */
6243+ do {
6244+ d = parent;
6245+ dput(parent);
6246+ parent = dget_parent(d);
6247+ di_read_lock_parent3(parent, !AuLock_IR);
6248+ h_parent = au_h_dptr(parent, bdst);
6249+ di_read_unlock(parent, !AuLock_IR);
6250+ } while (!h_parent);
6251+
6252+ if (d != real_parent)
6253+ di_write_lock_child3(d);
6254+
6255+ /* somebody else might create while we were sleeping */
6256+ h_dentry = au_h_dptr(d, bdst);
6257+ if (!h_dentry || d_is_negative(h_dentry)) {
6258+ if (h_dentry)
6259+ au_update_dbtop(d);
6260+
6261+ au_pin_set_dentry(&pin, d);
6262+ err = au_do_pin(&pin);
6263+ if (!err) {
6264+ err = cp(d, bdst, &pin, h_parent, arg);
6265+ au_unpin(&pin);
6266+ }
6267+ }
6268+
6269+ if (d != real_parent)
6270+ di_write_unlock(d);
6271+ if (unlikely(err))
6272+ break;
6273+ }
6274+
6275+out:
6276+ dput(parent);
6277+ return err;
6278+}
6279+
6280+static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
6281+ struct au_pin *pin,
6282+ struct dentry *h_parent __maybe_unused,
6283+ void *arg __maybe_unused)
6284+{
6285+ struct au_cp_generic cpg = {
6286+ .dentry = dentry,
6287+ .bdst = bdst,
6288+ .bsrc = -1,
6289+ .len = 0,
6290+ .pin = pin,
6291+ .flags = AuCpup_DTIME
6292+ };
6293+ return au_sio_cpup_simple(&cpg);
6294+}
6295+
6296+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
6297+{
6298+ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
6299+}
6300+
6301+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
6302+{
6303+ int err;
6304+ struct dentry *parent;
6305+ struct inode *dir;
6306+
6307+ parent = dget_parent(dentry);
6308+ dir = d_inode(parent);
6309+ err = 0;
6310+ if (au_h_iptr(dir, bdst))
6311+ goto out;
6312+
6313+ di_read_unlock(parent, AuLock_IR);
6314+ di_write_lock_parent(parent);
6315+ /* someone else might change our inode while we were sleeping */
6316+ if (!au_h_iptr(dir, bdst))
6317+ err = au_cpup_dirs(dentry, bdst);
6318+ di_downgrade_lock(parent, AuLock_IR);
6319+
6320+out:
6321+ dput(parent);
6322+ return err;
6323+}
6324diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
6325--- /usr/share/empty/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100
6326+++ linux/fs/aufs/cpup.h 2020-01-27 10:57:18.168871450 +0100
6327@@ -0,0 +1,100 @@
6328+/* SPDX-License-Identifier: GPL-2.0 */
6329+/*
6330+ * Copyright (C) 2005-2020 Junjiro R. Okajima
6331+ *
6332+ * This program, aufs is free software; you can redistribute it and/or modify
6333+ * it under the terms of the GNU General Public License as published by
6334+ * the Free Software Foundation; either version 2 of the License, or
6335+ * (at your option) any later version.
6336+ *
6337+ * This program is distributed in the hope that it will be useful,
6338+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6339+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6340+ * GNU General Public License for more details.
6341+ *
6342+ * You should have received a copy of the GNU General Public License
6343+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
6344+ */
6345+
6346+/*
6347+ * copy-up/down functions
6348+ */
6349+
6350+#ifndef __AUFS_CPUP_H__
6351+#define __AUFS_CPUP_H__
6352+
6353+#ifdef __KERNEL__
6354+
6355+#include <linux/path.h>
6356+
6357+struct inode;
6358+struct file;
6359+struct au_pin;
6360+
6361+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags);
6362+void au_cpup_attr_timesizes(struct inode *inode);
6363+void au_cpup_attr_nlink(struct inode *inode, int force);
6364+void au_cpup_attr_changeable(struct inode *inode);
6365+void au_cpup_igen(struct inode *inode, struct inode *h_inode);
6366+void au_cpup_attr_all(struct inode *inode, int force);
6367+
6368+/* ---------------------------------------------------------------------- */
6369+
6370+struct au_cp_generic {
6371+ struct dentry *dentry;
6372+ aufs_bindex_t bdst, bsrc;
6373+ loff_t len;
6374+ struct au_pin *pin;
6375+ unsigned int flags;
6376+};
6377+
6378+/* cpup flags */
6379+#define AuCpup_DTIME 1 /* do dtime_store/revert */
6380+#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino,
6381+ for link(2) */
6382+#define AuCpup_RENAME (1 << 2) /* rename after cpup */
6383+#define AuCpup_HOPEN (1 << 3) /* call h_open_pre/post() in
6384+ cpup */
6385+#define AuCpup_OVERWRITE (1 << 4) /* allow overwriting the
6386+ existing entry */
6387+#define AuCpup_RWDST (1 << 5) /* force write target even if
6388+ the branch is marked as RO */
6389+
6390+#ifndef CONFIG_AUFS_BR_HFSPLUS
6391+#undef AuCpup_HOPEN
6392+#define AuCpup_HOPEN 0
6393+#endif
6394+
6395+#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name)
6396+#define au_fset_cpup(flags, name) \
6397+ do { (flags) |= AuCpup_##name; } while (0)
6398+#define au_fclr_cpup(flags, name) \
6399+ do { (flags) &= ~AuCpup_##name; } while (0)
6400+
6401+int au_copy_file(struct file *dst, struct file *src, loff_t len);
6402+int au_sio_cpup_simple(struct au_cp_generic *cpg);
6403+int au_sio_cpdown_simple(struct au_cp_generic *cpg);
6404+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file);
6405+
6406+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
6407+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
6408+ struct au_pin *pin,
6409+ struct dentry *h_parent, void *arg),
6410+ void *arg);
6411+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
6412+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
6413+
6414+/* ---------------------------------------------------------------------- */
6415+
6416+/* keep timestamps when copyup */
6417+struct au_dtime {
6418+ struct dentry *dt_dentry;
6419+ struct path dt_h_path;
6420+ struct timespec64 dt_atime, dt_mtime;
6421+};
6422+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
6423+ struct path *h_path);
6424+void au_dtime_revert(struct au_dtime *dt);
6425+
6426+#endif /* __KERNEL__ */
6427+#endif /* __AUFS_CPUP_H__ */
6428diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
6429--- /usr/share/empty/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
6430+++ linux/fs/aufs/dbgaufs.c 2020-01-27 10:57:18.168871450 +0100
6431@@ -0,0 +1,526 @@
6432+// SPDX-License-Identifier: GPL-2.0
6433+/*
6434+ * Copyright (C) 2005-2020 Junjiro R. Okajima
6435+ *
6436+ * This program, aufs is free software; you can redistribute it and/or modify
6437+ * it under the terms of the GNU General Public License as published by
6438+ * the Free Software Foundation; either version 2 of the License, or
6439+ * (at your option) any later version.
6440+ *
6441+ * This program is distributed in the hope that it will be useful,
6442+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6443+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6444+ * GNU General Public License for more details.
6445+ *
6446+ * You should have received a copy of the GNU General Public License
6447+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
6448+ */
6449+
6450+/*
6451+ * debugfs interface
6452+ */
6453+
6454+#include <linux/debugfs.h>
6455+#include "aufs.h"
6456+
6457+#ifndef CONFIG_SYSFS
6458+#error DEBUG_FS depends upon SYSFS
6459+#endif
6460+
6461+static struct dentry *dbgaufs;
6462+static const mode_t dbgaufs_mode = 0444;
6463+
6464+/* 20 is max digits length of ulong 64 */
6465+struct dbgaufs_arg {
6466+ int n;
6467+ char a[20 * 4];
6468+};
6469+
6470+/*
6471+ * common function for all XINO files
6472+ */
6473+static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
6474+ struct file *file)
6475+{
6476+ void *p;
6477+
6478+ p = file->private_data;
6479+ if (p) {
6480+ /* this is struct dbgaufs_arg */
6481+ AuDebugOn(!au_kfree_sz_test(p));
6482+ au_kfree_do_rcu(p);
6483+ }
6484+ return 0;
6485+}
6486+
6487+static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt,
6488+ int cnt)
6489+{
6490+ int err;
6491+ struct kstat st;
6492+ struct dbgaufs_arg *p;
6493+
6494+ err = -ENOMEM;
6495+ p = kmalloc(sizeof(*p), GFP_NOFS);
6496+ if (unlikely(!p))
6497+ goto out;
6498+
6499+ err = 0;
6500+ p->n = 0;
6501+ file->private_data = p;
6502+ if (!xf)
6503+ goto out;
6504+
6505+ err = vfsub_getattr(&xf->f_path, &st);
6506+ if (!err) {
6507+ if (do_fcnt)
6508+ p->n = snprintf
6509+ (p->a, sizeof(p->a), "%d, %llux%u %lld\n",
6510+ cnt, st.blocks, st.blksize,
6511+ (long long)st.size);
6512+ else
6513+ p->n = snprintf(p->a, sizeof(p->a), "%llux%u %lld\n",
6514+ st.blocks, st.blksize,
6515+ (long long)st.size);
6516+ AuDebugOn(p->n >= sizeof(p->a));
6517+ } else {
6518+ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
6519+ err = 0;
6520+ }
6521+
6522+out:
6523+ return err;
6524+}
6525+
6526+static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
6527+ size_t count, loff_t *ppos)
6528+{
6529+ struct dbgaufs_arg *p;
6530+
6531+ p = file->private_data;
6532+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
6533+}
6534+
6535+/* ---------------------------------------------------------------------- */
6536+
6537+struct dbgaufs_plink_arg {
6538+ int n;
6539+ char a[];
6540+};
6541+
6542+static int dbgaufs_plink_release(struct inode *inode __maybe_unused,
6543+ struct file *file)
6544+{
6545+ free_page((unsigned long)file->private_data);
6546+ return 0;
6547+}
6548+
6549+static int dbgaufs_plink_open(struct inode *inode, struct file *file)
6550+{
6551+ int err, i, limit;
6552+ unsigned long n, sum;
6553+ struct dbgaufs_plink_arg *p;
6554+ struct au_sbinfo *sbinfo;
6555+ struct super_block *sb;
6556+ struct hlist_bl_head *hbl;
6557+
6558+ err = -ENOMEM;
6559+ p = (void *)get_zeroed_page(GFP_NOFS);
6560+ if (unlikely(!p))
6561+ goto out;
6562+
6563+ err = -EFBIG;
6564+ sbinfo = inode->i_private;
6565+ sb = sbinfo->si_sb;
6566+ si_noflush_read_lock(sb);
6567+ if (au_opt_test(au_mntflags(sb), PLINK)) {
6568+ limit = PAGE_SIZE - sizeof(p->n);
6569+
6570+ /* the number of buckets */
6571+ n = snprintf(p->a + p->n, limit, "%d\n", AuPlink_NHASH);
6572+ p->n += n;
6573+ limit -= n;
6574+
6575+ sum = 0;
6576+ for (i = 0, hbl = sbinfo->si_plink; i < AuPlink_NHASH;
6577+ i++, hbl++) {
6578+ n = au_hbl_count(hbl);
6579+ sum += n;
6580+
6581+ n = snprintf(p->a + p->n, limit, "%lu ", n);
6582+ p->n += n;
6583+ limit -= n;
6584+ if (unlikely(limit <= 0))
6585+ goto out_free;
6586+ }
6587+ p->a[p->n - 1] = '\n';
6588+
6589+ /* the sum of plinks */
6590+ n = snprintf(p->a + p->n, limit, "%lu\n", sum);
6591+ p->n += n;
6592+ limit -= n;
6593+ if (unlikely(limit <= 0))
6594+ goto out_free;
6595+ } else {
6596+#define str "1\n0\n0\n"
6597+ p->n = sizeof(str) - 1;
6598+ strcpy(p->a, str);
6599+#undef str
6600+ }
6601+ si_read_unlock(sb);
6602+
6603+ err = 0;
6604+ file->private_data = p;
6605+ goto out; /* success */
6606+
6607+out_free:
6608+ free_page((unsigned long)p);
6609+out:
6610+ return err;
6611+}
6612+
6613+static ssize_t dbgaufs_plink_read(struct file *file, char __user *buf,
6614+ size_t count, loff_t *ppos)
6615+{
6616+ struct dbgaufs_plink_arg *p;
6617+
6618+ p = file->private_data;
6619+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
6620+}
6621+
6622+static const struct file_operations dbgaufs_plink_fop = {
6623+ .owner = THIS_MODULE,
6624+ .open = dbgaufs_plink_open,
6625+ .release = dbgaufs_plink_release,
6626+ .read = dbgaufs_plink_read
6627+};
6628+
6629+/* ---------------------------------------------------------------------- */
6630+
6631+static int dbgaufs_xib_open(struct inode *inode, struct file *file)
6632+{
6633+ int err;
6634+ struct au_sbinfo *sbinfo;
6635+ struct super_block *sb;
6636+
6637+ sbinfo = inode->i_private;
6638+ sb = sbinfo->si_sb;
6639+ si_noflush_read_lock(sb);
6640+ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0, /*cnt*/0);
6641+ si_read_unlock(sb);
6642+ return err;
6643+}
6644+
6645+static const struct file_operations dbgaufs_xib_fop = {
6646+ .owner = THIS_MODULE,
6647+ .open = dbgaufs_xib_open,
6648+ .release = dbgaufs_xi_release,
6649+ .read = dbgaufs_xi_read
6650+};
6651+
6652+/* ---------------------------------------------------------------------- */
6653+
6654+#define DbgaufsXi_PREFIX "xi"
6655+
6656+static int dbgaufs_xino_open(struct inode *inode, struct file *file)
6657+{
6658+ int err, idx;
6659+ long l;
6660+ aufs_bindex_t bindex;
6661+ char *p, a[sizeof(DbgaufsXi_PREFIX) + 8];
6662+ struct au_sbinfo *sbinfo;
6663+ struct super_block *sb;
6664+ struct au_xino *xi;
6665+ struct file *xf;
6666+ struct qstr *name;
6667+ struct au_branch *br;
6668+
6669+ err = -ENOENT;
6670+ name = &file->f_path.dentry->d_name;
6671+ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
6672+ || memcmp(name->name, DbgaufsXi_PREFIX,
6673+ sizeof(DbgaufsXi_PREFIX) - 1)))
6674+ goto out;
6675+
6676+ AuDebugOn(name->len >= sizeof(a));
6677+ memcpy(a, name->name, name->len);
6678+ a[name->len] = '\0';
6679+ p = strchr(a, '-');
6680+ if (p)
6681+ *p = '\0';
6682+ err = kstrtol(a + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
6683+ if (unlikely(err))
6684+ goto out;
6685+ bindex = l;
6686+ idx = 0;
6687+ if (p) {
6688+ err = kstrtol(p + 1, 10, &l);
6689+ if (unlikely(err))
6690+ goto out;
6691+ idx = l;
6692+ }
6693+
6694+ err = -ENOENT;
6695+ sbinfo = inode->i_private;
6696+ sb = sbinfo->si_sb;
6697+ si_noflush_read_lock(sb);
6698+ if (unlikely(bindex < 0 || bindex > au_sbbot(sb)))
6699+ goto out_si;
6700+ br = au_sbr(sb, bindex);
6701+ xi = br->br_xino;
6702+ if (unlikely(idx >= xi->xi_nfile))
6703+ goto out_si;
6704+ xf = au_xino_file(xi, idx);
6705+ if (xf)
6706+ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1,
6707+ au_xino_count(br));
6708+
6709+out_si:
6710+ si_read_unlock(sb);
6711+out:
6712+ AuTraceErr(err);
6713+ return err;
6714+}
6715+
6716+static const struct file_operations dbgaufs_xino_fop = {
6717+ .owner = THIS_MODULE,
6718+ .open = dbgaufs_xino_open,
6719+ .release = dbgaufs_xi_release,
6720+ .read = dbgaufs_xi_read
6721+};
6722+
6723+void dbgaufs_xino_del(struct au_branch *br)
6724+{
6725+ struct dentry *dbgaufs;
6726+
6727+ dbgaufs = br->br_dbgaufs;
6728+ if (!dbgaufs)
6729+ return;
6730+
6731+ br->br_dbgaufs = NULL;
6732+ /* debugfs acquires the parent i_mutex */
6733+ lockdep_off();
6734+ debugfs_remove(dbgaufs);
6735+ lockdep_on();
6736+}
6737+
6738+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
6739+{
6740+ aufs_bindex_t bbot;
6741+ struct au_branch *br;
6742+
6743+ if (!au_sbi(sb)->si_dbgaufs)
6744+ return;
6745+
6746+ bbot = au_sbbot(sb);
6747+ for (; bindex <= bbot; bindex++) {
6748+ br = au_sbr(sb, bindex);
6749+ dbgaufs_xino_del(br);
6750+ }
6751+}
6752+
6753+static void dbgaufs_br_do_add(struct super_block *sb, aufs_bindex_t bindex,
6754+ unsigned int idx, struct dentry *parent,
6755+ struct au_sbinfo *sbinfo)
6756+{
6757+ struct au_branch *br;
6758+ struct dentry *d;
6759+ /* "xi" bindex(5) "-" idx(2) NULL */
6760+ char name[sizeof(DbgaufsXi_PREFIX) + 8];
6761+
6762+ if (!idx)
6763+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
6764+ else
6765+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d-%u",
6766+ bindex, idx);
6767+ br = au_sbr(sb, bindex);
6768+ if (br->br_dbgaufs) {
6769+ struct qstr qstr = QSTR_INIT(name, strlen(name));
6770+
6771+ if (!au_qstreq(&br->br_dbgaufs->d_name, &qstr)) {
6772+ /* debugfs acquires the parent i_mutex */
6773+ lockdep_off();
6774+ d = debugfs_rename(parent, br->br_dbgaufs, parent,
6775+ name);
6776+ lockdep_on();
6777+ if (unlikely(!d))
6778+ pr_warn("failed renaming %pd/%s, ignored.\n",
6779+ parent, name);
6780+ }
6781+ } else {
6782+ lockdep_off();
6783+ br->br_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
6784+ sbinfo, &dbgaufs_xino_fop);
6785+ lockdep_on();
6786+ if (unlikely(!br->br_dbgaufs))
6787+ pr_warn("failed creating %pd/%s, ignored.\n",
6788+ parent, name);
6789+ }
6790+}
6791+
6792+static void dbgaufs_br_add(struct super_block *sb, aufs_bindex_t bindex,
6793+ struct dentry *parent, struct au_sbinfo *sbinfo)
6794+{
6795+ struct au_branch *br;
6796+ struct au_xino *xi;
6797+ unsigned int u;
6798+
6799+ br = au_sbr(sb, bindex);
6800+ xi = br->br_xino;
6801+ for (u = 0; u < xi->xi_nfile; u++)
6802+ dbgaufs_br_do_add(sb, bindex, u, parent, sbinfo);
6803+}
6804+
6805+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex, int topdown)
6806+{
6807+ struct au_sbinfo *sbinfo;
6808+ struct dentry *parent;
6809+ aufs_bindex_t bbot;
6810+
6811+ if (!au_opt_test(au_mntflags(sb), XINO))
6812+ return;
6813+
6814+ sbinfo = au_sbi(sb);
6815+ parent = sbinfo->si_dbgaufs;
6816+ if (!parent)
6817+ return;
6818+
6819+ bbot = au_sbbot(sb);
6820+ if (topdown)
6821+ for (; bindex <= bbot; bindex++)
6822+ dbgaufs_br_add(sb, bindex, parent, sbinfo);
6823+ else
6824+ for (; bbot >= bindex; bbot--)
6825+ dbgaufs_br_add(sb, bbot, parent, sbinfo);
6826+}
6827+
6828+/* ---------------------------------------------------------------------- */
6829+
6830+#ifdef CONFIG_AUFS_EXPORT
6831+static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
6832+{
6833+ int err;
6834+ struct au_sbinfo *sbinfo;
6835+ struct super_block *sb;
6836+
6837+ sbinfo = inode->i_private;
6838+ sb = sbinfo->si_sb;
6839+ si_noflush_read_lock(sb);
6840+ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0, /*cnt*/0);
6841+ si_read_unlock(sb);
6842+ return err;
6843+}
6844+
6845+static const struct file_operations dbgaufs_xigen_fop = {
6846+ .owner = THIS_MODULE,
6847+ .open = dbgaufs_xigen_open,
6848+ .release = dbgaufs_xi_release,
6849+ .read = dbgaufs_xi_read
6850+};
6851+
6852+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
6853+{
6854+ int err;
6855+
6856+ /*
6857+ * This function is a dynamic '__init' function actually,
6858+ * so the tiny check for si_rwsem is unnecessary.
6859+ */
6860+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6861+
6862+ err = -EIO;
6863+ sbinfo->si_dbgaufs_xigen = debugfs_create_file
6864+ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6865+ &dbgaufs_xigen_fop);
6866+ if (sbinfo->si_dbgaufs_xigen)
6867+ err = 0;
6868+
6869+ return err;
6870+}
6871+#else
6872+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
6873+{
6874+ return 0;
6875+}
6876+#endif /* CONFIG_AUFS_EXPORT */
6877+
6878+/* ---------------------------------------------------------------------- */
6879+
6880+void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
6881+{
6882+ /*
6883+ * This function is a dynamic '__fin' function actually,
6884+ * so the tiny check for si_rwsem is unnecessary.
6885+ */
6886+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6887+
6888+ debugfs_remove_recursive(sbinfo->si_dbgaufs);
6889+ sbinfo->si_dbgaufs = NULL;
6890+}
6891+
6892+int dbgaufs_si_init(struct au_sbinfo *sbinfo)
6893+{
6894+ int err;
6895+ char name[SysaufsSiNameLen];
6896+
6897+ /*
6898+ * This function is a dynamic '__init' function actually,
6899+ * so the tiny check for si_rwsem is unnecessary.
6900+ */
6901+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6902+
6903+ err = -ENOENT;
6904+ if (!dbgaufs) {
6905+ AuErr1("/debug/aufs is uninitialized\n");
6906+ goto out;
6907+ }
6908+
6909+ err = -EIO;
6910+ sysaufs_name(sbinfo, name);
6911+ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
6912+ if (unlikely(!sbinfo->si_dbgaufs))
6913+ goto out;
6914+
6915+ /* regardless plink/noplink option */
6916+ sbinfo->si_dbgaufs_plink = debugfs_create_file
6917+ ("plink", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6918+ &dbgaufs_plink_fop);
6919+ if (unlikely(!sbinfo->si_dbgaufs_plink))
6920+ goto out_dir;
6921+
6922+ /* regardless xino/noxino option */
6923+ sbinfo->si_dbgaufs_xib = debugfs_create_file
6924+ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6925+ &dbgaufs_xib_fop);
6926+ if (unlikely(!sbinfo->si_dbgaufs_xib))
6927+ goto out_dir;
6928+
6929+ err = dbgaufs_xigen_init(sbinfo);
6930+ if (!err)
6931+ goto out; /* success */
6932+
6933+out_dir:
6934+ dbgaufs_si_fin(sbinfo);
6935+out:
6936+ if (unlikely(err))
6937+ pr_err("debugfs/aufs failed\n");
6938+ return err;
6939+}
6940+
6941+/* ---------------------------------------------------------------------- */
6942+
6943+void dbgaufs_fin(void)
6944+{
6945+ debugfs_remove(dbgaufs);
6946+}
6947+
6948+int __init dbgaufs_init(void)
6949+{
6950+ int err;
6951+
6952+ err = -EIO;
6953+ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
6954+ if (dbgaufs)
6955+ err = 0;
6956+ return err;
6957+}
6958diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
6959--- /usr/share/empty/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
6960+++ linux/fs/aufs/dbgaufs.h 2020-01-27 10:57:18.168871450 +0100
6961@@ -0,0 +1,53 @@
6962+/* SPDX-License-Identifier: GPL-2.0 */
6963+/*
6964+ * Copyright (C) 2005-2020 Junjiro R. Okajima
6965+ *
6966+ * This program, aufs is free software; you can redistribute it and/or modify
6967+ * it under the terms of the GNU General Public License as published by
6968+ * the Free Software Foundation; either version 2 of the License, or
6969+ * (at your option) any later version.
6970+ *
6971+ * This program is distributed in the hope that it will be useful,
6972+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6973+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6974+ * GNU General Public License for more details.
6975+ *
6976+ * You should have received a copy of the GNU General Public License
6977+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
6978+ */
6979+
6980+/*
6981+ * debugfs interface
6982+ */
6983+
6984+#ifndef __DBGAUFS_H__
6985+#define __DBGAUFS_H__
6986+
6987+#ifdef __KERNEL__
6988+
6989+struct super_block;
6990+struct au_sbinfo;
6991+struct au_branch;
6992+
6993+#ifdef CONFIG_DEBUG_FS
6994+/* dbgaufs.c */
6995+void dbgaufs_xino_del(struct au_branch *br);
6996+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
6997+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex, int topdown);
6998+void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
6999+int dbgaufs_si_init(struct au_sbinfo *sbinfo);
7000+void dbgaufs_fin(void);
7001+int __init dbgaufs_init(void);
7002+#else
7003+AuStubVoid(dbgaufs_xino_del, struct au_branch *br)
7004+AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
7005+AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex,
7006+ int topdown)
7007+AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
7008+AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
7009+AuStubVoid(dbgaufs_fin, void)
7010+AuStubInt0(__init dbgaufs_init, void)
7011+#endif /* CONFIG_DEBUG_FS */
7012+
7013+#endif /* __KERNEL__ */
7014+#endif /* __DBGAUFS_H__ */
7015diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
7016--- /usr/share/empty/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100
7017+++ linux/fs/aufs/dcsub.c 2020-01-27 10:57:18.168871450 +0100
7018@@ -0,0 +1,225 @@
7019+// SPDX-License-Identifier: GPL-2.0
7020+/*
7021+ * Copyright (C) 2005-2020 Junjiro R. Okajima
7022+ *
7023+ * This program, aufs is free software; you can redistribute it and/or modify
7024+ * it under the terms of the GNU General Public License as published by
7025+ * the Free Software Foundation; either version 2 of the License, or
7026+ * (at your option) any later version.
7027+ *
7028+ * This program is distributed in the hope that it will be useful,
7029+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7030+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7031+ * GNU General Public License for more details.
7032+ *
7033+ * You should have received a copy of the GNU General Public License
7034+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7035+ */
7036+
7037+/*
7038+ * sub-routines for dentry cache
7039+ */
7040+
7041+#include "aufs.h"
7042+
7043+static void au_dpage_free(struct au_dpage *dpage)
7044+{
7045+ int i;
7046+ struct dentry **p;
7047+
7048+ p = dpage->dentries;
7049+ for (i = 0; i < dpage->ndentry; i++)
7050+ dput(*p++);
7051+ free_page((unsigned long)dpage->dentries);
7052+}
7053+
7054+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
7055+{
7056+ int err;
7057+ void *p;
7058+
7059+ err = -ENOMEM;
7060+ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
7061+ if (unlikely(!dpages->dpages))
7062+ goto out;
7063+
7064+ p = (void *)__get_free_page(gfp);
7065+ if (unlikely(!p))
7066+ goto out_dpages;
7067+
7068+ dpages->dpages[0].ndentry = 0;
7069+ dpages->dpages[0].dentries = p;
7070+ dpages->ndpage = 1;
7071+ return 0; /* success */
7072+
7073+out_dpages:
7074+ au_kfree_try_rcu(dpages->dpages);
7075+out:
7076+ return err;
7077+}
7078+
7079+void au_dpages_free(struct au_dcsub_pages *dpages)
7080+{
7081+ int i;
7082+ struct au_dpage *p;
7083+
7084+ p = dpages->dpages;
7085+ for (i = 0; i < dpages->ndpage; i++)
7086+ au_dpage_free(p++);
7087+ au_kfree_try_rcu(dpages->dpages);
7088+}
7089+
7090+static int au_dpages_append(struct au_dcsub_pages *dpages,
7091+ struct dentry *dentry, gfp_t gfp)
7092+{
7093+ int err, sz;
7094+ struct au_dpage *dpage;
7095+ void *p;
7096+
7097+ dpage = dpages->dpages + dpages->ndpage - 1;
7098+ sz = PAGE_SIZE / sizeof(dentry);
7099+ if (unlikely(dpage->ndentry >= sz)) {
7100+ AuLabel(new dpage);
7101+ err = -ENOMEM;
7102+ sz = dpages->ndpage * sizeof(*dpages->dpages);
7103+ p = au_kzrealloc(dpages->dpages, sz,
7104+ sz + sizeof(*dpages->dpages), gfp,
7105+ /*may_shrink*/0);
7106+ if (unlikely(!p))
7107+ goto out;
7108+
7109+ dpages->dpages = p;
7110+ dpage = dpages->dpages + dpages->ndpage;
7111+ p = (void *)__get_free_page(gfp);
7112+ if (unlikely(!p))
7113+ goto out;
7114+
7115+ dpage->ndentry = 0;
7116+ dpage->dentries = p;
7117+ dpages->ndpage++;
7118+ }
7119+
7120+ AuDebugOn(au_dcount(dentry) <= 0);
7121+ dpage->dentries[dpage->ndentry++] = dget_dlock(dentry);
7122+ return 0; /* success */
7123+
7124+out:
7125+ return err;
7126+}
7127+
7128+/* todo: BAD approach */
7129+/* copied from linux/fs/dcache.c */
7130+enum d_walk_ret {
7131+ D_WALK_CONTINUE,
7132+ D_WALK_QUIT,
7133+ D_WALK_NORETRY,
7134+ D_WALK_SKIP,
7135+};
7136+
7137+extern void d_walk(struct dentry *parent, void *data,
7138+ enum d_walk_ret (*enter)(void *, struct dentry *));
7139+
7140+struct ac_dpages_arg {
7141+ int err;
7142+ struct au_dcsub_pages *dpages;
7143+ struct super_block *sb;
7144+ au_dpages_test test;
7145+ void *arg;
7146+};
7147+
7148+static enum d_walk_ret au_call_dpages_append(void *_arg, struct dentry *dentry)
7149+{
7150+ enum d_walk_ret ret;
7151+ struct ac_dpages_arg *arg = _arg;
7152+
7153+ ret = D_WALK_CONTINUE;
7154+ if (dentry->d_sb == arg->sb
7155+ && !IS_ROOT(dentry)
7156+ && au_dcount(dentry) > 0
7157+ && au_di(dentry)
7158+ && (!arg->test || arg->test(dentry, arg->arg))) {
7159+ arg->err = au_dpages_append(arg->dpages, dentry, GFP_ATOMIC);
7160+ if (unlikely(arg->err))
7161+ ret = D_WALK_QUIT;
7162+ }
7163+
7164+ return ret;
7165+}
7166+
7167+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
7168+ au_dpages_test test, void *arg)
7169+{
7170+ struct ac_dpages_arg args = {
7171+ .err = 0,
7172+ .dpages = dpages,
7173+ .sb = root->d_sb,
7174+ .test = test,
7175+ .arg = arg
7176+ };
7177+
7178+ d_walk(root, &args, au_call_dpages_append);
7179+
7180+ return args.err;
7181+}
7182+
7183+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
7184+ int do_include, au_dpages_test test, void *arg)
7185+{
7186+ int err;
7187+
7188+ err = 0;
7189+ write_seqlock(&rename_lock);
7190+ spin_lock(&dentry->d_lock);
7191+ if (do_include
7192+ && au_dcount(dentry) > 0
7193+ && (!test || test(dentry, arg)))
7194+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
7195+ spin_unlock(&dentry->d_lock);
7196+ if (unlikely(err))
7197+ goto out;
7198+
7199+ /*
7200+ * RCU for vfsmount is unnecessary since this is a traverse in a single
7201+ * mount
7202+ */
7203+ while (!IS_ROOT(dentry)) {
7204+ dentry = dentry->d_parent; /* rename_lock is locked */
7205+ spin_lock(&dentry->d_lock);
7206+ if (au_dcount(dentry) > 0
7207+ && (!test || test(dentry, arg)))
7208+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
7209+ spin_unlock(&dentry->d_lock);
7210+ if (unlikely(err))
7211+ break;
7212+ }
7213+
7214+out:
7215+ write_sequnlock(&rename_lock);
7216+ return err;
7217+}
7218+
7219+static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg)
7220+{
7221+ return au_di(dentry) && dentry->d_sb == arg;
7222+}
7223+
7224+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
7225+ struct dentry *dentry, int do_include)
7226+{
7227+ return au_dcsub_pages_rev(dpages, dentry, do_include,
7228+ au_dcsub_dpages_aufs, dentry->d_sb);
7229+}
7230+
7231+int au_test_subdir(struct dentry *d1, struct dentry *d2)
7232+{
7233+ struct path path[2] = {
7234+ {
7235+ .dentry = d1
7236+ },
7237+ {
7238+ .dentry = d2
7239+ }
7240+ };
7241+
7242+ return path_is_under(path + 0, path + 1);
7243+}
7244diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
7245--- /usr/share/empty/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100
7246+++ linux/fs/aufs/dcsub.h 2020-01-27 10:57:18.168871450 +0100
7247@@ -0,0 +1,137 @@
7248+/* SPDX-License-Identifier: GPL-2.0 */
7249+/*
7250+ * Copyright (C) 2005-2020 Junjiro R. Okajima
7251+ *
7252+ * This program, aufs is free software; you can redistribute it and/or modify
7253+ * it under the terms of the GNU General Public License as published by
7254+ * the Free Software Foundation; either version 2 of the License, or
7255+ * (at your option) any later version.
7256+ *
7257+ * This program is distributed in the hope that it will be useful,
7258+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7259+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7260+ * GNU General Public License for more details.
7261+ *
7262+ * You should have received a copy of the GNU General Public License
7263+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7264+ */
7265+
7266+/*
7267+ * sub-routines for dentry cache
7268+ */
7269+
7270+#ifndef __AUFS_DCSUB_H__
7271+#define __AUFS_DCSUB_H__
7272+
7273+#ifdef __KERNEL__
7274+
7275+#include <linux/dcache.h>
7276+#include <linux/fs.h>
7277+
7278+struct au_dpage {
7279+ int ndentry;
7280+ struct dentry **dentries;
7281+};
7282+
7283+struct au_dcsub_pages {
7284+ int ndpage;
7285+ struct au_dpage *dpages;
7286+};
7287+
7288+/* ---------------------------------------------------------------------- */
7289+
7290+/* dcsub.c */
7291+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
7292+void au_dpages_free(struct au_dcsub_pages *dpages);
7293+typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
7294+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
7295+ au_dpages_test test, void *arg);
7296+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
7297+ int do_include, au_dpages_test test, void *arg);
7298+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
7299+ struct dentry *dentry, int do_include);
7300+int au_test_subdir(struct dentry *d1, struct dentry *d2);
7301+
7302+/* ---------------------------------------------------------------------- */
7303+
7304+/*
7305+ * todo: in linux-3.13, several similar (but faster) helpers are added to
7306+ * include/linux/dcache.h. Try them (in the future).
7307+ */
7308+
7309+static inline int au_d_hashed_positive(struct dentry *d)
7310+{
7311+ int err;
7312+ struct inode *inode = d_inode(d);
7313+
7314+ err = 0;
7315+ if (unlikely(d_unhashed(d)
7316+ || d_is_negative(d)
7317+ || !inode->i_nlink))
7318+ err = -ENOENT;
7319+ return err;
7320+}
7321+
7322+static inline int au_d_linkable(struct dentry *d)
7323+{
7324+ int err;
7325+ struct inode *inode = d_inode(d);
7326+
7327+ err = au_d_hashed_positive(d);
7328+ if (err
7329+ && d_is_positive(d)
7330+ && (inode->i_state & I_LINKABLE))
7331+ err = 0;
7332+ return err;
7333+}
7334+
7335+static inline int au_d_alive(struct dentry *d)
7336+{
7337+ int err;
7338+ struct inode *inode;
7339+
7340+ err = 0;
7341+ if (!IS_ROOT(d))
7342+ err = au_d_hashed_positive(d);
7343+ else {
7344+ inode = d_inode(d);
7345+ if (unlikely(d_unlinked(d)
7346+ || d_is_negative(d)
7347+ || !inode->i_nlink))
7348+ err = -ENOENT;
7349+ }
7350+ return err;
7351+}
7352+
7353+static inline int au_alive_dir(struct dentry *d)
7354+{
7355+ int err;
7356+
7357+ err = au_d_alive(d);
7358+ if (unlikely(err || IS_DEADDIR(d_inode(d))))
7359+ err = -ENOENT;
7360+ return err;
7361+}
7362+
7363+static inline int au_qstreq(struct qstr *a, struct qstr *b)
7364+{
7365+ return a->len == b->len
7366+ && !memcmp(a->name, b->name, a->len);
7367+}
7368+
7369+/*
7370+ * by the commit
7371+ * 360f547 2015-01-25 dcache: let the dentry count go down to zero without
7372+ * taking d_lock
7373+ * the type of d_lockref.count became int, but the inlined function d_count()
7374+ * still returns unsigned int.
7375+ * I don't know why. Maybe it is for every d_count() users?
7376+ * Anyway au_dcount() lives on.
7377+ */
7378+static inline int au_dcount(struct dentry *d)
7379+{
7380+ return (int)d_count(d);
7381+}
7382+
7383+#endif /* __KERNEL__ */
7384+#endif /* __AUFS_DCSUB_H__ */
7385diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
7386--- /usr/share/empty/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
7387+++ linux/fs/aufs/debug.c 2020-01-27 10:57:18.168871450 +0100
7388@@ -0,0 +1,441 @@
7389+// SPDX-License-Identifier: GPL-2.0
7390+/*
7391+ * Copyright (C) 2005-2020 Junjiro R. Okajima
7392+ *
7393+ * This program, aufs is free software; you can redistribute it and/or modify
7394+ * it under the terms of the GNU General Public License as published by
7395+ * the Free Software Foundation; either version 2 of the License, or
7396+ * (at your option) any later version.
7397+ *
7398+ * This program is distributed in the hope that it will be useful,
7399+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7400+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7401+ * GNU General Public License for more details.
7402+ *
7403+ * You should have received a copy of the GNU General Public License
7404+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7405+ */
7406+
7407+/*
7408+ * debug print functions
7409+ */
7410+
7411+#include <linux/iversion.h>
7412+#include "aufs.h"
7413+
7414+/* Returns 0, or -errno. arg is in kp->arg. */
7415+static int param_atomic_t_set(const char *val, const struct kernel_param *kp)
7416+{
7417+ int err, n;
7418+
7419+ err = kstrtoint(val, 0, &n);
7420+ if (!err) {
7421+ if (n > 0)
7422+ au_debug_on();
7423+ else
7424+ au_debug_off();
7425+ }
7426+ return err;
7427+}
7428+
7429+/* Returns length written or -errno. Buffer is 4k (ie. be short!) */
7430+static int param_atomic_t_get(char *buffer, const struct kernel_param *kp)
7431+{
7432+ atomic_t *a;
7433+
7434+ a = kp->arg;
7435+ return sprintf(buffer, "%d", atomic_read(a));
7436+}
7437+
7438+static struct kernel_param_ops param_ops_atomic_t = {
7439+ .set = param_atomic_t_set,
7440+ .get = param_atomic_t_get
7441+ /* void (*free)(void *arg) */
7442+};
7443+
7444+atomic_t aufs_debug = ATOMIC_INIT(0);
7445+MODULE_PARM_DESC(debug, "debug print");
7446+module_param_named(debug, aufs_debug, atomic_t, 0664);
7447+
7448+DEFINE_MUTEX(au_dbg_mtx); /* just to serialize the dbg msgs */
7449+char *au_plevel = KERN_DEBUG;
7450+#define dpri(fmt, ...) do { \
7451+ if ((au_plevel \
7452+ && strcmp(au_plevel, KERN_DEBUG)) \
7453+ || au_debug_test()) \
7454+ printk("%s" fmt, au_plevel, ##__VA_ARGS__); \
7455+} while (0)
7456+
7457+/* ---------------------------------------------------------------------- */
7458+
7459+void au_dpri_whlist(struct au_nhash *whlist)
7460+{
7461+ unsigned long ul, n;
7462+ struct hlist_head *head;
7463+ struct au_vdir_wh *pos;
7464+
7465+ n = whlist->nh_num;
7466+ head = whlist->nh_head;
7467+ for (ul = 0; ul < n; ul++) {
7468+ hlist_for_each_entry(pos, head, wh_hash)
7469+ dpri("b%d, %.*s, %d\n",
7470+ pos->wh_bindex,
7471+ pos->wh_str.len, pos->wh_str.name,
7472+ pos->wh_str.len);
7473+ head++;
7474+ }
7475+}
7476+
7477+void au_dpri_vdir(struct au_vdir *vdir)
7478+{
7479+ unsigned long ul;
7480+ union au_vdir_deblk_p p;
7481+ unsigned char *o;
7482+
7483+ if (!vdir || IS_ERR(vdir)) {
7484+ dpri("err %ld\n", PTR_ERR(vdir));
7485+ return;
7486+ }
7487+
7488+ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %llu\n",
7489+ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
7490+ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
7491+ for (ul = 0; ul < vdir->vd_nblk; ul++) {
7492+ p.deblk = vdir->vd_deblk[ul];
7493+ o = p.deblk;
7494+ dpri("[%lu]: %p\n", ul, o);
7495+ }
7496+}
7497+
7498+static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn,
7499+ struct dentry *wh)
7500+{
7501+ char *n = NULL;
7502+ int l = 0;
7503+
7504+ if (!inode || IS_ERR(inode)) {
7505+ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
7506+ return -1;
7507+ }
7508+
7509+ /* the type of i_blocks depends upon CONFIG_LBDAF */
7510+ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
7511+ && sizeof(inode->i_blocks) != sizeof(u64));
7512+ if (wh) {
7513+ n = (void *)wh->d_name.name;
7514+ l = wh->d_name.len;
7515+ }
7516+
7517+ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
7518+ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
7519+ bindex, inode,
7520+ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
7521+ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
7522+ i_size_read(inode), (unsigned long long)inode->i_blocks,
7523+ hn, (long long)timespec64_to_ns(&inode->i_ctime) & 0x0ffff,
7524+ inode->i_mapping ? inode->i_mapping->nrpages : 0,
7525+ inode->i_state, inode->i_flags, inode_peek_iversion(inode),
7526+ inode->i_generation,
7527+ l ? ", wh " : "", l, n);
7528+ return 0;
7529+}
7530+
7531+void au_dpri_inode(struct inode *inode)
7532+{
7533+ struct au_iinfo *iinfo;
7534+ struct au_hinode *hi;
7535+ aufs_bindex_t bindex;
7536+ int err, hn;
7537+
7538+ err = do_pri_inode(-1, inode, -1, NULL);
7539+ if (err || !au_test_aufs(inode->i_sb) || au_is_bad_inode(inode))
7540+ return;
7541+
7542+ iinfo = au_ii(inode);
7543+ dpri("i-1: btop %d, bbot %d, gen %d\n",
7544+ iinfo->ii_btop, iinfo->ii_bbot, au_iigen(inode, NULL));
7545+ if (iinfo->ii_btop < 0)
7546+ return;
7547+ hn = 0;
7548+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot; bindex++) {
7549+ hi = au_hinode(iinfo, bindex);
7550+ hn = !!au_hn(hi);
7551+ do_pri_inode(bindex, hi->hi_inode, hn, hi->hi_whdentry);
7552+ }
7553+}
7554+
7555+void au_dpri_dalias(struct inode *inode)
7556+{
7557+ struct dentry *d;
7558+
7559+ spin_lock(&inode->i_lock);
7560+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias)
7561+ au_dpri_dentry(d);
7562+ spin_unlock(&inode->i_lock);
7563+}
7564+
7565+static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
7566+{
7567+ struct dentry *wh = NULL;
7568+ int hn;
7569+ struct inode *inode;
7570+ struct au_iinfo *iinfo;
7571+ struct au_hinode *hi;
7572+
7573+ if (!dentry || IS_ERR(dentry)) {
7574+ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
7575+ return -1;
7576+ }
7577+ /* do not call dget_parent() here */
7578+ /* note: access d_xxx without d_lock */
7579+ dpri("d%d: %p, %pd2?, %s, cnt %d, flags 0x%x, %shashed\n",
7580+ bindex, dentry, dentry,
7581+ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
7582+ au_dcount(dentry), dentry->d_flags,
7583+ d_unhashed(dentry) ? "un" : "");
7584+ hn = -1;
7585+ inode = NULL;
7586+ if (d_is_positive(dentry))
7587+ inode = d_inode(dentry);
7588+ if (inode
7589+ && au_test_aufs(dentry->d_sb)
7590+ && bindex >= 0
7591+ && !au_is_bad_inode(inode)) {
7592+ iinfo = au_ii(inode);
7593+ hi = au_hinode(iinfo, bindex);
7594+ hn = !!au_hn(hi);
7595+ wh = hi->hi_whdentry;
7596+ }
7597+ do_pri_inode(bindex, inode, hn, wh);
7598+ return 0;
7599+}
7600+
7601+void au_dpri_dentry(struct dentry *dentry)
7602+{
7603+ struct au_dinfo *dinfo;
7604+ aufs_bindex_t bindex;
7605+ int err;
7606+
7607+ err = do_pri_dentry(-1, dentry);
7608+ if (err || !au_test_aufs(dentry->d_sb))
7609+ return;
7610+
7611+ dinfo = au_di(dentry);
7612+ if (!dinfo)
7613+ return;
7614+ dpri("d-1: btop %d, bbot %d, bwh %d, bdiropq %d, gen %d, tmp %d\n",
7615+ dinfo->di_btop, dinfo->di_bbot,
7616+ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry),
7617+ dinfo->di_tmpfile);
7618+ if (dinfo->di_btop < 0)
7619+ return;
7620+ for (bindex = dinfo->di_btop; bindex <= dinfo->di_bbot; bindex++)
7621+ do_pri_dentry(bindex, au_hdentry(dinfo, bindex)->hd_dentry);
7622+}
7623+
7624+static int do_pri_file(aufs_bindex_t bindex, struct file *file)
7625+{
7626+ char a[32];
7627+
7628+ if (!file || IS_ERR(file)) {
7629+ dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
7630+ return -1;
7631+ }
7632+ a[0] = 0;
7633+ if (bindex < 0
7634+ && !IS_ERR_OR_NULL(file->f_path.dentry)
7635+ && au_test_aufs(file->f_path.dentry->d_sb)
7636+ && au_fi(file))
7637+ snprintf(a, sizeof(a), ", gen %d, mmapped %d",
7638+ au_figen(file), atomic_read(&au_fi(file)->fi_mmapped));
7639+ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
7640+ bindex, file->f_mode, file->f_flags, (long)file_count(file),
7641+ file->f_version, file->f_pos, a);
7642+ if (!IS_ERR_OR_NULL(file->f_path.dentry))
7643+ do_pri_dentry(bindex, file->f_path.dentry);
7644+ return 0;
7645+}
7646+
7647+void au_dpri_file(struct file *file)
7648+{
7649+ struct au_finfo *finfo;
7650+ struct au_fidir *fidir;
7651+ struct au_hfile *hfile;
7652+ aufs_bindex_t bindex;
7653+ int err;
7654+
7655+ err = do_pri_file(-1, file);
7656+ if (err
7657+ || IS_ERR_OR_NULL(file->f_path.dentry)
7658+ || !au_test_aufs(file->f_path.dentry->d_sb))
7659+ return;
7660+
7661+ finfo = au_fi(file);
7662+ if (!finfo)
7663+ return;
7664+ if (finfo->fi_btop < 0)
7665+ return;
7666+ fidir = finfo->fi_hdir;
7667+ if (!fidir)
7668+ do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
7669+ else
7670+ for (bindex = finfo->fi_btop;
7671+ bindex >= 0 && bindex <= fidir->fd_bbot;
7672+ bindex++) {
7673+ hfile = fidir->fd_hfile + bindex;
7674+ do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
7675+ }
7676+}
7677+
7678+static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
7679+{
7680+ struct vfsmount *mnt;
7681+ struct super_block *sb;
7682+
7683+ if (!br || IS_ERR(br))
7684+ goto out;
7685+ mnt = au_br_mnt(br);
7686+ if (!mnt || IS_ERR(mnt))
7687+ goto out;
7688+ sb = mnt->mnt_sb;
7689+ if (!sb || IS_ERR(sb))
7690+ goto out;
7691+
7692+ dpri("s%d: {perm 0x%x, id %d, wbr %p}, "
7693+ "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
7694+ "xino %d\n",
7695+ bindex, br->br_perm, br->br_id, br->br_wbr,
7696+ au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
7697+ sb->s_flags, sb->s_count,
7698+ atomic_read(&sb->s_active),
7699+ !!au_xino_file(br->br_xino, /*idx*/-1));
7700+ return 0;
7701+
7702+out:
7703+ dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
7704+ return -1;
7705+}
7706+
7707+void au_dpri_sb(struct super_block *sb)
7708+{
7709+ struct au_sbinfo *sbinfo;
7710+ aufs_bindex_t bindex;
7711+ int err;
7712+ /* to reduce stack size */
7713+ struct {
7714+ struct vfsmount mnt;
7715+ struct au_branch fake;
7716+ } *a;
7717+
7718+ /* this function can be called from magic sysrq */
7719+ a = kzalloc(sizeof(*a), GFP_ATOMIC);
7720+ if (unlikely(!a)) {
7721+ dpri("no memory\n");
7722+ return;
7723+ }
7724+
7725+ a->mnt.mnt_sb = sb;
7726+ a->fake.br_path.mnt = &a->mnt;
7727+ err = do_pri_br(-1, &a->fake);
7728+ au_kfree_rcu(a);
7729+ dpri("dev 0x%x\n", sb->s_dev);
7730+ if (err || !au_test_aufs(sb))
7731+ return;
7732+
7733+ sbinfo = au_sbi(sb);
7734+ if (!sbinfo)
7735+ return;
7736+ dpri("nw %d, gen %u, kobj %d\n",
7737+ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
7738+ kref_read(&sbinfo->si_kobj.kref));
7739+ for (bindex = 0; bindex <= sbinfo->si_bbot; bindex++)
7740+ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
7741+}
7742+
7743+/* ---------------------------------------------------------------------- */
7744+
7745+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
7746+{
7747+ struct inode *h_inode, *inode = d_inode(dentry);
7748+ struct dentry *h_dentry;
7749+ aufs_bindex_t bindex, bbot, bi;
7750+
7751+ if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */)
7752+ return;
7753+
7754+ bbot = au_dbbot(dentry);
7755+ bi = au_ibbot(inode);
7756+ if (bi < bbot)
7757+ bbot = bi;
7758+ bindex = au_dbtop(dentry);
7759+ bi = au_ibtop(inode);
7760+ if (bi > bindex)
7761+ bindex = bi;
7762+
7763+ for (; bindex <= bbot; bindex++) {
7764+ h_dentry = au_h_dptr(dentry, bindex);
7765+ if (!h_dentry)
7766+ continue;
7767+ h_inode = au_h_iptr(inode, bindex);
7768+ if (unlikely(h_inode != d_inode(h_dentry))) {
7769+ au_debug_on();
7770+ AuDbg("b%d, %s:%d\n", bindex, func, line);
7771+ AuDbgDentry(dentry);
7772+ AuDbgInode(inode);
7773+ au_debug_off();
7774+ BUG();
7775+ }
7776+ }
7777+}
7778+
7779+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
7780+{
7781+ int err, i, j;
7782+ struct au_dcsub_pages dpages;
7783+ struct au_dpage *dpage;
7784+ struct dentry **dentries;
7785+
7786+ err = au_dpages_init(&dpages, GFP_NOFS);
7787+ AuDebugOn(err);
7788+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
7789+ AuDebugOn(err);
7790+ for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
7791+ dpage = dpages.dpages + i;
7792+ dentries = dpage->dentries;
7793+ for (j = dpage->ndentry - 1; !err && j >= 0; j--)
7794+ AuDebugOn(au_digen_test(dentries[j], sigen));
7795+ }
7796+ au_dpages_free(&dpages);
7797+}
7798+
7799+void au_dbg_verify_kthread(void)
7800+{
7801+ if (au_wkq_test()) {
7802+ au_dbg_blocked();
7803+ /*
7804+ * It may be recursive, but udba=notify between two aufs mounts,
7805+ * where a single ro branch is shared, is not a problem.
7806+ */
7807+ /* WARN_ON(1); */
7808+ }
7809+}
7810+
7811+/* ---------------------------------------------------------------------- */
7812+
7813+int __init au_debug_init(void)
7814+{
7815+ aufs_bindex_t bindex;
7816+ struct au_vdir_destr destr;
7817+
7818+ bindex = -1;
7819+ AuDebugOn(bindex >= 0);
7820+
7821+ destr.len = -1;
7822+ AuDebugOn(destr.len < NAME_MAX);
7823+
7824+#ifdef CONFIG_4KSTACKS
7825+ pr_warn("CONFIG_4KSTACKS is defined.\n");
7826+#endif
7827+
7828+ return 0;
7829+}
7830diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
7831--- /usr/share/empty/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100
7832+++ linux/fs/aufs/debug.h 2020-01-27 10:57:18.168871450 +0100
7833@@ -0,0 +1,226 @@
7834+/* SPDX-License-Identifier: GPL-2.0 */
7835+/*
7836+ * Copyright (C) 2005-2020 Junjiro R. Okajima
7837+ *
7838+ * This program, aufs is free software; you can redistribute it and/or modify
7839+ * it under the terms of the GNU General Public License as published by
7840+ * the Free Software Foundation; either version 2 of the License, or
7841+ * (at your option) any later version.
7842+ *
7843+ * This program is distributed in the hope that it will be useful,
7844+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7845+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7846+ * GNU General Public License for more details.
7847+ *
7848+ * You should have received a copy of the GNU General Public License
7849+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7850+ */
7851+
7852+/*
7853+ * debug print functions
7854+ */
7855+
7856+#ifndef __AUFS_DEBUG_H__
7857+#define __AUFS_DEBUG_H__
7858+
7859+#ifdef __KERNEL__
7860+
7861+#include <linux/atomic.h>
7862+#include <linux/module.h>
7863+#include <linux/kallsyms.h>
7864+#include <linux/sysrq.h>
7865+
7866+#ifdef CONFIG_AUFS_DEBUG
7867+#define AuDebugOn(a) BUG_ON(a)
7868+
7869+/* module parameter */
7870+extern atomic_t aufs_debug;
7871+static inline void au_debug_on(void)
7872+{
7873+ atomic_inc(&aufs_debug);
7874+}
7875+static inline void au_debug_off(void)
7876+{
7877+ atomic_dec_if_positive(&aufs_debug);
7878+}
7879+
7880+static inline int au_debug_test(void)
7881+{
7882+ return atomic_read(&aufs_debug) > 0;
7883+}
7884+#else
7885+#define AuDebugOn(a) do {} while (0)
7886+AuStubVoid(au_debug_on, void)
7887+AuStubVoid(au_debug_off, void)
7888+AuStubInt0(au_debug_test, void)
7889+#endif /* CONFIG_AUFS_DEBUG */
7890+
7891+#define param_check_atomic_t(name, p) __param_check(name, p, atomic_t)
7892+
7893+/* ---------------------------------------------------------------------- */
7894+
7895+/* debug print */
7896+
7897+#define AuDbg(fmt, ...) do { \
7898+ if (au_debug_test()) \
7899+ pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
7900+} while (0)
7901+#define AuLabel(l) AuDbg(#l "\n")
7902+#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__)
7903+#define AuWarn1(fmt, ...) do { \
7904+ static unsigned char _c; \
7905+ if (!_c++) \
7906+ pr_warn(fmt, ##__VA_ARGS__); \
7907+} while (0)
7908+
7909+#define AuErr1(fmt, ...) do { \
7910+ static unsigned char _c; \
7911+ if (!_c++) \
7912+ pr_err(fmt, ##__VA_ARGS__); \
7913+} while (0)
7914+
7915+#define AuIOErr1(fmt, ...) do { \
7916+ static unsigned char _c; \
7917+ if (!_c++) \
7918+ AuIOErr(fmt, ##__VA_ARGS__); \
7919+} while (0)
7920+
7921+#define AuUnsupportMsg "This operation is not supported." \
7922+ " Please report this application to aufs-users ML."
7923+#define AuUnsupport(fmt, ...) do { \
7924+ pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
7925+ dump_stack(); \
7926+} while (0)
7927+
7928+#define AuTraceErr(e) do { \
7929+ if (unlikely((e) < 0)) \
7930+ AuDbg("err %d\n", (int)(e)); \
7931+} while (0)
7932+
7933+#define AuTraceErrPtr(p) do { \
7934+ if (IS_ERR(p)) \
7935+ AuDbg("err %ld\n", PTR_ERR(p)); \
7936+} while (0)
7937+
7938+/* dirty macros for debug print, use with "%.*s" and caution */
7939+#define AuLNPair(qstr) (qstr)->len, (qstr)->name
7940+
7941+/* ---------------------------------------------------------------------- */
7942+
7943+struct dentry;
7944+#ifdef CONFIG_AUFS_DEBUG
7945+extern struct mutex au_dbg_mtx;
7946+extern char *au_plevel;
7947+struct au_nhash;
7948+void au_dpri_whlist(struct au_nhash *whlist);
7949+struct au_vdir;
7950+void au_dpri_vdir(struct au_vdir *vdir);
7951+struct inode;
7952+void au_dpri_inode(struct inode *inode);
7953+void au_dpri_dalias(struct inode *inode);
7954+void au_dpri_dentry(struct dentry *dentry);
7955+struct file;
7956+void au_dpri_file(struct file *filp);
7957+struct super_block;
7958+void au_dpri_sb(struct super_block *sb);
7959+
7960+#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__)
7961+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line);
7962+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
7963+void au_dbg_verify_kthread(void);
7964+
7965+int __init au_debug_init(void);
7966+
7967+#define AuDbgWhlist(w) do { \
7968+ mutex_lock(&au_dbg_mtx); \
7969+ AuDbg(#w "\n"); \
7970+ au_dpri_whlist(w); \
7971+ mutex_unlock(&au_dbg_mtx); \
7972+} while (0)
7973+
7974+#define AuDbgVdir(v) do { \
7975+ mutex_lock(&au_dbg_mtx); \
7976+ AuDbg(#v "\n"); \
7977+ au_dpri_vdir(v); \
7978+ mutex_unlock(&au_dbg_mtx); \
7979+} while (0)
7980+
7981+#define AuDbgInode(i) do { \
7982+ mutex_lock(&au_dbg_mtx); \
7983+ AuDbg(#i "\n"); \
7984+ au_dpri_inode(i); \
7985+ mutex_unlock(&au_dbg_mtx); \
7986+} while (0)
7987+
7988+#define AuDbgDAlias(i) do { \
7989+ mutex_lock(&au_dbg_mtx); \
7990+ AuDbg(#i "\n"); \
7991+ au_dpri_dalias(i); \
7992+ mutex_unlock(&au_dbg_mtx); \
7993+} while (0)
7994+
7995+#define AuDbgDentry(d) do { \
7996+ mutex_lock(&au_dbg_mtx); \
7997+ AuDbg(#d "\n"); \
7998+ au_dpri_dentry(d); \
7999+ mutex_unlock(&au_dbg_mtx); \
8000+} while (0)
8001+
8002+#define AuDbgFile(f) do { \
8003+ mutex_lock(&au_dbg_mtx); \
8004+ AuDbg(#f "\n"); \
8005+ au_dpri_file(f); \
8006+ mutex_unlock(&au_dbg_mtx); \
8007+} while (0)
8008+
8009+#define AuDbgSb(sb) do { \
8010+ mutex_lock(&au_dbg_mtx); \
8011+ AuDbg(#sb "\n"); \
8012+ au_dpri_sb(sb); \
8013+ mutex_unlock(&au_dbg_mtx); \
8014+} while (0)
8015+
8016+#define AuDbgSym(addr) do { \
8017+ char sym[KSYM_SYMBOL_LEN]; \
8018+ sprint_symbol(sym, (unsigned long)addr); \
8019+ AuDbg("%s\n", sym); \
8020+} while (0)
8021+#else
8022+AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
8023+AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
8024+AuStubVoid(au_dbg_verify_kthread, void)
8025+AuStubInt0(__init au_debug_init, void)
8026+
8027+#define AuDbgWhlist(w) do {} while (0)
8028+#define AuDbgVdir(v) do {} while (0)
8029+#define AuDbgInode(i) do {} while (0)
8030+#define AuDbgDAlias(i) do {} while (0)
8031+#define AuDbgDentry(d) do {} while (0)
8032+#define AuDbgFile(f) do {} while (0)
8033+#define AuDbgSb(sb) do {} while (0)
8034+#define AuDbgSym(addr) do {} while (0)
8035+#endif /* CONFIG_AUFS_DEBUG */
8036+
8037+/* ---------------------------------------------------------------------- */
8038+
8039+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
8040+int __init au_sysrq_init(void);
8041+void au_sysrq_fin(void);
8042+
8043+#ifdef CONFIG_HW_CONSOLE
8044+#define au_dbg_blocked() do { \
8045+ WARN_ON(1); \
8046+ handle_sysrq('w'); \
8047+} while (0)
8048+#else
8049+AuStubVoid(au_dbg_blocked, void)
8050+#endif
8051+
8052+#else
8053+AuStubInt0(__init au_sysrq_init, void)
8054+AuStubVoid(au_sysrq_fin, void)
8055+AuStubVoid(au_dbg_blocked, void)
8056+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
8057+
8058+#endif /* __KERNEL__ */
8059+#endif /* __AUFS_DEBUG_H__ */
8060diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
8061--- /usr/share/empty/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100
8062+++ linux/fs/aufs/dentry.c 2020-01-27 10:57:18.168871450 +0100
8063@@ -0,0 +1,1154 @@
8064+// SPDX-License-Identifier: GPL-2.0
8065+/*
8066+ * Copyright (C) 2005-2020 Junjiro R. Okajima
8067+ *
8068+ * This program, aufs is free software; you can redistribute it and/or modify
8069+ * it under the terms of the GNU General Public License as published by
8070+ * the Free Software Foundation; either version 2 of the License, or
8071+ * (at your option) any later version.
8072+ *
8073+ * This program is distributed in the hope that it will be useful,
8074+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8075+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8076+ * GNU General Public License for more details.
8077+ *
8078+ * You should have received a copy of the GNU General Public License
8079+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
8080+ */
8081+
8082+/*
8083+ * lookup and dentry operations
8084+ */
8085+
8086+#include <linux/iversion.h>
8087+#include <linux/namei.h>
8088+#include "aufs.h"
8089+
8090+/*
8091+ * returns positive/negative dentry, NULL or an error.
8092+ * NULL means whiteout-ed or not-found.
8093+ */
8094+static struct dentry*
8095+au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
8096+ aufs_bindex_t bindex, struct au_do_lookup_args *args)
8097+{
8098+ struct dentry *h_dentry;
8099+ struct inode *h_inode;
8100+ struct au_branch *br;
8101+ int wh_found, opq;
8102+ unsigned char wh_able;
8103+ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
8104+ const unsigned char ignore_perm = !!au_ftest_lkup(args->flags,
8105+ IGNORE_PERM);
8106+
8107+ wh_found = 0;
8108+ br = au_sbr(dentry->d_sb, bindex);
8109+ wh_able = !!au_br_whable(br->br_perm);
8110+ if (wh_able)
8111+ wh_found = au_wh_test(h_parent, &args->whname, ignore_perm);
8112+ h_dentry = ERR_PTR(wh_found);
8113+ if (!wh_found)
8114+ goto real_lookup;
8115+ if (unlikely(wh_found < 0))
8116+ goto out;
8117+
8118+ /* We found a whiteout */
8119+ /* au_set_dbbot(dentry, bindex); */
8120+ au_set_dbwh(dentry, bindex);
8121+ if (!allow_neg)
8122+ return NULL; /* success */
8123+
8124+real_lookup:
8125+ if (!ignore_perm)
8126+ h_dentry = vfsub_lkup_one(args->name, h_parent);
8127+ else
8128+ h_dentry = au_sio_lkup_one(args->name, h_parent);
8129+ if (IS_ERR(h_dentry)) {
8130+ if (PTR_ERR(h_dentry) == -ENAMETOOLONG
8131+ && !allow_neg)
8132+ h_dentry = NULL;
8133+ goto out;
8134+ }
8135+
8136+ h_inode = d_inode(h_dentry);
8137+ if (d_is_negative(h_dentry)) {
8138+ if (!allow_neg)
8139+ goto out_neg;
8140+ } else if (wh_found
8141+ || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
8142+ goto out_neg;
8143+ else if (au_ftest_lkup(args->flags, DIRREN)
8144+ /* && h_inode */
8145+ && !au_dr_lkup_h_ino(args, bindex, h_inode->i_ino)) {
8146+ AuDbg("b%d %pd ignored hi%llu\n", bindex, h_dentry,
8147+ (unsigned long long)h_inode->i_ino);
8148+ goto out_neg;
8149+ }
8150+
8151+ if (au_dbbot(dentry) <= bindex)
8152+ au_set_dbbot(dentry, bindex);
8153+ if (au_dbtop(dentry) < 0 || bindex < au_dbtop(dentry))
8154+ au_set_dbtop(dentry, bindex);
8155+ au_set_h_dptr(dentry, bindex, h_dentry);
8156+
8157+ if (!d_is_dir(h_dentry)
8158+ || !wh_able
8159+ || (d_really_is_positive(dentry) && !d_is_dir(dentry)))
8160+ goto out; /* success */
8161+
8162+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD);
8163+ opq = au_diropq_test(h_dentry);
8164+ inode_unlock_shared(h_inode);
8165+ if (opq > 0)
8166+ au_set_dbdiropq(dentry, bindex);
8167+ else if (unlikely(opq < 0)) {
8168+ au_set_h_dptr(dentry, bindex, NULL);
8169+ h_dentry = ERR_PTR(opq);
8170+ }
8171+ goto out;
8172+
8173+out_neg:
8174+ dput(h_dentry);
8175+ h_dentry = NULL;
8176+out:
8177+ return h_dentry;
8178+}
8179+
8180+static int au_test_shwh(struct super_block *sb, const struct qstr *name)
8181+{
8182+ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
8183+ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
8184+ return -EPERM;
8185+ return 0;
8186+}
8187+
8188+/*
8189+ * returns the number of lower positive dentries,
8190+ * otherwise an error.
8191+ * can be called at unlinking with @type is zero.
8192+ */
8193+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop,
8194+ unsigned int flags)
8195+{
8196+ int npositive, err;
8197+ aufs_bindex_t bindex, btail, bdiropq;
8198+ unsigned char isdir, dirperm1, dirren;
8199+ struct au_do_lookup_args args = {
8200+ .flags = flags,
8201+ .name = &dentry->d_name
8202+ };
8203+ struct dentry *parent;
8204+ struct super_block *sb;
8205+
8206+ sb = dentry->d_sb;
8207+ err = au_test_shwh(sb, args.name);
8208+ if (unlikely(err))
8209+ goto out;
8210+
8211+ err = au_wh_name_alloc(&args.whname, args.name);
8212+ if (unlikely(err))
8213+ goto out;
8214+
8215+ isdir = !!d_is_dir(dentry);
8216+ dirperm1 = !!au_opt_test(au_mntflags(sb), DIRPERM1);
8217+ dirren = !!au_opt_test(au_mntflags(sb), DIRREN);
8218+ if (dirren)
8219+ au_fset_lkup(args.flags, DIRREN);
8220+
8221+ npositive = 0;
8222+ parent = dget_parent(dentry);
8223+ btail = au_dbtaildir(parent);
8224+ for (bindex = btop; bindex <= btail; bindex++) {
8225+ struct dentry *h_parent, *h_dentry;
8226+ struct inode *h_inode, *h_dir;
8227+ struct au_branch *br;
8228+
8229+ h_dentry = au_h_dptr(dentry, bindex);
8230+ if (h_dentry) {
8231+ if (d_is_positive(h_dentry))
8232+ npositive++;
8233+ break;
8234+ }
8235+ h_parent = au_h_dptr(parent, bindex);
8236+ if (!h_parent || !d_is_dir(h_parent))
8237+ continue;
8238+
8239+ if (dirren) {
8240+ /* if the inum matches, then use the prepared name */
8241+ err = au_dr_lkup_name(&args, bindex);
8242+ if (unlikely(err))
8243+ goto out_parent;
8244+ }
8245+
8246+ h_dir = d_inode(h_parent);
8247+ inode_lock_shared_nested(h_dir, AuLsc_I_PARENT);
8248+ h_dentry = au_do_lookup(h_parent, dentry, bindex, &args);
8249+ inode_unlock_shared(h_dir);
8250+ err = PTR_ERR(h_dentry);
8251+ if (IS_ERR(h_dentry))
8252+ goto out_parent;
8253+ if (h_dentry)
8254+ au_fclr_lkup(args.flags, ALLOW_NEG);
8255+ if (dirperm1)
8256+ au_fset_lkup(args.flags, IGNORE_PERM);
8257+
8258+ if (au_dbwh(dentry) == bindex)
8259+ break;
8260+ if (!h_dentry)
8261+ continue;
8262+ if (d_is_negative(h_dentry))
8263+ continue;
8264+ h_inode = d_inode(h_dentry);
8265+ npositive++;
8266+ if (!args.type)
8267+ args.type = h_inode->i_mode & S_IFMT;
8268+ if (args.type != S_IFDIR)
8269+ break;
8270+ else if (isdir) {
8271+ /* the type of lower may be different */
8272+ bdiropq = au_dbdiropq(dentry);
8273+ if (bdiropq >= 0 && bdiropq <= bindex)
8274+ break;
8275+ }
8276+ br = au_sbr(sb, bindex);
8277+ if (dirren
8278+ && au_dr_hino_test_add(&br->br_dirren, h_inode->i_ino,
8279+ /*add_ent*/NULL)) {
8280+ /* prepare next name to lookup */
8281+ err = au_dr_lkup(&args, dentry, bindex);
8282+ if (unlikely(err))
8283+ goto out_parent;
8284+ }
8285+ }
8286+
8287+ if (npositive) {
8288+ AuLabel(positive);
8289+ au_update_dbtop(dentry);
8290+ }
8291+ err = npositive;
8292+ if (unlikely(!au_opt_test(au_mntflags(sb), UDBA_NONE)
8293+ && au_dbtop(dentry) < 0)) {
8294+ err = -EIO;
8295+ AuIOErr("both of real entry and whiteout found, %pd, err %d\n",
8296+ dentry, err);
8297+ }
8298+
8299+out_parent:
8300+ dput(parent);
8301+ au_kfree_try_rcu(args.whname.name);
8302+ if (dirren)
8303+ au_dr_lkup_fin(&args);
8304+out:
8305+ return err;
8306+}
8307+
8308+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent)
8309+{
8310+ struct dentry *dentry;
8311+ int wkq_err;
8312+
8313+ if (!au_test_h_perm_sio(d_inode(parent), MAY_EXEC))
8314+ dentry = vfsub_lkup_one(name, parent);
8315+ else {
8316+ struct vfsub_lkup_one_args args = {
8317+ .errp = &dentry,
8318+ .name = name,
8319+ .parent = parent
8320+ };
8321+
8322+ wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args);
8323+ if (unlikely(wkq_err))
8324+ dentry = ERR_PTR(wkq_err);
8325+ }
8326+
8327+ return dentry;
8328+}
8329+
8330+/*
8331+ * lookup @dentry on @bindex which should be negative.
8332+ */
8333+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh)
8334+{
8335+ int err;
8336+ struct dentry *parent, *h_parent, *h_dentry;
8337+ struct au_branch *br;
8338+
8339+ parent = dget_parent(dentry);
8340+ h_parent = au_h_dptr(parent, bindex);
8341+ br = au_sbr(dentry->d_sb, bindex);
8342+ if (wh)
8343+ h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
8344+ else
8345+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent);
8346+ err = PTR_ERR(h_dentry);
8347+ if (IS_ERR(h_dentry))
8348+ goto out;
8349+ if (unlikely(d_is_positive(h_dentry))) {
8350+ err = -EIO;
8351+ AuIOErr("%pd should be negative on b%d.\n", h_dentry, bindex);
8352+ dput(h_dentry);
8353+ goto out;
8354+ }
8355+
8356+ err = 0;
8357+ if (bindex < au_dbtop(dentry))
8358+ au_set_dbtop(dentry, bindex);
8359+ if (au_dbbot(dentry) < bindex)
8360+ au_set_dbbot(dentry, bindex);
8361+ au_set_h_dptr(dentry, bindex, h_dentry);
8362+
8363+out:
8364+ dput(parent);
8365+ return err;
8366+}
8367+
8368+/* ---------------------------------------------------------------------- */
8369+
8370+/* subset of struct inode */
8371+struct au_iattr {
8372+ unsigned long i_ino;
8373+ /* unsigned int i_nlink; */
8374+ kuid_t i_uid;
8375+ kgid_t i_gid;
8376+ u64 i_version;
8377+/*
8378+ loff_t i_size;
8379+ blkcnt_t i_blocks;
8380+*/
8381+ umode_t i_mode;
8382+};
8383+
8384+static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
8385+{
8386+ ia->i_ino = h_inode->i_ino;
8387+ /* ia->i_nlink = h_inode->i_nlink; */
8388+ ia->i_uid = h_inode->i_uid;
8389+ ia->i_gid = h_inode->i_gid;
8390+ ia->i_version = inode_query_iversion(h_inode);
8391+/*
8392+ ia->i_size = h_inode->i_size;
8393+ ia->i_blocks = h_inode->i_blocks;
8394+*/
8395+ ia->i_mode = (h_inode->i_mode & S_IFMT);
8396+}
8397+
8398+static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
8399+{
8400+ return ia->i_ino != h_inode->i_ino
8401+ /* || ia->i_nlink != h_inode->i_nlink */
8402+ || !uid_eq(ia->i_uid, h_inode->i_uid)
8403+ || !gid_eq(ia->i_gid, h_inode->i_gid)
8404+ || !inode_eq_iversion(h_inode, ia->i_version)
8405+/*
8406+ || ia->i_size != h_inode->i_size
8407+ || ia->i_blocks != h_inode->i_blocks
8408+*/
8409+ || ia->i_mode != (h_inode->i_mode & S_IFMT);
8410+}
8411+
8412+static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
8413+ struct au_branch *br)
8414+{
8415+ int err;
8416+ struct au_iattr ia;
8417+ struct inode *h_inode;
8418+ struct dentry *h_d;
8419+ struct super_block *h_sb;
8420+
8421+ err = 0;
8422+ memset(&ia, -1, sizeof(ia));
8423+ h_sb = h_dentry->d_sb;
8424+ h_inode = NULL;
8425+ if (d_is_positive(h_dentry)) {
8426+ h_inode = d_inode(h_dentry);
8427+ au_iattr_save(&ia, h_inode);
8428+ } else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
8429+ /* nfs d_revalidate may return 0 for negative dentry */
8430+ /* fuse d_revalidate always return 0 for negative dentry */
8431+ goto out;
8432+
8433+ /* main purpose is namei.c:cached_lookup() and d_revalidate */
8434+ h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent);
8435+ err = PTR_ERR(h_d);
8436+ if (IS_ERR(h_d))
8437+ goto out;
8438+
8439+ err = 0;
8440+ if (unlikely(h_d != h_dentry
8441+ || d_inode(h_d) != h_inode
8442+ || (h_inode && au_iattr_test(&ia, h_inode))))
8443+ err = au_busy_or_stale();
8444+ dput(h_d);
8445+
8446+out:
8447+ AuTraceErr(err);
8448+ return err;
8449+}
8450+
8451+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
8452+ struct dentry *h_parent, struct au_branch *br)
8453+{
8454+ int err;
8455+
8456+ err = 0;
8457+ if (udba == AuOpt_UDBA_REVAL
8458+ && !au_test_fs_remote(h_dentry->d_sb)) {
8459+ IMustLock(h_dir);
8460+ err = (d_inode(h_dentry->d_parent) != h_dir);
8461+ } else if (udba != AuOpt_UDBA_NONE)
8462+ err = au_h_verify_dentry(h_dentry, h_parent, br);
8463+
8464+ return err;
8465+}
8466+
8467+/* ---------------------------------------------------------------------- */
8468+
8469+static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
8470+{
8471+ int err;
8472+ aufs_bindex_t new_bindex, bindex, bbot, bwh, bdiropq;
8473+ struct au_hdentry tmp, *p, *q;
8474+ struct au_dinfo *dinfo;
8475+ struct super_block *sb;
8476+
8477+ DiMustWriteLock(dentry);
8478+
8479+ sb = dentry->d_sb;
8480+ dinfo = au_di(dentry);
8481+ bbot = dinfo->di_bbot;
8482+ bwh = dinfo->di_bwh;
8483+ bdiropq = dinfo->di_bdiropq;
8484+ bindex = dinfo->di_btop;
8485+ p = au_hdentry(dinfo, bindex);
8486+ for (; bindex <= bbot; bindex++, p++) {
8487+ if (!p->hd_dentry)
8488+ continue;
8489+
8490+ new_bindex = au_br_index(sb, p->hd_id);
8491+ if (new_bindex == bindex)
8492+ continue;
8493+
8494+ if (dinfo->di_bwh == bindex)
8495+ bwh = new_bindex;
8496+ if (dinfo->di_bdiropq == bindex)
8497+ bdiropq = new_bindex;
8498+ if (new_bindex < 0) {
8499+ au_hdput(p);
8500+ p->hd_dentry = NULL;
8501+ continue;
8502+ }
8503+
8504+ /* swap two lower dentries, and loop again */
8505+ q = au_hdentry(dinfo, new_bindex);
8506+ tmp = *q;
8507+ *q = *p;
8508+ *p = tmp;
8509+ if (tmp.hd_dentry) {
8510+ bindex--;
8511+ p--;
8512+ }
8513+ }
8514+
8515+ dinfo->di_bwh = -1;
8516+ if (bwh >= 0 && bwh <= au_sbbot(sb) && au_sbr_whable(sb, bwh))
8517+ dinfo->di_bwh = bwh;
8518+
8519+ dinfo->di_bdiropq = -1;
8520+ if (bdiropq >= 0
8521+ && bdiropq <= au_sbbot(sb)
8522+ && au_sbr_whable(sb, bdiropq))
8523+ dinfo->di_bdiropq = bdiropq;
8524+
8525+ err = -EIO;
8526+ dinfo->di_btop = -1;
8527+ dinfo->di_bbot = -1;
8528+ bbot = au_dbbot(parent);
8529+ bindex = 0;
8530+ p = au_hdentry(dinfo, bindex);
8531+ for (; bindex <= bbot; bindex++, p++)
8532+ if (p->hd_dentry) {
8533+ dinfo->di_btop = bindex;
8534+ break;
8535+ }
8536+
8537+ if (dinfo->di_btop >= 0) {
8538+ bindex = bbot;
8539+ p = au_hdentry(dinfo, bindex);
8540+ for (; bindex >= 0; bindex--, p--)
8541+ if (p->hd_dentry) {
8542+ dinfo->di_bbot = bindex;
8543+ err = 0;
8544+ break;
8545+ }
8546+ }
8547+
8548+ return err;
8549+}
8550+
8551+static void au_do_hide(struct dentry *dentry)
8552+{
8553+ struct inode *inode;
8554+
8555+ if (d_really_is_positive(dentry)) {
8556+ inode = d_inode(dentry);
8557+ if (!d_is_dir(dentry)) {
8558+ if (inode->i_nlink && !d_unhashed(dentry))
8559+ drop_nlink(inode);
8560+ } else {
8561+ clear_nlink(inode);
8562+ /* stop next lookup */
8563+ inode->i_flags |= S_DEAD;
8564+ }
8565+ smp_mb(); /* necessary? */
8566+ }
8567+ d_drop(dentry);
8568+}
8569+
8570+static int au_hide_children(struct dentry *parent)
8571+{
8572+ int err, i, j, ndentry;
8573+ struct au_dcsub_pages dpages;
8574+ struct au_dpage *dpage;
8575+ struct dentry *dentry;
8576+
8577+ err = au_dpages_init(&dpages, GFP_NOFS);
8578+ if (unlikely(err))
8579+ goto out;
8580+ err = au_dcsub_pages(&dpages, parent, NULL, NULL);
8581+ if (unlikely(err))
8582+ goto out_dpages;
8583+
8584+ /* in reverse order */
8585+ for (i = dpages.ndpage - 1; i >= 0; i--) {
8586+ dpage = dpages.dpages + i;
8587+ ndentry = dpage->ndentry;
8588+ for (j = ndentry - 1; j >= 0; j--) {
8589+ dentry = dpage->dentries[j];
8590+ if (dentry != parent)
8591+ au_do_hide(dentry);
8592+ }
8593+ }
8594+
8595+out_dpages:
8596+ au_dpages_free(&dpages);
8597+out:
8598+ return err;
8599+}
8600+
8601+static void au_hide(struct dentry *dentry)
8602+{
8603+ int err;
8604+
8605+ AuDbgDentry(dentry);
8606+ if (d_is_dir(dentry)) {
8607+ /* shrink_dcache_parent(dentry); */
8608+ err = au_hide_children(dentry);
8609+ if (unlikely(err))
8610+ AuIOErr("%pd, failed hiding children, ignored %d\n",
8611+ dentry, err);
8612+ }
8613+ au_do_hide(dentry);
8614+}
8615+
8616+/*
8617+ * By adding a dirty branch, a cached dentry may be affected in various ways.
8618+ *
8619+ * a dirty branch is added
8620+ * - on the top of layers
8621+ * - in the middle of layers
8622+ * - to the bottom of layers
8623+ *
8624+ * on the added branch there exists
8625+ * - a whiteout
8626+ * - a diropq
8627+ * - a same named entry
8628+ * + exist
8629+ * * negative --> positive
8630+ * * positive --> positive
8631+ * - type is unchanged
8632+ * - type is changed
8633+ * + doesn't exist
8634+ * * negative --> negative
8635+ * * positive --> negative (rejected by au_br_del() for non-dir case)
8636+ * - none
8637+ */
8638+static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
8639+ struct au_dinfo *tmp)
8640+{
8641+ int err;
8642+ aufs_bindex_t bindex, bbot;
8643+ struct {
8644+ struct dentry *dentry;
8645+ struct inode *inode;
8646+ mode_t mode;
8647+ } orig_h, tmp_h = {
8648+ .dentry = NULL
8649+ };
8650+ struct au_hdentry *hd;
8651+ struct inode *inode, *h_inode;
8652+ struct dentry *h_dentry;
8653+
8654+ err = 0;
8655+ AuDebugOn(dinfo->di_btop < 0);
8656+ orig_h.mode = 0;
8657+ orig_h.dentry = au_hdentry(dinfo, dinfo->di_btop)->hd_dentry;
8658+ orig_h.inode = NULL;
8659+ if (d_is_positive(orig_h.dentry)) {
8660+ orig_h.inode = d_inode(orig_h.dentry);
8661+ orig_h.mode = orig_h.inode->i_mode & S_IFMT;
8662+ }
8663+ if (tmp->di_btop >= 0) {
8664+ tmp_h.dentry = au_hdentry(tmp, tmp->di_btop)->hd_dentry;
8665+ if (d_is_positive(tmp_h.dentry)) {
8666+ tmp_h.inode = d_inode(tmp_h.dentry);
8667+ tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
8668+ }
8669+ }
8670+
8671+ inode = NULL;
8672+ if (d_really_is_positive(dentry))
8673+ inode = d_inode(dentry);
8674+ if (!orig_h.inode) {
8675+ AuDbg("negative originally\n");
8676+ if (inode) {
8677+ au_hide(dentry);
8678+ goto out;
8679+ }
8680+ AuDebugOn(inode);
8681+ AuDebugOn(dinfo->di_btop != dinfo->di_bbot);
8682+ AuDebugOn(dinfo->di_bdiropq != -1);
8683+
8684+ if (!tmp_h.inode) {
8685+ AuDbg("negative --> negative\n");
8686+ /* should have only one negative lower */
8687+ if (tmp->di_btop >= 0
8688+ && tmp->di_btop < dinfo->di_btop) {
8689+ AuDebugOn(tmp->di_btop != tmp->di_bbot);
8690+ AuDebugOn(dinfo->di_btop != dinfo->di_bbot);
8691+ au_set_h_dptr(dentry, dinfo->di_btop, NULL);
8692+ au_di_cp(dinfo, tmp);
8693+ hd = au_hdentry(tmp, tmp->di_btop);
8694+ au_set_h_dptr(dentry, tmp->di_btop,
8695+ dget(hd->hd_dentry));
8696+ }
8697+ au_dbg_verify_dinode(dentry);
8698+ } else {
8699+ AuDbg("negative --> positive\n");
8700+ /*
8701+ * similar to the behaviour of creating with bypassing
8702+ * aufs.
8703+ * unhash it in order to force an error in the
8704+ * succeeding create operation.
8705+ * we should not set S_DEAD here.
8706+ */
8707+ d_drop(dentry);
8708+ /* au_di_swap(tmp, dinfo); */
8709+ au_dbg_verify_dinode(dentry);
8710+ }
8711+ } else {
8712+ AuDbg("positive originally\n");
8713+ /* inode may be NULL */
8714+ AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode);
8715+ if (!tmp_h.inode) {
8716+ AuDbg("positive --> negative\n");
8717+ /* or bypassing aufs */
8718+ au_hide(dentry);
8719+ if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_btop)
8720+ dinfo->di_bwh = tmp->di_bwh;
8721+ if (inode)
8722+ err = au_refresh_hinode_self(inode);
8723+ au_dbg_verify_dinode(dentry);
8724+ } else if (orig_h.mode == tmp_h.mode) {
8725+ AuDbg("positive --> positive, same type\n");
8726+ if (!S_ISDIR(orig_h.mode)
8727+ && dinfo->di_btop > tmp->di_btop) {
8728+ /*
8729+ * similar to the behaviour of removing and
8730+ * creating.
8731+ */
8732+ au_hide(dentry);
8733+ if (inode)
8734+ err = au_refresh_hinode_self(inode);
8735+ au_dbg_verify_dinode(dentry);
8736+ } else {
8737+ /* fill empty slots */
8738+ if (dinfo->di_btop > tmp->di_btop)
8739+ dinfo->di_btop = tmp->di_btop;
8740+ if (dinfo->di_bbot < tmp->di_bbot)
8741+ dinfo->di_bbot = tmp->di_bbot;
8742+ dinfo->di_bwh = tmp->di_bwh;
8743+ dinfo->di_bdiropq = tmp->di_bdiropq;
8744+ bbot = dinfo->di_bbot;
8745+ bindex = tmp->di_btop;
8746+ hd = au_hdentry(tmp, bindex);
8747+ for (; bindex <= bbot; bindex++, hd++) {
8748+ if (au_h_dptr(dentry, bindex))
8749+ continue;
8750+ h_dentry = hd->hd_dentry;
8751+ if (!h_dentry)
8752+ continue;
8753+ AuDebugOn(d_is_negative(h_dentry));
8754+ h_inode = d_inode(h_dentry);
8755+ AuDebugOn(orig_h.mode
8756+ != (h_inode->i_mode
8757+ & S_IFMT));
8758+ au_set_h_dptr(dentry, bindex,
8759+ dget(h_dentry));
8760+ }
8761+ if (inode)
8762+ err = au_refresh_hinode(inode, dentry);
8763+ au_dbg_verify_dinode(dentry);
8764+ }
8765+ } else {
8766+ AuDbg("positive --> positive, different type\n");
8767+ /* similar to the behaviour of removing and creating */
8768+ au_hide(dentry);
8769+ if (inode)
8770+ err = au_refresh_hinode_self(inode);
8771+ au_dbg_verify_dinode(dentry);
8772+ }
8773+ }
8774+
8775+out:
8776+ return err;
8777+}
8778+
8779+void au_refresh_dop(struct dentry *dentry, int force_reval)
8780+{
8781+ const struct dentry_operations *dop
8782+ = force_reval ? &aufs_dop : dentry->d_sb->s_d_op;
8783+ static const unsigned int mask
8784+ = DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE;
8785+
8786+ BUILD_BUG_ON(sizeof(mask) != sizeof(dentry->d_flags));
8787+
8788+ if (dentry->d_op == dop)
8789+ return;
8790+
8791+ AuDbg("%pd\n", dentry);
8792+ spin_lock(&dentry->d_lock);
8793+ if (dop == &aufs_dop)
8794+ dentry->d_flags |= mask;
8795+ else
8796+ dentry->d_flags &= ~mask;
8797+ dentry->d_op = dop;
8798+ spin_unlock(&dentry->d_lock);
8799+}
8800+
8801+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
8802+{
8803+ int err, ebrange, nbr;
8804+ unsigned int sigen;
8805+ struct au_dinfo *dinfo, *tmp;
8806+ struct super_block *sb;
8807+ struct inode *inode;
8808+
8809+ DiMustWriteLock(dentry);
8810+ AuDebugOn(IS_ROOT(dentry));
8811+ AuDebugOn(d_really_is_negative(parent));
8812+
8813+ sb = dentry->d_sb;
8814+ sigen = au_sigen(sb);
8815+ err = au_digen_test(parent, sigen);
8816+ if (unlikely(err))
8817+ goto out;
8818+
8819+ nbr = au_sbbot(sb) + 1;
8820+ dinfo = au_di(dentry);
8821+ err = au_di_realloc(dinfo, nbr, /*may_shrink*/0);
8822+ if (unlikely(err))
8823+ goto out;
8824+ ebrange = au_dbrange_test(dentry);
8825+ if (!ebrange)
8826+ ebrange = au_do_refresh_hdentry(dentry, parent);
8827+
8828+ if (d_unhashed(dentry) || ebrange /* || dinfo->di_tmpfile */) {
8829+ AuDebugOn(au_dbtop(dentry) < 0 && au_dbbot(dentry) >= 0);
8830+ if (d_really_is_positive(dentry)) {
8831+ inode = d_inode(dentry);
8832+ err = au_refresh_hinode_self(inode);
8833+ }
8834+ au_dbg_verify_dinode(dentry);
8835+ if (!err)
8836+ goto out_dgen; /* success */
8837+ goto out;
8838+ }
8839+
8840+ /* temporary dinfo */
8841+ AuDbgDentry(dentry);
8842+ err = -ENOMEM;
8843+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
8844+ if (unlikely(!tmp))
8845+ goto out;
8846+ au_di_swap(tmp, dinfo);
8847+ /* returns the number of positive dentries */
8848+ /*
8849+ * if current working dir is removed, it returns an error.
8850+ * but the dentry is legal.
8851+ */
8852+ err = au_lkup_dentry(dentry, /*btop*/0, AuLkup_ALLOW_NEG);
8853+ AuDbgDentry(dentry);
8854+ au_di_swap(tmp, dinfo);
8855+ if (err == -ENOENT)
8856+ err = 0;
8857+ if (err >= 0) {
8858+ /* compare/refresh by dinfo */
8859+ AuDbgDentry(dentry);
8860+ err = au_refresh_by_dinfo(dentry, dinfo, tmp);
8861+ au_dbg_verify_dinode(dentry);
8862+ AuTraceErr(err);
8863+ }
8864+ au_di_realloc(dinfo, nbr, /*may_shrink*/1); /* harmless if err */
8865+ au_rw_write_unlock(&tmp->di_rwsem);
8866+ au_di_free(tmp);
8867+ if (unlikely(err))
8868+ goto out;
8869+
8870+out_dgen:
8871+ au_update_digen(dentry);
8872+out:
8873+ if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) {
8874+ AuIOErr("failed refreshing %pd, %d\n", dentry, err);
8875+ AuDbgDentry(dentry);
8876+ }
8877+ AuTraceErr(err);
8878+ return err;
8879+}
8880+
8881+static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags,
8882+ struct dentry *dentry, aufs_bindex_t bindex)
8883+{
8884+ int err, valid;
8885+
8886+ err = 0;
8887+ if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE))
8888+ goto out;
8889+
8890+ AuDbg("b%d\n", bindex);
8891+ /*
8892+ * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
8893+ * due to whiteout and branch permission.
8894+ */
8895+ flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
8896+ | LOOKUP_FOLLOW | LOOKUP_EXCL);
8897+ /* it may return tri-state */
8898+ valid = h_dentry->d_op->d_revalidate(h_dentry, flags);
8899+
8900+ if (unlikely(valid < 0))
8901+ err = valid;
8902+ else if (!valid)
8903+ err = -EINVAL;
8904+
8905+out:
8906+ AuTraceErr(err);
8907+ return err;
8908+}
8909+
8910+/* todo: remove this */
8911+static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
8912+ unsigned int flags, int do_udba, int dirren)
8913+{
8914+ int err;
8915+ umode_t mode, h_mode;
8916+ aufs_bindex_t bindex, btail, btop, ibs, ibe;
8917+ unsigned char plus, unhashed, is_root, h_plus, h_nfs, tmpfile;
8918+ struct inode *h_inode, *h_cached_inode;
8919+ struct dentry *h_dentry;
8920+ struct qstr *name, *h_name;
8921+
8922+ err = 0;
8923+ plus = 0;
8924+ mode = 0;
8925+ ibs = -1;
8926+ ibe = -1;
8927+ unhashed = !!d_unhashed(dentry);
8928+ is_root = !!IS_ROOT(dentry);
8929+ name = &dentry->d_name;
8930+ tmpfile = au_di(dentry)->di_tmpfile;
8931+
8932+ /*
8933+ * Theoretically, REVAL test should be unnecessary in case of
8934+ * {FS,I}NOTIFY.
8935+ * But {fs,i}notify doesn't fire some necessary events,
8936+ * IN_ATTRIB for atime/nlink/pageio
8937+ * Let's do REVAL test too.
8938+ */
8939+ if (do_udba && inode) {
8940+ mode = (inode->i_mode & S_IFMT);
8941+ plus = (inode->i_nlink > 0);
8942+ ibs = au_ibtop(inode);
8943+ ibe = au_ibbot(inode);
8944+ }
8945+
8946+ btop = au_dbtop(dentry);
8947+ btail = btop;
8948+ if (inode && S_ISDIR(inode->i_mode))
8949+ btail = au_dbtaildir(dentry);
8950+ for (bindex = btop; bindex <= btail; bindex++) {
8951+ h_dentry = au_h_dptr(dentry, bindex);
8952+ if (!h_dentry)
8953+ continue;
8954+
8955+ AuDbg("b%d, %pd\n", bindex, h_dentry);
8956+ h_nfs = !!au_test_nfs(h_dentry->d_sb);
8957+ spin_lock(&h_dentry->d_lock);
8958+ h_name = &h_dentry->d_name;
8959+ if (unlikely(do_udba
8960+ && !is_root
8961+ && ((!h_nfs
8962+ && (unhashed != !!d_unhashed(h_dentry)
8963+ || (!tmpfile && !dirren
8964+ && !au_qstreq(name, h_name))
8965+ ))
8966+ || (h_nfs
8967+ && !(flags & LOOKUP_OPEN)
8968+ && (h_dentry->d_flags
8969+ & DCACHE_NFSFS_RENAMED)))
8970+ )) {
8971+ int h_unhashed;
8972+
8973+ h_unhashed = d_unhashed(h_dentry);
8974+ spin_unlock(&h_dentry->d_lock);
8975+ AuDbg("unhash 0x%x 0x%x, %pd %pd\n",
8976+ unhashed, h_unhashed, dentry, h_dentry);
8977+ goto err;
8978+ }
8979+ spin_unlock(&h_dentry->d_lock);
8980+
8981+ err = au_do_h_d_reval(h_dentry, flags, dentry, bindex);
8982+ if (unlikely(err))
8983+ /* do not goto err, to keep the errno */
8984+ break;
8985+
8986+ /* todo: plink too? */
8987+ if (!do_udba)
8988+ continue;
8989+
8990+ /* UDBA tests */
8991+ if (unlikely(!!inode != d_is_positive(h_dentry)))
8992+ goto err;
8993+
8994+ h_inode = NULL;
8995+ if (d_is_positive(h_dentry))
8996+ h_inode = d_inode(h_dentry);
8997+ h_plus = plus;
8998+ h_mode = mode;
8999+ h_cached_inode = h_inode;
9000+ if (h_inode) {
9001+ h_mode = (h_inode->i_mode & S_IFMT);
9002+ h_plus = (h_inode->i_nlink > 0);
9003+ }
9004+ if (inode && ibs <= bindex && bindex <= ibe)
9005+ h_cached_inode = au_h_iptr(inode, bindex);
9006+
9007+ if (!h_nfs) {
9008+ if (unlikely(plus != h_plus && !tmpfile))
9009+ goto err;
9010+ } else {
9011+ if (unlikely(!(h_dentry->d_flags & DCACHE_NFSFS_RENAMED)
9012+ && !is_root
9013+ && !IS_ROOT(h_dentry)
9014+ && unhashed != d_unhashed(h_dentry)))
9015+ goto err;
9016+ }
9017+ if (unlikely(mode != h_mode
9018+ || h_cached_inode != h_inode))
9019+ goto err;
9020+ continue;
9021+
9022+err:
9023+ err = -EINVAL;
9024+ break;
9025+ }
9026+
9027+ AuTraceErr(err);
9028+ return err;
9029+}
9030+
9031+/* todo: consolidate with do_refresh() and au_reval_for_attr() */
9032+static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
9033+{
9034+ int err;
9035+ struct dentry *parent;
9036+
9037+ if (!au_digen_test(dentry, sigen))
9038+ return 0;
9039+
9040+ parent = dget_parent(dentry);
9041+ di_read_lock_parent(parent, AuLock_IR);
9042+ AuDebugOn(au_digen_test(parent, sigen));
9043+ au_dbg_verify_gen(parent, sigen);
9044+ err = au_refresh_dentry(dentry, parent);
9045+ di_read_unlock(parent, AuLock_IR);
9046+ dput(parent);
9047+ AuTraceErr(err);
9048+ return err;
9049+}
9050+
9051+int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
9052+{
9053+ int err;
9054+ struct dentry *d, *parent;
9055+
9056+ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
9057+ return simple_reval_dpath(dentry, sigen);
9058+
9059+ /* slow loop, keep it simple and stupid */
9060+ /* cf: au_cpup_dirs() */
9061+ err = 0;
9062+ parent = NULL;
9063+ while (au_digen_test(dentry, sigen)) {
9064+ d = dentry;
9065+ while (1) {
9066+ dput(parent);
9067+ parent = dget_parent(d);
9068+ if (!au_digen_test(parent, sigen))
9069+ break;
9070+ d = parent;
9071+ }
9072+
9073+ if (d != dentry)
9074+ di_write_lock_child2(d);
9075+
9076+ /* someone might update our dentry while we were sleeping */
9077+ if (au_digen_test(d, sigen)) {
9078+ /*
9079+ * todo: consolidate with simple_reval_dpath(),
9080+ * do_refresh() and au_reval_for_attr().
9081+ */
9082+ di_read_lock_parent(parent, AuLock_IR);
9083+ err = au_refresh_dentry(d, parent);
9084+ di_read_unlock(parent, AuLock_IR);
9085+ }
9086+
9087+ if (d != dentry)
9088+ di_write_unlock(d);
9089+ dput(parent);
9090+ if (unlikely(err))
9091+ break;
9092+ }
9093+
9094+ return err;
9095+}
9096+
9097+/*
9098+ * if valid returns 1, otherwise 0.
9099+ */
9100+static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags)
9101+{
9102+ int valid, err;
9103+ unsigned int sigen;
9104+ unsigned char do_udba, dirren;
9105+ struct super_block *sb;
9106+ struct inode *inode;
9107+
9108+ /* todo: support rcu-walk? */
9109+ if (flags & LOOKUP_RCU)
9110+ return -ECHILD;
9111+
9112+ valid = 0;
9113+ if (unlikely(!au_di(dentry)))
9114+ goto out;
9115+
9116+ valid = 1;
9117+ sb = dentry->d_sb;
9118+ /*
9119+ * todo: very ugly
9120+ * i_mutex of parent dir may be held,
9121+ * but we should not return 'invalid' due to busy.
9122+ */
9123+ err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM);
9124+ if (unlikely(err)) {
9125+ valid = err;
9126+ AuTraceErr(err);
9127+ goto out;
9128+ }
9129+ inode = NULL;
9130+ if (d_really_is_positive(dentry))
9131+ inode = d_inode(dentry);
9132+ if (unlikely(inode && au_is_bad_inode(inode))) {
9133+ err = -EINVAL;
9134+ AuTraceErr(err);
9135+ goto out_dgrade;
9136+ }
9137+ if (unlikely(au_dbrange_test(dentry))) {
9138+ err = -EINVAL;
9139+ AuTraceErr(err);
9140+ goto out_dgrade;
9141+ }
9142+
9143+ sigen = au_sigen(sb);
9144+ if (au_digen_test(dentry, sigen)) {
9145+ AuDebugOn(IS_ROOT(dentry));
9146+ err = au_reval_dpath(dentry, sigen);
9147+ if (unlikely(err)) {
9148+ AuTraceErr(err);
9149+ goto out_dgrade;
9150+ }
9151+ }
9152+ di_downgrade_lock(dentry, AuLock_IR);
9153+
9154+ err = -EINVAL;
9155+ if (!(flags & (LOOKUP_OPEN | LOOKUP_EMPTY))
9156+ && inode
9157+ && !(inode->i_state && I_LINKABLE)
9158+ && (IS_DEADDIR(inode) || !inode->i_nlink)) {
9159+ AuTraceErr(err);
9160+ goto out_inval;
9161+ }
9162+
9163+ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
9164+ if (do_udba && inode) {
9165+ aufs_bindex_t btop = au_ibtop(inode);
9166+ struct inode *h_inode;
9167+
9168+ if (btop >= 0) {
9169+ h_inode = au_h_iptr(inode, btop);
9170+ if (h_inode && au_test_higen(inode, h_inode)) {
9171+ AuTraceErr(err);
9172+ goto out_inval;
9173+ }
9174+ }
9175+ }
9176+
9177+ dirren = !!au_opt_test(au_mntflags(sb), DIRREN);
9178+ err = h_d_revalidate(dentry, inode, flags, do_udba, dirren);
9179+ if (unlikely(!err && do_udba && au_dbtop(dentry) < 0)) {
9180+ err = -EIO;
9181+ AuDbg("both of real entry and whiteout found, %p, err %d\n",
9182+ dentry, err);
9183+ }
9184+ goto out_inval;
9185+
9186+out_dgrade:
9187+ di_downgrade_lock(dentry, AuLock_IR);
9188+out_inval:
9189+ aufs_read_unlock(dentry, AuLock_IR);
9190+ AuTraceErr(err);
9191+ valid = !err;
9192+out:
9193+ if (!valid) {
9194+ AuDbg("%pd invalid, %d\n", dentry, valid);
9195+ d_drop(dentry);
9196+ }
9197+ return valid;
9198+}
9199+
9200+static void aufs_d_release(struct dentry *dentry)
9201+{
9202+ if (au_di(dentry)) {
9203+ au_di_fin(dentry);
9204+ au_hn_di_reinit(dentry);
9205+ }
9206+}
9207+
9208+const struct dentry_operations aufs_dop = {
9209+ .d_revalidate = aufs_d_revalidate,
9210+ .d_weak_revalidate = aufs_d_revalidate,
9211+ .d_release = aufs_d_release
9212+};
9213+
9214+/* aufs_dop without d_revalidate */
9215+const struct dentry_operations aufs_dop_noreval = {
9216+ .d_release = aufs_d_release
9217+};
9218diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
9219--- /usr/share/empty/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
9220+++ linux/fs/aufs/dentry.h 2020-01-27 10:57:18.168871450 +0100
9221@@ -0,0 +1,268 @@
9222+/* SPDX-License-Identifier: GPL-2.0 */
9223+/*
9224+ * Copyright (C) 2005-2020 Junjiro R. Okajima
9225+ *
9226+ * This program, aufs is free software; you can redistribute it and/or modify
9227+ * it under the terms of the GNU General Public License as published by
9228+ * the Free Software Foundation; either version 2 of the License, or
9229+ * (at your option) any later version.
9230+ *
9231+ * This program is distributed in the hope that it will be useful,
9232+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9233+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9234+ * GNU General Public License for more details.
9235+ *
9236+ * You should have received a copy of the GNU General Public License
9237+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
9238+ */
9239+
9240+/*
9241+ * lookup and dentry operations
9242+ */
9243+
9244+#ifndef __AUFS_DENTRY_H__
9245+#define __AUFS_DENTRY_H__
9246+
9247+#ifdef __KERNEL__
9248+
9249+#include <linux/dcache.h>
9250+#include "dirren.h"
9251+#include "rwsem.h"
9252+
9253+struct au_hdentry {
9254+ struct dentry *hd_dentry;
9255+ aufs_bindex_t hd_id;
9256+};
9257+
9258+struct au_dinfo {
9259+ atomic_t di_generation;
9260+
9261+ struct au_rwsem di_rwsem;
9262+ aufs_bindex_t di_btop, di_bbot, di_bwh, di_bdiropq;
9263+ unsigned char di_tmpfile; /* to allow the different name */
9264+ struct au_hdentry *di_hdentry;
9265+ struct rcu_head rcu;
9266+} ____cacheline_aligned_in_smp;
9267+
9268+/* ---------------------------------------------------------------------- */
9269+
9270+/* flags for au_lkup_dentry() */
9271+#define AuLkup_ALLOW_NEG 1
9272+#define AuLkup_IGNORE_PERM (1 << 1)
9273+#define AuLkup_DIRREN (1 << 2)
9274+#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name)
9275+#define au_fset_lkup(flags, name) \
9276+ do { (flags) |= AuLkup_##name; } while (0)
9277+#define au_fclr_lkup(flags, name) \
9278+ do { (flags) &= ~AuLkup_##name; } while (0)
9279+
9280+#ifndef CONFIG_AUFS_DIRREN
9281+#undef AuLkup_DIRREN
9282+#define AuLkup_DIRREN 0
9283+#endif
9284+
9285+struct au_do_lookup_args {
9286+ unsigned int flags;
9287+ mode_t type;
9288+ struct qstr whname, *name;
9289+ struct au_dr_lookup dirren;
9290+};
9291+
9292+/* ---------------------------------------------------------------------- */
9293+
9294+/* dentry.c */
9295+extern const struct dentry_operations aufs_dop, aufs_dop_noreval;
9296+struct au_branch;
9297+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent);
9298+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
9299+ struct dentry *h_parent, struct au_branch *br);
9300+
9301+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop,
9302+ unsigned int flags);
9303+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh);
9304+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
9305+int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
9306+void au_refresh_dop(struct dentry *dentry, int force_reval);
9307+
9308+/* dinfo.c */
9309+void au_di_init_once(void *_di);
9310+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
9311+void au_di_free(struct au_dinfo *dinfo);
9312+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
9313+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
9314+int au_di_init(struct dentry *dentry);
9315+void au_di_fin(struct dentry *dentry);
9316+int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink);
9317+
9318+void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
9319+void di_read_unlock(struct dentry *d, int flags);
9320+void di_downgrade_lock(struct dentry *d, int flags);
9321+void di_write_lock(struct dentry *d, unsigned int lsc);
9322+void di_write_unlock(struct dentry *d);
9323+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
9324+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
9325+void di_write_unlock2(struct dentry *d1, struct dentry *d2);
9326+
9327+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
9328+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
9329+aufs_bindex_t au_dbtail(struct dentry *dentry);
9330+aufs_bindex_t au_dbtaildir(struct dentry *dentry);
9331+
9332+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
9333+ struct dentry *h_dentry);
9334+int au_digen_test(struct dentry *dentry, unsigned int sigen);
9335+int au_dbrange_test(struct dentry *dentry);
9336+void au_update_digen(struct dentry *dentry);
9337+void au_update_dbrange(struct dentry *dentry, int do_put_zero);
9338+void au_update_dbtop(struct dentry *dentry);
9339+void au_update_dbbot(struct dentry *dentry);
9340+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
9341+
9342+/* ---------------------------------------------------------------------- */
9343+
9344+static inline struct au_dinfo *au_di(struct dentry *dentry)
9345+{
9346+ return dentry->d_fsdata;
9347+}
9348+
9349+/* ---------------------------------------------------------------------- */
9350+
9351+/* lock subclass for dinfo */
9352+enum {
9353+ AuLsc_DI_CHILD, /* child first */
9354+ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */
9355+ AuLsc_DI_CHILD3, /* copyup dirs */
9356+ AuLsc_DI_PARENT,
9357+ AuLsc_DI_PARENT2,
9358+ AuLsc_DI_PARENT3,
9359+ AuLsc_DI_TMP /* temp for replacing dinfo */
9360+};
9361+
9362+/*
9363+ * di_read_lock_child, di_write_lock_child,
9364+ * di_read_lock_child2, di_write_lock_child2,
9365+ * di_read_lock_child3, di_write_lock_child3,
9366+ * di_read_lock_parent, di_write_lock_parent,
9367+ * di_read_lock_parent2, di_write_lock_parent2,
9368+ * di_read_lock_parent3, di_write_lock_parent3,
9369+ */
9370+#define AuReadLockFunc(name, lsc) \
9371+static inline void di_read_lock_##name(struct dentry *d, int flags) \
9372+{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
9373+
9374+#define AuWriteLockFunc(name, lsc) \
9375+static inline void di_write_lock_##name(struct dentry *d) \
9376+{ di_write_lock(d, AuLsc_DI_##lsc); }
9377+
9378+#define AuRWLockFuncs(name, lsc) \
9379+ AuReadLockFunc(name, lsc) \
9380+ AuWriteLockFunc(name, lsc)
9381+
9382+AuRWLockFuncs(child, CHILD);
9383+AuRWLockFuncs(child2, CHILD2);
9384+AuRWLockFuncs(child3, CHILD3);
9385+AuRWLockFuncs(parent, PARENT);
9386+AuRWLockFuncs(parent2, PARENT2);
9387+AuRWLockFuncs(parent3, PARENT3);
9388+
9389+#undef AuReadLockFunc
9390+#undef AuWriteLockFunc
9391+#undef AuRWLockFuncs
9392+
9393+#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
9394+#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
9395+#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
9396+
9397+/* ---------------------------------------------------------------------- */
9398+
9399+/* todo: memory barrier? */
9400+static inline unsigned int au_digen(struct dentry *d)
9401+{
9402+ return atomic_read(&au_di(d)->di_generation);
9403+}
9404+
9405+static inline void au_h_dentry_init(struct au_hdentry *hdentry)
9406+{
9407+ hdentry->hd_dentry = NULL;
9408+}
9409+
9410+static inline struct au_hdentry *au_hdentry(struct au_dinfo *di,
9411+ aufs_bindex_t bindex)
9412+{
9413+ return di->di_hdentry + bindex;
9414+}
9415+
9416+static inline void au_hdput(struct au_hdentry *hd)
9417+{
9418+ if (hd)
9419+ dput(hd->hd_dentry);
9420+}
9421+
9422+static inline aufs_bindex_t au_dbtop(struct dentry *dentry)
9423+{
9424+ DiMustAnyLock(dentry);
9425+ return au_di(dentry)->di_btop;
9426+}
9427+
9428+static inline aufs_bindex_t au_dbbot(struct dentry *dentry)
9429+{
9430+ DiMustAnyLock(dentry);
9431+ return au_di(dentry)->di_bbot;
9432+}
9433+
9434+static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
9435+{
9436+ DiMustAnyLock(dentry);
9437+ return au_di(dentry)->di_bwh;
9438+}
9439+
9440+static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
9441+{
9442+ DiMustAnyLock(dentry);
9443+ return au_di(dentry)->di_bdiropq;
9444+}
9445+
9446+/* todo: hard/soft set? */
9447+static inline void au_set_dbtop(struct dentry *dentry, aufs_bindex_t bindex)
9448+{
9449+ DiMustWriteLock(dentry);
9450+ au_di(dentry)->di_btop = bindex;
9451+}
9452+
9453+static inline void au_set_dbbot(struct dentry *dentry, aufs_bindex_t bindex)
9454+{
9455+ DiMustWriteLock(dentry);
9456+ au_di(dentry)->di_bbot = bindex;
9457+}
9458+
9459+static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
9460+{
9461+ DiMustWriteLock(dentry);
9462+ /* dbwh can be outside of btop - bbot range */
9463+ au_di(dentry)->di_bwh = bindex;
9464+}
9465+
9466+static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
9467+{
9468+ DiMustWriteLock(dentry);
9469+ au_di(dentry)->di_bdiropq = bindex;
9470+}
9471+
9472+/* ---------------------------------------------------------------------- */
9473+
9474+#ifdef CONFIG_AUFS_HNOTIFY
9475+static inline void au_digen_dec(struct dentry *d)
9476+{
9477+ atomic_dec(&au_di(d)->di_generation);
9478+}
9479+
9480+static inline void au_hn_di_reinit(struct dentry *dentry)
9481+{
9482+ dentry->d_fsdata = NULL;
9483+}
9484+#else
9485+AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
9486+#endif /* CONFIG_AUFS_HNOTIFY */
9487+
9488+#endif /* __KERNEL__ */
9489+#endif /* __AUFS_DENTRY_H__ */
9490diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
9491--- /usr/share/empty/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100
9492+++ linux/fs/aufs/dinfo.c 2020-01-27 10:57:18.168871450 +0100
9493@@ -0,0 +1,554 @@
9494+// SPDX-License-Identifier: GPL-2.0
9495+/*
9496+ * Copyright (C) 2005-2020 Junjiro R. Okajima
9497+ *
9498+ * This program, aufs is free software; you can redistribute it and/or modify
9499+ * it under the terms of the GNU General Public License as published by
9500+ * the Free Software Foundation; either version 2 of the License, or
9501+ * (at your option) any later version.
9502+ *
9503+ * This program is distributed in the hope that it will be useful,
9504+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9505+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9506+ * GNU General Public License for more details.
9507+ *
9508+ * You should have received a copy of the GNU General Public License
9509+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
9510+ */
9511+
9512+/*
9513+ * dentry private data
9514+ */
9515+
9516+#include "aufs.h"
9517+
9518+void au_di_init_once(void *_dinfo)
9519+{
9520+ struct au_dinfo *dinfo = _dinfo;
9521+
9522+ au_rw_init(&dinfo->di_rwsem);
9523+}
9524+
9525+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
9526+{
9527+ struct au_dinfo *dinfo;
9528+ int nbr, i;
9529+
9530+ dinfo = au_cache_alloc_dinfo();
9531+ if (unlikely(!dinfo))
9532+ goto out;
9533+
9534+ nbr = au_sbbot(sb) + 1;
9535+ if (nbr <= 0)
9536+ nbr = 1;
9537+ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
9538+ if (dinfo->di_hdentry) {
9539+ au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
9540+ dinfo->di_btop = -1;
9541+ dinfo->di_bbot = -1;
9542+ dinfo->di_bwh = -1;
9543+ dinfo->di_bdiropq = -1;
9544+ dinfo->di_tmpfile = 0;
9545+ for (i = 0; i < nbr; i++)
9546+ dinfo->di_hdentry[i].hd_id = -1;
9547+ goto out;
9548+ }
9549+
9550+ au_cache_free_dinfo(dinfo);
9551+ dinfo = NULL;
9552+
9553+out:
9554+ return dinfo;
9555+}
9556+
9557+void au_di_free(struct au_dinfo *dinfo)
9558+{
9559+ struct au_hdentry *p;
9560+ aufs_bindex_t bbot, bindex;
9561+
9562+ /* dentry may not be revalidated */
9563+ bindex = dinfo->di_btop;
9564+ if (bindex >= 0) {
9565+ bbot = dinfo->di_bbot;
9566+ p = au_hdentry(dinfo, bindex);
9567+ while (bindex++ <= bbot)
9568+ au_hdput(p++);
9569+ }
9570+ au_kfree_try_rcu(dinfo->di_hdentry);
9571+ au_cache_free_dinfo(dinfo);
9572+}
9573+
9574+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
9575+{
9576+ struct au_hdentry *p;
9577+ aufs_bindex_t bi;
9578+
9579+ AuRwMustWriteLock(&a->di_rwsem);
9580+ AuRwMustWriteLock(&b->di_rwsem);
9581+
9582+#define DiSwap(v, name) \
9583+ do { \
9584+ v = a->di_##name; \
9585+ a->di_##name = b->di_##name; \
9586+ b->di_##name = v; \
9587+ } while (0)
9588+
9589+ DiSwap(p, hdentry);
9590+ DiSwap(bi, btop);
9591+ DiSwap(bi, bbot);
9592+ DiSwap(bi, bwh);
9593+ DiSwap(bi, bdiropq);
9594+ /* smp_mb(); */
9595+
9596+#undef DiSwap
9597+}
9598+
9599+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
9600+{
9601+ AuRwMustWriteLock(&dst->di_rwsem);
9602+ AuRwMustWriteLock(&src->di_rwsem);
9603+
9604+ dst->di_btop = src->di_btop;
9605+ dst->di_bbot = src->di_bbot;
9606+ dst->di_bwh = src->di_bwh;
9607+ dst->di_bdiropq = src->di_bdiropq;
9608+ /* smp_mb(); */
9609+}
9610+
9611+int au_di_init(struct dentry *dentry)
9612+{
9613+ int err;
9614+ struct super_block *sb;
9615+ struct au_dinfo *dinfo;
9616+
9617+ err = 0;
9618+ sb = dentry->d_sb;
9619+ dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
9620+ if (dinfo) {
9621+ atomic_set(&dinfo->di_generation, au_sigen(sb));
9622+ /* smp_mb(); */ /* atomic_set */
9623+ dentry->d_fsdata = dinfo;
9624+ } else
9625+ err = -ENOMEM;
9626+
9627+ return err;
9628+}
9629+
9630+void au_di_fin(struct dentry *dentry)
9631+{
9632+ struct au_dinfo *dinfo;
9633+
9634+ dinfo = au_di(dentry);
9635+ AuRwDestroy(&dinfo->di_rwsem);
9636+ au_di_free(dinfo);
9637+}
9638+
9639+int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink)
9640+{
9641+ int err, sz;
9642+ struct au_hdentry *hdp;
9643+
9644+ AuRwMustWriteLock(&dinfo->di_rwsem);
9645+
9646+ err = -ENOMEM;
9647+ sz = sizeof(*hdp) * (dinfo->di_bbot + 1);
9648+ if (!sz)
9649+ sz = sizeof(*hdp);
9650+ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS,
9651+ may_shrink);
9652+ if (hdp) {
9653+ dinfo->di_hdentry = hdp;
9654+ err = 0;
9655+ }
9656+
9657+ return err;
9658+}
9659+
9660+/* ---------------------------------------------------------------------- */
9661+
9662+static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
9663+{
9664+ switch (lsc) {
9665+ case AuLsc_DI_CHILD:
9666+ ii_write_lock_child(inode);
9667+ break;
9668+ case AuLsc_DI_CHILD2:
9669+ ii_write_lock_child2(inode);
9670+ break;
9671+ case AuLsc_DI_CHILD3:
9672+ ii_write_lock_child3(inode);
9673+ break;
9674+ case AuLsc_DI_PARENT:
9675+ ii_write_lock_parent(inode);
9676+ break;
9677+ case AuLsc_DI_PARENT2:
9678+ ii_write_lock_parent2(inode);
9679+ break;
9680+ case AuLsc_DI_PARENT3:
9681+ ii_write_lock_parent3(inode);
9682+ break;
9683+ default:
9684+ BUG();
9685+ }
9686+}
9687+
9688+static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
9689+{
9690+ switch (lsc) {
9691+ case AuLsc_DI_CHILD:
9692+ ii_read_lock_child(inode);
9693+ break;
9694+ case AuLsc_DI_CHILD2:
9695+ ii_read_lock_child2(inode);
9696+ break;
9697+ case AuLsc_DI_CHILD3:
9698+ ii_read_lock_child3(inode);
9699+ break;
9700+ case AuLsc_DI_PARENT:
9701+ ii_read_lock_parent(inode);
9702+ break;
9703+ case AuLsc_DI_PARENT2:
9704+ ii_read_lock_parent2(inode);
9705+ break;
9706+ case AuLsc_DI_PARENT3:
9707+ ii_read_lock_parent3(inode);
9708+ break;
9709+ default:
9710+ BUG();
9711+ }
9712+}
9713+
9714+void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
9715+{
9716+ struct inode *inode;
9717+
9718+ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
9719+ if (d_really_is_positive(d)) {
9720+ inode = d_inode(d);
9721+ if (au_ftest_lock(flags, IW))
9722+ do_ii_write_lock(inode, lsc);
9723+ else if (au_ftest_lock(flags, IR))
9724+ do_ii_read_lock(inode, lsc);
9725+ }
9726+}
9727+
9728+void di_read_unlock(struct dentry *d, int flags)
9729+{
9730+ struct inode *inode;
9731+
9732+ if (d_really_is_positive(d)) {
9733+ inode = d_inode(d);
9734+ if (au_ftest_lock(flags, IW)) {
9735+ au_dbg_verify_dinode(d);
9736+ ii_write_unlock(inode);
9737+ } else if (au_ftest_lock(flags, IR)) {
9738+ au_dbg_verify_dinode(d);
9739+ ii_read_unlock(inode);
9740+ }
9741+ }
9742+ au_rw_read_unlock(&au_di(d)->di_rwsem);
9743+}
9744+
9745+void di_downgrade_lock(struct dentry *d, int flags)
9746+{
9747+ if (d_really_is_positive(d) && au_ftest_lock(flags, IR))
9748+ ii_downgrade_lock(d_inode(d));
9749+ au_rw_dgrade_lock(&au_di(d)->di_rwsem);
9750+}
9751+
9752+void di_write_lock(struct dentry *d, unsigned int lsc)
9753+{
9754+ au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
9755+ if (d_really_is_positive(d))
9756+ do_ii_write_lock(d_inode(d), lsc);
9757+}
9758+
9759+void di_write_unlock(struct dentry *d)
9760+{
9761+ au_dbg_verify_dinode(d);
9762+ if (d_really_is_positive(d))
9763+ ii_write_unlock(d_inode(d));
9764+ au_rw_write_unlock(&au_di(d)->di_rwsem);
9765+}
9766+
9767+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
9768+{
9769+ AuDebugOn(d1 == d2
9770+ || d_inode(d1) == d_inode(d2)
9771+ || d1->d_sb != d2->d_sb);
9772+
9773+ if ((isdir && au_test_subdir(d1, d2))
9774+ || d1 < d2) {
9775+ di_write_lock_child(d1);
9776+ di_write_lock_child2(d2);
9777+ } else {
9778+ di_write_lock_child(d2);
9779+ di_write_lock_child2(d1);
9780+ }
9781+}
9782+
9783+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
9784+{
9785+ AuDebugOn(d1 == d2
9786+ || d_inode(d1) == d_inode(d2)
9787+ || d1->d_sb != d2->d_sb);
9788+
9789+ if ((isdir && au_test_subdir(d1, d2))
9790+ || d1 < d2) {
9791+ di_write_lock_parent(d1);
9792+ di_write_lock_parent2(d2);
9793+ } else {
9794+ di_write_lock_parent(d2);
9795+ di_write_lock_parent2(d1);
9796+ }
9797+}
9798+
9799+void di_write_unlock2(struct dentry *d1, struct dentry *d2)
9800+{
9801+ di_write_unlock(d1);
9802+ if (d_inode(d1) == d_inode(d2))
9803+ au_rw_write_unlock(&au_di(d2)->di_rwsem);
9804+ else
9805+ di_write_unlock(d2);
9806+}
9807+
9808+/* ---------------------------------------------------------------------- */
9809+
9810+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
9811+{
9812+ struct dentry *d;
9813+
9814+ DiMustAnyLock(dentry);
9815+
9816+ if (au_dbtop(dentry) < 0 || bindex < au_dbtop(dentry))
9817+ return NULL;
9818+ AuDebugOn(bindex < 0);
9819+ d = au_hdentry(au_di(dentry), bindex)->hd_dentry;
9820+ AuDebugOn(d && au_dcount(d) <= 0);
9821+ return d;
9822+}
9823+
9824+/*
9825+ * extended version of au_h_dptr().
9826+ * returns a hashed and positive (or linkable) h_dentry in bindex, NULL, or
9827+ * error.
9828+ */
9829+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
9830+{
9831+ struct dentry *h_dentry;
9832+ struct inode *inode, *h_inode;
9833+
9834+ AuDebugOn(d_really_is_negative(dentry));
9835+
9836+ h_dentry = NULL;
9837+ if (au_dbtop(dentry) <= bindex
9838+ && bindex <= au_dbbot(dentry))
9839+ h_dentry = au_h_dptr(dentry, bindex);
9840+ if (h_dentry && !au_d_linkable(h_dentry)) {
9841+ dget(h_dentry);
9842+ goto out; /* success */
9843+ }
9844+
9845+ inode = d_inode(dentry);
9846+ AuDebugOn(bindex < au_ibtop(inode));
9847+ AuDebugOn(au_ibbot(inode) < bindex);
9848+ h_inode = au_h_iptr(inode, bindex);
9849+ h_dentry = d_find_alias(h_inode);
9850+ if (h_dentry) {
9851+ if (!IS_ERR(h_dentry)) {
9852+ if (!au_d_linkable(h_dentry))
9853+ goto out; /* success */
9854+ dput(h_dentry);
9855+ } else
9856+ goto out;
9857+ }
9858+
9859+ if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
9860+ h_dentry = au_plink_lkup(inode, bindex);
9861+ AuDebugOn(!h_dentry);
9862+ if (!IS_ERR(h_dentry)) {
9863+ if (!au_d_hashed_positive(h_dentry))
9864+ goto out; /* success */
9865+ dput(h_dentry);
9866+ h_dentry = NULL;
9867+ }
9868+ }
9869+
9870+out:
9871+ AuDbgDentry(h_dentry);
9872+ return h_dentry;
9873+}
9874+
9875+aufs_bindex_t au_dbtail(struct dentry *dentry)
9876+{
9877+ aufs_bindex_t bbot, bwh;
9878+
9879+ bbot = au_dbbot(dentry);
9880+ if (0 <= bbot) {
9881+ bwh = au_dbwh(dentry);
9882+ if (!bwh)
9883+ return bwh;
9884+ if (0 < bwh && bwh < bbot)
9885+ return bwh - 1;
9886+ }
9887+ return bbot;
9888+}
9889+
9890+aufs_bindex_t au_dbtaildir(struct dentry *dentry)
9891+{
9892+ aufs_bindex_t bbot, bopq;
9893+
9894+ bbot = au_dbtail(dentry);
9895+ if (0 <= bbot) {
9896+ bopq = au_dbdiropq(dentry);
9897+ if (0 <= bopq && bopq < bbot)
9898+ bbot = bopq;
9899+ }
9900+ return bbot;
9901+}
9902+
9903+/* ---------------------------------------------------------------------- */
9904+
9905+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
9906+ struct dentry *h_dentry)
9907+{
9908+ struct au_dinfo *dinfo;
9909+ struct au_hdentry *hd;
9910+ struct au_branch *br;
9911+
9912+ DiMustWriteLock(dentry);
9913+
9914+ dinfo = au_di(dentry);
9915+ hd = au_hdentry(dinfo, bindex);
9916+ au_hdput(hd);
9917+ hd->hd_dentry = h_dentry;
9918+ if (h_dentry) {
9919+ br = au_sbr(dentry->d_sb, bindex);
9920+ hd->hd_id = br->br_id;
9921+ }
9922+}
9923+
9924+int au_dbrange_test(struct dentry *dentry)
9925+{
9926+ int err;
9927+ aufs_bindex_t btop, bbot;
9928+
9929+ err = 0;
9930+ btop = au_dbtop(dentry);
9931+ bbot = au_dbbot(dentry);
9932+ if (btop >= 0)
9933+ AuDebugOn(bbot < 0 && btop > bbot);
9934+ else {
9935+ err = -EIO;
9936+ AuDebugOn(bbot >= 0);
9937+ }
9938+
9939+ return err;
9940+}
9941+
9942+int au_digen_test(struct dentry *dentry, unsigned int sigen)
9943+{
9944+ int err;
9945+
9946+ err = 0;
9947+ if (unlikely(au_digen(dentry) != sigen
9948+ || au_iigen_test(d_inode(dentry), sigen)))
9949+ err = -EIO;
9950+
9951+ return err;
9952+}
9953+
9954+void au_update_digen(struct dentry *dentry)
9955+{
9956+ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
9957+ /* smp_mb(); */ /* atomic_set */
9958+}
9959+
9960+void au_update_dbrange(struct dentry *dentry, int do_put_zero)
9961+{
9962+ struct au_dinfo *dinfo;
9963+ struct dentry *h_d;
9964+ struct au_hdentry *hdp;
9965+ aufs_bindex_t bindex, bbot;
9966+
9967+ DiMustWriteLock(dentry);
9968+
9969+ dinfo = au_di(dentry);
9970+ if (!dinfo || dinfo->di_btop < 0)
9971+ return;
9972+
9973+ if (do_put_zero) {
9974+ bbot = dinfo->di_bbot;
9975+ bindex = dinfo->di_btop;
9976+ hdp = au_hdentry(dinfo, bindex);
9977+ for (; bindex <= bbot; bindex++, hdp++) {
9978+ h_d = hdp->hd_dentry;
9979+ if (h_d && d_is_negative(h_d))
9980+ au_set_h_dptr(dentry, bindex, NULL);
9981+ }
9982+ }
9983+
9984+ dinfo->di_btop = 0;
9985+ hdp = au_hdentry(dinfo, dinfo->di_btop);
9986+ for (; dinfo->di_btop <= dinfo->di_bbot; dinfo->di_btop++, hdp++)
9987+ if (hdp->hd_dentry)
9988+ break;
9989+ if (dinfo->di_btop > dinfo->di_bbot) {
9990+ dinfo->di_btop = -1;
9991+ dinfo->di_bbot = -1;
9992+ return;
9993+ }
9994+
9995+ hdp = au_hdentry(dinfo, dinfo->di_bbot);
9996+ for (; dinfo->di_bbot >= 0; dinfo->di_bbot--, hdp--)
9997+ if (hdp->hd_dentry)
9998+ break;
9999+ AuDebugOn(dinfo->di_btop > dinfo->di_bbot || dinfo->di_bbot < 0);
10000+}
10001+
10002+void au_update_dbtop(struct dentry *dentry)
10003+{
10004+ aufs_bindex_t bindex, bbot;
10005+ struct dentry *h_dentry;
10006+
10007+ bbot = au_dbbot(dentry);
10008+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++) {
10009+ h_dentry = au_h_dptr(dentry, bindex);
10010+ if (!h_dentry)
10011+ continue;
10012+ if (d_is_positive(h_dentry)) {
10013+ au_set_dbtop(dentry, bindex);
10014+ return;
10015+ }
10016+ au_set_h_dptr(dentry, bindex, NULL);
10017+ }
10018+}
10019+
10020+void au_update_dbbot(struct dentry *dentry)
10021+{
10022+ aufs_bindex_t bindex, btop;
10023+ struct dentry *h_dentry;
10024+
10025+ btop = au_dbtop(dentry);
10026+ for (bindex = au_dbbot(dentry); bindex >= btop; bindex--) {
10027+ h_dentry = au_h_dptr(dentry, bindex);
10028+ if (!h_dentry)
10029+ continue;
10030+ if (d_is_positive(h_dentry)) {
10031+ au_set_dbbot(dentry, bindex);
10032+ return;
10033+ }
10034+ au_set_h_dptr(dentry, bindex, NULL);
10035+ }
10036+}
10037+
10038+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
10039+{
10040+ aufs_bindex_t bindex, bbot;
10041+
10042+ bbot = au_dbbot(dentry);
10043+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++)
10044+ if (au_h_dptr(dentry, bindex) == h_dentry)
10045+ return bindex;
10046+ return -1;
10047+}
10048diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
10049--- /usr/share/empty/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
10050+++ linux/fs/aufs/dir.c 2020-01-27 10:57:18.168871450 +0100
10051@@ -0,0 +1,763 @@
10052+// SPDX-License-Identifier: GPL-2.0
10053+/*
10054+ * Copyright (C) 2005-2020 Junjiro R. Okajima
10055+ *
10056+ * This program, aufs is free software; you can redistribute it and/or modify
10057+ * it under the terms of the GNU General Public License as published by
10058+ * the Free Software Foundation; either version 2 of the License, or
10059+ * (at your option) any later version.
10060+ *
10061+ * This program is distributed in the hope that it will be useful,
10062+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10063+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10064+ * GNU General Public License for more details.
10065+ *
10066+ * You should have received a copy of the GNU General Public License
10067+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
10068+ */
10069+
10070+/*
10071+ * directory operations
10072+ */
10073+
10074+#include <linux/fs_stack.h>
10075+#include <linux/iversion.h>
10076+#include "aufs.h"
10077+
10078+void au_add_nlink(struct inode *dir, struct inode *h_dir)
10079+{
10080+ unsigned int nlink;
10081+
10082+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
10083+
10084+ nlink = dir->i_nlink;
10085+ nlink += h_dir->i_nlink - 2;
10086+ if (h_dir->i_nlink < 2)
10087+ nlink += 2;
10088+ smp_mb(); /* for i_nlink */
10089+ /* 0 can happen in revaliding */
10090+ set_nlink(dir, nlink);
10091+}
10092+
10093+void au_sub_nlink(struct inode *dir, struct inode *h_dir)
10094+{
10095+ unsigned int nlink;
10096+
10097+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
10098+
10099+ nlink = dir->i_nlink;
10100+ nlink -= h_dir->i_nlink - 2;
10101+ if (h_dir->i_nlink < 2)
10102+ nlink -= 2;
10103+ smp_mb(); /* for i_nlink */
10104+ /* nlink == 0 means the branch-fs is broken */
10105+ set_nlink(dir, nlink);
10106+}
10107+
10108+loff_t au_dir_size(struct file *file, struct dentry *dentry)
10109+{
10110+ loff_t sz;
10111+ aufs_bindex_t bindex, bbot;
10112+ struct file *h_file;
10113+ struct dentry *h_dentry;
10114+
10115+ sz = 0;
10116+ if (file) {
10117+ AuDebugOn(!d_is_dir(file->f_path.dentry));
10118+
10119+ bbot = au_fbbot_dir(file);
10120+ for (bindex = au_fbtop(file);
10121+ bindex <= bbot && sz < KMALLOC_MAX_SIZE;
10122+ bindex++) {
10123+ h_file = au_hf_dir(file, bindex);
10124+ if (h_file && file_inode(h_file))
10125+ sz += vfsub_f_size_read(h_file);
10126+ }
10127+ } else {
10128+ AuDebugOn(!dentry);
10129+ AuDebugOn(!d_is_dir(dentry));
10130+
10131+ bbot = au_dbtaildir(dentry);
10132+ for (bindex = au_dbtop(dentry);
10133+ bindex <= bbot && sz < KMALLOC_MAX_SIZE;
10134+ bindex++) {
10135+ h_dentry = au_h_dptr(dentry, bindex);
10136+ if (h_dentry && d_is_positive(h_dentry))
10137+ sz += i_size_read(d_inode(h_dentry));
10138+ }
10139+ }
10140+ if (sz < KMALLOC_MAX_SIZE)
10141+ sz = roundup_pow_of_two(sz);
10142+ if (sz > KMALLOC_MAX_SIZE)
10143+ sz = KMALLOC_MAX_SIZE;
10144+ else if (sz < NAME_MAX) {
10145+ BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX);
10146+ sz = AUFS_RDBLK_DEF;
10147+ }
10148+ return sz;
10149+}
10150+
10151+struct au_dir_ts_arg {
10152+ struct dentry *dentry;
10153+ aufs_bindex_t brid;
10154+};
10155+
10156+static void au_do_dir_ts(void *arg)
10157+{
10158+ struct au_dir_ts_arg *a = arg;
10159+ struct au_dtime dt;
10160+ struct path h_path;
10161+ struct inode *dir, *h_dir;
10162+ struct super_block *sb;
10163+ struct au_branch *br;
10164+ struct au_hinode *hdir;
10165+ int err;
10166+ aufs_bindex_t btop, bindex;
10167+
10168+ sb = a->dentry->d_sb;
10169+ if (d_really_is_negative(a->dentry))
10170+ goto out;
10171+ /* no dir->i_mutex lock */
10172+ aufs_read_lock(a->dentry, AuLock_DW); /* noflush */
10173+
10174+ dir = d_inode(a->dentry);
10175+ btop = au_ibtop(dir);
10176+ bindex = au_br_index(sb, a->brid);
10177+ if (bindex < btop)
10178+ goto out_unlock;
10179+
10180+ br = au_sbr(sb, bindex);
10181+ h_path.dentry = au_h_dptr(a->dentry, bindex);
10182+ if (!h_path.dentry)
10183+ goto out_unlock;
10184+ h_path.mnt = au_br_mnt(br);
10185+ au_dtime_store(&dt, a->dentry, &h_path);
10186+
10187+ br = au_sbr(sb, btop);
10188+ if (!au_br_writable(br->br_perm))
10189+ goto out_unlock;
10190+ h_path.dentry = au_h_dptr(a->dentry, btop);
10191+ h_path.mnt = au_br_mnt(br);
10192+ err = vfsub_mnt_want_write(h_path.mnt);
10193+ if (err)
10194+ goto out_unlock;
10195+ hdir = au_hi(dir, btop);
10196+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
10197+ h_dir = au_h_iptr(dir, btop);
10198+ if (h_dir->i_nlink
10199+ && timespec64_compare(&h_dir->i_mtime, &dt.dt_mtime) < 0) {
10200+ dt.dt_h_path = h_path;
10201+ au_dtime_revert(&dt);
10202+ }
10203+ au_hn_inode_unlock(hdir);
10204+ vfsub_mnt_drop_write(h_path.mnt);
10205+ au_cpup_attr_timesizes(dir);
10206+
10207+out_unlock:
10208+ aufs_read_unlock(a->dentry, AuLock_DW);
10209+out:
10210+ dput(a->dentry);
10211+ au_nwt_done(&au_sbi(sb)->si_nowait);
10212+ au_kfree_try_rcu(arg);
10213+}
10214+
10215+void au_dir_ts(struct inode *dir, aufs_bindex_t bindex)
10216+{
10217+ int perm, wkq_err;
10218+ aufs_bindex_t btop;
10219+ struct au_dir_ts_arg *arg;
10220+ struct dentry *dentry;
10221+ struct super_block *sb;
10222+
10223+ IMustLock(dir);
10224+
10225+ dentry = d_find_any_alias(dir);
10226+ AuDebugOn(!dentry);
10227+ sb = dentry->d_sb;
10228+ btop = au_ibtop(dir);
10229+ if (btop == bindex) {
10230+ au_cpup_attr_timesizes(dir);
10231+ goto out;
10232+ }
10233+
10234+ perm = au_sbr_perm(sb, btop);
10235+ if (!au_br_writable(perm))
10236+ goto out;
10237+
10238+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
10239+ if (!arg)
10240+ goto out;
10241+
10242+ arg->dentry = dget(dentry); /* will be dput-ted by au_do_dir_ts() */
10243+ arg->brid = au_sbr_id(sb, bindex);
10244+ wkq_err = au_wkq_nowait(au_do_dir_ts, arg, sb, /*flags*/0);
10245+ if (unlikely(wkq_err)) {
10246+ pr_err("wkq %d\n", wkq_err);
10247+ dput(dentry);
10248+ au_kfree_try_rcu(arg);
10249+ }
10250+
10251+out:
10252+ dput(dentry);
10253+}
10254+
10255+/* ---------------------------------------------------------------------- */
10256+
10257+static int reopen_dir(struct file *file)
10258+{
10259+ int err;
10260+ unsigned int flags;
10261+ aufs_bindex_t bindex, btail, btop;
10262+ struct dentry *dentry, *h_dentry;
10263+ struct file *h_file;
10264+
10265+ /* open all lower dirs */
10266+ dentry = file->f_path.dentry;
10267+ btop = au_dbtop(dentry);
10268+ for (bindex = au_fbtop(file); bindex < btop; bindex++)
10269+ au_set_h_fptr(file, bindex, NULL);
10270+ au_set_fbtop(file, btop);
10271+
10272+ btail = au_dbtaildir(dentry);
10273+ for (bindex = au_fbbot_dir(file); btail < bindex; bindex--)
10274+ au_set_h_fptr(file, bindex, NULL);
10275+ au_set_fbbot_dir(file, btail);
10276+
10277+ flags = vfsub_file_flags(file);
10278+ for (bindex = btop; bindex <= btail; bindex++) {
10279+ h_dentry = au_h_dptr(dentry, bindex);
10280+ if (!h_dentry)
10281+ continue;
10282+ h_file = au_hf_dir(file, bindex);
10283+ if (h_file)
10284+ continue;
10285+
10286+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
10287+ err = PTR_ERR(h_file);
10288+ if (IS_ERR(h_file))
10289+ goto out; /* close all? */
10290+ au_set_h_fptr(file, bindex, h_file);
10291+ }
10292+ au_update_figen(file);
10293+ /* todo: necessary? */
10294+ /* file->f_ra = h_file->f_ra; */
10295+ err = 0;
10296+
10297+out:
10298+ return err;
10299+}
10300+
10301+static int do_open_dir(struct file *file, int flags, struct file *h_file)
10302+{
10303+ int err;
10304+ aufs_bindex_t bindex, btail;
10305+ struct dentry *dentry, *h_dentry;
10306+ struct vfsmount *mnt;
10307+
10308+ FiMustWriteLock(file);
10309+ AuDebugOn(h_file);
10310+
10311+ err = 0;
10312+ mnt = file->f_path.mnt;
10313+ dentry = file->f_path.dentry;
10314+ file->f_version = inode_query_iversion(d_inode(dentry));
10315+ bindex = au_dbtop(dentry);
10316+ au_set_fbtop(file, bindex);
10317+ btail = au_dbtaildir(dentry);
10318+ au_set_fbbot_dir(file, btail);
10319+ for (; !err && bindex <= btail; bindex++) {
10320+ h_dentry = au_h_dptr(dentry, bindex);
10321+ if (!h_dentry)
10322+ continue;
10323+
10324+ err = vfsub_test_mntns(mnt, h_dentry->d_sb);
10325+ if (unlikely(err))
10326+ break;
10327+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
10328+ if (IS_ERR(h_file)) {
10329+ err = PTR_ERR(h_file);
10330+ break;
10331+ }
10332+ au_set_h_fptr(file, bindex, h_file);
10333+ }
10334+ au_update_figen(file);
10335+ /* todo: necessary? */
10336+ /* file->f_ra = h_file->f_ra; */
10337+ if (!err)
10338+ return 0; /* success */
10339+
10340+ /* close all */
10341+ for (bindex = au_fbtop(file); bindex <= btail; bindex++)
10342+ au_set_h_fptr(file, bindex, NULL);
10343+ au_set_fbtop(file, -1);
10344+ au_set_fbbot_dir(file, -1);
10345+
10346+ return err;
10347+}
10348+
10349+static int aufs_open_dir(struct inode *inode __maybe_unused,
10350+ struct file *file)
10351+{
10352+ int err;
10353+ struct super_block *sb;
10354+ struct au_fidir *fidir;
10355+
10356+ err = -ENOMEM;
10357+ sb = file->f_path.dentry->d_sb;
10358+ si_read_lock(sb, AuLock_FLUSH);
10359+ fidir = au_fidir_alloc(sb);
10360+ if (fidir) {
10361+ struct au_do_open_args args = {
10362+ .open = do_open_dir,
10363+ .fidir = fidir
10364+ };
10365+ err = au_do_open(file, &args);
10366+ if (unlikely(err))
10367+ au_kfree_rcu(fidir);
10368+ }
10369+ si_read_unlock(sb);
10370+ return err;
10371+}
10372+
10373+static int aufs_release_dir(struct inode *inode __maybe_unused,
10374+ struct file *file)
10375+{
10376+ struct au_vdir *vdir_cache;
10377+ struct au_finfo *finfo;
10378+ struct au_fidir *fidir;
10379+ struct au_hfile *hf;
10380+ aufs_bindex_t bindex, bbot;
10381+
10382+ finfo = au_fi(file);
10383+ fidir = finfo->fi_hdir;
10384+ if (fidir) {
10385+ au_hbl_del(&finfo->fi_hlist,
10386+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
10387+ vdir_cache = fidir->fd_vdir_cache; /* lock-free */
10388+ if (vdir_cache)
10389+ au_vdir_free(vdir_cache);
10390+
10391+ bindex = finfo->fi_btop;
10392+ if (bindex >= 0) {
10393+ hf = fidir->fd_hfile + bindex;
10394+ /*
10395+ * calls fput() instead of filp_close(),
10396+ * since no dnotify or lock for the lower file.
10397+ */
10398+ bbot = fidir->fd_bbot;
10399+ for (; bindex <= bbot; bindex++, hf++)
10400+ if (hf->hf_file)
10401+ au_hfput(hf, /*execed*/0);
10402+ }
10403+ au_kfree_rcu(fidir);
10404+ finfo->fi_hdir = NULL;
10405+ }
10406+ au_finfo_fin(file);
10407+ return 0;
10408+}
10409+
10410+/* ---------------------------------------------------------------------- */
10411+
10412+static int au_do_flush_dir(struct file *file, fl_owner_t id)
10413+{
10414+ int err;
10415+ aufs_bindex_t bindex, bbot;
10416+ struct file *h_file;
10417+
10418+ err = 0;
10419+ bbot = au_fbbot_dir(file);
10420+ for (bindex = au_fbtop(file); !err && bindex <= bbot; bindex++) {
10421+ h_file = au_hf_dir(file, bindex);
10422+ if (h_file)
10423+ err = vfsub_flush(h_file, id);
10424+ }
10425+ return err;
10426+}
10427+
10428+static int aufs_flush_dir(struct file *file, fl_owner_t id)
10429+{
10430+ return au_do_flush(file, id, au_do_flush_dir);
10431+}
10432+
10433+/* ---------------------------------------------------------------------- */
10434+
10435+static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
10436+{
10437+ int err;
10438+ aufs_bindex_t bbot, bindex;
10439+ struct inode *inode;
10440+ struct super_block *sb;
10441+
10442+ err = 0;
10443+ sb = dentry->d_sb;
10444+ inode = d_inode(dentry);
10445+ IMustLock(inode);
10446+ bbot = au_dbbot(dentry);
10447+ for (bindex = au_dbtop(dentry); !err && bindex <= bbot; bindex++) {
10448+ struct path h_path;
10449+
10450+ if (au_test_ro(sb, bindex, inode))
10451+ continue;
10452+ h_path.dentry = au_h_dptr(dentry, bindex);
10453+ if (!h_path.dentry)
10454+ continue;
10455+
10456+ h_path.mnt = au_sbr_mnt(sb, bindex);
10457+ err = vfsub_fsync(NULL, &h_path, datasync);
10458+ }
10459+
10460+ return err;
10461+}
10462+
10463+static int au_do_fsync_dir(struct file *file, int datasync)
10464+{
10465+ int err;
10466+ aufs_bindex_t bbot, bindex;
10467+ struct file *h_file;
10468+ struct super_block *sb;
10469+ struct inode *inode;
10470+
10471+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1, /*fi_lsc*/0);
10472+ if (unlikely(err))
10473+ goto out;
10474+
10475+ inode = file_inode(file);
10476+ sb = inode->i_sb;
10477+ bbot = au_fbbot_dir(file);
10478+ for (bindex = au_fbtop(file); !err && bindex <= bbot; bindex++) {
10479+ h_file = au_hf_dir(file, bindex);
10480+ if (!h_file || au_test_ro(sb, bindex, inode))
10481+ continue;
10482+
10483+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
10484+ }
10485+
10486+out:
10487+ return err;
10488+}
10489+
10490+/*
10491+ * @file may be NULL
10492+ */
10493+static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end,
10494+ int datasync)
10495+{
10496+ int err;
10497+ struct dentry *dentry;
10498+ struct inode *inode;
10499+ struct super_block *sb;
10500+
10501+ err = 0;
10502+ dentry = file->f_path.dentry;
10503+ inode = d_inode(dentry);
10504+ inode_lock(inode);
10505+ sb = dentry->d_sb;
10506+ si_noflush_read_lock(sb);
10507+ if (file)
10508+ err = au_do_fsync_dir(file, datasync);
10509+ else {
10510+ di_write_lock_child(dentry);
10511+ err = au_do_fsync_dir_no_file(dentry, datasync);
10512+ }
10513+ au_cpup_attr_timesizes(inode);
10514+ di_write_unlock(dentry);
10515+ if (file)
10516+ fi_write_unlock(file);
10517+
10518+ si_read_unlock(sb);
10519+ inode_unlock(inode);
10520+ return err;
10521+}
10522+
10523+/* ---------------------------------------------------------------------- */
10524+
10525+static int aufs_iterate_shared(struct file *file, struct dir_context *ctx)
10526+{
10527+ int err;
10528+ struct dentry *dentry;
10529+ struct inode *inode, *h_inode;
10530+ struct super_block *sb;
10531+
10532+ AuDbg("%pD, ctx{%ps, %llu}\n", file, ctx->actor, ctx->pos);
10533+
10534+ dentry = file->f_path.dentry;
10535+ inode = d_inode(dentry);
10536+ IMustLock(inode);
10537+
10538+ sb = dentry->d_sb;
10539+ si_read_lock(sb, AuLock_FLUSH);
10540+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1, /*fi_lsc*/0);
10541+ if (unlikely(err))
10542+ goto out;
10543+ err = au_alive_dir(dentry);
10544+ if (!err)
10545+ err = au_vdir_init(file);
10546+ di_downgrade_lock(dentry, AuLock_IR);
10547+ if (unlikely(err))
10548+ goto out_unlock;
10549+
10550+ h_inode = au_h_iptr(inode, au_ibtop(inode));
10551+ if (!au_test_nfsd()) {
10552+ err = au_vdir_fill_de(file, ctx);
10553+ fsstack_copy_attr_atime(inode, h_inode);
10554+ } else {
10555+ /*
10556+ * nfsd filldir may call lookup_one_len(), vfs_getattr(),
10557+ * encode_fh() and others.
10558+ */
10559+ atomic_inc(&h_inode->i_count);
10560+ di_read_unlock(dentry, AuLock_IR);
10561+ si_read_unlock(sb);
10562+ err = au_vdir_fill_de(file, ctx);
10563+ fsstack_copy_attr_atime(inode, h_inode);
10564+ fi_write_unlock(file);
10565+ iput(h_inode);
10566+
10567+ AuTraceErr(err);
10568+ return err;
10569+ }
10570+
10571+out_unlock:
10572+ di_read_unlock(dentry, AuLock_IR);
10573+ fi_write_unlock(file);
10574+out:
10575+ si_read_unlock(sb);
10576+ return err;
10577+}
10578+
10579+/* ---------------------------------------------------------------------- */
10580+
10581+#define AuTestEmpty_WHONLY 1
10582+#define AuTestEmpty_CALLED (1 << 1)
10583+#define AuTestEmpty_SHWH (1 << 2)
10584+#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
10585+#define au_fset_testempty(flags, name) \
10586+ do { (flags) |= AuTestEmpty_##name; } while (0)
10587+#define au_fclr_testempty(flags, name) \
10588+ do { (flags) &= ~AuTestEmpty_##name; } while (0)
10589+
10590+#ifndef CONFIG_AUFS_SHWH
10591+#undef AuTestEmpty_SHWH
10592+#define AuTestEmpty_SHWH 0
10593+#endif
10594+
10595+struct test_empty_arg {
10596+ struct dir_context ctx;
10597+ struct au_nhash *whlist;
10598+ unsigned int flags;
10599+ int err;
10600+ aufs_bindex_t bindex;
10601+};
10602+
10603+static int test_empty_cb(struct dir_context *ctx, const char *__name,
10604+ int namelen, loff_t offset __maybe_unused, u64 ino,
10605+ unsigned int d_type)
10606+{
10607+ struct test_empty_arg *arg = container_of(ctx, struct test_empty_arg,
10608+ ctx);
10609+ char *name = (void *)__name;
10610+
10611+ arg->err = 0;
10612+ au_fset_testempty(arg->flags, CALLED);
10613+ /* smp_mb(); */
10614+ if (name[0] == '.'
10615+ && (namelen == 1 || (name[1] == '.' && namelen == 2)))
10616+ goto out; /* success */
10617+
10618+ if (namelen <= AUFS_WH_PFX_LEN
10619+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
10620+ if (au_ftest_testempty(arg->flags, WHONLY)
10621+ && !au_nhash_test_known_wh(arg->whlist, name, namelen))
10622+ arg->err = -ENOTEMPTY;
10623+ goto out;
10624+ }
10625+
10626+ name += AUFS_WH_PFX_LEN;
10627+ namelen -= AUFS_WH_PFX_LEN;
10628+ if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
10629+ arg->err = au_nhash_append_wh
10630+ (arg->whlist, name, namelen, ino, d_type, arg->bindex,
10631+ au_ftest_testempty(arg->flags, SHWH));
10632+
10633+out:
10634+ /* smp_mb(); */
10635+ AuTraceErr(arg->err);
10636+ return arg->err;
10637+}
10638+
10639+static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
10640+{
10641+ int err;
10642+ struct file *h_file;
10643+ struct au_branch *br;
10644+
10645+ h_file = au_h_open(dentry, arg->bindex,
10646+ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
10647+ /*file*/NULL, /*force_wr*/0);
10648+ err = PTR_ERR(h_file);
10649+ if (IS_ERR(h_file))
10650+ goto out;
10651+
10652+ err = 0;
10653+ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
10654+ && !file_inode(h_file)->i_nlink)
10655+ goto out_put;
10656+
10657+ do {
10658+ arg->err = 0;
10659+ au_fclr_testempty(arg->flags, CALLED);
10660+ /* smp_mb(); */
10661+ err = vfsub_iterate_dir(h_file, &arg->ctx);
10662+ if (err >= 0)
10663+ err = arg->err;
10664+ } while (!err && au_ftest_testempty(arg->flags, CALLED));
10665+
10666+out_put:
10667+ fput(h_file);
10668+ br = au_sbr(dentry->d_sb, arg->bindex);
10669+ au_lcnt_dec(&br->br_nfiles);
10670+out:
10671+ return err;
10672+}
10673+
10674+struct do_test_empty_args {
10675+ int *errp;
10676+ struct dentry *dentry;
10677+ struct test_empty_arg *arg;
10678+};
10679+
10680+static void call_do_test_empty(void *args)
10681+{
10682+ struct do_test_empty_args *a = args;
10683+ *a->errp = do_test_empty(a->dentry, a->arg);
10684+}
10685+
10686+static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
10687+{
10688+ int err, wkq_err;
10689+ struct dentry *h_dentry;
10690+ struct inode *h_inode;
10691+
10692+ h_dentry = au_h_dptr(dentry, arg->bindex);
10693+ h_inode = d_inode(h_dentry);
10694+ /* todo: i_mode changes anytime? */
10695+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD);
10696+ err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
10697+ inode_unlock_shared(h_inode);
10698+ if (!err)
10699+ err = do_test_empty(dentry, arg);
10700+ else {
10701+ struct do_test_empty_args args = {
10702+ .errp = &err,
10703+ .dentry = dentry,
10704+ .arg = arg
10705+ };
10706+ unsigned int flags = arg->flags;
10707+
10708+ wkq_err = au_wkq_wait(call_do_test_empty, &args);
10709+ if (unlikely(wkq_err))
10710+ err = wkq_err;
10711+ arg->flags = flags;
10712+ }
10713+
10714+ return err;
10715+}
10716+
10717+int au_test_empty_lower(struct dentry *dentry)
10718+{
10719+ int err;
10720+ unsigned int rdhash;
10721+ aufs_bindex_t bindex, btop, btail;
10722+ struct au_nhash whlist;
10723+ struct test_empty_arg arg = {
10724+ .ctx = {
10725+ .actor = test_empty_cb
10726+ }
10727+ };
10728+ int (*test_empty)(struct dentry *dentry, struct test_empty_arg *arg);
10729+
10730+ SiMustAnyLock(dentry->d_sb);
10731+
10732+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
10733+ if (!rdhash)
10734+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry));
10735+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
10736+ if (unlikely(err))
10737+ goto out;
10738+
10739+ arg.flags = 0;
10740+ arg.whlist = &whlist;
10741+ btop = au_dbtop(dentry);
10742+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
10743+ au_fset_testempty(arg.flags, SHWH);
10744+ test_empty = do_test_empty;
10745+ if (au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1))
10746+ test_empty = sio_test_empty;
10747+ arg.bindex = btop;
10748+ err = test_empty(dentry, &arg);
10749+ if (unlikely(err))
10750+ goto out_whlist;
10751+
10752+ au_fset_testempty(arg.flags, WHONLY);
10753+ btail = au_dbtaildir(dentry);
10754+ for (bindex = btop + 1; !err && bindex <= btail; bindex++) {
10755+ struct dentry *h_dentry;
10756+
10757+ h_dentry = au_h_dptr(dentry, bindex);
10758+ if (h_dentry && d_is_positive(h_dentry)) {
10759+ arg.bindex = bindex;
10760+ err = test_empty(dentry, &arg);
10761+ }
10762+ }
10763+
10764+out_whlist:
10765+ au_nhash_wh_free(&whlist);
10766+out:
10767+ return err;
10768+}
10769+
10770+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
10771+{
10772+ int err;
10773+ struct test_empty_arg arg = {
10774+ .ctx = {
10775+ .actor = test_empty_cb
10776+ }
10777+ };
10778+ aufs_bindex_t bindex, btail;
10779+
10780+ err = 0;
10781+ arg.whlist = whlist;
10782+ arg.flags = AuTestEmpty_WHONLY;
10783+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
10784+ au_fset_testempty(arg.flags, SHWH);
10785+ btail = au_dbtaildir(dentry);
10786+ for (bindex = au_dbtop(dentry); !err && bindex <= btail; bindex++) {
10787+ struct dentry *h_dentry;
10788+
10789+ h_dentry = au_h_dptr(dentry, bindex);
10790+ if (h_dentry && d_is_positive(h_dentry)) {
10791+ arg.bindex = bindex;
10792+ err = sio_test_empty(dentry, &arg);
10793+ }
10794+ }
10795+
10796+ return err;
10797+}
10798+
10799+/* ---------------------------------------------------------------------- */
10800+
10801+const struct file_operations aufs_dir_fop = {
10802+ .owner = THIS_MODULE,
10803+ .llseek = default_llseek,
10804+ .read = generic_read_dir,
10805+ .iterate_shared = aufs_iterate_shared,
10806+ .unlocked_ioctl = aufs_ioctl_dir,
10807+#ifdef CONFIG_COMPAT
10808+ .compat_ioctl = aufs_compat_ioctl_dir,
10809+#endif
10810+ .open = aufs_open_dir,
10811+ .release = aufs_release_dir,
10812+ .flush = aufs_flush_dir,
10813+ .fsync = aufs_fsync_dir
10814+};
10815diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
10816--- /usr/share/empty/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100
10817+++ linux/fs/aufs/dir.h 2020-01-27 10:57:18.168871450 +0100
10818@@ -0,0 +1,134 @@
10819+/* SPDX-License-Identifier: GPL-2.0 */
10820+/*
10821+ * Copyright (C) 2005-2020 Junjiro R. Okajima
10822+ *
10823+ * This program, aufs is free software; you can redistribute it and/or modify
10824+ * it under the terms of the GNU General Public License as published by
10825+ * the Free Software Foundation; either version 2 of the License, or
10826+ * (at your option) any later version.
10827+ *
10828+ * This program is distributed in the hope that it will be useful,
10829+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10830+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10831+ * GNU General Public License for more details.
10832+ *
10833+ * You should have received a copy of the GNU General Public License
10834+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
10835+ */
10836+
10837+/*
10838+ * directory operations
10839+ */
10840+
10841+#ifndef __AUFS_DIR_H__
10842+#define __AUFS_DIR_H__
10843+
10844+#ifdef __KERNEL__
10845+
10846+#include <linux/fs.h>
10847+
10848+/* ---------------------------------------------------------------------- */
10849+
10850+/* need to be faster and smaller */
10851+
10852+struct au_nhash {
10853+ unsigned int nh_num;
10854+ struct hlist_head *nh_head;
10855+};
10856+
10857+struct au_vdir_destr {
10858+ unsigned char len;
10859+ unsigned char name[0];
10860+} __packed;
10861+
10862+struct au_vdir_dehstr {
10863+ struct hlist_node hash;
10864+ struct au_vdir_destr *str;
10865+ struct rcu_head rcu;
10866+} ____cacheline_aligned_in_smp;
10867+
10868+struct au_vdir_de {
10869+ ino_t de_ino;
10870+ unsigned char de_type;
10871+ /* caution: packed */
10872+ struct au_vdir_destr de_str;
10873+} __packed;
10874+
10875+struct au_vdir_wh {
10876+ struct hlist_node wh_hash;
10877+#ifdef CONFIG_AUFS_SHWH
10878+ ino_t wh_ino;
10879+ aufs_bindex_t wh_bindex;
10880+ unsigned char wh_type;
10881+#else
10882+ aufs_bindex_t wh_bindex;
10883+#endif
10884+ /* caution: packed */
10885+ struct au_vdir_destr wh_str;
10886+} __packed;
10887+
10888+union au_vdir_deblk_p {
10889+ unsigned char *deblk;
10890+ struct au_vdir_de *de;
10891+};
10892+
10893+struct au_vdir {
10894+ unsigned char **vd_deblk;
10895+ unsigned long vd_nblk;
10896+ struct {
10897+ unsigned long ul;
10898+ union au_vdir_deblk_p p;
10899+ } vd_last;
10900+
10901+ u64 vd_version;
10902+ unsigned int vd_deblk_sz;
10903+ unsigned long vd_jiffy;
10904+ struct rcu_head rcu;
10905+} ____cacheline_aligned_in_smp;
10906+
10907+/* ---------------------------------------------------------------------- */
10908+
10909+/* dir.c */
10910+extern const struct file_operations aufs_dir_fop;
10911+void au_add_nlink(struct inode *dir, struct inode *h_dir);
10912+void au_sub_nlink(struct inode *dir, struct inode *h_dir);
10913+loff_t au_dir_size(struct file *file, struct dentry *dentry);
10914+void au_dir_ts(struct inode *dir, aufs_bindex_t bsrc);
10915+int au_test_empty_lower(struct dentry *dentry);
10916+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
10917+
10918+/* vdir.c */
10919+unsigned int au_rdhash_est(loff_t sz);
10920+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
10921+void au_nhash_wh_free(struct au_nhash *whlist);
10922+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
10923+ int limit);
10924+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
10925+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
10926+ unsigned int d_type, aufs_bindex_t bindex,
10927+ unsigned char shwh);
10928+void au_vdir_free(struct au_vdir *vdir);
10929+int au_vdir_init(struct file *file);
10930+int au_vdir_fill_de(struct file *file, struct dir_context *ctx);
10931+
10932+/* ioctl.c */
10933+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
10934+
10935+#ifdef CONFIG_AUFS_RDU
10936+/* rdu.c */
10937+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
10938+#ifdef CONFIG_COMPAT
10939+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
10940+ unsigned long arg);
10941+#endif
10942+#else
10943+AuStub(long, au_rdu_ioctl, return -EINVAL, struct file *file,
10944+ unsigned int cmd, unsigned long arg)
10945+#ifdef CONFIG_COMPAT
10946+AuStub(long, au_rdu_compat_ioctl, return -EINVAL, struct file *file,
10947+ unsigned int cmd, unsigned long arg)
10948+#endif
10949+#endif
10950+
10951+#endif /* __KERNEL__ */
10952+#endif /* __AUFS_DIR_H__ */
10953diff -urN /usr/share/empty/fs/aufs/dirren.c linux/fs/aufs/dirren.c
10954--- /usr/share/empty/fs/aufs/dirren.c 1970-01-01 01:00:00.000000000 +0100
10955+++ linux/fs/aufs/dirren.c 2020-01-27 10:57:18.168871450 +0100
10956@@ -0,0 +1,1316 @@
10957+// SPDX-License-Identifier: GPL-2.0
10958+/*
10959+ * Copyright (C) 2017-2020 Junjiro R. Okajima
10960+ *
10961+ * This program, aufs is free software; you can redistribute it and/or modify
10962+ * it under the terms of the GNU General Public License as published by
10963+ * the Free Software Foundation; either version 2 of the License, or
10964+ * (at your option) any later version.
10965+ *
10966+ * This program is distributed in the hope that it will be useful,
10967+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10968+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10969+ * GNU General Public License for more details.
10970+ *
10971+ * You should have received a copy of the GNU General Public License
10972+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
10973+ */
10974+
10975+/*
10976+ * special handling in renaming a directory
10977+ * in order to support looking-up the before-renamed name on the lower readonly
10978+ * branches
10979+ */
10980+
10981+#include <linux/byteorder/generic.h>
10982+#include "aufs.h"
10983+
10984+static void au_dr_hino_del(struct au_dr_br *dr, struct au_dr_hino *ent)
10985+{
10986+ int idx;
10987+
10988+ idx = au_dr_ihash(ent->dr_h_ino);
10989+ au_hbl_del(&ent->dr_hnode, dr->dr_h_ino + idx);
10990+}
10991+
10992+static int au_dr_hino_test_empty(struct au_dr_br *dr)
10993+{
10994+ int ret, i;
10995+ struct hlist_bl_head *hbl;
10996+
10997+ ret = 1;
10998+ for (i = 0; ret && i < AuDirren_NHASH; i++) {
10999+ hbl = dr->dr_h_ino + i;
11000+ hlist_bl_lock(hbl);
11001+ ret &= hlist_bl_empty(hbl);
11002+ hlist_bl_unlock(hbl);
11003+ }
11004+
11005+ return ret;
11006+}
11007+
11008+static struct au_dr_hino *au_dr_hino_find(struct au_dr_br *dr, ino_t ino)
11009+{
11010+ struct au_dr_hino *found, *ent;
11011+ struct hlist_bl_head *hbl;
11012+ struct hlist_bl_node *pos;
11013+ int idx;
11014+
11015+ found = NULL;
11016+ idx = au_dr_ihash(ino);
11017+ hbl = dr->dr_h_ino + idx;
11018+ hlist_bl_lock(hbl);
11019+ hlist_bl_for_each_entry(ent, pos, hbl, dr_hnode)
11020+ if (ent->dr_h_ino == ino) {
11021+ found = ent;
11022+ break;
11023+ }
11024+ hlist_bl_unlock(hbl);
11025+
11026+ return found;
11027+}
11028+
11029+int au_dr_hino_test_add(struct au_dr_br *dr, ino_t ino,
11030+ struct au_dr_hino *add_ent)
11031+{
11032+ int found, idx;
11033+ struct hlist_bl_head *hbl;
11034+ struct hlist_bl_node *pos;
11035+ struct au_dr_hino *ent;
11036+
11037+ found = 0;
11038+ idx = au_dr_ihash(ino);
11039+ hbl = dr->dr_h_ino + idx;
11040+#if 0 /* debug print */
11041+ {
11042+ struct hlist_bl_node *tmp;
11043+
11044+ hlist_bl_for_each_entry_safe(ent, pos, tmp, hbl, dr_hnode)
11045+ AuDbg("hi%llu\n", (unsigned long long)ent->dr_h_ino);
11046+ }
11047+#endif
11048+ hlist_bl_lock(hbl);
11049+ hlist_bl_for_each_entry(ent, pos, hbl, dr_hnode)
11050+ if (ent->dr_h_ino == ino) {
11051+ found = 1;
11052+ break;
11053+ }
11054+ if (!found && add_ent)
11055+ hlist_bl_add_head(&add_ent->dr_hnode, hbl);
11056+ hlist_bl_unlock(hbl);
11057+
11058+ if (!found && add_ent)
11059+ AuDbg("i%llu added\n", (unsigned long long)add_ent->dr_h_ino);
11060+
11061+ return found;
11062+}
11063+
11064+void au_dr_hino_free(struct au_dr_br *dr)
11065+{
11066+ int i;
11067+ struct hlist_bl_head *hbl;
11068+ struct hlist_bl_node *pos, *tmp;
11069+ struct au_dr_hino *ent;
11070+
11071+ /* SiMustWriteLock(sb); */
11072+
11073+ for (i = 0; i < AuDirren_NHASH; i++) {
11074+ hbl = dr->dr_h_ino + i;
11075+ /* no spinlock since sbinfo must be write-locked */
11076+ hlist_bl_for_each_entry_safe(ent, pos, tmp, hbl, dr_hnode)
11077+ au_kfree_rcu(ent);
11078+ INIT_HLIST_BL_HEAD(hbl);
11079+ }
11080+}
11081+
11082+/* returns the number of inodes or an error */
11083+static int au_dr_hino_store(struct super_block *sb, struct au_branch *br,
11084+ struct file *hinofile)
11085+{
11086+ int err, i;
11087+ ssize_t ssz;
11088+ loff_t pos, oldsize;
11089+ __be64 u64;
11090+ struct inode *hinoinode;
11091+ struct hlist_bl_head *hbl;
11092+ struct hlist_bl_node *n1, *n2;
11093+ struct au_dr_hino *ent;
11094+
11095+ SiMustWriteLock(sb);
11096+ AuDebugOn(!au_br_writable(br->br_perm));
11097+
11098+ hinoinode = file_inode(hinofile);
11099+ oldsize = i_size_read(hinoinode);
11100+
11101+ err = 0;
11102+ pos = 0;
11103+ hbl = br->br_dirren.dr_h_ino;
11104+ for (i = 0; !err && i < AuDirren_NHASH; i++, hbl++) {
11105+ /* no bit-lock since sbinfo must be write-locked */
11106+ hlist_bl_for_each_entry_safe(ent, n1, n2, hbl, dr_hnode) {
11107+ AuDbg("hi%llu, %pD2\n",
11108+ (unsigned long long)ent->dr_h_ino, hinofile);
11109+ u64 = cpu_to_be64(ent->dr_h_ino);
11110+ ssz = vfsub_write_k(hinofile, &u64, sizeof(u64), &pos);
11111+ if (ssz == sizeof(u64))
11112+ continue;
11113+
11114+ /* write error */
11115+ pr_err("ssz %zd, %pD2\n", ssz, hinofile);
11116+ err = -ENOSPC;
11117+ if (ssz < 0)
11118+ err = ssz;
11119+ break;
11120+ }
11121+ }
11122+ /* regardless the error */
11123+ if (pos < oldsize) {
11124+ err = vfsub_trunc(&hinofile->f_path, pos, /*attr*/0, hinofile);
11125+ AuTraceErr(err);
11126+ }
11127+
11128+ AuTraceErr(err);
11129+ return err;
11130+}
11131+
11132+static int au_dr_hino_load(struct au_dr_br *dr, struct file *hinofile)
11133+{
11134+ int err, hidx;
11135+ ssize_t ssz;
11136+ size_t sz, n;
11137+ loff_t pos;
11138+ uint64_t u64;
11139+ struct au_dr_hino *ent;
11140+ struct inode *hinoinode;
11141+ struct hlist_bl_head *hbl;
11142+
11143+ err = 0;
11144+ pos = 0;
11145+ hbl = dr->dr_h_ino;
11146+ hinoinode = file_inode(hinofile);
11147+ sz = i_size_read(hinoinode);
11148+ AuDebugOn(sz % sizeof(u64));
11149+ n = sz / sizeof(u64);
11150+ while (n--) {
11151+ ssz = vfsub_read_k(hinofile, &u64, sizeof(u64), &pos);
11152+ if (unlikely(ssz != sizeof(u64))) {
11153+ pr_err("ssz %zd, %pD2\n", ssz, hinofile);
11154+ err = -EINVAL;
11155+ if (ssz < 0)
11156+ err = ssz;
11157+ goto out_free;
11158+ }
11159+
11160+ ent = kmalloc(sizeof(*ent), GFP_NOFS);
11161+ if (!ent) {
11162+ err = -ENOMEM;
11163+ AuTraceErr(err);
11164+ goto out_free;
11165+ }
11166+ ent->dr_h_ino = be64_to_cpu((__force __be64)u64);
11167+ AuDbg("hi%llu, %pD2\n",
11168+ (unsigned long long)ent->dr_h_ino, hinofile);
11169+ hidx = au_dr_ihash(ent->dr_h_ino);
11170+ au_hbl_add(&ent->dr_hnode, hbl + hidx);
11171+ }
11172+ goto out; /* success */
11173+
11174+out_free:
11175+ au_dr_hino_free(dr);
11176+out:
11177+ AuTraceErr(err);
11178+ return err;
11179+}
11180+
11181+/*
11182+ * @bindex/@br is a switch to distinguish whether suspending hnotify or not.
11183+ * @path is a switch to distinguish load and store.
11184+ */
11185+static int au_dr_hino(struct super_block *sb, aufs_bindex_t bindex,
11186+ struct au_branch *br, const struct path *path)
11187+{
11188+ int err, flags;
11189+ unsigned char load, suspend;
11190+ struct file *hinofile;
11191+ struct au_hinode *hdir;
11192+ struct inode *dir, *delegated;
11193+ struct path hinopath;
11194+ struct qstr hinoname = QSTR_INIT(AUFS_WH_DR_BRHINO,
11195+ sizeof(AUFS_WH_DR_BRHINO) - 1);
11196+
11197+ AuDebugOn(bindex < 0 && !br);
11198+ AuDebugOn(bindex >= 0 && br);
11199+
11200+ err = -EINVAL;
11201+ suspend = !br;
11202+ if (suspend)
11203+ br = au_sbr(sb, bindex);
11204+ load = !!path;
11205+ if (!load) {
11206+ path = &br->br_path;
11207+ AuDebugOn(!au_br_writable(br->br_perm));
11208+ if (unlikely(!au_br_writable(br->br_perm)))
11209+ goto out;
11210+ }
11211+
11212+ hdir = NULL;
11213+ if (suspend) {
11214+ dir = d_inode(sb->s_root);
11215+ hdir = au_hinode(au_ii(dir), bindex);
11216+ dir = hdir->hi_inode;
11217+ au_hn_inode_lock_nested(hdir, AuLsc_I_CHILD);
11218+ } else {
11219+ dir = d_inode(path->dentry);
11220+ inode_lock_nested(dir, AuLsc_I_CHILD);
11221+ }
11222+ hinopath.dentry = vfsub_lkup_one(&hinoname, path->dentry);
11223+ err = PTR_ERR(hinopath.dentry);
11224+ if (IS_ERR(hinopath.dentry))
11225+ goto out_unlock;
11226+
11227+ err = 0;
11228+ flags = O_RDONLY;
11229+ if (load) {
11230+ if (d_is_negative(hinopath.dentry))
11231+ goto out_dput; /* success */
11232+ } else {
11233+ if (au_dr_hino_test_empty(&br->br_dirren)) {
11234+ if (d_is_positive(hinopath.dentry)) {
11235+ delegated = NULL;
11236+ err = vfsub_unlink(dir, &hinopath, &delegated,
11237+ /*force*/0);
11238+ AuTraceErr(err);
11239+ if (unlikely(err))
11240+ pr_err("ignored err %d, %pd2\n",
11241+ err, hinopath.dentry);
11242+ if (unlikely(err == -EWOULDBLOCK))
11243+ iput(delegated);
11244+ err = 0;
11245+ }
11246+ goto out_dput;
11247+ } else if (!d_is_positive(hinopath.dentry)) {
11248+ err = vfsub_create(dir, &hinopath, 0600,
11249+ /*want_excl*/false);
11250+ AuTraceErr(err);
11251+ if (unlikely(err))
11252+ goto out_dput;
11253+ }
11254+ flags = O_WRONLY;
11255+ }
11256+ hinopath.mnt = path->mnt;
11257+ hinofile = vfsub_dentry_open(&hinopath, flags);
11258+ if (suspend)
11259+ au_hn_inode_unlock(hdir);
11260+ else
11261+ inode_unlock(dir);
11262+ dput(hinopath.dentry);
11263+ AuTraceErrPtr(hinofile);
11264+ if (IS_ERR(hinofile)) {
11265+ err = PTR_ERR(hinofile);
11266+ goto out;
11267+ }
11268+
11269+ if (load)
11270+ err = au_dr_hino_load(&br->br_dirren, hinofile);
11271+ else
11272+ err = au_dr_hino_store(sb, br, hinofile);
11273+ fput(hinofile);
11274+ goto out;
11275+
11276+out_dput:
11277+ dput(hinopath.dentry);
11278+out_unlock:
11279+ if (suspend)
11280+ au_hn_inode_unlock(hdir);
11281+ else
11282+ inode_unlock(dir);
11283+out:
11284+ AuTraceErr(err);
11285+ return err;
11286+}
11287+
11288+/* ---------------------------------------------------------------------- */
11289+
11290+static int au_dr_brid_init(struct au_dr_brid *brid, const struct path *path)
11291+{
11292+ int err;
11293+ struct kstatfs kstfs;
11294+ dev_t dev;
11295+ struct dentry *dentry;
11296+ struct super_block *sb;
11297+
11298+ err = vfs_statfs((void *)path, &kstfs);
11299+ AuTraceErr(err);
11300+ if (unlikely(err))
11301+ goto out;
11302+
11303+ /* todo: support for UUID */
11304+
11305+ if (kstfs.f_fsid.val[0] || kstfs.f_fsid.val[1]) {
11306+ brid->type = AuBrid_FSID;
11307+ brid->fsid = kstfs.f_fsid;
11308+ } else {
11309+ dentry = path->dentry;
11310+ sb = dentry->d_sb;
11311+ dev = sb->s_dev;
11312+ if (dev) {
11313+ brid->type = AuBrid_DEV;
11314+ brid->dev = dev;
11315+ }
11316+ }
11317+
11318+out:
11319+ return err;
11320+}
11321+
11322+int au_dr_br_init(struct super_block *sb, struct au_branch *br,
11323+ const struct path *path)
11324+{
11325+ int err, i;
11326+ struct au_dr_br *dr;
11327+ struct hlist_bl_head *hbl;
11328+
11329+ dr = &br->br_dirren;
11330+ hbl = dr->dr_h_ino;
11331+ for (i = 0; i < AuDirren_NHASH; i++, hbl++)
11332+ INIT_HLIST_BL_HEAD(hbl);
11333+
11334+ err = au_dr_brid_init(&dr->dr_brid, path);
11335+ if (unlikely(err))
11336+ goto out;
11337+
11338+ if (au_opt_test(au_mntflags(sb), DIRREN))
11339+ err = au_dr_hino(sb, /*bindex*/-1, br, path);
11340+
11341+out:
11342+ AuTraceErr(err);
11343+ return err;
11344+}
11345+
11346+int au_dr_br_fin(struct super_block *sb, struct au_branch *br)
11347+{
11348+ int err;
11349+
11350+ err = 0;
11351+ if (au_br_writable(br->br_perm))
11352+ err = au_dr_hino(sb, /*bindex*/-1, br, /*path*/NULL);
11353+ if (!err)
11354+ au_dr_hino_free(&br->br_dirren);
11355+
11356+ return err;
11357+}
11358+
11359+/* ---------------------------------------------------------------------- */
11360+
11361+static int au_brid_str(struct au_dr_brid *brid, struct inode *h_inode,
11362+ char *buf, size_t sz)
11363+{
11364+ int err;
11365+ unsigned int major, minor;
11366+ char *p;
11367+
11368+ p = buf;
11369+ err = snprintf(p, sz, "%d_", brid->type);
11370+ AuDebugOn(err > sz);
11371+ p += err;
11372+ sz -= err;
11373+ switch (brid->type) {
11374+ case AuBrid_Unset:
11375+ return -EINVAL;
11376+ case AuBrid_UUID:
11377+ err = snprintf(p, sz, "%pU", brid->uuid.b);
11378+ break;
11379+ case AuBrid_FSID:
11380+ err = snprintf(p, sz, "%08x-%08x",
11381+ brid->fsid.val[0], brid->fsid.val[1]);
11382+ break;
11383+ case AuBrid_DEV:
11384+ major = MAJOR(brid->dev);
11385+ minor = MINOR(brid->dev);
11386+ if (major <= 0xff && minor <= 0xff)
11387+ err = snprintf(p, sz, "%02x%02x", major, minor);
11388+ else
11389+ err = snprintf(p, sz, "%03x:%05x", major, minor);
11390+ break;
11391+ }
11392+ AuDebugOn(err > sz);
11393+ p += err;
11394+ sz -= err;
11395+ err = snprintf(p, sz, "_%llu", (unsigned long long)h_inode->i_ino);
11396+ AuDebugOn(err > sz);
11397+ p += err;
11398+ sz -= err;
11399+
11400+ return p - buf;
11401+}
11402+
11403+static int au_drinfo_name(struct au_branch *br, char *name, int len)
11404+{
11405+ int rlen;
11406+ struct dentry *br_dentry;
11407+ struct inode *br_inode;
11408+
11409+ br_dentry = au_br_dentry(br);
11410+ br_inode = d_inode(br_dentry);
11411+ rlen = au_brid_str(&br->br_dirren.dr_brid, br_inode, name, len);
11412+ AuDebugOn(rlen >= AUFS_DIRREN_ENV_VAL_SZ);
11413+ AuDebugOn(rlen > len);
11414+
11415+ return rlen;
11416+}
11417+
11418+/* ---------------------------------------------------------------------- */
11419+
11420+/*
11421+ * from the given @h_dentry, construct drinfo at @*fdata.
11422+ * when the size of @*fdata is not enough, reallocate and return new @fdata and
11423+ * @allocated.
11424+ */
11425+static int au_drinfo_construct(struct au_drinfo_fdata **fdata,
11426+ struct dentry *h_dentry,
11427+ unsigned char *allocated)
11428+{
11429+ int err, v;
11430+ struct au_drinfo_fdata *f, *p;
11431+ struct au_drinfo *drinfo;
11432+ struct inode *h_inode;
11433+ struct qstr *qname;
11434+
11435+ err = 0;
11436+ f = *fdata;
11437+ h_inode = d_inode(h_dentry);
11438+ qname = &h_dentry->d_name;
11439+ drinfo = &f->drinfo;
11440+ drinfo->ino = (__force uint64_t)cpu_to_be64(h_inode->i_ino);
11441+ drinfo->oldnamelen = qname->len;
11442+ if (*allocated < sizeof(*f) + qname->len) {
11443+ v = roundup_pow_of_two(*allocated + qname->len);
11444+ p = au_krealloc(f, v, GFP_NOFS, /*may_shrink*/0);
11445+ if (unlikely(!p)) {
11446+ err = -ENOMEM;
11447+ AuTraceErr(err);
11448+ goto out;
11449+ }
11450+ f = p;
11451+ *fdata = f;
11452+ *allocated = v;
11453+ drinfo = &f->drinfo;
11454+ }
11455+ memcpy(drinfo->oldname, qname->name, qname->len);
11456+ AuDbg("i%llu, %.*s\n",
11457+ be64_to_cpu((__force __be64)drinfo->ino), drinfo->oldnamelen,
11458+ drinfo->oldname);
11459+
11460+out:
11461+ AuTraceErr(err);
11462+ return err;
11463+}
11464+
11465+/* callers have to free the return value */
11466+static struct au_drinfo *au_drinfo_read_k(struct file *file, ino_t h_ino)
11467+{
11468+ struct au_drinfo *ret, *drinfo;
11469+ struct au_drinfo_fdata fdata;
11470+ int len;
11471+ loff_t pos;
11472+ ssize_t ssz;
11473+
11474+ ret = ERR_PTR(-EIO);
11475+ pos = 0;
11476+ ssz = vfsub_read_k(file, &fdata, sizeof(fdata), &pos);
11477+ if (unlikely(ssz != sizeof(fdata))) {
11478+ AuIOErr("ssz %zd, %u, %pD2\n",
11479+ ssz, (unsigned int)sizeof(fdata), file);
11480+ goto out;
11481+ }
11482+
11483+ fdata.magic = ntohl((__force __be32)fdata.magic);
11484+ switch (fdata.magic) {
11485+ case AUFS_DRINFO_MAGIC_V1:
11486+ break;
11487+ default:
11488+ AuIOErr("magic-num 0x%x, 0x%x, %pD2\n",
11489+ fdata.magic, AUFS_DRINFO_MAGIC_V1, file);
11490+ goto out;
11491+ }
11492+
11493+ drinfo = &fdata.drinfo;
11494+ len = drinfo->oldnamelen;
11495+ if (!len) {
11496+ AuIOErr("broken drinfo %pD2\n", file);
11497+ goto out;
11498+ }
11499+
11500+ ret = NULL;
11501+ drinfo->ino = be64_to_cpu((__force __be64)drinfo->ino);
11502+ if (unlikely(h_ino && drinfo->ino != h_ino)) {
11503+ AuDbg("ignored i%llu, i%llu, %pD2\n",
11504+ (unsigned long long)drinfo->ino,
11505+ (unsigned long long)h_ino, file);
11506+ goto out; /* success */
11507+ }
11508+
11509+ ret = kmalloc(sizeof(*ret) + len, GFP_NOFS);
11510+ if (unlikely(!ret)) {
11511+ ret = ERR_PTR(-ENOMEM);
11512+ AuTraceErrPtr(ret);
11513+ goto out;
11514+ }
11515+
11516+ *ret = *drinfo;
11517+ ssz = vfsub_read_k(file, (void *)ret->oldname, len, &pos);
11518+ if (unlikely(ssz != len)) {
11519+ au_kfree_rcu(ret);
11520+ ret = ERR_PTR(-EIO);
11521+ AuIOErr("ssz %zd, %u, %pD2\n", ssz, len, file);
11522+ goto out;
11523+ }
11524+
11525+ AuDbg("oldname %.*s\n", ret->oldnamelen, ret->oldname);
11526+
11527+out:
11528+ return ret;
11529+}
11530+
11531+/* ---------------------------------------------------------------------- */
11532+
11533+/* in order to be revertible */
11534+struct au_drinfo_rev_elm {
11535+ int created;
11536+ struct dentry *info_dentry;
11537+ struct au_drinfo *info_last;
11538+};
11539+
11540+struct au_drinfo_rev {
11541+ unsigned char already;
11542+ aufs_bindex_t nelm;
11543+ struct au_drinfo_rev_elm elm[0];
11544+};
11545+
11546+/* todo: isn't it too large? */
11547+struct au_drinfo_store {
11548+ struct path h_ppath;
11549+ struct dentry *h_dentry;
11550+ struct au_drinfo_fdata *fdata;
11551+ char *infoname; /* inside of whname, just after PFX */
11552+ char whname[sizeof(AUFS_WH_DR_INFO_PFX) + AUFS_DIRREN_ENV_VAL_SZ];
11553+ aufs_bindex_t btgt, btail;
11554+ unsigned char no_sio,
11555+ allocated, /* current size of *fdata */
11556+ infonamelen, /* room size for p */
11557+ whnamelen, /* length of the generated name */
11558+ renameback; /* renamed back */
11559+};
11560+
11561+/* on rename(2) error, the caller should revert it using @elm */
11562+static int au_drinfo_do_store(struct au_drinfo_store *w,
11563+ struct au_drinfo_rev_elm *elm)
11564+{
11565+ int err, len;
11566+ ssize_t ssz;
11567+ loff_t pos;
11568+ struct path infopath = {
11569+ .mnt = w->h_ppath.mnt
11570+ };
11571+ struct inode *h_dir, *h_inode, *delegated;
11572+ struct file *infofile;
11573+ struct qstr *qname;
11574+
11575+ AuDebugOn(elm
11576+ && memcmp(elm, page_address(ZERO_PAGE(0)), sizeof(*elm)));
11577+
11578+ infopath.dentry = vfsub_lookup_one_len(w->whname, w->h_ppath.dentry,
11579+ w->whnamelen);
11580+ AuTraceErrPtr(infopath.dentry);
11581+ if (IS_ERR(infopath.dentry)) {
11582+ err = PTR_ERR(infopath.dentry);
11583+ goto out;
11584+ }
11585+
11586+ err = 0;
11587+ h_dir = d_inode(w->h_ppath.dentry);
11588+ if (elm && d_is_negative(infopath.dentry)) {
11589+ err = vfsub_create(h_dir, &infopath, 0600, /*want_excl*/true);
11590+ AuTraceErr(err);
11591+ if (unlikely(err))
11592+ goto out_dput;
11593+ elm->created = 1;
11594+ elm->info_dentry = dget(infopath.dentry);
11595+ }
11596+
11597+ infofile = vfsub_dentry_open(&infopath, O_RDWR);
11598+ AuTraceErrPtr(infofile);
11599+ if (IS_ERR(infofile)) {
11600+ err = PTR_ERR(infofile);
11601+ goto out_dput;
11602+ }
11603+
11604+ h_inode = d_inode(infopath.dentry);
11605+ if (elm && i_size_read(h_inode)) {
11606+ h_inode = d_inode(w->h_dentry);
11607+ elm->info_last = au_drinfo_read_k(infofile, h_inode->i_ino);
11608+ AuTraceErrPtr(elm->info_last);
11609+ if (IS_ERR(elm->info_last)) {
11610+ err = PTR_ERR(elm->info_last);
11611+ elm->info_last = NULL;
11612+ AuDebugOn(elm->info_dentry);
11613+ goto out_fput;
11614+ }
11615+ }
11616+
11617+ if (elm && w->renameback) {
11618+ delegated = NULL;
11619+ err = vfsub_unlink(h_dir, &infopath, &delegated, /*force*/0);
11620+ AuTraceErr(err);
11621+ if (unlikely(err == -EWOULDBLOCK))
11622+ iput(delegated);
11623+ goto out_fput;
11624+ }
11625+
11626+ pos = 0;
11627+ qname = &w->h_dentry->d_name;
11628+ len = sizeof(*w->fdata) + qname->len;
11629+ if (!elm)
11630+ len = sizeof(*w->fdata) + w->fdata->drinfo.oldnamelen;
11631+ ssz = vfsub_write_k(infofile, w->fdata, len, &pos);
11632+ if (ssz == len) {
11633+ AuDbg("hi%llu, %.*s\n", w->fdata->drinfo.ino,
11634+ w->fdata->drinfo.oldnamelen, w->fdata->drinfo.oldname);
11635+ goto out_fput; /* success */
11636+ } else {
11637+ err = -EIO;
11638+ if (ssz < 0)
11639+ err = ssz;
11640+ /* the caller should revert it using @elm */
11641+ }
11642+
11643+out_fput:
11644+ fput(infofile);
11645+out_dput:
11646+ dput(infopath.dentry);
11647+out:
11648+ AuTraceErr(err);
11649+ return err;
11650+}
11651+
11652+struct au_call_drinfo_do_store_args {
11653+ int *errp;
11654+ struct au_drinfo_store *w;
11655+ struct au_drinfo_rev_elm *elm;
11656+};
11657+
11658+static void au_call_drinfo_do_store(void *args)
11659+{
11660+ struct au_call_drinfo_do_store_args *a = args;
11661+
11662+ *a->errp = au_drinfo_do_store(a->w, a->elm);
11663+}
11664+
11665+static int au_drinfo_store_sio(struct au_drinfo_store *w,
11666+ struct au_drinfo_rev_elm *elm)
11667+{
11668+ int err, wkq_err;
11669+
11670+ if (w->no_sio)
11671+ err = au_drinfo_do_store(w, elm);
11672+ else {
11673+ struct au_call_drinfo_do_store_args a = {
11674+ .errp = &err,
11675+ .w = w,
11676+ .elm = elm
11677+ };
11678+ wkq_err = au_wkq_wait(au_call_drinfo_do_store, &a);
11679+ if (unlikely(wkq_err))
11680+ err = wkq_err;
11681+ }
11682+ AuTraceErr(err);
11683+
11684+ return err;
11685+}
11686+
11687+static int au_drinfo_store_work_init(struct au_drinfo_store *w,
11688+ aufs_bindex_t btgt)
11689+{
11690+ int err;
11691+
11692+ memset(w, 0, sizeof(*w));
11693+ w->allocated = roundup_pow_of_two(sizeof(*w->fdata) + 40);
11694+ strcpy(w->whname, AUFS_WH_DR_INFO_PFX);
11695+ w->infoname = w->whname + sizeof(AUFS_WH_DR_INFO_PFX) - 1;
11696+ w->infonamelen = sizeof(w->whname) - sizeof(AUFS_WH_DR_INFO_PFX);
11697+ w->btgt = btgt;
11698+ w->no_sio = !!uid_eq(current_fsuid(), GLOBAL_ROOT_UID);
11699+
11700+ err = -ENOMEM;
11701+ w->fdata = kcalloc(1, w->allocated, GFP_NOFS);
11702+ if (unlikely(!w->fdata)) {
11703+ AuTraceErr(err);
11704+ goto out;
11705+ }
11706+ w->fdata->magic = (__force uint32_t)htonl(AUFS_DRINFO_MAGIC_V1);
11707+ err = 0;
11708+
11709+out:
11710+ return err;
11711+}
11712+
11713+static void au_drinfo_store_work_fin(struct au_drinfo_store *w)
11714+{
11715+ au_kfree_rcu(w->fdata);
11716+}
11717+
11718+static void au_drinfo_store_rev(struct au_drinfo_rev *rev,
11719+ struct au_drinfo_store *w)
11720+{
11721+ struct au_drinfo_rev_elm *elm;
11722+ struct inode *h_dir, *delegated;
11723+ int err, nelm;
11724+ struct path infopath = {
11725+ .mnt = w->h_ppath.mnt
11726+ };
11727+
11728+ h_dir = d_inode(w->h_ppath.dentry);
11729+ IMustLock(h_dir);
11730+
11731+ err = 0;
11732+ elm = rev->elm;
11733+ for (nelm = rev->nelm; nelm > 0; nelm--, elm++) {
11734+ AuDebugOn(elm->created && elm->info_last);
11735+ if (elm->created) {
11736+ AuDbg("here\n");
11737+ delegated = NULL;
11738+ infopath.dentry = elm->info_dentry;
11739+ err = vfsub_unlink(h_dir, &infopath, &delegated,
11740+ !w->no_sio);
11741+ AuTraceErr(err);
11742+ if (unlikely(err == -EWOULDBLOCK))
11743+ iput(delegated);
11744+ dput(elm->info_dentry);
11745+ } else if (elm->info_last) {
11746+ AuDbg("here\n");
11747+ w->fdata->drinfo = *elm->info_last;
11748+ memcpy(w->fdata->drinfo.oldname,
11749+ elm->info_last->oldname,
11750+ elm->info_last->oldnamelen);
11751+ err = au_drinfo_store_sio(w, /*elm*/NULL);
11752+ au_kfree_rcu(elm->info_last);
11753+ }
11754+ if (unlikely(err))
11755+ AuIOErr("%d, %s\n", err, w->whname);
11756+ /* go on even if err */
11757+ }
11758+}
11759+
11760+/* caller has to call au_dr_rename_fin() later */
11761+static int au_drinfo_store(struct dentry *dentry, aufs_bindex_t btgt,
11762+ struct qstr *dst_name, void *_rev)
11763+{
11764+ int err, sz, nelm;
11765+ aufs_bindex_t bindex, btail;
11766+ struct au_drinfo_store work;
11767+ struct au_drinfo_rev *rev, **p;
11768+ struct au_drinfo_rev_elm *elm;
11769+ struct super_block *sb;
11770+ struct au_branch *br;
11771+ struct au_hinode *hdir;
11772+
11773+ err = au_drinfo_store_work_init(&work, btgt);
11774+ AuTraceErr(err);
11775+ if (unlikely(err))
11776+ goto out;
11777+
11778+ err = -ENOMEM;
11779+ btail = au_dbtaildir(dentry);
11780+ nelm = btail - btgt;
11781+ sz = sizeof(*rev) + sizeof(*elm) * nelm;
11782+ rev = kcalloc(1, sz, GFP_NOFS);
11783+ if (unlikely(!rev)) {
11784+ AuTraceErr(err);
11785+ goto out_args;
11786+ }
11787+ rev->nelm = nelm;
11788+ elm = rev->elm;
11789+ p = _rev;
11790+ *p = rev;
11791+
11792+ err = 0;
11793+ sb = dentry->d_sb;
11794+ work.h_ppath.dentry = au_h_dptr(dentry, btgt);
11795+ work.h_ppath.mnt = au_sbr_mnt(sb, btgt);
11796+ hdir = au_hi(d_inode(dentry), btgt);
11797+ au_hn_inode_lock_nested(hdir, AuLsc_I_CHILD);
11798+ for (bindex = btgt + 1; bindex <= btail; bindex++, elm++) {
11799+ work.h_dentry = au_h_dptr(dentry, bindex);
11800+ if (!work.h_dentry)
11801+ continue;
11802+
11803+ err = au_drinfo_construct(&work.fdata, work.h_dentry,
11804+ &work.allocated);
11805+ AuTraceErr(err);
11806+ if (unlikely(err))
11807+ break;
11808+
11809+ work.renameback = au_qstreq(&work.h_dentry->d_name, dst_name);
11810+ br = au_sbr(sb, bindex);
11811+ work.whnamelen = sizeof(AUFS_WH_DR_INFO_PFX) - 1;
11812+ work.whnamelen += au_drinfo_name(br, work.infoname,
11813+ work.infonamelen);
11814+ AuDbg("whname %.*s, i%llu, %.*s\n",
11815+ work.whnamelen, work.whname,
11816+ be64_to_cpu((__force __be64)work.fdata->drinfo.ino),
11817+ work.fdata->drinfo.oldnamelen,
11818+ work.fdata->drinfo.oldname);
11819+
11820+ err = au_drinfo_store_sio(&work, elm);
11821+ AuTraceErr(err);
11822+ if (unlikely(err))
11823+ break;
11824+ }
11825+ if (unlikely(err)) {
11826+ /* revert all drinfo */
11827+ au_drinfo_store_rev(rev, &work);
11828+ au_kfree_try_rcu(rev);
11829+ *p = NULL;
11830+ }
11831+ au_hn_inode_unlock(hdir);
11832+
11833+out_args:
11834+ au_drinfo_store_work_fin(&work);
11835+out:
11836+ return err;
11837+}
11838+
11839+/* ---------------------------------------------------------------------- */
11840+
11841+int au_dr_rename(struct dentry *src, aufs_bindex_t bindex,
11842+ struct qstr *dst_name, void *_rev)
11843+{
11844+ int err, already;
11845+ ino_t ino;
11846+ struct super_block *sb;
11847+ struct au_branch *br;
11848+ struct au_dr_br *dr;
11849+ struct dentry *h_dentry;
11850+ struct inode *h_inode;
11851+ struct au_dr_hino *ent;
11852+ struct au_drinfo_rev *rev, **p;
11853+
11854+ AuDbg("bindex %d\n", bindex);
11855+
11856+ err = -ENOMEM;
11857+ ent = kmalloc(sizeof(*ent), GFP_NOFS);
11858+ if (unlikely(!ent))
11859+ goto out;
11860+
11861+ sb = src->d_sb;
11862+ br = au_sbr(sb, bindex);
11863+ dr = &br->br_dirren;
11864+ h_dentry = au_h_dptr(src, bindex);
11865+ h_inode = d_inode(h_dentry);
11866+ ino = h_inode->i_ino;
11867+ ent->dr_h_ino = ino;
11868+ already = au_dr_hino_test_add(dr, ino, ent);
11869+ AuDbg("b%d, hi%llu, already %d\n",
11870+ bindex, (unsigned long long)ino, already);
11871+
11872+ err = au_drinfo_store(src, bindex, dst_name, _rev);
11873+ AuTraceErr(err);
11874+ if (!err) {
11875+ p = _rev;
11876+ rev = *p;
11877+ rev->already = already;
11878+ goto out; /* success */
11879+ }
11880+
11881+ /* revert */
11882+ if (!already)
11883+ au_dr_hino_del(dr, ent);
11884+ au_kfree_rcu(ent);
11885+
11886+out:
11887+ AuTraceErr(err);
11888+ return err;
11889+}
11890+
11891+void au_dr_rename_fin(struct dentry *src, aufs_bindex_t btgt, void *_rev)
11892+{
11893+ struct au_drinfo_rev *rev;
11894+ struct au_drinfo_rev_elm *elm;
11895+ int nelm;
11896+
11897+ rev = _rev;
11898+ elm = rev->elm;
11899+ for (nelm = rev->nelm; nelm > 0; nelm--, elm++) {
11900+ dput(elm->info_dentry);
11901+ au_kfree_rcu(elm->info_last);
11902+ }
11903+ au_kfree_try_rcu(rev);
11904+}
11905+
11906+void au_dr_rename_rev(struct dentry *src, aufs_bindex_t btgt, void *_rev)
11907+{
11908+ int err;
11909+ struct au_drinfo_store work;
11910+ struct au_drinfo_rev *rev = _rev;
11911+ struct super_block *sb;
11912+ struct au_branch *br;
11913+ struct inode *h_inode;
11914+ struct au_dr_br *dr;
11915+ struct au_dr_hino *ent;
11916+
11917+ err = au_drinfo_store_work_init(&work, btgt);
11918+ if (unlikely(err))
11919+ goto out;
11920+
11921+ sb = src->d_sb;
11922+ br = au_sbr(sb, btgt);
11923+ work.h_ppath.dentry = au_h_dptr(src, btgt);
11924+ work.h_ppath.mnt = au_br_mnt(br);
11925+ au_drinfo_store_rev(rev, &work);
11926+ au_drinfo_store_work_fin(&work);
11927+ if (rev->already)
11928+ goto out;
11929+
11930+ dr = &br->br_dirren;
11931+ h_inode = d_inode(work.h_ppath.dentry);
11932+ ent = au_dr_hino_find(dr, h_inode->i_ino);
11933+ BUG_ON(!ent);
11934+ au_dr_hino_del(dr, ent);
11935+ au_kfree_rcu(ent);
11936+
11937+out:
11938+ au_kfree_try_rcu(rev);
11939+ if (unlikely(err))
11940+ pr_err("failed to remove dirren info\n");
11941+}
11942+
11943+/* ---------------------------------------------------------------------- */
11944+
11945+static struct au_drinfo *au_drinfo_do_load(struct path *h_ppath,
11946+ char *whname, int whnamelen,
11947+ struct dentry **info_dentry)
11948+{
11949+ struct au_drinfo *drinfo;
11950+ struct file *f;
11951+ struct inode *h_dir;
11952+ struct path infopath;
11953+ int unlocked;
11954+
11955+ AuDbg("%pd/%.*s\n", h_ppath->dentry, whnamelen, whname);
11956+
11957+ *info_dentry = NULL;
11958+ drinfo = NULL;
11959+ unlocked = 0;
11960+ h_dir = d_inode(h_ppath->dentry);
11961+ inode_lock_shared_nested(h_dir, AuLsc_I_PARENT);
11962+ infopath.dentry = vfsub_lookup_one_len(whname, h_ppath->dentry,
11963+ whnamelen);
11964+ if (IS_ERR(infopath.dentry)) {
11965+ drinfo = (void *)infopath.dentry;
11966+ goto out;
11967+ }
11968+
11969+ if (d_is_negative(infopath.dentry))
11970+ goto out_dput; /* success */
11971+
11972+ infopath.mnt = h_ppath->mnt;
11973+ f = vfsub_dentry_open(&infopath, O_RDONLY);
11974+ inode_unlock_shared(h_dir);
11975+ unlocked = 1;
11976+ if (IS_ERR(f)) {
11977+ drinfo = (void *)f;
11978+ goto out_dput;
11979+ }
11980+
11981+ drinfo = au_drinfo_read_k(f, /*h_ino*/0);
11982+ if (IS_ERR_OR_NULL(drinfo))
11983+ goto out_fput;
11984+
11985+ AuDbg("oldname %.*s\n", drinfo->oldnamelen, drinfo->oldname);
11986+ *info_dentry = dget(infopath.dentry); /* keep it alive */
11987+
11988+out_fput:
11989+ fput(f);
11990+out_dput:
11991+ dput(infopath.dentry);
11992+out:
11993+ if (!unlocked)
11994+ inode_unlock_shared(h_dir);
11995+ AuTraceErrPtr(drinfo);
11996+ return drinfo;
11997+}
11998+
11999+struct au_drinfo_do_load_args {
12000+ struct au_drinfo **drinfop;
12001+ struct path *h_ppath;
12002+ char *whname;
12003+ int whnamelen;
12004+ struct dentry **info_dentry;
12005+};
12006+
12007+static void au_call_drinfo_do_load(void *args)
12008+{
12009+ struct au_drinfo_do_load_args *a = args;
12010+
12011+ *a->drinfop = au_drinfo_do_load(a->h_ppath, a->whname, a->whnamelen,
12012+ a->info_dentry);
12013+}
12014+
12015+struct au_drinfo_load {
12016+ struct path h_ppath;
12017+ struct qstr *qname;
12018+ unsigned char no_sio;
12019+
12020+ aufs_bindex_t ninfo;
12021+ struct au_drinfo **drinfo;
12022+};
12023+
12024+static int au_drinfo_load(struct au_drinfo_load *w, aufs_bindex_t bindex,
12025+ struct au_branch *br)
12026+{
12027+ int err, wkq_err, whnamelen, e;
12028+ char whname[sizeof(AUFS_WH_DR_INFO_PFX) + AUFS_DIRREN_ENV_VAL_SZ]
12029+ = AUFS_WH_DR_INFO_PFX;
12030+ struct au_drinfo *drinfo;
12031+ struct qstr oldname;
12032+ struct inode *h_dir, *delegated;
12033+ struct dentry *info_dentry;
12034+ struct path infopath;
12035+
12036+ whnamelen = sizeof(AUFS_WH_DR_INFO_PFX) - 1;
12037+ whnamelen += au_drinfo_name(br, whname + whnamelen,
12038+ sizeof(whname) - whnamelen);
12039+ if (w->no_sio)
12040+ drinfo = au_drinfo_do_load(&w->h_ppath, whname, whnamelen,
12041+ &info_dentry);
12042+ else {
12043+ struct au_drinfo_do_load_args args = {
12044+ .drinfop = &drinfo,
12045+ .h_ppath = &w->h_ppath,
12046+ .whname = whname,
12047+ .whnamelen = whnamelen,
12048+ .info_dentry = &info_dentry
12049+ };
12050+ wkq_err = au_wkq_wait(au_call_drinfo_do_load, &args);
12051+ if (unlikely(wkq_err))
12052+ drinfo = ERR_PTR(wkq_err);
12053+ }
12054+ err = PTR_ERR(drinfo);
12055+ if (IS_ERR_OR_NULL(drinfo))
12056+ goto out;
12057+
12058+ err = 0;
12059+ oldname.len = drinfo->oldnamelen;
12060+ oldname.name = drinfo->oldname;
12061+ if (au_qstreq(w->qname, &oldname)) {
12062+ /* the name is renamed back */
12063+ au_kfree_rcu(drinfo);
12064+ drinfo = NULL;
12065+
12066+ infopath.dentry = info_dentry;
12067+ infopath.mnt = w->h_ppath.mnt;
12068+ h_dir = d_inode(w->h_ppath.dentry);
12069+ delegated = NULL;
12070+ inode_lock_nested(h_dir, AuLsc_I_PARENT);
12071+ e = vfsub_unlink(h_dir, &infopath, &delegated, !w->no_sio);
12072+ inode_unlock(h_dir);
12073+ if (unlikely(e))
12074+ AuIOErr("ignored %d, %pd2\n", e, &infopath.dentry);
12075+ if (unlikely(e == -EWOULDBLOCK))
12076+ iput(delegated);
12077+ }
12078+ au_kfree_rcu(w->drinfo[bindex]);
12079+ w->drinfo[bindex] = drinfo;
12080+ dput(info_dentry);
12081+
12082+out:
12083+ AuTraceErr(err);
12084+ return err;
12085+}
12086+
12087+/* ---------------------------------------------------------------------- */
12088+
12089+static void au_dr_lkup_free(struct au_drinfo **drinfo, int n)
12090+{
12091+ struct au_drinfo **p = drinfo;
12092+
12093+ while (n-- > 0)
12094+ au_kfree_rcu(*drinfo++);
12095+ au_kfree_try_rcu(p);
12096+}
12097+
12098+int au_dr_lkup(struct au_do_lookup_args *lkup, struct dentry *dentry,
12099+ aufs_bindex_t btgt)
12100+{
12101+ int err, ninfo;
12102+ struct au_drinfo_load w;
12103+ aufs_bindex_t bindex, bbot;
12104+ struct au_branch *br;
12105+ struct inode *h_dir;
12106+ struct au_dr_hino *ent;
12107+ struct super_block *sb;
12108+
12109+ AuDbg("%.*s, name %.*s, whname %.*s, b%d\n",
12110+ AuLNPair(&dentry->d_name), AuLNPair(&lkup->dirren.dr_name),
12111+ AuLNPair(&lkup->whname), btgt);
12112+
12113+ sb = dentry->d_sb;
12114+ bbot = au_sbbot(sb);
12115+ w.ninfo = bbot + 1;
12116+ if (!lkup->dirren.drinfo) {
12117+ lkup->dirren.drinfo = kcalloc(w.ninfo,
12118+ sizeof(*lkup->dirren.drinfo),
12119+ GFP_NOFS);
12120+ if (unlikely(!lkup->dirren.drinfo)) {
12121+ err = -ENOMEM;
12122+ goto out;
12123+ }
12124+ lkup->dirren.ninfo = w.ninfo;
12125+ }
12126+ w.drinfo = lkup->dirren.drinfo;
12127+ w.no_sio = !!uid_eq(current_fsuid(), GLOBAL_ROOT_UID);
12128+ w.h_ppath.dentry = au_h_dptr(dentry, btgt);
12129+ AuDebugOn(!w.h_ppath.dentry);
12130+ w.h_ppath.mnt = au_sbr_mnt(sb, btgt);
12131+ w.qname = &dentry->d_name;
12132+
12133+ ninfo = 0;
12134+ for (bindex = btgt + 1; bindex <= bbot; bindex++) {
12135+ br = au_sbr(sb, bindex);
12136+ err = au_drinfo_load(&w, bindex, br);
12137+ if (unlikely(err))
12138+ goto out_free;
12139+ if (w.drinfo[bindex])
12140+ ninfo++;
12141+ }
12142+ if (!ninfo) {
12143+ br = au_sbr(sb, btgt);
12144+ h_dir = d_inode(w.h_ppath.dentry);
12145+ ent = au_dr_hino_find(&br->br_dirren, h_dir->i_ino);
12146+ AuDebugOn(!ent);
12147+ au_dr_hino_del(&br->br_dirren, ent);
12148+ au_kfree_rcu(ent);
12149+ }
12150+ goto out; /* success */
12151+
12152+out_free:
12153+ au_dr_lkup_free(lkup->dirren.drinfo, lkup->dirren.ninfo);
12154+ lkup->dirren.ninfo = 0;
12155+ lkup->dirren.drinfo = NULL;
12156+out:
12157+ AuTraceErr(err);
12158+ return err;
12159+}
12160+
12161+void au_dr_lkup_fin(struct au_do_lookup_args *lkup)
12162+{
12163+ au_dr_lkup_free(lkup->dirren.drinfo, lkup->dirren.ninfo);
12164+}
12165+
12166+int au_dr_lkup_name(struct au_do_lookup_args *lkup, aufs_bindex_t btgt)
12167+{
12168+ int err;
12169+ struct au_drinfo *drinfo;
12170+
12171+ err = 0;
12172+ if (!lkup->dirren.drinfo)
12173+ goto out;
12174+ AuDebugOn(lkup->dirren.ninfo <= btgt);
12175+ drinfo = lkup->dirren.drinfo[btgt];
12176+ if (!drinfo)
12177+ goto out;
12178+
12179+ au_kfree_try_rcu(lkup->whname.name);
12180+ lkup->whname.name = NULL;
12181+ lkup->dirren.dr_name.len = drinfo->oldnamelen;
12182+ lkup->dirren.dr_name.name = drinfo->oldname;
12183+ lkup->name = &lkup->dirren.dr_name;
12184+ err = au_wh_name_alloc(&lkup->whname, lkup->name);
12185+ if (!err)
12186+ AuDbg("name %.*s, whname %.*s, b%d\n",
12187+ AuLNPair(lkup->name), AuLNPair(&lkup->whname),
12188+ btgt);
12189+
12190+out:
12191+ AuTraceErr(err);
12192+ return err;
12193+}
12194+
12195+int au_dr_lkup_h_ino(struct au_do_lookup_args *lkup, aufs_bindex_t bindex,
12196+ ino_t h_ino)
12197+{
12198+ int match;
12199+ struct au_drinfo *drinfo;
12200+
12201+ match = 1;
12202+ if (!lkup->dirren.drinfo)
12203+ goto out;
12204+ AuDebugOn(lkup->dirren.ninfo <= bindex);
12205+ drinfo = lkup->dirren.drinfo[bindex];
12206+ if (!drinfo)
12207+ goto out;
12208+
12209+ match = (drinfo->ino == h_ino);
12210+ AuDbg("match %d\n", match);
12211+
12212+out:
12213+ return match;
12214+}
12215+
12216+/* ---------------------------------------------------------------------- */
12217+
12218+int au_dr_opt_set(struct super_block *sb)
12219+{
12220+ int err;
12221+ aufs_bindex_t bindex, bbot;
12222+ struct au_branch *br;
12223+
12224+ err = 0;
12225+ bbot = au_sbbot(sb);
12226+ for (bindex = 0; !err && bindex <= bbot; bindex++) {
12227+ br = au_sbr(sb, bindex);
12228+ err = au_dr_hino(sb, bindex, /*br*/NULL, &br->br_path);
12229+ }
12230+
12231+ return err;
12232+}
12233+
12234+int au_dr_opt_flush(struct super_block *sb)
12235+{
12236+ int err;
12237+ aufs_bindex_t bindex, bbot;
12238+ struct au_branch *br;
12239+
12240+ err = 0;
12241+ bbot = au_sbbot(sb);
12242+ for (bindex = 0; !err && bindex <= bbot; bindex++) {
12243+ br = au_sbr(sb, bindex);
12244+ if (au_br_writable(br->br_perm))
12245+ err = au_dr_hino(sb, bindex, /*br*/NULL, /*path*/NULL);
12246+ }
12247+
12248+ return err;
12249+}
12250+
12251+int au_dr_opt_clr(struct super_block *sb, int no_flush)
12252+{
12253+ int err;
12254+ aufs_bindex_t bindex, bbot;
12255+ struct au_branch *br;
12256+
12257+ err = 0;
12258+ if (!no_flush) {
12259+ err = au_dr_opt_flush(sb);
12260+ if (unlikely(err))
12261+ goto out;
12262+ }
12263+
12264+ bbot = au_sbbot(sb);
12265+ for (bindex = 0; bindex <= bbot; bindex++) {
12266+ br = au_sbr(sb, bindex);
12267+ au_dr_hino_free(&br->br_dirren);
12268+ }
12269+
12270+out:
12271+ return err;
12272+}
12273diff -urN /usr/share/empty/fs/aufs/dirren.h linux/fs/aufs/dirren.h
12274--- /usr/share/empty/fs/aufs/dirren.h 1970-01-01 01:00:00.000000000 +0100
12275+++ linux/fs/aufs/dirren.h 2020-01-27 10:57:18.168871450 +0100
12276@@ -0,0 +1,140 @@
12277+/* SPDX-License-Identifier: GPL-2.0 */
12278+/*
12279+ * Copyright (C) 2017-2020 Junjiro R. Okajima
12280+ *
12281+ * This program, aufs is free software; you can redistribute it and/or modify
12282+ * it under the terms of the GNU General Public License as published by
12283+ * the Free Software Foundation; either version 2 of the License, or
12284+ * (at your option) any later version.
12285+ *
12286+ * This program is distributed in the hope that it will be useful,
12287+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12288+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12289+ * GNU General Public License for more details.
12290+ *
12291+ * You should have received a copy of the GNU General Public License
12292+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
12293+ */
12294+
12295+/*
12296+ * renamed dir info
12297+ */
12298+
12299+#ifndef __AUFS_DIRREN_H__
12300+#define __AUFS_DIRREN_H__
12301+
12302+#ifdef __KERNEL__
12303+
12304+#include <linux/dcache.h>
12305+#include <linux/statfs.h>
12306+#include <linux/uuid.h>
12307+#include "hbl.h"
12308+
12309+#define AuDirren_NHASH 100
12310+
12311+#ifdef CONFIG_AUFS_DIRREN
12312+enum au_brid_type {
12313+ AuBrid_Unset,
12314+ AuBrid_UUID,
12315+ AuBrid_FSID,
12316+ AuBrid_DEV
12317+};
12318+
12319+struct au_dr_brid {
12320+ enum au_brid_type type;
12321+ union {
12322+ uuid_t uuid; /* unimplemented yet */
12323+ fsid_t fsid;
12324+ dev_t dev;
12325+ };
12326+};
12327+
12328+/* 20 is the max digits length of ulong 64 */
12329+/* brid-type "_" uuid "_" inum */
12330+#define AUFS_DIRREN_FNAME_SZ (1 + 1 + UUID_STRING_LEN + 20)
12331+#define AUFS_DIRREN_ENV_VAL_SZ (AUFS_DIRREN_FNAME_SZ + 1 + 20)
12332+
12333+struct au_dr_hino {
12334+ struct hlist_bl_node dr_hnode;
12335+ ino_t dr_h_ino;
12336+};
12337+
12338+struct au_dr_br {
12339+ struct hlist_bl_head dr_h_ino[AuDirren_NHASH];
12340+ struct au_dr_brid dr_brid;
12341+};
12342+
12343+struct au_dr_lookup {
12344+ /* dr_name is pointed by struct au_do_lookup_args.name */
12345+ struct qstr dr_name; /* subset of dr_info */
12346+ aufs_bindex_t ninfo;
12347+ struct au_drinfo **drinfo;
12348+};
12349+#else
12350+struct au_dr_hino;
12351+/* empty */
12352+struct au_dr_br { };
12353+struct au_dr_lookup { };
12354+#endif
12355+
12356+/* ---------------------------------------------------------------------- */
12357+
12358+struct au_branch;
12359+struct au_do_lookup_args;
12360+struct au_hinode;
12361+#ifdef CONFIG_AUFS_DIRREN
12362+int au_dr_hino_test_add(struct au_dr_br *dr, ino_t h_ino,
12363+ struct au_dr_hino *add_ent);
12364+void au_dr_hino_free(struct au_dr_br *dr);
12365+int au_dr_br_init(struct super_block *sb, struct au_branch *br,
12366+ const struct path *path);
12367+int au_dr_br_fin(struct super_block *sb, struct au_branch *br);
12368+int au_dr_rename(struct dentry *src, aufs_bindex_t bindex,
12369+ struct qstr *dst_name, void *_rev);
12370+void au_dr_rename_fin(struct dentry *src, aufs_bindex_t btgt, void *rev);
12371+void au_dr_rename_rev(struct dentry *src, aufs_bindex_t bindex, void *rev);
12372+int au_dr_lkup(struct au_do_lookup_args *lkup, struct dentry *dentry,
12373+ aufs_bindex_t bindex);
12374+int au_dr_lkup_name(struct au_do_lookup_args *lkup, aufs_bindex_t btgt);
12375+int au_dr_lkup_h_ino(struct au_do_lookup_args *lkup, aufs_bindex_t bindex,
12376+ ino_t h_ino);
12377+void au_dr_lkup_fin(struct au_do_lookup_args *lkup);
12378+int au_dr_opt_set(struct super_block *sb);
12379+int au_dr_opt_flush(struct super_block *sb);
12380+int au_dr_opt_clr(struct super_block *sb, int no_flush);
12381+#else
12382+AuStubInt0(au_dr_hino_test_add, struct au_dr_br *dr, ino_t h_ino,
12383+ struct au_dr_hino *add_ent);
12384+AuStubVoid(au_dr_hino_free, struct au_dr_br *dr);
12385+AuStubInt0(au_dr_br_init, struct super_block *sb, struct au_branch *br,
12386+ const struct path *path);
12387+AuStubInt0(au_dr_br_fin, struct super_block *sb, struct au_branch *br);
12388+AuStubInt0(au_dr_rename, struct dentry *src, aufs_bindex_t bindex,
12389+ struct qstr *dst_name, void *_rev);
12390+AuStubVoid(au_dr_rename_fin, struct dentry *src, aufs_bindex_t btgt, void *rev);
12391+AuStubVoid(au_dr_rename_rev, struct dentry *src, aufs_bindex_t bindex,
12392+ void *rev);
12393+AuStubInt0(au_dr_lkup, struct au_do_lookup_args *lkup, struct dentry *dentry,
12394+ aufs_bindex_t bindex);
12395+AuStubInt0(au_dr_lkup_name, struct au_do_lookup_args *lkup, aufs_bindex_t btgt);
12396+AuStubInt0(au_dr_lkup_h_ino, struct au_do_lookup_args *lkup,
12397+ aufs_bindex_t bindex, ino_t h_ino);
12398+AuStubVoid(au_dr_lkup_fin, struct au_do_lookup_args *lkup);
12399+AuStubInt0(au_dr_opt_set, struct super_block *sb);
12400+AuStubInt0(au_dr_opt_flush, struct super_block *sb);
12401+AuStubInt0(au_dr_opt_clr, struct super_block *sb, int no_flush);
12402+#endif
12403+
12404+/* ---------------------------------------------------------------------- */
12405+
12406+#ifdef CONFIG_AUFS_DIRREN
12407+static inline int au_dr_ihash(ino_t h_ino)
12408+{
12409+ return h_ino % AuDirren_NHASH;
12410+}
12411+#else
12412+AuStubInt0(au_dr_ihash, ino_t h_ino);
12413+#endif
12414+
12415+#endif /* __KERNEL__ */
12416+#endif /* __AUFS_DIRREN_H__ */
12417diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
12418--- /usr/share/empty/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100
12419+++ linux/fs/aufs/dynop.c 2020-01-27 10:57:18.168871450 +0100
12420@@ -0,0 +1,367 @@
12421+// SPDX-License-Identifier: GPL-2.0
12422+/*
12423+ * Copyright (C) 2010-2020 Junjiro R. Okajima
12424+ *
12425+ * This program, aufs is free software; you can redistribute it and/or modify
12426+ * it under the terms of the GNU General Public License as published by
12427+ * the Free Software Foundation; either version 2 of the License, or
12428+ * (at your option) any later version.
12429+ *
12430+ * This program is distributed in the hope that it will be useful,
12431+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12432+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12433+ * GNU General Public License for more details.
12434+ *
12435+ * You should have received a copy of the GNU General Public License
12436+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
12437+ */
12438+
12439+/*
12440+ * dynamically customizable operations for regular files
12441+ */
12442+
12443+#include "aufs.h"
12444+
12445+#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop)
12446+
12447+/*
12448+ * How large will these lists be?
12449+ * Usually just a few elements, 20-30 at most for each, I guess.
12450+ */
12451+static struct hlist_bl_head dynop[AuDyLast];
12452+
12453+static struct au_dykey *dy_gfind_get(struct hlist_bl_head *hbl,
12454+ const void *h_op)
12455+{
12456+ struct au_dykey *key, *tmp;
12457+ struct hlist_bl_node *pos;
12458+
12459+ key = NULL;
12460+ hlist_bl_lock(hbl);
12461+ hlist_bl_for_each_entry(tmp, pos, hbl, dk_hnode)
12462+ if (tmp->dk_op.dy_hop == h_op) {
12463+ if (kref_get_unless_zero(&tmp->dk_kref))
12464+ key = tmp;
12465+ break;
12466+ }
12467+ hlist_bl_unlock(hbl);
12468+
12469+ return key;
12470+}
12471+
12472+static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
12473+{
12474+ struct au_dykey **k, *found;
12475+ const void *h_op = key->dk_op.dy_hop;
12476+ int i;
12477+
12478+ found = NULL;
12479+ k = br->br_dykey;
12480+ for (i = 0; i < AuBrDynOp; i++)
12481+ if (k[i]) {
12482+ if (k[i]->dk_op.dy_hop == h_op) {
12483+ found = k[i];
12484+ break;
12485+ }
12486+ } else
12487+ break;
12488+ if (!found) {
12489+ spin_lock(&br->br_dykey_lock);
12490+ for (; i < AuBrDynOp; i++)
12491+ if (k[i]) {
12492+ if (k[i]->dk_op.dy_hop == h_op) {
12493+ found = k[i];
12494+ break;
12495+ }
12496+ } else {
12497+ k[i] = key;
12498+ break;
12499+ }
12500+ spin_unlock(&br->br_dykey_lock);
12501+ BUG_ON(i == AuBrDynOp); /* expand the array */
12502+ }
12503+
12504+ return found;
12505+}
12506+
12507+/* kref_get() if @key is already added */
12508+static struct au_dykey *dy_gadd(struct hlist_bl_head *hbl, struct au_dykey *key)
12509+{
12510+ struct au_dykey *tmp, *found;
12511+ struct hlist_bl_node *pos;
12512+ const void *h_op = key->dk_op.dy_hop;
12513+
12514+ found = NULL;
12515+ hlist_bl_lock(hbl);
12516+ hlist_bl_for_each_entry(tmp, pos, hbl, dk_hnode)
12517+ if (tmp->dk_op.dy_hop == h_op) {
12518+ if (kref_get_unless_zero(&tmp->dk_kref))
12519+ found = tmp;
12520+ break;
12521+ }
12522+ if (!found)
12523+ hlist_bl_add_head(&key->dk_hnode, hbl);
12524+ hlist_bl_unlock(hbl);
12525+
12526+ if (!found)
12527+ DyPrSym(key);
12528+ return found;
12529+}
12530+
12531+static void dy_free_rcu(struct rcu_head *rcu)
12532+{
12533+ struct au_dykey *key;
12534+
12535+ key = container_of(rcu, struct au_dykey, dk_rcu);
12536+ DyPrSym(key);
12537+ kfree(key);
12538+}
12539+
12540+static void dy_free(struct kref *kref)
12541+{
12542+ struct au_dykey *key;
12543+ struct hlist_bl_head *hbl;
12544+
12545+ key = container_of(kref, struct au_dykey, dk_kref);
12546+ hbl = dynop + key->dk_op.dy_type;
12547+ au_hbl_del(&key->dk_hnode, hbl);
12548+ call_rcu(&key->dk_rcu, dy_free_rcu);
12549+}
12550+
12551+void au_dy_put(struct au_dykey *key)
12552+{
12553+ kref_put(&key->dk_kref, dy_free);
12554+}
12555+
12556+/* ---------------------------------------------------------------------- */
12557+
12558+#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *))
12559+
12560+#ifdef CONFIG_AUFS_DEBUG
12561+#define DyDbgDeclare(cnt) unsigned int cnt = 0
12562+#define DyDbgInc(cnt) do { cnt++; } while (0)
12563+#else
12564+#define DyDbgDeclare(cnt) do {} while (0)
12565+#define DyDbgInc(cnt) do {} while (0)
12566+#endif
12567+
12568+#define DySet(func, dst, src, h_op, h_sb) do { \
12569+ DyDbgInc(cnt); \
12570+ if (h_op->func) { \
12571+ if (src.func) \
12572+ dst.func = src.func; \
12573+ else \
12574+ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \
12575+ } \
12576+} while (0)
12577+
12578+#define DySetForce(func, dst, src) do { \
12579+ AuDebugOn(!src.func); \
12580+ DyDbgInc(cnt); \
12581+ dst.func = src.func; \
12582+} while (0)
12583+
12584+#define DySetAop(func) \
12585+ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
12586+#define DySetAopForce(func) \
12587+ DySetForce(func, dyaop->da_op, aufs_aop)
12588+
12589+static void dy_aop(struct au_dykey *key, const void *h_op,
12590+ struct super_block *h_sb __maybe_unused)
12591+{
12592+ struct au_dyaop *dyaop = (void *)key;
12593+ const struct address_space_operations *h_aop = h_op;
12594+ DyDbgDeclare(cnt);
12595+
12596+ AuDbg("%s\n", au_sbtype(h_sb));
12597+
12598+ DySetAop(writepage);
12599+ DySetAopForce(readpage); /* force */
12600+ DySetAop(writepages);
12601+ DySetAop(set_page_dirty);
12602+ DySetAop(readpages);
12603+ DySetAop(write_begin);
12604+ DySetAop(write_end);
12605+ DySetAop(bmap);
12606+ DySetAop(invalidatepage);
12607+ DySetAop(releasepage);
12608+ DySetAop(freepage);
12609+ /* this one will be changed according to an aufs mount option */
12610+ DySetAop(direct_IO);
12611+ DySetAop(migratepage);
12612+ DySetAop(isolate_page);
12613+ DySetAop(putback_page);
12614+ DySetAop(launder_page);
12615+ DySetAop(is_partially_uptodate);
12616+ DySetAop(is_dirty_writeback);
12617+ DySetAop(error_remove_page);
12618+ DySetAop(swap_activate);
12619+ DySetAop(swap_deactivate);
12620+
12621+ DyDbgSize(cnt, *h_aop);
12622+}
12623+
12624+/* ---------------------------------------------------------------------- */
12625+
12626+static void dy_bug(struct kref *kref)
12627+{
12628+ BUG();
12629+}
12630+
12631+static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
12632+{
12633+ struct au_dykey *key, *old;
12634+ struct hlist_bl_head *hbl;
12635+ struct op {
12636+ unsigned int sz;
12637+ void (*set)(struct au_dykey *key, const void *h_op,
12638+ struct super_block *h_sb __maybe_unused);
12639+ };
12640+ static const struct op a[] = {
12641+ [AuDy_AOP] = {
12642+ .sz = sizeof(struct au_dyaop),
12643+ .set = dy_aop
12644+ }
12645+ };
12646+ const struct op *p;
12647+
12648+ hbl = dynop + op->dy_type;
12649+ key = dy_gfind_get(hbl, op->dy_hop);
12650+ if (key)
12651+ goto out_add; /* success */
12652+
12653+ p = a + op->dy_type;
12654+ key = kzalloc(p->sz, GFP_NOFS);
12655+ if (unlikely(!key)) {
12656+ key = ERR_PTR(-ENOMEM);
12657+ goto out;
12658+ }
12659+
12660+ key->dk_op.dy_hop = op->dy_hop;
12661+ kref_init(&key->dk_kref);
12662+ p->set(key, op->dy_hop, au_br_sb(br));
12663+ old = dy_gadd(hbl, key);
12664+ if (old) {
12665+ au_kfree_rcu(key);
12666+ key = old;
12667+ }
12668+
12669+out_add:
12670+ old = dy_bradd(br, key);
12671+ if (old)
12672+ /* its ref-count should never be zero here */
12673+ kref_put(&key->dk_kref, dy_bug);
12674+out:
12675+ return key;
12676+}
12677+
12678+/* ---------------------------------------------------------------------- */
12679+/*
12680+ * Aufs prohibits O_DIRECT by default even if the branch supports it.
12681+ * This behaviour is necessary to return an error from open(O_DIRECT) instead
12682+ * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
12683+ * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
12684+ * See the aufs manual in detail.
12685+ */
12686+static void dy_adx(struct au_dyaop *dyaop, int do_dx)
12687+{
12688+ if (!do_dx)
12689+ dyaop->da_op.direct_IO = NULL;
12690+ else
12691+ dyaop->da_op.direct_IO = aufs_aop.direct_IO;
12692+}
12693+
12694+static struct au_dyaop *dy_aget(struct au_branch *br,
12695+ const struct address_space_operations *h_aop,
12696+ int do_dx)
12697+{
12698+ struct au_dyaop *dyaop;
12699+ struct au_dynop op;
12700+
12701+ op.dy_type = AuDy_AOP;
12702+ op.dy_haop = h_aop;
12703+ dyaop = (void *)dy_get(&op, br);
12704+ if (IS_ERR(dyaop))
12705+ goto out;
12706+ dy_adx(dyaop, do_dx);
12707+
12708+out:
12709+ return dyaop;
12710+}
12711+
12712+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
12713+ struct inode *h_inode)
12714+{
12715+ int err, do_dx;
12716+ struct super_block *sb;
12717+ struct au_branch *br;
12718+ struct au_dyaop *dyaop;
12719+
12720+ AuDebugOn(!S_ISREG(h_inode->i_mode));
12721+ IiMustWriteLock(inode);
12722+
12723+ sb = inode->i_sb;
12724+ br = au_sbr(sb, bindex);
12725+ do_dx = !!au_opt_test(au_mntflags(sb), DIO);
12726+ dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
12727+ err = PTR_ERR(dyaop);
12728+ if (IS_ERR(dyaop))
12729+ /* unnecessary to call dy_fput() */
12730+ goto out;
12731+
12732+ err = 0;
12733+ inode->i_mapping->a_ops = &dyaop->da_op;
12734+
12735+out:
12736+ return err;
12737+}
12738+
12739+/*
12740+ * Is it safe to replace a_ops during the inode/file is in operation?
12741+ * Yes, I hope so.
12742+ */
12743+int au_dy_irefresh(struct inode *inode)
12744+{
12745+ int err;
12746+ aufs_bindex_t btop;
12747+ struct inode *h_inode;
12748+
12749+ err = 0;
12750+ if (S_ISREG(inode->i_mode)) {
12751+ btop = au_ibtop(inode);
12752+ h_inode = au_h_iptr(inode, btop);
12753+ err = au_dy_iaop(inode, btop, h_inode);
12754+ }
12755+ return err;
12756+}
12757+
12758+void au_dy_arefresh(int do_dx)
12759+{
12760+ struct hlist_bl_head *hbl;
12761+ struct hlist_bl_node *pos;
12762+ struct au_dykey *key;
12763+
12764+ hbl = dynop + AuDy_AOP;
12765+ hlist_bl_lock(hbl);
12766+ hlist_bl_for_each_entry(key, pos, hbl, dk_hnode)
12767+ dy_adx((void *)key, do_dx);
12768+ hlist_bl_unlock(hbl);
12769+}
12770+
12771+/* ---------------------------------------------------------------------- */
12772+
12773+void __init au_dy_init(void)
12774+{
12775+ int i;
12776+
12777+ for (i = 0; i < AuDyLast; i++)
12778+ INIT_HLIST_BL_HEAD(dynop + i);
12779+}
12780+
12781+void au_dy_fin(void)
12782+{
12783+ int i;
12784+
12785+ for (i = 0; i < AuDyLast; i++)
12786+ WARN_ON(!hlist_bl_empty(dynop + i));
12787+}
12788diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
12789--- /usr/share/empty/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100
12790+++ linux/fs/aufs/dynop.h 2020-01-27 10:57:18.168871450 +0100
12791@@ -0,0 +1,77 @@
12792+/* SPDX-License-Identifier: GPL-2.0 */
12793+/*
12794+ * Copyright (C) 2010-2020 Junjiro R. Okajima
12795+ *
12796+ * This program, aufs is free software; you can redistribute it and/or modify
12797+ * it under the terms of the GNU General Public License as published by
12798+ * the Free Software Foundation; either version 2 of the License, or
12799+ * (at your option) any later version.
12800+ *
12801+ * This program is distributed in the hope that it will be useful,
12802+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12803+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12804+ * GNU General Public License for more details.
12805+ *
12806+ * You should have received a copy of the GNU General Public License
12807+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
12808+ */
12809+
12810+/*
12811+ * dynamically customizable operations (for regular files only)
12812+ */
12813+
12814+#ifndef __AUFS_DYNOP_H__
12815+#define __AUFS_DYNOP_H__
12816+
12817+#ifdef __KERNEL__
12818+
12819+#include <linux/fs.h>
12820+#include <linux/kref.h>
12821+
12822+enum {AuDy_AOP, AuDyLast};
12823+
12824+struct au_dynop {
12825+ int dy_type;
12826+ union {
12827+ const void *dy_hop;
12828+ const struct address_space_operations *dy_haop;
12829+ };
12830+};
12831+
12832+struct au_dykey {
12833+ union {
12834+ struct hlist_bl_node dk_hnode;
12835+ struct rcu_head dk_rcu;
12836+ };
12837+ struct au_dynop dk_op;
12838+
12839+ /*
12840+ * during I am in the branch local array, kref is gotten. when the
12841+ * branch is removed, kref is put.
12842+ */
12843+ struct kref dk_kref;
12844+};
12845+
12846+/* stop unioning since their sizes are very different from each other */
12847+struct au_dyaop {
12848+ struct au_dykey da_key;
12849+ struct address_space_operations da_op; /* not const */
12850+};
12851+/* make sure that 'struct au_dykey *' can be any type */
12852+static_assert(!offsetof(struct au_dyaop, da_key));
12853+
12854+/* ---------------------------------------------------------------------- */
12855+
12856+/* dynop.c */
12857+struct au_branch;
12858+void au_dy_put(struct au_dykey *key);
12859+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
12860+ struct inode *h_inode);
12861+int au_dy_irefresh(struct inode *inode);
12862+void au_dy_arefresh(int do_dio);
12863+
12864+void __init au_dy_init(void);
12865+void au_dy_fin(void);
12866+
12867+#endif /* __KERNEL__ */
12868+#endif /* __AUFS_DYNOP_H__ */
12869diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
12870--- /usr/share/empty/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
12871+++ linux/fs/aufs/export.c 2020-01-27 10:57:18.168871450 +0100
12872@@ -0,0 +1,838 @@
12873+// SPDX-License-Identifier: GPL-2.0
12874+/*
12875+ * Copyright (C) 2005-2020 Junjiro R. Okajima
12876+ *
12877+ * This program, aufs is free software; you can redistribute it and/or modify
12878+ * it under the terms of the GNU General Public License as published by
12879+ * the Free Software Foundation; either version 2 of the License, or
12880+ * (at your option) any later version.
12881+ *
12882+ * This program is distributed in the hope that it will be useful,
12883+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12884+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12885+ * GNU General Public License for more details.
12886+ *
12887+ * You should have received a copy of the GNU General Public License
12888+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
12889+ */
12890+
12891+/*
12892+ * export via nfs
12893+ */
12894+
12895+#include <linux/exportfs.h>
12896+#include <linux/fs_struct.h>
12897+#include <linux/namei.h>
12898+#include <linux/nsproxy.h>
12899+#include <linux/random.h>
12900+#include <linux/writeback.h>
12901+#include "aufs.h"
12902+
12903+union conv {
12904+#ifdef CONFIG_AUFS_INO_T_64
12905+ __u32 a[2];
12906+#else
12907+ __u32 a[1];
12908+#endif
12909+ ino_t ino;
12910+};
12911+
12912+static ino_t decode_ino(__u32 *a)
12913+{
12914+ union conv u;
12915+
12916+ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
12917+ u.a[0] = a[0];
12918+#ifdef CONFIG_AUFS_INO_T_64
12919+ u.a[1] = a[1];
12920+#endif
12921+ return u.ino;
12922+}
12923+
12924+static void encode_ino(__u32 *a, ino_t ino)
12925+{
12926+ union conv u;
12927+
12928+ u.ino = ino;
12929+ a[0] = u.a[0];
12930+#ifdef CONFIG_AUFS_INO_T_64
12931+ a[1] = u.a[1];
12932+#endif
12933+}
12934+
12935+/* NFS file handle */
12936+enum {
12937+ Fh_br_id,
12938+ Fh_sigen,
12939+#ifdef CONFIG_AUFS_INO_T_64
12940+ /* support 64bit inode number */
12941+ Fh_ino1,
12942+ Fh_ino2,
12943+ Fh_dir_ino1,
12944+ Fh_dir_ino2,
12945+#else
12946+ Fh_ino1,
12947+ Fh_dir_ino1,
12948+#endif
12949+ Fh_igen,
12950+ Fh_h_type,
12951+ Fh_tail,
12952+
12953+ Fh_ino = Fh_ino1,
12954+ Fh_dir_ino = Fh_dir_ino1
12955+};
12956+
12957+static int au_test_anon(struct dentry *dentry)
12958+{
12959+ /* note: read d_flags without d_lock */
12960+ return !!(dentry->d_flags & DCACHE_DISCONNECTED);
12961+}
12962+
12963+int au_test_nfsd(void)
12964+{
12965+ int ret;
12966+ struct task_struct *tsk = current;
12967+ char comm[sizeof(tsk->comm)];
12968+
12969+ ret = 0;
12970+ if (tsk->flags & PF_KTHREAD) {
12971+ get_task_comm(comm, tsk);
12972+ ret = !strcmp(comm, "nfsd");
12973+ }
12974+
12975+ return ret;
12976+}
12977+
12978+/* ---------------------------------------------------------------------- */
12979+/* inode generation external table */
12980+
12981+void au_xigen_inc(struct inode *inode)
12982+{
12983+ loff_t pos;
12984+ ssize_t sz;
12985+ __u32 igen;
12986+ struct super_block *sb;
12987+ struct au_sbinfo *sbinfo;
12988+
12989+ sb = inode->i_sb;
12990+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
12991+
12992+ sbinfo = au_sbi(sb);
12993+ pos = inode->i_ino;
12994+ pos *= sizeof(igen);
12995+ igen = inode->i_generation + 1;
12996+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
12997+ sizeof(igen), &pos);
12998+ if (sz == sizeof(igen))
12999+ return; /* success */
13000+
13001+ if (unlikely(sz >= 0))
13002+ AuIOErr("xigen error (%zd)\n", sz);
13003+}
13004+
13005+int au_xigen_new(struct inode *inode)
13006+{
13007+ int err;
13008+ loff_t pos;
13009+ ssize_t sz;
13010+ struct super_block *sb;
13011+ struct au_sbinfo *sbinfo;
13012+ struct file *file;
13013+
13014+ err = 0;
13015+ /* todo: dirty, at mount time */
13016+ if (inode->i_ino == AUFS_ROOT_INO)
13017+ goto out;
13018+ sb = inode->i_sb;
13019+ SiMustAnyLock(sb);
13020+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
13021+ goto out;
13022+
13023+ err = -EFBIG;
13024+ pos = inode->i_ino;
13025+ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
13026+ AuIOErr1("too large i%lld\n", pos);
13027+ goto out;
13028+ }
13029+ pos *= sizeof(inode->i_generation);
13030+
13031+ err = 0;
13032+ sbinfo = au_sbi(sb);
13033+ file = sbinfo->si_xigen;
13034+ BUG_ON(!file);
13035+
13036+ if (vfsub_f_size_read(file)
13037+ < pos + sizeof(inode->i_generation)) {
13038+ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
13039+ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
13040+ sizeof(inode->i_generation), &pos);
13041+ } else
13042+ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
13043+ sizeof(inode->i_generation), &pos);
13044+ if (sz == sizeof(inode->i_generation))
13045+ goto out; /* success */
13046+
13047+ err = sz;
13048+ if (unlikely(sz >= 0)) {
13049+ err = -EIO;
13050+ AuIOErr("xigen error (%zd)\n", sz);
13051+ }
13052+
13053+out:
13054+ return err;
13055+}
13056+
13057+int au_xigen_set(struct super_block *sb, struct path *path)
13058+{
13059+ int err;
13060+ struct au_sbinfo *sbinfo;
13061+ struct file *file;
13062+
13063+ SiMustWriteLock(sb);
13064+
13065+ sbinfo = au_sbi(sb);
13066+ file = au_xino_create2(sb, path, sbinfo->si_xigen);
13067+ err = PTR_ERR(file);
13068+ if (IS_ERR(file))
13069+ goto out;
13070+ err = 0;
13071+ if (sbinfo->si_xigen)
13072+ fput(sbinfo->si_xigen);
13073+ sbinfo->si_xigen = file;
13074+
13075+out:
13076+ AuTraceErr(err);
13077+ return err;
13078+}
13079+
13080+void au_xigen_clr(struct super_block *sb)
13081+{
13082+ struct au_sbinfo *sbinfo;
13083+
13084+ SiMustWriteLock(sb);
13085+
13086+ sbinfo = au_sbi(sb);
13087+ if (sbinfo->si_xigen) {
13088+ fput(sbinfo->si_xigen);
13089+ sbinfo->si_xigen = NULL;
13090+ }
13091+}
13092+
13093+/* ---------------------------------------------------------------------- */
13094+
13095+static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
13096+ ino_t dir_ino)
13097+{
13098+ struct dentry *dentry, *d;
13099+ struct inode *inode;
13100+ unsigned int sigen;
13101+
13102+ dentry = NULL;
13103+ inode = ilookup(sb, ino);
13104+ if (!inode)
13105+ goto out;
13106+
13107+ dentry = ERR_PTR(-ESTALE);
13108+ sigen = au_sigen(sb);
13109+ if (unlikely(au_is_bad_inode(inode)
13110+ || IS_DEADDIR(inode)
13111+ || sigen != au_iigen(inode, NULL)))
13112+ goto out_iput;
13113+
13114+ dentry = NULL;
13115+ if (!dir_ino || S_ISDIR(inode->i_mode))
13116+ dentry = d_find_alias(inode);
13117+ else {
13118+ spin_lock(&inode->i_lock);
13119+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
13120+ spin_lock(&d->d_lock);
13121+ if (!au_test_anon(d)
13122+ && d_inode(d->d_parent)->i_ino == dir_ino) {
13123+ dentry = dget_dlock(d);
13124+ spin_unlock(&d->d_lock);
13125+ break;
13126+ }
13127+ spin_unlock(&d->d_lock);
13128+ }
13129+ spin_unlock(&inode->i_lock);
13130+ }
13131+ if (unlikely(dentry && au_digen_test(dentry, sigen))) {
13132+ /* need to refresh */
13133+ dput(dentry);
13134+ dentry = NULL;
13135+ }
13136+
13137+out_iput:
13138+ iput(inode);
13139+out:
13140+ AuTraceErrPtr(dentry);
13141+ return dentry;
13142+}
13143+
13144+/* ---------------------------------------------------------------------- */
13145+
13146+/* todo: dirty? */
13147+/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
13148+
13149+struct au_compare_mnt_args {
13150+ /* input */
13151+ struct super_block *sb;
13152+
13153+ /* output */
13154+ struct vfsmount *mnt;
13155+};
13156+
13157+static int au_compare_mnt(struct vfsmount *mnt, void *arg)
13158+{
13159+ struct au_compare_mnt_args *a = arg;
13160+
13161+ if (mnt->mnt_sb != a->sb)
13162+ return 0;
13163+ a->mnt = mntget(mnt);
13164+ return 1;
13165+}
13166+
13167+static struct vfsmount *au_mnt_get(struct super_block *sb)
13168+{
13169+ int err;
13170+ struct path root;
13171+ struct au_compare_mnt_args args = {
13172+ .sb = sb
13173+ };
13174+
13175+ get_fs_root(current->fs, &root);
13176+ rcu_read_lock();
13177+ err = iterate_mounts(au_compare_mnt, &args, root.mnt);
13178+ rcu_read_unlock();
13179+ path_put(&root);
13180+ AuDebugOn(!err);
13181+ AuDebugOn(!args.mnt);
13182+ return args.mnt;
13183+}
13184+
13185+struct au_nfsd_si_lock {
13186+ unsigned int sigen;
13187+ aufs_bindex_t bindex, br_id;
13188+ unsigned char force_lock;
13189+};
13190+
13191+static int si_nfsd_read_lock(struct super_block *sb,
13192+ struct au_nfsd_si_lock *nsi_lock)
13193+{
13194+ int err;
13195+ aufs_bindex_t bindex;
13196+
13197+ si_read_lock(sb, AuLock_FLUSH);
13198+
13199+ /* branch id may be wrapped around */
13200+ err = 0;
13201+ bindex = au_br_index(sb, nsi_lock->br_id);
13202+ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
13203+ goto out; /* success */
13204+
13205+ err = -ESTALE;
13206+ bindex = -1;
13207+ if (!nsi_lock->force_lock)
13208+ si_read_unlock(sb);
13209+
13210+out:
13211+ nsi_lock->bindex = bindex;
13212+ return err;
13213+}
13214+
13215+struct find_name_by_ino {
13216+ struct dir_context ctx;
13217+ int called, found;
13218+ ino_t ino;
13219+ char *name;
13220+ int namelen;
13221+};
13222+
13223+static int
13224+find_name_by_ino(struct dir_context *ctx, const char *name, int namelen,
13225+ loff_t offset, u64 ino, unsigned int d_type)
13226+{
13227+ struct find_name_by_ino *a = container_of(ctx, struct find_name_by_ino,
13228+ ctx);
13229+
13230+ a->called++;
13231+ if (a->ino != ino)
13232+ return 0;
13233+
13234+ memcpy(a->name, name, namelen);
13235+ a->namelen = namelen;
13236+ a->found = 1;
13237+ return 1;
13238+}
13239+
13240+static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
13241+ struct au_nfsd_si_lock *nsi_lock)
13242+{
13243+ struct dentry *dentry, *parent;
13244+ struct file *file;
13245+ struct inode *dir;
13246+ struct find_name_by_ino arg = {
13247+ .ctx = {
13248+ .actor = find_name_by_ino
13249+ }
13250+ };
13251+ int err;
13252+
13253+ parent = path->dentry;
13254+ if (nsi_lock)
13255+ si_read_unlock(parent->d_sb);
13256+ file = vfsub_dentry_open(path, au_dir_roflags);
13257+ dentry = (void *)file;
13258+ if (IS_ERR(file))
13259+ goto out;
13260+
13261+ dentry = ERR_PTR(-ENOMEM);
13262+ arg.name = (void *)__get_free_page(GFP_NOFS);
13263+ if (unlikely(!arg.name))
13264+ goto out_file;
13265+ arg.ino = ino;
13266+ arg.found = 0;
13267+ do {
13268+ arg.called = 0;
13269+ /* smp_mb(); */
13270+ err = vfsub_iterate_dir(file, &arg.ctx);
13271+ } while (!err && !arg.found && arg.called);
13272+ dentry = ERR_PTR(err);
13273+ if (unlikely(err))
13274+ goto out_name;
13275+ /* instead of ENOENT */
13276+ dentry = ERR_PTR(-ESTALE);
13277+ if (!arg.found)
13278+ goto out_name;
13279+
13280+ /* do not call vfsub_lkup_one() */
13281+ dir = d_inode(parent);
13282+ dentry = vfsub_lookup_one_len_unlocked(arg.name, parent, arg.namelen);
13283+ AuTraceErrPtr(dentry);
13284+ if (IS_ERR(dentry))
13285+ goto out_name;
13286+ AuDebugOn(au_test_anon(dentry));
13287+ if (unlikely(d_really_is_negative(dentry))) {
13288+ dput(dentry);
13289+ dentry = ERR_PTR(-ENOENT);
13290+ }
13291+
13292+out_name:
13293+ free_page((unsigned long)arg.name);
13294+out_file:
13295+ fput(file);
13296+out:
13297+ if (unlikely(nsi_lock
13298+ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
13299+ if (!IS_ERR(dentry)) {
13300+ dput(dentry);
13301+ dentry = ERR_PTR(-ESTALE);
13302+ }
13303+ AuTraceErrPtr(dentry);
13304+ return dentry;
13305+}
13306+
13307+static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
13308+ ino_t dir_ino,
13309+ struct au_nfsd_si_lock *nsi_lock)
13310+{
13311+ struct dentry *dentry;
13312+ struct path path;
13313+
13314+ if (dir_ino != AUFS_ROOT_INO) {
13315+ path.dentry = decode_by_ino(sb, dir_ino, 0);
13316+ dentry = path.dentry;
13317+ if (!path.dentry || IS_ERR(path.dentry))
13318+ goto out;
13319+ AuDebugOn(au_test_anon(path.dentry));
13320+ } else
13321+ path.dentry = dget(sb->s_root);
13322+
13323+ path.mnt = au_mnt_get(sb);
13324+ dentry = au_lkup_by_ino(&path, ino, nsi_lock);
13325+ path_put(&path);
13326+
13327+out:
13328+ AuTraceErrPtr(dentry);
13329+ return dentry;
13330+}
13331+
13332+/* ---------------------------------------------------------------------- */
13333+
13334+static int h_acceptable(void *expv, struct dentry *dentry)
13335+{
13336+ return 1;
13337+}
13338+
13339+static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
13340+ char *buf, int len, struct super_block *sb)
13341+{
13342+ char *p;
13343+ int n;
13344+ struct path path;
13345+
13346+ p = d_path(h_rootpath, buf, len);
13347+ if (IS_ERR(p))
13348+ goto out;
13349+ n = strlen(p);
13350+
13351+ path.mnt = h_rootpath->mnt;
13352+ path.dentry = h_parent;
13353+ p = d_path(&path, buf, len);
13354+ if (IS_ERR(p))
13355+ goto out;
13356+ if (n != 1)
13357+ p += n;
13358+
13359+ path.mnt = au_mnt_get(sb);
13360+ path.dentry = sb->s_root;
13361+ p = d_path(&path, buf, len - strlen(p));
13362+ mntput(path.mnt);
13363+ if (IS_ERR(p))
13364+ goto out;
13365+ if (n != 1)
13366+ p[strlen(p)] = '/';
13367+
13368+out:
13369+ AuTraceErrPtr(p);
13370+ return p;
13371+}
13372+
13373+static
13374+struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
13375+ int fh_len, struct au_nfsd_si_lock *nsi_lock)
13376+{
13377+ struct dentry *dentry, *h_parent, *root;
13378+ struct super_block *h_sb;
13379+ char *pathname, *p;
13380+ struct vfsmount *h_mnt;
13381+ struct au_branch *br;
13382+ int err;
13383+ struct path path;
13384+
13385+ br = au_sbr(sb, nsi_lock->bindex);
13386+ h_mnt = au_br_mnt(br);
13387+ h_sb = h_mnt->mnt_sb;
13388+ /* todo: call lower fh_to_dentry()? fh_to_parent()? */
13389+ lockdep_off();
13390+ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
13391+ fh_len - Fh_tail, fh[Fh_h_type],
13392+ h_acceptable, /*context*/NULL);
13393+ lockdep_on();
13394+ dentry = h_parent;
13395+ if (unlikely(!h_parent || IS_ERR(h_parent))) {
13396+ AuWarn1("%s decode_fh failed, %ld\n",
13397+ au_sbtype(h_sb), PTR_ERR(h_parent));
13398+ goto out;
13399+ }
13400+ dentry = NULL;
13401+ if (unlikely(au_test_anon(h_parent))) {
13402+ AuWarn1("%s decode_fh returned a disconnected dentry\n",
13403+ au_sbtype(h_sb));
13404+ goto out_h_parent;
13405+ }
13406+
13407+ dentry = ERR_PTR(-ENOMEM);
13408+ pathname = (void *)__get_free_page(GFP_NOFS);
13409+ if (unlikely(!pathname))
13410+ goto out_h_parent;
13411+
13412+ root = sb->s_root;
13413+ path.mnt = h_mnt;
13414+ di_read_lock_parent(root, !AuLock_IR);
13415+ path.dentry = au_h_dptr(root, nsi_lock->bindex);
13416+ di_read_unlock(root, !AuLock_IR);
13417+ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
13418+ dentry = (void *)p;
13419+ if (IS_ERR(p))
13420+ goto out_pathname;
13421+
13422+ si_read_unlock(sb);
13423+ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
13424+ dentry = ERR_PTR(err);
13425+ if (unlikely(err))
13426+ goto out_relock;
13427+
13428+ dentry = ERR_PTR(-ENOENT);
13429+ AuDebugOn(au_test_anon(path.dentry));
13430+ if (unlikely(d_really_is_negative(path.dentry)))
13431+ goto out_path;
13432+
13433+ if (ino != d_inode(path.dentry)->i_ino)
13434+ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
13435+ else
13436+ dentry = dget(path.dentry);
13437+
13438+out_path:
13439+ path_put(&path);
13440+out_relock:
13441+ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
13442+ if (!IS_ERR(dentry)) {
13443+ dput(dentry);
13444+ dentry = ERR_PTR(-ESTALE);
13445+ }
13446+out_pathname:
13447+ free_page((unsigned long)pathname);
13448+out_h_parent:
13449+ dput(h_parent);
13450+out:
13451+ AuTraceErrPtr(dentry);
13452+ return dentry;
13453+}
13454+
13455+/* ---------------------------------------------------------------------- */
13456+
13457+static struct dentry *
13458+aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
13459+ int fh_type)
13460+{
13461+ struct dentry *dentry;
13462+ __u32 *fh = fid->raw;
13463+ struct au_branch *br;
13464+ ino_t ino, dir_ino;
13465+ struct au_nfsd_si_lock nsi_lock = {
13466+ .force_lock = 0
13467+ };
13468+
13469+ dentry = ERR_PTR(-ESTALE);
13470+ /* it should never happen, but the file handle is unreliable */
13471+ if (unlikely(fh_len < Fh_tail))
13472+ goto out;
13473+ nsi_lock.sigen = fh[Fh_sigen];
13474+ nsi_lock.br_id = fh[Fh_br_id];
13475+
13476+ /* branch id may be wrapped around */
13477+ br = NULL;
13478+ if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
13479+ goto out;
13480+ nsi_lock.force_lock = 1;
13481+
13482+ /* is this inode still cached? */
13483+ ino = decode_ino(fh + Fh_ino);
13484+ /* it should never happen */
13485+ if (unlikely(ino == AUFS_ROOT_INO))
13486+ goto out_unlock;
13487+
13488+ dir_ino = decode_ino(fh + Fh_dir_ino);
13489+ dentry = decode_by_ino(sb, ino, dir_ino);
13490+ if (IS_ERR(dentry))
13491+ goto out_unlock;
13492+ if (dentry)
13493+ goto accept;
13494+
13495+ /* is the parent dir cached? */
13496+ br = au_sbr(sb, nsi_lock.bindex);
13497+ au_lcnt_inc(&br->br_nfiles);
13498+ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
13499+ if (IS_ERR(dentry))
13500+ goto out_unlock;
13501+ if (dentry)
13502+ goto accept;
13503+
13504+ /* lookup path */
13505+ dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
13506+ if (IS_ERR(dentry))
13507+ goto out_unlock;
13508+ if (unlikely(!dentry))
13509+ /* todo?: make it ESTALE */
13510+ goto out_unlock;
13511+
13512+accept:
13513+ if (!au_digen_test(dentry, au_sigen(sb))
13514+ && d_inode(dentry)->i_generation == fh[Fh_igen])
13515+ goto out_unlock; /* success */
13516+
13517+ dput(dentry);
13518+ dentry = ERR_PTR(-ESTALE);
13519+out_unlock:
13520+ if (br)
13521+ au_lcnt_dec(&br->br_nfiles);
13522+ si_read_unlock(sb);
13523+out:
13524+ AuTraceErrPtr(dentry);
13525+ return dentry;
13526+}
13527+
13528+#if 0 /* reserved for future use */
13529+/* support subtreecheck option */
13530+static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
13531+ int fh_len, int fh_type)
13532+{
13533+ struct dentry *parent;
13534+ __u32 *fh = fid->raw;
13535+ ino_t dir_ino;
13536+
13537+ dir_ino = decode_ino(fh + Fh_dir_ino);
13538+ parent = decode_by_ino(sb, dir_ino, 0);
13539+ if (IS_ERR(parent))
13540+ goto out;
13541+ if (!parent)
13542+ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
13543+ dir_ino, fh, fh_len);
13544+
13545+out:
13546+ AuTraceErrPtr(parent);
13547+ return parent;
13548+}
13549+#endif
13550+
13551+/* ---------------------------------------------------------------------- */
13552+
13553+static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
13554+ struct inode *dir)
13555+{
13556+ int err;
13557+ aufs_bindex_t bindex;
13558+ struct super_block *sb, *h_sb;
13559+ struct dentry *dentry, *parent, *h_parent;
13560+ struct inode *h_dir;
13561+ struct au_branch *br;
13562+
13563+ err = -ENOSPC;
13564+ if (unlikely(*max_len <= Fh_tail)) {
13565+ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
13566+ goto out;
13567+ }
13568+
13569+ err = FILEID_ROOT;
13570+ if (inode->i_ino == AUFS_ROOT_INO) {
13571+ AuDebugOn(inode->i_ino != AUFS_ROOT_INO);
13572+ goto out;
13573+ }
13574+
13575+ h_parent = NULL;
13576+ sb = inode->i_sb;
13577+ err = si_read_lock(sb, AuLock_FLUSH);
13578+ if (unlikely(err))
13579+ goto out;
13580+
13581+#ifdef CONFIG_AUFS_DEBUG
13582+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
13583+ AuWarn1("NFS-exporting requires xino\n");
13584+#endif
13585+ err = -EIO;
13586+ parent = NULL;
13587+ ii_read_lock_child(inode);
13588+ bindex = au_ibtop(inode);
13589+ if (!dir) {
13590+ dentry = d_find_any_alias(inode);
13591+ if (unlikely(!dentry))
13592+ goto out_unlock;
13593+ AuDebugOn(au_test_anon(dentry));
13594+ parent = dget_parent(dentry);
13595+ dput(dentry);
13596+ if (unlikely(!parent))
13597+ goto out_unlock;
13598+ if (d_really_is_positive(parent))
13599+ dir = d_inode(parent);
13600+ }
13601+
13602+ ii_read_lock_parent(dir);
13603+ h_dir = au_h_iptr(dir, bindex);
13604+ ii_read_unlock(dir);
13605+ if (unlikely(!h_dir))
13606+ goto out_parent;
13607+ h_parent = d_find_any_alias(h_dir);
13608+ if (unlikely(!h_parent))
13609+ goto out_hparent;
13610+
13611+ err = -EPERM;
13612+ br = au_sbr(sb, bindex);
13613+ h_sb = au_br_sb(br);
13614+ if (unlikely(!h_sb->s_export_op)) {
13615+ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
13616+ goto out_hparent;
13617+ }
13618+
13619+ fh[Fh_br_id] = br->br_id;
13620+ fh[Fh_sigen] = au_sigen(sb);
13621+ encode_ino(fh + Fh_ino, inode->i_ino);
13622+ encode_ino(fh + Fh_dir_ino, dir->i_ino);
13623+ fh[Fh_igen] = inode->i_generation;
13624+
13625+ *max_len -= Fh_tail;
13626+ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
13627+ max_len,
13628+ /*connectable or subtreecheck*/0);
13629+ err = fh[Fh_h_type];
13630+ *max_len += Fh_tail;
13631+ /* todo: macros? */
13632+ if (err != FILEID_INVALID)
13633+ err = 99;
13634+ else
13635+ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
13636+
13637+out_hparent:
13638+ dput(h_parent);
13639+out_parent:
13640+ dput(parent);
13641+out_unlock:
13642+ ii_read_unlock(inode);
13643+ si_read_unlock(sb);
13644+out:
13645+ if (unlikely(err < 0))
13646+ err = FILEID_INVALID;
13647+ return err;
13648+}
13649+
13650+/* ---------------------------------------------------------------------- */
13651+
13652+static int aufs_commit_metadata(struct inode *inode)
13653+{
13654+ int err;
13655+ aufs_bindex_t bindex;
13656+ struct super_block *sb;
13657+ struct inode *h_inode;
13658+ int (*f)(struct inode *inode);
13659+
13660+ sb = inode->i_sb;
13661+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
13662+ ii_write_lock_child(inode);
13663+ bindex = au_ibtop(inode);
13664+ AuDebugOn(bindex < 0);
13665+ h_inode = au_h_iptr(inode, bindex);
13666+
13667+ f = h_inode->i_sb->s_export_op->commit_metadata;
13668+ if (f)
13669+ err = f(h_inode);
13670+ else {
13671+ struct writeback_control wbc = {
13672+ .sync_mode = WB_SYNC_ALL,
13673+ .nr_to_write = 0 /* metadata only */
13674+ };
13675+
13676+ err = sync_inode(h_inode, &wbc);
13677+ }
13678+
13679+ au_cpup_attr_timesizes(inode);
13680+ ii_write_unlock(inode);
13681+ si_read_unlock(sb);
13682+ return err;
13683+}
13684+
13685+/* ---------------------------------------------------------------------- */
13686+
13687+static struct export_operations aufs_export_op = {
13688+ .fh_to_dentry = aufs_fh_to_dentry,
13689+ /* .fh_to_parent = aufs_fh_to_parent, */
13690+ .encode_fh = aufs_encode_fh,
13691+ .commit_metadata = aufs_commit_metadata
13692+};
13693+
13694+void au_export_init(struct super_block *sb)
13695+{
13696+ struct au_sbinfo *sbinfo;
13697+ __u32 u;
13698+
13699+ BUILD_BUG_ON_MSG(IS_BUILTIN(CONFIG_AUFS_FS)
13700+ && IS_MODULE(CONFIG_EXPORTFS),
13701+ AUFS_NAME ": unsupported configuration "
13702+ "CONFIG_EXPORTFS=m and CONFIG_AUFS_FS=y");
13703+
13704+ sb->s_export_op = &aufs_export_op;
13705+ sbinfo = au_sbi(sb);
13706+ sbinfo->si_xigen = NULL;
13707+ get_random_bytes(&u, sizeof(u));
13708+ BUILD_BUG_ON(sizeof(u) != sizeof(int));
13709+ atomic_set(&sbinfo->si_xigen_next, u);
13710+}
13711diff -urN /usr/share/empty/fs/aufs/fhsm.c linux/fs/aufs/fhsm.c
13712--- /usr/share/empty/fs/aufs/fhsm.c 1970-01-01 01:00:00.000000000 +0100
13713+++ linux/fs/aufs/fhsm.c 2020-01-27 10:57:18.172204883 +0100
13714@@ -0,0 +1,427 @@
13715+// SPDX-License-Identifier: GPL-2.0
13716+/*
13717+ * Copyright (C) 2011-2020 Junjiro R. Okajima
13718+ *
13719+ * This program, aufs is free software; you can redistribute it and/or modify
13720+ * it under the terms of the GNU General Public License as published by
13721+ * the Free Software Foundation; either version 2 of the License, or
13722+ * (at your option) any later version.
13723+ *
13724+ * This program is distributed in the hope that it will be useful,
13725+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13726+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13727+ * GNU General Public License for more details.
13728+ *
13729+ * You should have received a copy of the GNU General Public License
13730+ * along with this program; if not, write to the Free Software
13731+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13732+ */
13733+
13734+/*
13735+ * File-based Hierarchy Storage Management
13736+ */
13737+
13738+#include <linux/anon_inodes.h>
13739+#include <linux/poll.h>
13740+#include <linux/seq_file.h>
13741+#include <linux/statfs.h>
13742+#include "aufs.h"
13743+
13744+static aufs_bindex_t au_fhsm_bottom(struct super_block *sb)
13745+{
13746+ struct au_sbinfo *sbinfo;
13747+ struct au_fhsm *fhsm;
13748+
13749+ SiMustAnyLock(sb);
13750+
13751+ sbinfo = au_sbi(sb);
13752+ fhsm = &sbinfo->si_fhsm;
13753+ AuDebugOn(!fhsm);
13754+ return fhsm->fhsm_bottom;
13755+}
13756+
13757+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex)
13758+{
13759+ struct au_sbinfo *sbinfo;
13760+ struct au_fhsm *fhsm;
13761+
13762+ SiMustWriteLock(sb);
13763+
13764+ sbinfo = au_sbi(sb);
13765+ fhsm = &sbinfo->si_fhsm;
13766+ AuDebugOn(!fhsm);
13767+ fhsm->fhsm_bottom = bindex;
13768+}
13769+
13770+/* ---------------------------------------------------------------------- */
13771+
13772+static int au_fhsm_test_jiffy(struct au_sbinfo *sbinfo, struct au_branch *br)
13773+{
13774+ struct au_br_fhsm *bf;
13775+
13776+ bf = br->br_fhsm;
13777+ MtxMustLock(&bf->bf_lock);
13778+
13779+ return !bf->bf_readable
13780+ || time_after(jiffies,
13781+ bf->bf_jiffy + sbinfo->si_fhsm.fhsm_expire);
13782+}
13783+
13784+/* ---------------------------------------------------------------------- */
13785+
13786+static void au_fhsm_notify(struct super_block *sb, int val)
13787+{
13788+ struct au_sbinfo *sbinfo;
13789+ struct au_fhsm *fhsm;
13790+
13791+ SiMustAnyLock(sb);
13792+
13793+ sbinfo = au_sbi(sb);
13794+ fhsm = &sbinfo->si_fhsm;
13795+ if (au_fhsm_pid(fhsm)
13796+ && atomic_read(&fhsm->fhsm_readable) != -1) {
13797+ atomic_set(&fhsm->fhsm_readable, val);
13798+ if (val)
13799+ wake_up(&fhsm->fhsm_wqh);
13800+ }
13801+}
13802+
13803+static int au_fhsm_stfs(struct super_block *sb, aufs_bindex_t bindex,
13804+ struct aufs_stfs *rstfs, int do_lock, int do_notify)
13805+{
13806+ int err;
13807+ struct au_branch *br;
13808+ struct au_br_fhsm *bf;
13809+
13810+ br = au_sbr(sb, bindex);
13811+ AuDebugOn(au_br_rdonly(br));
13812+ bf = br->br_fhsm;
13813+ AuDebugOn(!bf);
13814+
13815+ if (do_lock)
13816+ mutex_lock(&bf->bf_lock);
13817+ else
13818+ MtxMustLock(&bf->bf_lock);
13819+
13820+ /* sb->s_root for NFS is unreliable */
13821+ err = au_br_stfs(br, &bf->bf_stfs);
13822+ if (unlikely(err)) {
13823+ AuErr1("FHSM failed (%d), b%d, ignored.\n", bindex, err);
13824+ goto out;
13825+ }
13826+
13827+ bf->bf_jiffy = jiffies;
13828+ bf->bf_readable = 1;
13829+ if (do_notify)
13830+ au_fhsm_notify(sb, /*val*/1);
13831+ if (rstfs)
13832+ *rstfs = bf->bf_stfs;
13833+
13834+out:
13835+ if (do_lock)
13836+ mutex_unlock(&bf->bf_lock);
13837+ au_fhsm_notify(sb, /*val*/1);
13838+
13839+ return err;
13840+}
13841+
13842+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force)
13843+{
13844+ int err;
13845+ struct au_sbinfo *sbinfo;
13846+ struct au_fhsm *fhsm;
13847+ struct au_branch *br;
13848+ struct au_br_fhsm *bf;
13849+
13850+ AuDbg("b%d, force %d\n", bindex, force);
13851+ SiMustAnyLock(sb);
13852+
13853+ sbinfo = au_sbi(sb);
13854+ fhsm = &sbinfo->si_fhsm;
13855+ if (!au_ftest_si(sbinfo, FHSM)
13856+ || fhsm->fhsm_bottom == bindex)
13857+ return;
13858+
13859+ br = au_sbr(sb, bindex);
13860+ bf = br->br_fhsm;
13861+ AuDebugOn(!bf);
13862+ mutex_lock(&bf->bf_lock);
13863+ if (force
13864+ || au_fhsm_pid(fhsm)
13865+ || au_fhsm_test_jiffy(sbinfo, br))
13866+ err = au_fhsm_stfs(sb, bindex, /*rstfs*/NULL, /*do_lock*/0,
13867+ /*do_notify*/1);
13868+ mutex_unlock(&bf->bf_lock);
13869+}
13870+
13871+void au_fhsm_wrote_all(struct super_block *sb, int force)
13872+{
13873+ aufs_bindex_t bindex, bbot;
13874+ struct au_branch *br;
13875+
13876+ /* exclude the bottom */
13877+ bbot = au_fhsm_bottom(sb);
13878+ for (bindex = 0; bindex < bbot; bindex++) {
13879+ br = au_sbr(sb, bindex);
13880+ if (au_br_fhsm(br->br_perm))
13881+ au_fhsm_wrote(sb, bindex, force);
13882+ }
13883+}
13884+
13885+/* ---------------------------------------------------------------------- */
13886+
13887+static __poll_t au_fhsm_poll(struct file *file, struct poll_table_struct *wait)
13888+{
13889+ __poll_t mask;
13890+ struct au_sbinfo *sbinfo;
13891+ struct au_fhsm *fhsm;
13892+
13893+ mask = 0;
13894+ sbinfo = file->private_data;
13895+ fhsm = &sbinfo->si_fhsm;
13896+ poll_wait(file, &fhsm->fhsm_wqh, wait);
13897+ if (atomic_read(&fhsm->fhsm_readable))
13898+ mask = EPOLLIN /* | EPOLLRDNORM */;
13899+
13900+ if (!mask)
13901+ AuDbg("mask 0x%x\n", mask);
13902+ return mask;
13903+}
13904+
13905+static int au_fhsm_do_read_one(struct aufs_stbr __user *stbr,
13906+ struct aufs_stfs *stfs, __s16 brid)
13907+{
13908+ int err;
13909+
13910+ err = copy_to_user(&stbr->stfs, stfs, sizeof(*stfs));
13911+ if (!err)
13912+ err = __put_user(brid, &stbr->brid);
13913+ if (unlikely(err))
13914+ err = -EFAULT;
13915+
13916+ return err;
13917+}
13918+
13919+static ssize_t au_fhsm_do_read(struct super_block *sb,
13920+ struct aufs_stbr __user *stbr, size_t count)
13921+{
13922+ ssize_t err;
13923+ int nstbr;
13924+ aufs_bindex_t bindex, bbot;
13925+ struct au_branch *br;
13926+ struct au_br_fhsm *bf;
13927+
13928+ /* except the bottom branch */
13929+ err = 0;
13930+ nstbr = 0;
13931+ bbot = au_fhsm_bottom(sb);
13932+ for (bindex = 0; !err && bindex < bbot; bindex++) {
13933+ br = au_sbr(sb, bindex);
13934+ if (!au_br_fhsm(br->br_perm))
13935+ continue;
13936+
13937+ bf = br->br_fhsm;
13938+ mutex_lock(&bf->bf_lock);
13939+ if (bf->bf_readable) {
13940+ err = -EFAULT;
13941+ if (count >= sizeof(*stbr))
13942+ err = au_fhsm_do_read_one(stbr++, &bf->bf_stfs,
13943+ br->br_id);
13944+ if (!err) {
13945+ bf->bf_readable = 0;
13946+ count -= sizeof(*stbr);
13947+ nstbr++;
13948+ }
13949+ }
13950+ mutex_unlock(&bf->bf_lock);
13951+ }
13952+ if (!err)
13953+ err = sizeof(*stbr) * nstbr;
13954+
13955+ return err;
13956+}
13957+
13958+static ssize_t au_fhsm_read(struct file *file, char __user *buf, size_t count,
13959+ loff_t *pos)
13960+{
13961+ ssize_t err;
13962+ int readable;
13963+ aufs_bindex_t nfhsm, bindex, bbot;
13964+ struct au_sbinfo *sbinfo;
13965+ struct au_fhsm *fhsm;
13966+ struct au_branch *br;
13967+ struct super_block *sb;
13968+
13969+ err = 0;
13970+ sbinfo = file->private_data;
13971+ fhsm = &sbinfo->si_fhsm;
13972+need_data:
13973+ spin_lock_irq(&fhsm->fhsm_wqh.lock);
13974+ if (!atomic_read(&fhsm->fhsm_readable)) {
13975+ if (vfsub_file_flags(file) & O_NONBLOCK)
13976+ err = -EAGAIN;
13977+ else
13978+ err = wait_event_interruptible_locked_irq
13979+ (fhsm->fhsm_wqh,
13980+ atomic_read(&fhsm->fhsm_readable));
13981+ }
13982+ spin_unlock_irq(&fhsm->fhsm_wqh.lock);
13983+ if (unlikely(err))
13984+ goto out;
13985+
13986+ /* sb may already be dead */
13987+ au_rw_read_lock(&sbinfo->si_rwsem);
13988+ readable = atomic_read(&fhsm->fhsm_readable);
13989+ if (readable > 0) {
13990+ sb = sbinfo->si_sb;
13991+ AuDebugOn(!sb);
13992+ /* exclude the bottom branch */
13993+ nfhsm = 0;
13994+ bbot = au_fhsm_bottom(sb);
13995+ for (bindex = 0; bindex < bbot; bindex++) {
13996+ br = au_sbr(sb, bindex);
13997+ if (au_br_fhsm(br->br_perm))
13998+ nfhsm++;
13999+ }
14000+ err = -EMSGSIZE;
14001+ if (nfhsm * sizeof(struct aufs_stbr) <= count) {
14002+ atomic_set(&fhsm->fhsm_readable, 0);
14003+ err = au_fhsm_do_read(sbinfo->si_sb, (void __user *)buf,
14004+ count);
14005+ }
14006+ }
14007+ au_rw_read_unlock(&sbinfo->si_rwsem);
14008+ if (!readable)
14009+ goto need_data;
14010+
14011+out:
14012+ return err;
14013+}
14014+
14015+static int au_fhsm_release(struct inode *inode, struct file *file)
14016+{
14017+ struct au_sbinfo *sbinfo;
14018+ struct au_fhsm *fhsm;
14019+
14020+ /* sb may already be dead */
14021+ sbinfo = file->private_data;
14022+ fhsm = &sbinfo->si_fhsm;
14023+ spin_lock(&fhsm->fhsm_spin);
14024+ fhsm->fhsm_pid = 0;
14025+ spin_unlock(&fhsm->fhsm_spin);
14026+ kobject_put(&sbinfo->si_kobj);
14027+
14028+ return 0;
14029+}
14030+
14031+static const struct file_operations au_fhsm_fops = {
14032+ .owner = THIS_MODULE,
14033+ .llseek = noop_llseek,
14034+ .read = au_fhsm_read,
14035+ .poll = au_fhsm_poll,
14036+ .release = au_fhsm_release
14037+};
14038+
14039+int au_fhsm_fd(struct super_block *sb, int oflags)
14040+{
14041+ int err, fd;
14042+ struct au_sbinfo *sbinfo;
14043+ struct au_fhsm *fhsm;
14044+
14045+ err = -EPERM;
14046+ if (unlikely(!capable(CAP_SYS_ADMIN)))
14047+ goto out;
14048+
14049+ err = -EINVAL;
14050+ if (unlikely(oflags & ~(O_CLOEXEC | O_NONBLOCK)))
14051+ goto out;
14052+
14053+ err = 0;
14054+ sbinfo = au_sbi(sb);
14055+ fhsm = &sbinfo->si_fhsm;
14056+ spin_lock(&fhsm->fhsm_spin);
14057+ if (!fhsm->fhsm_pid)
14058+ fhsm->fhsm_pid = current->pid;
14059+ else
14060+ err = -EBUSY;
14061+ spin_unlock(&fhsm->fhsm_spin);
14062+ if (unlikely(err))
14063+ goto out;
14064+
14065+ oflags |= O_RDONLY;
14066+ /* oflags |= FMODE_NONOTIFY; */
14067+ fd = anon_inode_getfd("[aufs_fhsm]", &au_fhsm_fops, sbinfo, oflags);
14068+ err = fd;
14069+ if (unlikely(fd < 0))
14070+ goto out_pid;
14071+
14072+ /* succeed regardless 'fhsm' status */
14073+ kobject_get(&sbinfo->si_kobj);
14074+ si_noflush_read_lock(sb);
14075+ if (au_ftest_si(sbinfo, FHSM))
14076+ au_fhsm_wrote_all(sb, /*force*/0);
14077+ si_read_unlock(sb);
14078+ goto out; /* success */
14079+
14080+out_pid:
14081+ spin_lock(&fhsm->fhsm_spin);
14082+ fhsm->fhsm_pid = 0;
14083+ spin_unlock(&fhsm->fhsm_spin);
14084+out:
14085+ AuTraceErr(err);
14086+ return err;
14087+}
14088+
14089+/* ---------------------------------------------------------------------- */
14090+
14091+int au_fhsm_br_alloc(struct au_branch *br)
14092+{
14093+ int err;
14094+
14095+ err = 0;
14096+ br->br_fhsm = kmalloc(sizeof(*br->br_fhsm), GFP_NOFS);
14097+ if (br->br_fhsm)
14098+ au_br_fhsm_init(br->br_fhsm);
14099+ else
14100+ err = -ENOMEM;
14101+
14102+ return err;
14103+}
14104+
14105+/* ---------------------------------------------------------------------- */
14106+
14107+void au_fhsm_fin(struct super_block *sb)
14108+{
14109+ au_fhsm_notify(sb, /*val*/-1);
14110+}
14111+
14112+void au_fhsm_init(struct au_sbinfo *sbinfo)
14113+{
14114+ struct au_fhsm *fhsm;
14115+
14116+ fhsm = &sbinfo->si_fhsm;
14117+ spin_lock_init(&fhsm->fhsm_spin);
14118+ init_waitqueue_head(&fhsm->fhsm_wqh);
14119+ atomic_set(&fhsm->fhsm_readable, 0);
14120+ fhsm->fhsm_expire
14121+ = msecs_to_jiffies(AUFS_FHSM_CACHE_DEF_SEC * MSEC_PER_SEC);
14122+ fhsm->fhsm_bottom = -1;
14123+}
14124+
14125+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec)
14126+{
14127+ sbinfo->si_fhsm.fhsm_expire
14128+ = msecs_to_jiffies(sec * MSEC_PER_SEC);
14129+}
14130+
14131+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo)
14132+{
14133+ unsigned int u;
14134+
14135+ if (!au_ftest_si(sbinfo, FHSM))
14136+ return;
14137+
14138+ u = jiffies_to_msecs(sbinfo->si_fhsm.fhsm_expire) / MSEC_PER_SEC;
14139+ if (u != AUFS_FHSM_CACHE_DEF_SEC)
14140+ seq_printf(seq, ",fhsm_sec=%u", u);
14141+}
14142diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
14143--- /usr/share/empty/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
14144+++ linux/fs/aufs/file.c 2020-01-27 10:57:18.172204883 +0100
14145@@ -0,0 +1,863 @@
14146+// SPDX-License-Identifier: GPL-2.0
14147+/*
14148+ * Copyright (C) 2005-2020 Junjiro R. Okajima
14149+ *
14150+ * This program, aufs is free software; you can redistribute it and/or modify
14151+ * it under the terms of the GNU General Public License as published by
14152+ * the Free Software Foundation; either version 2 of the License, or
14153+ * (at your option) any later version.
14154+ *
14155+ * This program is distributed in the hope that it will be useful,
14156+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14157+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14158+ * GNU General Public License for more details.
14159+ *
14160+ * You should have received a copy of the GNU General Public License
14161+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
14162+ */
14163+
14164+/*
14165+ * handling file/dir, and address_space operation
14166+ */
14167+
14168+#ifdef CONFIG_AUFS_DEBUG
14169+#include <linux/migrate.h>
14170+#endif
14171+#include <linux/pagemap.h>
14172+#include "aufs.h"
14173+
14174+/* drop flags for writing */
14175+unsigned int au_file_roflags(unsigned int flags)
14176+{
14177+ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
14178+ flags |= O_RDONLY | O_NOATIME;
14179+ return flags;
14180+}
14181+
14182+/* common functions to regular file and dir */
14183+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
14184+ struct file *file, int force_wr)
14185+{
14186+ struct file *h_file;
14187+ struct dentry *h_dentry;
14188+ struct inode *h_inode;
14189+ struct super_block *sb;
14190+ struct au_branch *br;
14191+ struct path h_path;
14192+ int err;
14193+
14194+ /* a race condition can happen between open and unlink/rmdir */
14195+ h_file = ERR_PTR(-ENOENT);
14196+ h_dentry = au_h_dptr(dentry, bindex);
14197+ if (au_test_nfsd() && (!h_dentry || d_is_negative(h_dentry)))
14198+ goto out;
14199+ h_inode = d_inode(h_dentry);
14200+ spin_lock(&h_dentry->d_lock);
14201+ err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
14202+ /* || !d_inode(dentry)->i_nlink */
14203+ ;
14204+ spin_unlock(&h_dentry->d_lock);
14205+ if (unlikely(err))
14206+ goto out;
14207+
14208+ sb = dentry->d_sb;
14209+ br = au_sbr(sb, bindex);
14210+ err = au_br_test_oflag(flags, br);
14211+ h_file = ERR_PTR(err);
14212+ if (unlikely(err))
14213+ goto out;
14214+
14215+ /* drop flags for writing */
14216+ if (au_test_ro(sb, bindex, d_inode(dentry))) {
14217+ if (force_wr && !(flags & O_WRONLY))
14218+ force_wr = 0;
14219+ flags = au_file_roflags(flags);
14220+ if (force_wr) {
14221+ h_file = ERR_PTR(-EROFS);
14222+ flags = au_file_roflags(flags);
14223+ if (unlikely(vfsub_native_ro(h_inode)
14224+ || IS_APPEND(h_inode)))
14225+ goto out;
14226+ flags &= ~O_ACCMODE;
14227+ flags |= O_WRONLY;
14228+ }
14229+ }
14230+ flags &= ~O_CREAT;
14231+ au_lcnt_inc(&br->br_nfiles);
14232+ h_path.dentry = h_dentry;
14233+ h_path.mnt = au_br_mnt(br);
14234+ h_file = vfsub_dentry_open(&h_path, flags);
14235+ if (IS_ERR(h_file))
14236+ goto out_br;
14237+
14238+ if (flags & __FMODE_EXEC) {
14239+ err = deny_write_access(h_file);
14240+ if (unlikely(err)) {
14241+ fput(h_file);
14242+ h_file = ERR_PTR(err);
14243+ goto out_br;
14244+ }
14245+ }
14246+ fsnotify_open(h_file);
14247+ goto out; /* success */
14248+
14249+out_br:
14250+ au_lcnt_dec(&br->br_nfiles);
14251+out:
14252+ return h_file;
14253+}
14254+
14255+static int au_cmoo(struct dentry *dentry)
14256+{
14257+ int err, cmoo, matched;
14258+ unsigned int udba;
14259+ struct path h_path;
14260+ struct au_pin pin;
14261+ struct au_cp_generic cpg = {
14262+ .dentry = dentry,
14263+ .bdst = -1,
14264+ .bsrc = -1,
14265+ .len = -1,
14266+ .pin = &pin,
14267+ .flags = AuCpup_DTIME | AuCpup_HOPEN
14268+ };
14269+ struct inode *delegated;
14270+ struct super_block *sb;
14271+ struct au_sbinfo *sbinfo;
14272+ struct au_fhsm *fhsm;
14273+ pid_t pid;
14274+ struct au_branch *br;
14275+ struct dentry *parent;
14276+ struct au_hinode *hdir;
14277+
14278+ DiMustWriteLock(dentry);
14279+ IiMustWriteLock(d_inode(dentry));
14280+
14281+ err = 0;
14282+ if (IS_ROOT(dentry))
14283+ goto out;
14284+ cpg.bsrc = au_dbtop(dentry);
14285+ if (!cpg.bsrc)
14286+ goto out;
14287+
14288+ sb = dentry->d_sb;
14289+ sbinfo = au_sbi(sb);
14290+ fhsm = &sbinfo->si_fhsm;
14291+ pid = au_fhsm_pid(fhsm);
14292+ rcu_read_lock();
14293+ matched = (pid
14294+ && (current->pid == pid
14295+ || rcu_dereference(current->real_parent)->pid == pid));
14296+ rcu_read_unlock();
14297+ if (matched)
14298+ goto out;
14299+
14300+ br = au_sbr(sb, cpg.bsrc);
14301+ cmoo = au_br_cmoo(br->br_perm);
14302+ if (!cmoo)
14303+ goto out;
14304+ if (!d_is_reg(dentry))
14305+ cmoo &= AuBrAttr_COO_ALL;
14306+ if (!cmoo)
14307+ goto out;
14308+
14309+ parent = dget_parent(dentry);
14310+ di_write_lock_parent(parent);
14311+ err = au_wbr_do_copyup_bu(dentry, cpg.bsrc - 1);
14312+ cpg.bdst = err;
14313+ if (unlikely(err < 0)) {
14314+ err = 0; /* there is no upper writable branch */
14315+ goto out_dgrade;
14316+ }
14317+ AuDbg("bsrc %d, bdst %d\n", cpg.bsrc, cpg.bdst);
14318+
14319+ /* do not respect the coo attrib for the target branch */
14320+ err = au_cpup_dirs(dentry, cpg.bdst);
14321+ if (unlikely(err))
14322+ goto out_dgrade;
14323+
14324+ di_downgrade_lock(parent, AuLock_IR);
14325+ udba = au_opt_udba(sb);
14326+ err = au_pin(&pin, dentry, cpg.bdst, udba,
14327+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
14328+ if (unlikely(err))
14329+ goto out_parent;
14330+
14331+ err = au_sio_cpup_simple(&cpg);
14332+ au_unpin(&pin);
14333+ if (unlikely(err))
14334+ goto out_parent;
14335+ if (!(cmoo & AuBrWAttr_MOO))
14336+ goto out_parent; /* success */
14337+
14338+ err = au_pin(&pin, dentry, cpg.bsrc, udba,
14339+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
14340+ if (unlikely(err))
14341+ goto out_parent;
14342+
14343+ h_path.mnt = au_br_mnt(br);
14344+ h_path.dentry = au_h_dptr(dentry, cpg.bsrc);
14345+ hdir = au_hi(d_inode(parent), cpg.bsrc);
14346+ delegated = NULL;
14347+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, /*force*/1);
14348+ au_unpin(&pin);
14349+ /* todo: keep h_dentry or not? */
14350+ if (unlikely(err == -EWOULDBLOCK)) {
14351+ pr_warn("cannot retry for NFSv4 delegation"
14352+ " for an internal unlink\n");
14353+ iput(delegated);
14354+ }
14355+ if (unlikely(err)) {
14356+ pr_err("unlink %pd after coo failed (%d), ignored\n",
14357+ dentry, err);
14358+ err = 0;
14359+ }
14360+ goto out_parent; /* success */
14361+
14362+out_dgrade:
14363+ di_downgrade_lock(parent, AuLock_IR);
14364+out_parent:
14365+ di_read_unlock(parent, AuLock_IR);
14366+ dput(parent);
14367+out:
14368+ AuTraceErr(err);
14369+ return err;
14370+}
14371+
14372+int au_do_open(struct file *file, struct au_do_open_args *args)
14373+{
14374+ int err, aopen = args->aopen;
14375+ struct dentry *dentry;
14376+ struct au_finfo *finfo;
14377+
14378+ if (!aopen)
14379+ err = au_finfo_init(file, args->fidir);
14380+ else {
14381+ lockdep_off();
14382+ err = au_finfo_init(file, args->fidir);
14383+ lockdep_on();
14384+ }
14385+ if (unlikely(err))
14386+ goto out;
14387+
14388+ dentry = file->f_path.dentry;
14389+ AuDebugOn(IS_ERR_OR_NULL(dentry));
14390+ di_write_lock_child(dentry);
14391+ err = au_cmoo(dentry);
14392+ di_downgrade_lock(dentry, AuLock_IR);
14393+ if (!err) {
14394+ if (!aopen)
14395+ err = args->open(file, vfsub_file_flags(file), NULL);
14396+ else {
14397+ lockdep_off();
14398+ err = args->open(file, vfsub_file_flags(file),
14399+ args->h_file);
14400+ lockdep_on();
14401+ }
14402+ }
14403+ di_read_unlock(dentry, AuLock_IR);
14404+
14405+ finfo = au_fi(file);
14406+ if (!err) {
14407+ finfo->fi_file = file;
14408+ au_hbl_add(&finfo->fi_hlist,
14409+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
14410+ }
14411+ if (!aopen)
14412+ fi_write_unlock(file);
14413+ else {
14414+ lockdep_off();
14415+ fi_write_unlock(file);
14416+ lockdep_on();
14417+ }
14418+ if (unlikely(err)) {
14419+ finfo->fi_hdir = NULL;
14420+ au_finfo_fin(file);
14421+ }
14422+
14423+out:
14424+ AuTraceErr(err);
14425+ return err;
14426+}
14427+
14428+int au_reopen_nondir(struct file *file)
14429+{
14430+ int err;
14431+ aufs_bindex_t btop;
14432+ struct dentry *dentry;
14433+ struct au_branch *br;
14434+ struct file *h_file, *h_file_tmp;
14435+
14436+ dentry = file->f_path.dentry;
14437+ btop = au_dbtop(dentry);
14438+ br = au_sbr(dentry->d_sb, btop);
14439+ h_file_tmp = NULL;
14440+ if (au_fbtop(file) == btop) {
14441+ h_file = au_hf_top(file);
14442+ if (file->f_mode == h_file->f_mode)
14443+ return 0; /* success */
14444+ h_file_tmp = h_file;
14445+ get_file(h_file_tmp);
14446+ au_lcnt_inc(&br->br_nfiles);
14447+ au_set_h_fptr(file, btop, NULL);
14448+ }
14449+ AuDebugOn(au_fi(file)->fi_hdir);
14450+ /*
14451+ * it can happen
14452+ * file exists on both of rw and ro
14453+ * open --> dbtop and fbtop are both 0
14454+ * prepend a branch as rw, "rw" become ro
14455+ * remove rw/file
14456+ * delete the top branch, "rw" becomes rw again
14457+ * --> dbtop is 1, fbtop is still 0
14458+ * write --> fbtop is 0 but dbtop is 1
14459+ */
14460+ /* AuDebugOn(au_fbtop(file) < btop); */
14461+
14462+ h_file = au_h_open(dentry, btop, vfsub_file_flags(file) & ~O_TRUNC,
14463+ file, /*force_wr*/0);
14464+ err = PTR_ERR(h_file);
14465+ if (IS_ERR(h_file)) {
14466+ if (h_file_tmp) {
14467+ /* revert */
14468+ au_set_h_fptr(file, btop, h_file_tmp);
14469+ h_file_tmp = NULL;
14470+ }
14471+ goto out; /* todo: close all? */
14472+ }
14473+
14474+ err = 0;
14475+ au_set_fbtop(file, btop);
14476+ au_set_h_fptr(file, btop, h_file);
14477+ au_update_figen(file);
14478+ /* todo: necessary? */
14479+ /* file->f_ra = h_file->f_ra; */
14480+
14481+out:
14482+ if (h_file_tmp) {
14483+ fput(h_file_tmp);
14484+ au_lcnt_dec(&br->br_nfiles);
14485+ }
14486+ return err;
14487+}
14488+
14489+/* ---------------------------------------------------------------------- */
14490+
14491+static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
14492+ struct dentry *hi_wh)
14493+{
14494+ int err;
14495+ aufs_bindex_t btop;
14496+ struct au_dinfo *dinfo;
14497+ struct dentry *h_dentry;
14498+ struct au_hdentry *hdp;
14499+
14500+ dinfo = au_di(file->f_path.dentry);
14501+ AuRwMustWriteLock(&dinfo->di_rwsem);
14502+
14503+ btop = dinfo->di_btop;
14504+ dinfo->di_btop = btgt;
14505+ hdp = au_hdentry(dinfo, btgt);
14506+ h_dentry = hdp->hd_dentry;
14507+ hdp->hd_dentry = hi_wh;
14508+ err = au_reopen_nondir(file);
14509+ hdp->hd_dentry = h_dentry;
14510+ dinfo->di_btop = btop;
14511+
14512+ return err;
14513+}
14514+
14515+static int au_ready_to_write_wh(struct file *file, loff_t len,
14516+ aufs_bindex_t bcpup, struct au_pin *pin)
14517+{
14518+ int err;
14519+ struct inode *inode, *h_inode;
14520+ struct dentry *h_dentry, *hi_wh;
14521+ struct au_cp_generic cpg = {
14522+ .dentry = file->f_path.dentry,
14523+ .bdst = bcpup,
14524+ .bsrc = -1,
14525+ .len = len,
14526+ .pin = pin
14527+ };
14528+
14529+ au_update_dbtop(cpg.dentry);
14530+ inode = d_inode(cpg.dentry);
14531+ h_inode = NULL;
14532+ if (au_dbtop(cpg.dentry) <= bcpup
14533+ && au_dbbot(cpg.dentry) >= bcpup) {
14534+ h_dentry = au_h_dptr(cpg.dentry, bcpup);
14535+ if (h_dentry && d_is_positive(h_dentry))
14536+ h_inode = d_inode(h_dentry);
14537+ }
14538+ hi_wh = au_hi_wh(inode, bcpup);
14539+ if (!hi_wh && !h_inode)
14540+ err = au_sio_cpup_wh(&cpg, file);
14541+ else
14542+ /* already copied-up after unlink */
14543+ err = au_reopen_wh(file, bcpup, hi_wh);
14544+
14545+ if (!err
14546+ && (inode->i_nlink > 1
14547+ || (inode->i_state & I_LINKABLE))
14548+ && au_opt_test(au_mntflags(cpg.dentry->d_sb), PLINK))
14549+ au_plink_append(inode, bcpup, au_h_dptr(cpg.dentry, bcpup));
14550+
14551+ return err;
14552+}
14553+
14554+/*
14555+ * prepare the @file for writing.
14556+ */
14557+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
14558+{
14559+ int err;
14560+ aufs_bindex_t dbtop;
14561+ struct dentry *parent;
14562+ struct inode *inode;
14563+ struct super_block *sb;
14564+ struct file *h_file;
14565+ struct au_cp_generic cpg = {
14566+ .dentry = file->f_path.dentry,
14567+ .bdst = -1,
14568+ .bsrc = -1,
14569+ .len = len,
14570+ .pin = pin,
14571+ .flags = AuCpup_DTIME
14572+ };
14573+
14574+ sb = cpg.dentry->d_sb;
14575+ inode = d_inode(cpg.dentry);
14576+ cpg.bsrc = au_fbtop(file);
14577+ err = au_test_ro(sb, cpg.bsrc, inode);
14578+ if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
14579+ err = au_pin(pin, cpg.dentry, cpg.bsrc, AuOpt_UDBA_NONE,
14580+ /*flags*/0);
14581+ goto out;
14582+ }
14583+
14584+ /* need to cpup or reopen */
14585+ parent = dget_parent(cpg.dentry);
14586+ di_write_lock_parent(parent);
14587+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
14588+ cpg.bdst = err;
14589+ if (unlikely(err < 0))
14590+ goto out_dgrade;
14591+ err = 0;
14592+
14593+ if (!d_unhashed(cpg.dentry) && !au_h_dptr(parent, cpg.bdst)) {
14594+ err = au_cpup_dirs(cpg.dentry, cpg.bdst);
14595+ if (unlikely(err))
14596+ goto out_dgrade;
14597+ }
14598+
14599+ err = au_pin(pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
14600+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
14601+ if (unlikely(err))
14602+ goto out_dgrade;
14603+
14604+ dbtop = au_dbtop(cpg.dentry);
14605+ if (dbtop <= cpg.bdst)
14606+ cpg.bsrc = cpg.bdst;
14607+
14608+ if (dbtop <= cpg.bdst /* just reopen */
14609+ || !d_unhashed(cpg.dentry) /* copyup and reopen */
14610+ ) {
14611+ h_file = au_h_open_pre(cpg.dentry, cpg.bsrc, /*force_wr*/0);
14612+ if (IS_ERR(h_file))
14613+ err = PTR_ERR(h_file);
14614+ else {
14615+ di_downgrade_lock(parent, AuLock_IR);
14616+ if (dbtop > cpg.bdst)
14617+ err = au_sio_cpup_simple(&cpg);
14618+ if (!err)
14619+ err = au_reopen_nondir(file);
14620+ au_h_open_post(cpg.dentry, cpg.bsrc, h_file);
14621+ }
14622+ } else { /* copyup as wh and reopen */
14623+ /*
14624+ * since writable hfsplus branch is not supported,
14625+ * h_open_pre/post() are unnecessary.
14626+ */
14627+ err = au_ready_to_write_wh(file, len, cpg.bdst, pin);
14628+ di_downgrade_lock(parent, AuLock_IR);
14629+ }
14630+
14631+ if (!err) {
14632+ au_pin_set_parent_lflag(pin, /*lflag*/0);
14633+ goto out_dput; /* success */
14634+ }
14635+ au_unpin(pin);
14636+ goto out_unlock;
14637+
14638+out_dgrade:
14639+ di_downgrade_lock(parent, AuLock_IR);
14640+out_unlock:
14641+ di_read_unlock(parent, AuLock_IR);
14642+out_dput:
14643+ dput(parent);
14644+out:
14645+ return err;
14646+}
14647+
14648+/* ---------------------------------------------------------------------- */
14649+
14650+int au_do_flush(struct file *file, fl_owner_t id,
14651+ int (*flush)(struct file *file, fl_owner_t id))
14652+{
14653+ int err;
14654+ struct super_block *sb;
14655+ struct inode *inode;
14656+
14657+ inode = file_inode(file);
14658+ sb = inode->i_sb;
14659+ si_noflush_read_lock(sb);
14660+ fi_read_lock(file);
14661+ ii_read_lock_child(inode);
14662+
14663+ err = flush(file, id);
14664+ au_cpup_attr_timesizes(inode);
14665+
14666+ ii_read_unlock(inode);
14667+ fi_read_unlock(file);
14668+ si_read_unlock(sb);
14669+ return err;
14670+}
14671+
14672+/* ---------------------------------------------------------------------- */
14673+
14674+static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
14675+{
14676+ int err;
14677+ struct au_pin pin;
14678+ struct au_finfo *finfo;
14679+ struct dentry *parent, *hi_wh;
14680+ struct inode *inode;
14681+ struct super_block *sb;
14682+ struct au_cp_generic cpg = {
14683+ .dentry = file->f_path.dentry,
14684+ .bdst = -1,
14685+ .bsrc = -1,
14686+ .len = -1,
14687+ .pin = &pin,
14688+ .flags = AuCpup_DTIME
14689+ };
14690+
14691+ FiMustWriteLock(file);
14692+
14693+ err = 0;
14694+ finfo = au_fi(file);
14695+ sb = cpg.dentry->d_sb;
14696+ inode = d_inode(cpg.dentry);
14697+ cpg.bdst = au_ibtop(inode);
14698+ if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry))
14699+ goto out;
14700+
14701+ parent = dget_parent(cpg.dentry);
14702+ if (au_test_ro(sb, cpg.bdst, inode)) {
14703+ di_read_lock_parent(parent, !AuLock_IR);
14704+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
14705+ cpg.bdst = err;
14706+ di_read_unlock(parent, !AuLock_IR);
14707+ if (unlikely(err < 0))
14708+ goto out_parent;
14709+ err = 0;
14710+ }
14711+
14712+ di_read_lock_parent(parent, AuLock_IR);
14713+ hi_wh = au_hi_wh(inode, cpg.bdst);
14714+ if (!S_ISDIR(inode->i_mode)
14715+ && au_opt_test(au_mntflags(sb), PLINK)
14716+ && au_plink_test(inode)
14717+ && !d_unhashed(cpg.dentry)
14718+ && cpg.bdst < au_dbtop(cpg.dentry)) {
14719+ err = au_test_and_cpup_dirs(cpg.dentry, cpg.bdst);
14720+ if (unlikely(err))
14721+ goto out_unlock;
14722+
14723+ /* always superio. */
14724+ err = au_pin(&pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
14725+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
14726+ if (!err) {
14727+ err = au_sio_cpup_simple(&cpg);
14728+ au_unpin(&pin);
14729+ }
14730+ } else if (hi_wh) {
14731+ /* already copied-up after unlink */
14732+ err = au_reopen_wh(file, cpg.bdst, hi_wh);
14733+ *need_reopen = 0;
14734+ }
14735+
14736+out_unlock:
14737+ di_read_unlock(parent, AuLock_IR);
14738+out_parent:
14739+ dput(parent);
14740+out:
14741+ return err;
14742+}
14743+
14744+static void au_do_refresh_dir(struct file *file)
14745+{
14746+ aufs_bindex_t bindex, bbot, new_bindex, brid;
14747+ struct au_hfile *p, tmp, *q;
14748+ struct au_finfo *finfo;
14749+ struct super_block *sb;
14750+ struct au_fidir *fidir;
14751+
14752+ FiMustWriteLock(file);
14753+
14754+ sb = file->f_path.dentry->d_sb;
14755+ finfo = au_fi(file);
14756+ fidir = finfo->fi_hdir;
14757+ AuDebugOn(!fidir);
14758+ p = fidir->fd_hfile + finfo->fi_btop;
14759+ brid = p->hf_br->br_id;
14760+ bbot = fidir->fd_bbot;
14761+ for (bindex = finfo->fi_btop; bindex <= bbot; bindex++, p++) {
14762+ if (!p->hf_file)
14763+ continue;
14764+
14765+ new_bindex = au_br_index(sb, p->hf_br->br_id);
14766+ if (new_bindex == bindex)
14767+ continue;
14768+ if (new_bindex < 0) {
14769+ au_set_h_fptr(file, bindex, NULL);
14770+ continue;
14771+ }
14772+
14773+ /* swap two lower inode, and loop again */
14774+ q = fidir->fd_hfile + new_bindex;
14775+ tmp = *q;
14776+ *q = *p;
14777+ *p = tmp;
14778+ if (tmp.hf_file) {
14779+ bindex--;
14780+ p--;
14781+ }
14782+ }
14783+
14784+ p = fidir->fd_hfile;
14785+ if (!au_test_mmapped(file) && !d_unlinked(file->f_path.dentry)) {
14786+ bbot = au_sbbot(sb);
14787+ for (finfo->fi_btop = 0; finfo->fi_btop <= bbot;
14788+ finfo->fi_btop++, p++)
14789+ if (p->hf_file) {
14790+ if (file_inode(p->hf_file))
14791+ break;
14792+ au_hfput(p, /*execed*/0);
14793+ }
14794+ } else {
14795+ bbot = au_br_index(sb, brid);
14796+ for (finfo->fi_btop = 0; finfo->fi_btop < bbot;
14797+ finfo->fi_btop++, p++)
14798+ if (p->hf_file)
14799+ au_hfput(p, /*execed*/0);
14800+ bbot = au_sbbot(sb);
14801+ }
14802+
14803+ p = fidir->fd_hfile + bbot;
14804+ for (fidir->fd_bbot = bbot; fidir->fd_bbot >= finfo->fi_btop;
14805+ fidir->fd_bbot--, p--)
14806+ if (p->hf_file) {
14807+ if (file_inode(p->hf_file))
14808+ break;
14809+ au_hfput(p, /*execed*/0);
14810+ }
14811+ AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
14812+}
14813+
14814+/*
14815+ * after branch manipulating, refresh the file.
14816+ */
14817+static int refresh_file(struct file *file, int (*reopen)(struct file *file))
14818+{
14819+ int err, need_reopen, nbr;
14820+ aufs_bindex_t bbot, bindex;
14821+ struct dentry *dentry;
14822+ struct super_block *sb;
14823+ struct au_finfo *finfo;
14824+ struct au_hfile *hfile;
14825+
14826+ dentry = file->f_path.dentry;
14827+ sb = dentry->d_sb;
14828+ nbr = au_sbbot(sb) + 1;
14829+ finfo = au_fi(file);
14830+ if (!finfo->fi_hdir) {
14831+ hfile = &finfo->fi_htop;
14832+ AuDebugOn(!hfile->hf_file);
14833+ bindex = au_br_index(sb, hfile->hf_br->br_id);
14834+ AuDebugOn(bindex < 0);
14835+ if (bindex != finfo->fi_btop)
14836+ au_set_fbtop(file, bindex);
14837+ } else {
14838+ err = au_fidir_realloc(finfo, nbr, /*may_shrink*/0);
14839+ if (unlikely(err))
14840+ goto out;
14841+ au_do_refresh_dir(file);
14842+ }
14843+
14844+ err = 0;
14845+ need_reopen = 1;
14846+ if (!au_test_mmapped(file))
14847+ err = au_file_refresh_by_inode(file, &need_reopen);
14848+ if (finfo->fi_hdir)
14849+ /* harmless if err */
14850+ au_fidir_realloc(finfo, nbr, /*may_shrink*/1);
14851+ if (!err && need_reopen && !d_unlinked(dentry))
14852+ err = reopen(file);
14853+ if (!err) {
14854+ au_update_figen(file);
14855+ goto out; /* success */
14856+ }
14857+
14858+ /* error, close all lower files */
14859+ if (finfo->fi_hdir) {
14860+ bbot = au_fbbot_dir(file);
14861+ for (bindex = au_fbtop(file); bindex <= bbot; bindex++)
14862+ au_set_h_fptr(file, bindex, NULL);
14863+ }
14864+
14865+out:
14866+ return err;
14867+}
14868+
14869+/* common function to regular file and dir */
14870+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
14871+ int wlock, unsigned int fi_lsc)
14872+{
14873+ int err;
14874+ unsigned int sigen, figen;
14875+ aufs_bindex_t btop;
14876+ unsigned char pseudo_link;
14877+ struct dentry *dentry;
14878+ struct inode *inode;
14879+
14880+ err = 0;
14881+ dentry = file->f_path.dentry;
14882+ inode = d_inode(dentry);
14883+ sigen = au_sigen(dentry->d_sb);
14884+ fi_write_lock_nested(file, fi_lsc);
14885+ figen = au_figen(file);
14886+ if (!fi_lsc)
14887+ di_write_lock_child(dentry);
14888+ else
14889+ di_write_lock_child2(dentry);
14890+ btop = au_dbtop(dentry);
14891+ pseudo_link = (btop != au_ibtop(inode));
14892+ if (sigen == figen && !pseudo_link && au_fbtop(file) == btop) {
14893+ if (!wlock) {
14894+ di_downgrade_lock(dentry, AuLock_IR);
14895+ fi_downgrade_lock(file);
14896+ }
14897+ goto out; /* success */
14898+ }
14899+
14900+ AuDbg("sigen %d, figen %d\n", sigen, figen);
14901+ if (au_digen_test(dentry, sigen)) {
14902+ err = au_reval_dpath(dentry, sigen);
14903+ AuDebugOn(!err && au_digen_test(dentry, sigen));
14904+ }
14905+
14906+ if (!err)
14907+ err = refresh_file(file, reopen);
14908+ if (!err) {
14909+ if (!wlock) {
14910+ di_downgrade_lock(dentry, AuLock_IR);
14911+ fi_downgrade_lock(file);
14912+ }
14913+ } else {
14914+ di_write_unlock(dentry);
14915+ fi_write_unlock(file);
14916+ }
14917+
14918+out:
14919+ return err;
14920+}
14921+
14922+/* ---------------------------------------------------------------------- */
14923+
14924+/* cf. aufs_nopage() */
14925+/* for madvise(2) */
14926+static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
14927+{
14928+ unlock_page(page);
14929+ return 0;
14930+}
14931+
14932+/* it will never be called, but necessary to support O_DIRECT */
14933+static ssize_t aufs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
14934+{ BUG(); return 0; }
14935+
14936+/* they will never be called. */
14937+#ifdef CONFIG_AUFS_DEBUG
14938+static int aufs_write_begin(struct file *file, struct address_space *mapping,
14939+ loff_t pos, unsigned len, unsigned flags,
14940+ struct page **pagep, void **fsdata)
14941+{ AuUnsupport(); return 0; }
14942+static int aufs_write_end(struct file *file, struct address_space *mapping,
14943+ loff_t pos, unsigned len, unsigned copied,
14944+ struct page *page, void *fsdata)
14945+{ AuUnsupport(); return 0; }
14946+static int aufs_writepage(struct page *page, struct writeback_control *wbc)
14947+{ AuUnsupport(); return 0; }
14948+
14949+static int aufs_set_page_dirty(struct page *page)
14950+{ AuUnsupport(); return 0; }
14951+static void aufs_invalidatepage(struct page *page, unsigned int offset,
14952+ unsigned int length)
14953+{ AuUnsupport(); }
14954+static int aufs_releasepage(struct page *page, gfp_t gfp)
14955+{ AuUnsupport(); return 0; }
14956+#if 0 /* called by memory compaction regardless file */
14957+static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
14958+ struct page *page, enum migrate_mode mode)
14959+{ AuUnsupport(); return 0; }
14960+#endif
14961+static bool aufs_isolate_page(struct page *page, isolate_mode_t mode)
14962+{ AuUnsupport(); return true; }
14963+static void aufs_putback_page(struct page *page)
14964+{ AuUnsupport(); }
14965+static int aufs_launder_page(struct page *page)
14966+{ AuUnsupport(); return 0; }
14967+static int aufs_is_partially_uptodate(struct page *page,
14968+ unsigned long from,
14969+ unsigned long count)
14970+{ AuUnsupport(); return 0; }
14971+static void aufs_is_dirty_writeback(struct page *page, bool *dirty,
14972+ bool *writeback)
14973+{ AuUnsupport(); }
14974+static int aufs_error_remove_page(struct address_space *mapping,
14975+ struct page *page)
14976+{ AuUnsupport(); return 0; }
14977+static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file,
14978+ sector_t *span)
14979+{ AuUnsupport(); return 0; }
14980+static void aufs_swap_deactivate(struct file *file)
14981+{ AuUnsupport(); }
14982+#endif /* CONFIG_AUFS_DEBUG */
14983+
14984+const struct address_space_operations aufs_aop = {
14985+ .readpage = aufs_readpage,
14986+ .direct_IO = aufs_direct_IO,
14987+#ifdef CONFIG_AUFS_DEBUG
14988+ .writepage = aufs_writepage,
14989+ /* no writepages, because of writepage */
14990+ .set_page_dirty = aufs_set_page_dirty,
14991+ /* no readpages, because of readpage */
14992+ .write_begin = aufs_write_begin,
14993+ .write_end = aufs_write_end,
14994+ /* no bmap, no block device */
14995+ .invalidatepage = aufs_invalidatepage,
14996+ .releasepage = aufs_releasepage,
14997+ /* is fallback_migrate_page ok? */
14998+ /* .migratepage = aufs_migratepage, */
14999+ .isolate_page = aufs_isolate_page,
15000+ .putback_page = aufs_putback_page,
15001+ .launder_page = aufs_launder_page,
15002+ .is_partially_uptodate = aufs_is_partially_uptodate,
15003+ .is_dirty_writeback = aufs_is_dirty_writeback,
15004+ .error_remove_page = aufs_error_remove_page,
15005+ .swap_activate = aufs_swap_activate,
15006+ .swap_deactivate = aufs_swap_deactivate
15007+#endif /* CONFIG_AUFS_DEBUG */
15008+};
15009diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
15010--- /usr/share/empty/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100
15011+++ linux/fs/aufs/file.h 2020-01-27 10:57:18.172204883 +0100
15012@@ -0,0 +1,342 @@
15013+/* SPDX-License-Identifier: GPL-2.0 */
15014+/*
15015+ * Copyright (C) 2005-2020 Junjiro R. Okajima
15016+ *
15017+ * This program, aufs is free software; you can redistribute it and/or modify
15018+ * it under the terms of the GNU General Public License as published by
15019+ * the Free Software Foundation; either version 2 of the License, or
15020+ * (at your option) any later version.
15021+ *
15022+ * This program is distributed in the hope that it will be useful,
15023+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15024+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15025+ * GNU General Public License for more details.
15026+ *
15027+ * You should have received a copy of the GNU General Public License
15028+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15029+ */
15030+
15031+/*
15032+ * file operations
15033+ */
15034+
15035+#ifndef __AUFS_FILE_H__
15036+#define __AUFS_FILE_H__
15037+
15038+#ifdef __KERNEL__
15039+
15040+#include <linux/file.h>
15041+#include <linux/fs.h>
15042+#include <linux/mm_types.h>
15043+#include <linux/poll.h>
15044+#include "rwsem.h"
15045+
15046+struct au_branch;
15047+struct au_hfile {
15048+ struct file *hf_file;
15049+ struct au_branch *hf_br;
15050+};
15051+
15052+struct au_vdir;
15053+struct au_fidir {
15054+ aufs_bindex_t fd_bbot;
15055+ aufs_bindex_t fd_nent;
15056+ struct au_vdir *fd_vdir_cache;
15057+ struct au_hfile fd_hfile[];
15058+};
15059+
15060+static inline int au_fidir_sz(int nent)
15061+{
15062+ AuDebugOn(nent < 0);
15063+ return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
15064+}
15065+
15066+struct au_finfo {
15067+ atomic_t fi_generation;
15068+
15069+ struct au_rwsem fi_rwsem;
15070+ aufs_bindex_t fi_btop;
15071+
15072+ /* do not union them */
15073+ struct { /* for non-dir */
15074+ struct au_hfile fi_htop;
15075+ atomic_t fi_mmapped;
15076+ };
15077+ struct au_fidir *fi_hdir; /* for dir only */
15078+
15079+ struct hlist_bl_node fi_hlist;
15080+ struct file *fi_file; /* very ugly */
15081+ struct rcu_head rcu;
15082+} ____cacheline_aligned_in_smp;
15083+
15084+/* ---------------------------------------------------------------------- */
15085+
15086+/* file.c */
15087+extern const struct address_space_operations aufs_aop;
15088+unsigned int au_file_roflags(unsigned int flags);
15089+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
15090+ struct file *file, int force_wr);
15091+struct au_do_open_args {
15092+ int aopen;
15093+ int (*open)(struct file *file, int flags,
15094+ struct file *h_file);
15095+ struct au_fidir *fidir;
15096+ struct file *h_file;
15097+};
15098+int au_do_open(struct file *file, struct au_do_open_args *args);
15099+int au_reopen_nondir(struct file *file);
15100+struct au_pin;
15101+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
15102+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
15103+ int wlock, unsigned int fi_lsc);
15104+int au_do_flush(struct file *file, fl_owner_t id,
15105+ int (*flush)(struct file *file, fl_owner_t id));
15106+
15107+/* poll.c */
15108+#ifdef CONFIG_AUFS_POLL
15109+__poll_t aufs_poll(struct file *file, struct poll_table_struct *pt);
15110+#endif
15111+
15112+#ifdef CONFIG_AUFS_BR_HFSPLUS
15113+/* hfsplus.c */
15114+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
15115+ int force_wr);
15116+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
15117+ struct file *h_file);
15118+#else
15119+AuStub(struct file *, au_h_open_pre, return NULL, struct dentry *dentry,
15120+ aufs_bindex_t bindex, int force_wr)
15121+AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
15122+ struct file *h_file);
15123+#endif
15124+
15125+/* f_op.c */
15126+extern const struct file_operations aufs_file_fop;
15127+int au_do_open_nondir(struct file *file, int flags, struct file *h_file);
15128+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
15129+struct file *au_read_pre(struct file *file, int keep_fi, unsigned int lsc);
15130+
15131+/* finfo.c */
15132+void au_hfput(struct au_hfile *hf, int execed);
15133+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
15134+ struct file *h_file);
15135+
15136+void au_update_figen(struct file *file);
15137+struct au_fidir *au_fidir_alloc(struct super_block *sb);
15138+int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink);
15139+
15140+void au_fi_init_once(void *_fi);
15141+void au_finfo_fin(struct file *file);
15142+int au_finfo_init(struct file *file, struct au_fidir *fidir);
15143+
15144+/* ioctl.c */
15145+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
15146+#ifdef CONFIG_COMPAT
15147+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
15148+ unsigned long arg);
15149+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
15150+ unsigned long arg);
15151+#endif
15152+
15153+/* ---------------------------------------------------------------------- */
15154+
15155+static inline struct au_finfo *au_fi(struct file *file)
15156+{
15157+ return file->private_data;
15158+}
15159+
15160+/* ---------------------------------------------------------------------- */
15161+
15162+#define fi_read_lock(f) au_rw_read_lock(&au_fi(f)->fi_rwsem)
15163+#define fi_write_lock(f) au_rw_write_lock(&au_fi(f)->fi_rwsem)
15164+#define fi_read_trylock(f) au_rw_read_trylock(&au_fi(f)->fi_rwsem)
15165+#define fi_write_trylock(f) au_rw_write_trylock(&au_fi(f)->fi_rwsem)
15166+/*
15167+#define fi_read_trylock_nested(f) \
15168+ au_rw_read_trylock_nested(&au_fi(f)->fi_rwsem)
15169+#define fi_write_trylock_nested(f) \
15170+ au_rw_write_trylock_nested(&au_fi(f)->fi_rwsem)
15171+*/
15172+
15173+#define fi_read_unlock(f) au_rw_read_unlock(&au_fi(f)->fi_rwsem)
15174+#define fi_write_unlock(f) au_rw_write_unlock(&au_fi(f)->fi_rwsem)
15175+#define fi_downgrade_lock(f) au_rw_dgrade_lock(&au_fi(f)->fi_rwsem)
15176+
15177+/* lock subclass for finfo */
15178+enum {
15179+ AuLsc_FI_1,
15180+ AuLsc_FI_2
15181+};
15182+
15183+static inline void fi_read_lock_nested(struct file *f, unsigned int lsc)
15184+{
15185+ au_rw_read_lock_nested(&au_fi(f)->fi_rwsem, lsc);
15186+}
15187+
15188+static inline void fi_write_lock_nested(struct file *f, unsigned int lsc)
15189+{
15190+ au_rw_write_lock_nested(&au_fi(f)->fi_rwsem, lsc);
15191+}
15192+
15193+/*
15194+ * fi_read_lock_1, fi_write_lock_1,
15195+ * fi_read_lock_2, fi_write_lock_2
15196+ */
15197+#define AuReadLockFunc(name) \
15198+static inline void fi_read_lock_##name(struct file *f) \
15199+{ fi_read_lock_nested(f, AuLsc_FI_##name); }
15200+
15201+#define AuWriteLockFunc(name) \
15202+static inline void fi_write_lock_##name(struct file *f) \
15203+{ fi_write_lock_nested(f, AuLsc_FI_##name); }
15204+
15205+#define AuRWLockFuncs(name) \
15206+ AuReadLockFunc(name) \
15207+ AuWriteLockFunc(name)
15208+
15209+AuRWLockFuncs(1);
15210+AuRWLockFuncs(2);
15211+
15212+#undef AuReadLockFunc
15213+#undef AuWriteLockFunc
15214+#undef AuRWLockFuncs
15215+
15216+#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
15217+#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
15218+#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
15219+
15220+/* ---------------------------------------------------------------------- */
15221+
15222+/* todo: hard/soft set? */
15223+static inline aufs_bindex_t au_fbtop(struct file *file)
15224+{
15225+ FiMustAnyLock(file);
15226+ return au_fi(file)->fi_btop;
15227+}
15228+
15229+static inline aufs_bindex_t au_fbbot_dir(struct file *file)
15230+{
15231+ FiMustAnyLock(file);
15232+ AuDebugOn(!au_fi(file)->fi_hdir);
15233+ return au_fi(file)->fi_hdir->fd_bbot;
15234+}
15235+
15236+static inline struct au_vdir *au_fvdir_cache(struct file *file)
15237+{
15238+ FiMustAnyLock(file);
15239+ AuDebugOn(!au_fi(file)->fi_hdir);
15240+ return au_fi(file)->fi_hdir->fd_vdir_cache;
15241+}
15242+
15243+static inline void au_set_fbtop(struct file *file, aufs_bindex_t bindex)
15244+{
15245+ FiMustWriteLock(file);
15246+ au_fi(file)->fi_btop = bindex;
15247+}
15248+
15249+static inline void au_set_fbbot_dir(struct file *file, aufs_bindex_t bindex)
15250+{
15251+ FiMustWriteLock(file);
15252+ AuDebugOn(!au_fi(file)->fi_hdir);
15253+ au_fi(file)->fi_hdir->fd_bbot = bindex;
15254+}
15255+
15256+static inline void au_set_fvdir_cache(struct file *file,
15257+ struct au_vdir *vdir_cache)
15258+{
15259+ FiMustWriteLock(file);
15260+ AuDebugOn(!au_fi(file)->fi_hdir);
15261+ au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
15262+}
15263+
15264+static inline struct file *au_hf_top(struct file *file)
15265+{
15266+ FiMustAnyLock(file);
15267+ AuDebugOn(au_fi(file)->fi_hdir);
15268+ return au_fi(file)->fi_htop.hf_file;
15269+}
15270+
15271+static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
15272+{
15273+ FiMustAnyLock(file);
15274+ AuDebugOn(!au_fi(file)->fi_hdir);
15275+ return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
15276+}
15277+
15278+/* todo: memory barrier? */
15279+static inline unsigned int au_figen(struct file *f)
15280+{
15281+ return atomic_read(&au_fi(f)->fi_generation);
15282+}
15283+
15284+static inline void au_set_mmapped(struct file *f)
15285+{
15286+ if (atomic_inc_return(&au_fi(f)->fi_mmapped))
15287+ return;
15288+ pr_warn("fi_mmapped wrapped around\n");
15289+ while (!atomic_inc_return(&au_fi(f)->fi_mmapped))
15290+ ;
15291+}
15292+
15293+static inline void au_unset_mmapped(struct file *f)
15294+{
15295+ atomic_dec(&au_fi(f)->fi_mmapped);
15296+}
15297+
15298+static inline int au_test_mmapped(struct file *f)
15299+{
15300+ return atomic_read(&au_fi(f)->fi_mmapped);
15301+}
15302+
15303+/* customize vma->vm_file */
15304+
15305+static inline void au_do_vm_file_reset(struct vm_area_struct *vma,
15306+ struct file *file)
15307+{
15308+ struct file *f;
15309+
15310+ f = vma->vm_file;
15311+ get_file(file);
15312+ vma->vm_file = file;
15313+ fput(f);
15314+}
15315+
15316+#ifdef CONFIG_MMU
15317+#define AuDbgVmRegion(file, vma) do {} while (0)
15318+
15319+static inline void au_vm_file_reset(struct vm_area_struct *vma,
15320+ struct file *file)
15321+{
15322+ au_do_vm_file_reset(vma, file);
15323+}
15324+#else
15325+#define AuDbgVmRegion(file, vma) \
15326+ AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
15327+
15328+static inline void au_vm_file_reset(struct vm_area_struct *vma,
15329+ struct file *file)
15330+{
15331+ struct file *f;
15332+
15333+ au_do_vm_file_reset(vma, file);
15334+ f = vma->vm_region->vm_file;
15335+ get_file(file);
15336+ vma->vm_region->vm_file = file;
15337+ fput(f);
15338+}
15339+#endif /* CONFIG_MMU */
15340+
15341+/* handle vma->vm_prfile */
15342+static inline void au_vm_prfile_set(struct vm_area_struct *vma,
15343+ struct file *file)
15344+{
15345+ get_file(file);
15346+ vma->vm_prfile = file;
15347+#ifndef CONFIG_MMU
15348+ get_file(file);
15349+ vma->vm_region->vm_prfile = file;
15350+#endif
15351+}
15352+
15353+#endif /* __KERNEL__ */
15354+#endif /* __AUFS_FILE_H__ */
15355diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
15356--- /usr/share/empty/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100
15357+++ linux/fs/aufs/finfo.c 2020-01-27 10:57:18.172204883 +0100
15358@@ -0,0 +1,149 @@
15359+// SPDX-License-Identifier: GPL-2.0
15360+/*
15361+ * Copyright (C) 2005-2020 Junjiro R. Okajima
15362+ *
15363+ * This program, aufs is free software; you can redistribute it and/or modify
15364+ * it under the terms of the GNU General Public License as published by
15365+ * the Free Software Foundation; either version 2 of the License, or
15366+ * (at your option) any later version.
15367+ *
15368+ * This program is distributed in the hope that it will be useful,
15369+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15370+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15371+ * GNU General Public License for more details.
15372+ *
15373+ * You should have received a copy of the GNU General Public License
15374+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15375+ */
15376+
15377+/*
15378+ * file private data
15379+ */
15380+
15381+#include "aufs.h"
15382+
15383+void au_hfput(struct au_hfile *hf, int execed)
15384+{
15385+ if (execed)
15386+ allow_write_access(hf->hf_file);
15387+ fput(hf->hf_file);
15388+ hf->hf_file = NULL;
15389+ au_lcnt_dec(&hf->hf_br->br_nfiles);
15390+ hf->hf_br = NULL;
15391+}
15392+
15393+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
15394+{
15395+ struct au_finfo *finfo = au_fi(file);
15396+ struct au_hfile *hf;
15397+ struct au_fidir *fidir;
15398+
15399+ fidir = finfo->fi_hdir;
15400+ if (!fidir) {
15401+ AuDebugOn(finfo->fi_btop != bindex);
15402+ hf = &finfo->fi_htop;
15403+ } else
15404+ hf = fidir->fd_hfile + bindex;
15405+
15406+ if (hf && hf->hf_file)
15407+ au_hfput(hf, vfsub_file_execed(file));
15408+ if (val) {
15409+ FiMustWriteLock(file);
15410+ AuDebugOn(IS_ERR_OR_NULL(file->f_path.dentry));
15411+ hf->hf_file = val;
15412+ hf->hf_br = au_sbr(file->f_path.dentry->d_sb, bindex);
15413+ }
15414+}
15415+
15416+void au_update_figen(struct file *file)
15417+{
15418+ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_path.dentry));
15419+ /* smp_mb(); */ /* atomic_set */
15420+}
15421+
15422+/* ---------------------------------------------------------------------- */
15423+
15424+struct au_fidir *au_fidir_alloc(struct super_block *sb)
15425+{
15426+ struct au_fidir *fidir;
15427+ int nbr;
15428+
15429+ nbr = au_sbbot(sb) + 1;
15430+ if (nbr < 2)
15431+ nbr = 2; /* initial allocate for 2 branches */
15432+ fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS);
15433+ if (fidir) {
15434+ fidir->fd_bbot = -1;
15435+ fidir->fd_nent = nbr;
15436+ }
15437+
15438+ return fidir;
15439+}
15440+
15441+int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink)
15442+{
15443+ int err;
15444+ struct au_fidir *fidir, *p;
15445+
15446+ AuRwMustWriteLock(&finfo->fi_rwsem);
15447+ fidir = finfo->fi_hdir;
15448+ AuDebugOn(!fidir);
15449+
15450+ err = -ENOMEM;
15451+ p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr),
15452+ GFP_NOFS, may_shrink);
15453+ if (p) {
15454+ p->fd_nent = nbr;
15455+ finfo->fi_hdir = p;
15456+ err = 0;
15457+ }
15458+
15459+ return err;
15460+}
15461+
15462+/* ---------------------------------------------------------------------- */
15463+
15464+void au_finfo_fin(struct file *file)
15465+{
15466+ struct au_finfo *finfo;
15467+
15468+ au_lcnt_dec(&au_sbi(file->f_path.dentry->d_sb)->si_nfiles);
15469+
15470+ finfo = au_fi(file);
15471+ AuDebugOn(finfo->fi_hdir);
15472+ AuRwDestroy(&finfo->fi_rwsem);
15473+ au_cache_free_finfo(finfo);
15474+}
15475+
15476+void au_fi_init_once(void *_finfo)
15477+{
15478+ struct au_finfo *finfo = _finfo;
15479+
15480+ au_rw_init(&finfo->fi_rwsem);
15481+}
15482+
15483+int au_finfo_init(struct file *file, struct au_fidir *fidir)
15484+{
15485+ int err;
15486+ struct au_finfo *finfo;
15487+ struct dentry *dentry;
15488+
15489+ err = -ENOMEM;
15490+ dentry = file->f_path.dentry;
15491+ finfo = au_cache_alloc_finfo();
15492+ if (unlikely(!finfo))
15493+ goto out;
15494+
15495+ err = 0;
15496+ au_lcnt_inc(&au_sbi(dentry->d_sb)->si_nfiles);
15497+ au_rw_write_lock(&finfo->fi_rwsem);
15498+ finfo->fi_btop = -1;
15499+ finfo->fi_hdir = fidir;
15500+ atomic_set(&finfo->fi_generation, au_digen(dentry));
15501+ /* smp_mb(); */ /* atomic_set */
15502+
15503+ file->private_data = finfo;
15504+
15505+out:
15506+ return err;
15507+}
15508diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
15509--- /usr/share/empty/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100
15510+++ linux/fs/aufs/f_op.c 2020-01-27 10:57:18.172204883 +0100
15511@@ -0,0 +1,819 @@
15512+// SPDX-License-Identifier: GPL-2.0
15513+/*
15514+ * Copyright (C) 2005-2020 Junjiro R. Okajima
15515+ *
15516+ * This program, aufs is free software; you can redistribute it and/or modify
15517+ * it under the terms of the GNU General Public License as published by
15518+ * the Free Software Foundation; either version 2 of the License, or
15519+ * (at your option) any later version.
15520+ *
15521+ * This program is distributed in the hope that it will be useful,
15522+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15523+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15524+ * GNU General Public License for more details.
15525+ *
15526+ * You should have received a copy of the GNU General Public License
15527+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15528+ */
15529+
15530+/*
15531+ * file and vm operations
15532+ */
15533+
15534+#include <linux/aio.h>
15535+#include <linux/fs_stack.h>
15536+#include <linux/mman.h>
15537+#include <linux/security.h>
15538+#include "aufs.h"
15539+
15540+int au_do_open_nondir(struct file *file, int flags, struct file *h_file)
15541+{
15542+ int err;
15543+ aufs_bindex_t bindex;
15544+ struct dentry *dentry, *h_dentry;
15545+ struct au_finfo *finfo;
15546+ struct inode *h_inode;
15547+
15548+ FiMustWriteLock(file);
15549+
15550+ err = 0;
15551+ dentry = file->f_path.dentry;
15552+ AuDebugOn(IS_ERR_OR_NULL(dentry));
15553+ finfo = au_fi(file);
15554+ memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
15555+ atomic_set(&finfo->fi_mmapped, 0);
15556+ bindex = au_dbtop(dentry);
15557+ if (!h_file) {
15558+ h_dentry = au_h_dptr(dentry, bindex);
15559+ err = vfsub_test_mntns(file->f_path.mnt, h_dentry->d_sb);
15560+ if (unlikely(err))
15561+ goto out;
15562+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
15563+ if (IS_ERR(h_file)) {
15564+ err = PTR_ERR(h_file);
15565+ goto out;
15566+ }
15567+ } else {
15568+ h_dentry = h_file->f_path.dentry;
15569+ err = vfsub_test_mntns(file->f_path.mnt, h_dentry->d_sb);
15570+ if (unlikely(err))
15571+ goto out;
15572+ /* br ref is already inc-ed */
15573+ }
15574+
15575+ if ((flags & __O_TMPFILE)
15576+ && !(flags & O_EXCL)) {
15577+ h_inode = file_inode(h_file);
15578+ spin_lock(&h_inode->i_lock);
15579+ h_inode->i_state |= I_LINKABLE;
15580+ spin_unlock(&h_inode->i_lock);
15581+ }
15582+ au_set_fbtop(file, bindex);
15583+ au_set_h_fptr(file, bindex, h_file);
15584+ au_update_figen(file);
15585+ /* todo: necessary? */
15586+ /* file->f_ra = h_file->f_ra; */
15587+
15588+out:
15589+ return err;
15590+}
15591+
15592+static int aufs_open_nondir(struct inode *inode __maybe_unused,
15593+ struct file *file)
15594+{
15595+ int err;
15596+ struct super_block *sb;
15597+ struct au_do_open_args args = {
15598+ .open = au_do_open_nondir
15599+ };
15600+
15601+ AuDbg("%pD, f_flags 0x%x, f_mode 0x%x\n",
15602+ file, vfsub_file_flags(file), file->f_mode);
15603+
15604+ sb = file->f_path.dentry->d_sb;
15605+ si_read_lock(sb, AuLock_FLUSH);
15606+ err = au_do_open(file, &args);
15607+ si_read_unlock(sb);
15608+ return err;
15609+}
15610+
15611+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
15612+{
15613+ struct au_finfo *finfo;
15614+ aufs_bindex_t bindex;
15615+
15616+ finfo = au_fi(file);
15617+ au_hbl_del(&finfo->fi_hlist,
15618+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
15619+ bindex = finfo->fi_btop;
15620+ if (bindex >= 0)
15621+ au_set_h_fptr(file, bindex, NULL);
15622+
15623+ au_finfo_fin(file);
15624+ return 0;
15625+}
15626+
15627+/* ---------------------------------------------------------------------- */
15628+
15629+static int au_do_flush_nondir(struct file *file, fl_owner_t id)
15630+{
15631+ int err;
15632+ struct file *h_file;
15633+
15634+ err = 0;
15635+ h_file = au_hf_top(file);
15636+ if (h_file)
15637+ err = vfsub_flush(h_file, id);
15638+ return err;
15639+}
15640+
15641+static int aufs_flush_nondir(struct file *file, fl_owner_t id)
15642+{
15643+ return au_do_flush(file, id, au_do_flush_nondir);
15644+}
15645+
15646+/* ---------------------------------------------------------------------- */
15647+/*
15648+ * read and write functions acquire [fdi]_rwsem once, but release before
15649+ * mmap_sem. This is because to stop a race condition between mmap(2).
15650+ * Releasing these aufs-rwsem should be safe, no branch-management (by keeping
15651+ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in
15652+ * read functions after [fdi]_rwsem are released, but it should be harmless.
15653+ */
15654+
15655+/* Callers should call au_read_post() or fput() in the end */
15656+struct file *au_read_pre(struct file *file, int keep_fi, unsigned int lsc)
15657+{
15658+ struct file *h_file;
15659+ int err;
15660+
15661+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0, lsc);
15662+ if (!err) {
15663+ di_read_unlock(file->f_path.dentry, AuLock_IR);
15664+ h_file = au_hf_top(file);
15665+ get_file(h_file);
15666+ if (!keep_fi)
15667+ fi_read_unlock(file);
15668+ } else
15669+ h_file = ERR_PTR(err);
15670+
15671+ return h_file;
15672+}
15673+
15674+static void au_read_post(struct inode *inode, struct file *h_file)
15675+{
15676+ /* update without lock, I don't think it a problem */
15677+ fsstack_copy_attr_atime(inode, file_inode(h_file));
15678+ fput(h_file);
15679+}
15680+
15681+struct au_write_pre {
15682+ /* input */
15683+ unsigned int lsc;
15684+
15685+ /* output */
15686+ blkcnt_t blks;
15687+ aufs_bindex_t btop;
15688+};
15689+
15690+/*
15691+ * return with iinfo is write-locked
15692+ * callers should call au_write_post() or iinfo_write_unlock() + fput() in the
15693+ * end
15694+ */
15695+static struct file *au_write_pre(struct file *file, int do_ready,
15696+ struct au_write_pre *wpre)
15697+{
15698+ struct file *h_file;
15699+ struct dentry *dentry;
15700+ int err;
15701+ unsigned int lsc;
15702+ struct au_pin pin;
15703+
15704+ lsc = 0;
15705+ if (wpre)
15706+ lsc = wpre->lsc;
15707+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1, lsc);
15708+ h_file = ERR_PTR(err);
15709+ if (unlikely(err))
15710+ goto out;
15711+
15712+ dentry = file->f_path.dentry;
15713+ if (do_ready) {
15714+ err = au_ready_to_write(file, -1, &pin);
15715+ if (unlikely(err)) {
15716+ h_file = ERR_PTR(err);
15717+ di_write_unlock(dentry);
15718+ goto out_fi;
15719+ }
15720+ }
15721+
15722+ di_downgrade_lock(dentry, /*flags*/0);
15723+ if (wpre)
15724+ wpre->btop = au_fbtop(file);
15725+ h_file = au_hf_top(file);
15726+ get_file(h_file);
15727+ if (wpre)
15728+ wpre->blks = file_inode(h_file)->i_blocks;
15729+ if (do_ready)
15730+ au_unpin(&pin);
15731+ di_read_unlock(dentry, /*flags*/0);
15732+
15733+out_fi:
15734+ fi_write_unlock(file);
15735+out:
15736+ return h_file;
15737+}
15738+
15739+static void au_write_post(struct inode *inode, struct file *h_file,
15740+ struct au_write_pre *wpre, ssize_t written)
15741+{
15742+ struct inode *h_inode;
15743+
15744+ au_cpup_attr_timesizes(inode);
15745+ AuDebugOn(au_ibtop(inode) != wpre->btop);
15746+ h_inode = file_inode(h_file);
15747+ inode->i_mode = h_inode->i_mode;
15748+ ii_write_unlock(inode);
15749+ /* AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks); */
15750+ if (written > 0)
15751+ au_fhsm_wrote(inode->i_sb, wpre->btop,
15752+ /*force*/h_inode->i_blocks > wpre->blks);
15753+ fput(h_file);
15754+}
15755+
15756+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
15757+ loff_t *ppos)
15758+{
15759+ ssize_t err;
15760+ struct inode *inode;
15761+ struct file *h_file;
15762+ struct super_block *sb;
15763+
15764+ inode = file_inode(file);
15765+ sb = inode->i_sb;
15766+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
15767+
15768+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
15769+ err = PTR_ERR(h_file);
15770+ if (IS_ERR(h_file))
15771+ goto out;
15772+
15773+ /* filedata may be obsoleted by concurrent copyup, but no problem */
15774+ err = vfsub_read_u(h_file, buf, count, ppos);
15775+ /* todo: necessary? */
15776+ /* file->f_ra = h_file->f_ra; */
15777+ au_read_post(inode, h_file);
15778+
15779+out:
15780+ si_read_unlock(sb);
15781+ return err;
15782+}
15783+
15784+/*
15785+ * todo: very ugly
15786+ * it locks both of i_mutex and si_rwsem for read in safe.
15787+ * if the plink maintenance mode continues forever (that is the problem),
15788+ * may loop forever.
15789+ */
15790+static void au_mtx_and_read_lock(struct inode *inode)
15791+{
15792+ int err;
15793+ struct super_block *sb = inode->i_sb;
15794+
15795+ while (1) {
15796+ inode_lock(inode);
15797+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
15798+ if (!err)
15799+ break;
15800+ inode_unlock(inode);
15801+ si_read_lock(sb, AuLock_NOPLMW);
15802+ si_read_unlock(sb);
15803+ }
15804+}
15805+
15806+static ssize_t aufs_write(struct file *file, const char __user *ubuf,
15807+ size_t count, loff_t *ppos)
15808+{
15809+ ssize_t err;
15810+ struct au_write_pre wpre;
15811+ struct inode *inode;
15812+ struct file *h_file;
15813+ char __user *buf = (char __user *)ubuf;
15814+
15815+ inode = file_inode(file);
15816+ au_mtx_and_read_lock(inode);
15817+
15818+ wpre.lsc = 0;
15819+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
15820+ err = PTR_ERR(h_file);
15821+ if (IS_ERR(h_file))
15822+ goto out;
15823+
15824+ err = vfsub_write_u(h_file, buf, count, ppos);
15825+ au_write_post(inode, h_file, &wpre, err);
15826+
15827+out:
15828+ si_read_unlock(inode->i_sb);
15829+ inode_unlock(inode);
15830+ return err;
15831+}
15832+
15833+static ssize_t au_do_iter(struct file *h_file, int rw, struct kiocb *kio,
15834+ struct iov_iter *iov_iter)
15835+{
15836+ ssize_t err;
15837+ struct file *file;
15838+ ssize_t (*iter)(struct kiocb *, struct iov_iter *);
15839+
15840+ err = security_file_permission(h_file, rw);
15841+ if (unlikely(err))
15842+ goto out;
15843+
15844+ err = -ENOSYS; /* the branch doesn't have its ->(read|write)_iter() */
15845+ iter = NULL;
15846+ if (rw == MAY_READ)
15847+ iter = h_file->f_op->read_iter;
15848+ else if (rw == MAY_WRITE)
15849+ iter = h_file->f_op->write_iter;
15850+
15851+ file = kio->ki_filp;
15852+ kio->ki_filp = h_file;
15853+ if (iter) {
15854+ lockdep_off();
15855+ err = iter(kio, iov_iter);
15856+ lockdep_on();
15857+ } else
15858+ /* currently there is no such fs */
15859+ WARN_ON_ONCE(1);
15860+ kio->ki_filp = file;
15861+
15862+out:
15863+ return err;
15864+}
15865+
15866+static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter)
15867+{
15868+ ssize_t err;
15869+ struct file *file, *h_file;
15870+ struct inode *inode;
15871+ struct super_block *sb;
15872+
15873+ file = kio->ki_filp;
15874+ inode = file_inode(file);
15875+ sb = inode->i_sb;
15876+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
15877+
15878+ h_file = au_read_pre(file, /*keep_fi*/1, /*lsc*/0);
15879+ err = PTR_ERR(h_file);
15880+ if (IS_ERR(h_file))
15881+ goto out;
15882+
15883+ if (au_test_loopback_kthread()) {
15884+ au_warn_loopback(h_file->f_path.dentry->d_sb);
15885+ if (file->f_mapping != h_file->f_mapping) {
15886+ file->f_mapping = h_file->f_mapping;
15887+ smp_mb(); /* unnecessary? */
15888+ }
15889+ }
15890+ fi_read_unlock(file);
15891+
15892+ err = au_do_iter(h_file, MAY_READ, kio, iov_iter);
15893+ /* todo: necessary? */
15894+ /* file->f_ra = h_file->f_ra; */
15895+ au_read_post(inode, h_file);
15896+
15897+out:
15898+ si_read_unlock(sb);
15899+ return err;
15900+}
15901+
15902+static ssize_t aufs_write_iter(struct kiocb *kio, struct iov_iter *iov_iter)
15903+{
15904+ ssize_t err;
15905+ struct au_write_pre wpre;
15906+ struct inode *inode;
15907+ struct file *file, *h_file;
15908+
15909+ file = kio->ki_filp;
15910+ inode = file_inode(file);
15911+ au_mtx_and_read_lock(inode);
15912+
15913+ wpre.lsc = 0;
15914+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
15915+ err = PTR_ERR(h_file);
15916+ if (IS_ERR(h_file))
15917+ goto out;
15918+
15919+ err = au_do_iter(h_file, MAY_WRITE, kio, iov_iter);
15920+ au_write_post(inode, h_file, &wpre, err);
15921+
15922+out:
15923+ si_read_unlock(inode->i_sb);
15924+ inode_unlock(inode);
15925+ return err;
15926+}
15927+
15928+static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
15929+ struct pipe_inode_info *pipe, size_t len,
15930+ unsigned int flags)
15931+{
15932+ ssize_t err;
15933+ struct file *h_file;
15934+ struct inode *inode;
15935+ struct super_block *sb;
15936+
15937+ inode = file_inode(file);
15938+ sb = inode->i_sb;
15939+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
15940+
15941+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
15942+ err = PTR_ERR(h_file);
15943+ if (IS_ERR(h_file))
15944+ goto out;
15945+
15946+ err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
15947+ /* todo: necessary? */
15948+ /* file->f_ra = h_file->f_ra; */
15949+ au_read_post(inode, h_file);
15950+
15951+out:
15952+ si_read_unlock(sb);
15953+ return err;
15954+}
15955+
15956+static ssize_t
15957+aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
15958+ size_t len, unsigned int flags)
15959+{
15960+ ssize_t err;
15961+ struct au_write_pre wpre;
15962+ struct inode *inode;
15963+ struct file *h_file;
15964+
15965+ inode = file_inode(file);
15966+ au_mtx_and_read_lock(inode);
15967+
15968+ wpre.lsc = 0;
15969+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
15970+ err = PTR_ERR(h_file);
15971+ if (IS_ERR(h_file))
15972+ goto out;
15973+
15974+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
15975+ au_write_post(inode, h_file, &wpre, err);
15976+
15977+out:
15978+ si_read_unlock(inode->i_sb);
15979+ inode_unlock(inode);
15980+ return err;
15981+}
15982+
15983+static long aufs_fallocate(struct file *file, int mode, loff_t offset,
15984+ loff_t len)
15985+{
15986+ long err;
15987+ struct au_write_pre wpre;
15988+ struct inode *inode;
15989+ struct file *h_file;
15990+
15991+ inode = file_inode(file);
15992+ au_mtx_and_read_lock(inode);
15993+
15994+ wpre.lsc = 0;
15995+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
15996+ err = PTR_ERR(h_file);
15997+ if (IS_ERR(h_file))
15998+ goto out;
15999+
16000+ lockdep_off();
16001+ err = vfs_fallocate(h_file, mode, offset, len);
16002+ lockdep_on();
16003+ au_write_post(inode, h_file, &wpre, /*written*/1);
16004+
16005+out:
16006+ si_read_unlock(inode->i_sb);
16007+ inode_unlock(inode);
16008+ return err;
16009+}
16010+
16011+static ssize_t aufs_copy_file_range(struct file *src, loff_t src_pos,
16012+ struct file *dst, loff_t dst_pos,
16013+ size_t len, unsigned int flags)
16014+{
16015+ ssize_t err;
16016+ struct au_write_pre wpre;
16017+ enum { SRC, DST };
16018+ struct {
16019+ struct inode *inode;
16020+ struct file *h_file;
16021+ struct super_block *h_sb;
16022+ } a[2];
16023+#define a_src a[SRC]
16024+#define a_dst a[DST]
16025+
16026+ err = -EINVAL;
16027+ a_src.inode = file_inode(src);
16028+ if (unlikely(!S_ISREG(a_src.inode->i_mode)))
16029+ goto out;
16030+ a_dst.inode = file_inode(dst);
16031+ if (unlikely(!S_ISREG(a_dst.inode->i_mode)))
16032+ goto out;
16033+
16034+ au_mtx_and_read_lock(a_dst.inode);
16035+ /*
16036+ * in order to match the order in di_write_lock2_{child,parent}(),
16037+ * use f_path.dentry for this comparison.
16038+ */
16039+ if (src->f_path.dentry < dst->f_path.dentry) {
16040+ a_src.h_file = au_read_pre(src, /*keep_fi*/1, AuLsc_FI_1);
16041+ err = PTR_ERR(a_src.h_file);
16042+ if (IS_ERR(a_src.h_file))
16043+ goto out_si;
16044+
16045+ wpre.lsc = AuLsc_FI_2;
16046+ a_dst.h_file = au_write_pre(dst, /*do_ready*/1, &wpre);
16047+ err = PTR_ERR(a_dst.h_file);
16048+ if (IS_ERR(a_dst.h_file)) {
16049+ au_read_post(a_src.inode, a_src.h_file);
16050+ goto out_si;
16051+ }
16052+ } else {
16053+ wpre.lsc = AuLsc_FI_1;
16054+ a_dst.h_file = au_write_pre(dst, /*do_ready*/1, &wpre);
16055+ err = PTR_ERR(a_dst.h_file);
16056+ if (IS_ERR(a_dst.h_file))
16057+ goto out_si;
16058+
16059+ a_src.h_file = au_read_pre(src, /*keep_fi*/1, AuLsc_FI_2);
16060+ err = PTR_ERR(a_src.h_file);
16061+ if (IS_ERR(a_src.h_file)) {
16062+ au_write_post(a_dst.inode, a_dst.h_file, &wpre,
16063+ /*written*/0);
16064+ goto out_si;
16065+ }
16066+ }
16067+
16068+ err = -EXDEV;
16069+ a_src.h_sb = file_inode(a_src.h_file)->i_sb;
16070+ a_dst.h_sb = file_inode(a_dst.h_file)->i_sb;
16071+ if (unlikely(a_src.h_sb != a_dst.h_sb)) {
16072+ AuDbgFile(src);
16073+ AuDbgFile(dst);
16074+ goto out_file;
16075+ }
16076+
16077+ err = vfsub_copy_file_range(a_src.h_file, src_pos, a_dst.h_file,
16078+ dst_pos, len, flags);
16079+
16080+out_file:
16081+ au_write_post(a_dst.inode, a_dst.h_file, &wpre, err);
16082+ fi_read_unlock(src);
16083+ au_read_post(a_src.inode, a_src.h_file);
16084+out_si:
16085+ si_read_unlock(a_dst.inode->i_sb);
16086+ inode_unlock(a_dst.inode);
16087+out:
16088+ return err;
16089+#undef a_src
16090+#undef a_dst
16091+}
16092+
16093+/* ---------------------------------------------------------------------- */
16094+
16095+/*
16096+ * The locking order around current->mmap_sem.
16097+ * - in most and regular cases
16098+ * file I/O syscall -- aufs_read() or something
16099+ * -- si_rwsem for read -- mmap_sem
16100+ * (Note that [fdi]i_rwsem are released before mmap_sem).
16101+ * - in mmap case
16102+ * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem
16103+ * This AB-BA order is definitely bad, but is not a problem since "si_rwsem for
16104+ * read" allows multiple processes to acquire it and [fdi]i_rwsem are not held
16105+ * in file I/O. Aufs needs to stop lockdep in aufs_mmap() though.
16106+ * It means that when aufs acquires si_rwsem for write, the process should never
16107+ * acquire mmap_sem.
16108+ *
16109+ * Actually aufs_iterate() holds [fdi]i_rwsem before mmap_sem, but this is not a
16110+ * problem either since any directory is not able to be mmap-ed.
16111+ * The similar scenario is applied to aufs_readlink() too.
16112+ */
16113+
16114+#if 0 /* stop calling security_file_mmap() */
16115+/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
16116+#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b)
16117+
16118+static unsigned long au_arch_prot_conv(unsigned long flags)
16119+{
16120+ /* currently ppc64 only */
16121+#ifdef CONFIG_PPC64
16122+ /* cf. linux/arch/powerpc/include/asm/mman.h */
16123+ AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO);
16124+ return AuConv_VM_PROT(flags, SAO);
16125+#else
16126+ AuDebugOn(arch_calc_vm_prot_bits(-1));
16127+ return 0;
16128+#endif
16129+}
16130+
16131+static unsigned long au_prot_conv(unsigned long flags)
16132+{
16133+ return AuConv_VM_PROT(flags, READ)
16134+ | AuConv_VM_PROT(flags, WRITE)
16135+ | AuConv_VM_PROT(flags, EXEC)
16136+ | au_arch_prot_conv(flags);
16137+}
16138+
16139+/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */
16140+#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b)
16141+
16142+static unsigned long au_flag_conv(unsigned long flags)
16143+{
16144+ return AuConv_VM_MAP(flags, GROWSDOWN)
16145+ | AuConv_VM_MAP(flags, DENYWRITE)
16146+ | AuConv_VM_MAP(flags, LOCKED);
16147+}
16148+#endif
16149+
16150+static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
16151+{
16152+ int err;
16153+ const unsigned char wlock
16154+ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
16155+ struct super_block *sb;
16156+ struct file *h_file;
16157+ struct inode *inode;
16158+
16159+ AuDbgVmRegion(file, vma);
16160+
16161+ inode = file_inode(file);
16162+ sb = inode->i_sb;
16163+ lockdep_off();
16164+ si_read_lock(sb, AuLock_NOPLMW);
16165+
16166+ h_file = au_write_pre(file, wlock, /*wpre*/NULL);
16167+ lockdep_on();
16168+ err = PTR_ERR(h_file);
16169+ if (IS_ERR(h_file))
16170+ goto out;
16171+
16172+ err = 0;
16173+ au_set_mmapped(file);
16174+ au_vm_file_reset(vma, h_file);
16175+ /*
16176+ * we cannot call security_mmap_file() here since it may acquire
16177+ * mmap_sem or i_mutex.
16178+ *
16179+ * err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
16180+ * au_flag_conv(vma->vm_flags));
16181+ */
16182+ if (!err)
16183+ err = call_mmap(h_file, vma);
16184+ if (!err) {
16185+ au_vm_prfile_set(vma, file);
16186+ fsstack_copy_attr_atime(inode, file_inode(h_file));
16187+ goto out_fput; /* success */
16188+ }
16189+ au_unset_mmapped(file);
16190+ au_vm_file_reset(vma, file);
16191+
16192+out_fput:
16193+ lockdep_off();
16194+ ii_write_unlock(inode);
16195+ lockdep_on();
16196+ fput(h_file);
16197+out:
16198+ lockdep_off();
16199+ si_read_unlock(sb);
16200+ lockdep_on();
16201+ AuTraceErr(err);
16202+ return err;
16203+}
16204+
16205+/* ---------------------------------------------------------------------- */
16206+
16207+static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end,
16208+ int datasync)
16209+{
16210+ int err;
16211+ struct au_write_pre wpre;
16212+ struct inode *inode;
16213+ struct file *h_file;
16214+
16215+ err = 0; /* -EBADF; */ /* posix? */
16216+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
16217+ goto out;
16218+
16219+ inode = file_inode(file);
16220+ au_mtx_and_read_lock(inode);
16221+
16222+ wpre.lsc = 0;
16223+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
16224+ err = PTR_ERR(h_file);
16225+ if (IS_ERR(h_file))
16226+ goto out_unlock;
16227+
16228+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
16229+ au_write_post(inode, h_file, &wpre, /*written*/0);
16230+
16231+out_unlock:
16232+ si_read_unlock(inode->i_sb);
16233+ inode_unlock(inode);
16234+out:
16235+ return err;
16236+}
16237+
16238+static int aufs_fasync(int fd, struct file *file, int flag)
16239+{
16240+ int err;
16241+ struct file *h_file;
16242+ struct super_block *sb;
16243+
16244+ sb = file->f_path.dentry->d_sb;
16245+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
16246+
16247+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
16248+ err = PTR_ERR(h_file);
16249+ if (IS_ERR(h_file))
16250+ goto out;
16251+
16252+ if (h_file->f_op->fasync)
16253+ err = h_file->f_op->fasync(fd, h_file, flag);
16254+ fput(h_file); /* instead of au_read_post() */
16255+
16256+out:
16257+ si_read_unlock(sb);
16258+ return err;
16259+}
16260+
16261+static int aufs_setfl(struct file *file, unsigned long arg)
16262+{
16263+ int err;
16264+ struct file *h_file;
16265+ struct super_block *sb;
16266+
16267+ sb = file->f_path.dentry->d_sb;
16268+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
16269+
16270+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
16271+ err = PTR_ERR(h_file);
16272+ if (IS_ERR(h_file))
16273+ goto out;
16274+
16275+ /* stop calling h_file->fasync */
16276+ arg |= vfsub_file_flags(file) & FASYNC;
16277+ err = setfl(/*unused fd*/-1, h_file, arg);
16278+ fput(h_file); /* instead of au_read_post() */
16279+
16280+out:
16281+ si_read_unlock(sb);
16282+ return err;
16283+}
16284+
16285+/* ---------------------------------------------------------------------- */
16286+
16287+/* no one supports this operation, currently */
16288+#if 0 /* reserved for future use */
16289+static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
16290+ size_t len, loff_t *pos, int more)
16291+{
16292+}
16293+#endif
16294+
16295+/* ---------------------------------------------------------------------- */
16296+
16297+const struct file_operations aufs_file_fop = {
16298+ .owner = THIS_MODULE,
16299+
16300+ .llseek = default_llseek,
16301+
16302+ .read = aufs_read,
16303+ .write = aufs_write,
16304+ .read_iter = aufs_read_iter,
16305+ .write_iter = aufs_write_iter,
16306+
16307+#ifdef CONFIG_AUFS_POLL
16308+ .poll = aufs_poll,
16309+#endif
16310+ .unlocked_ioctl = aufs_ioctl_nondir,
16311+#ifdef CONFIG_COMPAT
16312+ .compat_ioctl = aufs_compat_ioctl_nondir,
16313+#endif
16314+ .mmap = aufs_mmap,
16315+ .open = aufs_open_nondir,
16316+ .flush = aufs_flush_nondir,
16317+ .release = aufs_release_nondir,
16318+ .fsync = aufs_fsync_nondir,
16319+ .fasync = aufs_fasync,
16320+ /* .sendpage = aufs_sendpage, */
16321+ .setfl = aufs_setfl,
16322+ .splice_write = aufs_splice_write,
16323+ .splice_read = aufs_splice_read,
16324+#if 0 /* reserved for future use */
16325+ .aio_splice_write = aufs_aio_splice_write,
16326+ .aio_splice_read = aufs_aio_splice_read,
16327+#endif
16328+ .fallocate = aufs_fallocate,
16329+ .copy_file_range = aufs_copy_file_range
16330+};
16331diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
16332--- /usr/share/empty/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100
16333+++ linux/fs/aufs/fstype.h 2020-01-27 10:57:18.172204883 +0100
16334@@ -0,0 +1,401 @@
16335+/* SPDX-License-Identifier: GPL-2.0 */
16336+/*
16337+ * Copyright (C) 2005-2020 Junjiro R. Okajima
16338+ *
16339+ * This program, aufs is free software; you can redistribute it and/or modify
16340+ * it under the terms of the GNU General Public License as published by
16341+ * the Free Software Foundation; either version 2 of the License, or
16342+ * (at your option) any later version.
16343+ *
16344+ * This program is distributed in the hope that it will be useful,
16345+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16346+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16347+ * GNU General Public License for more details.
16348+ *
16349+ * You should have received a copy of the GNU General Public License
16350+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16351+ */
16352+
16353+/*
16354+ * judging filesystem type
16355+ */
16356+
16357+#ifndef __AUFS_FSTYPE_H__
16358+#define __AUFS_FSTYPE_H__
16359+
16360+#ifdef __KERNEL__
16361+
16362+#include <linux/fs.h>
16363+#include <linux/magic.h>
16364+#include <linux/nfs_fs.h>
16365+#include <linux/romfs_fs.h>
16366+
16367+static inline int au_test_aufs(struct super_block *sb)
16368+{
16369+ return sb->s_magic == AUFS_SUPER_MAGIC;
16370+}
16371+
16372+static inline const char *au_sbtype(struct super_block *sb)
16373+{
16374+ return sb->s_type->name;
16375+}
16376+
16377+static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
16378+{
16379+#if IS_ENABLED(CONFIG_ISO9660_FS)
16380+ return sb->s_magic == ISOFS_SUPER_MAGIC;
16381+#else
16382+ return 0;
16383+#endif
16384+}
16385+
16386+static inline int au_test_romfs(struct super_block *sb __maybe_unused)
16387+{
16388+#if IS_ENABLED(CONFIG_ROMFS_FS)
16389+ return sb->s_magic == ROMFS_MAGIC;
16390+#else
16391+ return 0;
16392+#endif
16393+}
16394+
16395+static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
16396+{
16397+#if IS_ENABLED(CONFIG_CRAMFS)
16398+ return sb->s_magic == CRAMFS_MAGIC;
16399+#endif
16400+ return 0;
16401+}
16402+
16403+static inline int au_test_nfs(struct super_block *sb __maybe_unused)
16404+{
16405+#if IS_ENABLED(CONFIG_NFS_FS)
16406+ return sb->s_magic == NFS_SUPER_MAGIC;
16407+#else
16408+ return 0;
16409+#endif
16410+}
16411+
16412+static inline int au_test_fuse(struct super_block *sb __maybe_unused)
16413+{
16414+#if IS_ENABLED(CONFIG_FUSE_FS)
16415+ return sb->s_magic == FUSE_SUPER_MAGIC;
16416+#else
16417+ return 0;
16418+#endif
16419+}
16420+
16421+static inline int au_test_xfs(struct super_block *sb __maybe_unused)
16422+{
16423+#if IS_ENABLED(CONFIG_XFS_FS)
16424+ return sb->s_magic == XFS_SB_MAGIC;
16425+#else
16426+ return 0;
16427+#endif
16428+}
16429+
16430+static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
16431+{
16432+#ifdef CONFIG_TMPFS
16433+ return sb->s_magic == TMPFS_MAGIC;
16434+#else
16435+ return 0;
16436+#endif
16437+}
16438+
16439+static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
16440+{
16441+#if IS_ENABLED(CONFIG_ECRYPT_FS)
16442+ return !strcmp(au_sbtype(sb), "ecryptfs");
16443+#else
16444+ return 0;
16445+#endif
16446+}
16447+
16448+static inline int au_test_ramfs(struct super_block *sb)
16449+{
16450+ return sb->s_magic == RAMFS_MAGIC;
16451+}
16452+
16453+static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
16454+{
16455+#if IS_ENABLED(CONFIG_UBIFS_FS)
16456+ return sb->s_magic == UBIFS_SUPER_MAGIC;
16457+#else
16458+ return 0;
16459+#endif
16460+}
16461+
16462+static inline int au_test_procfs(struct super_block *sb __maybe_unused)
16463+{
16464+#ifdef CONFIG_PROC_FS
16465+ return sb->s_magic == PROC_SUPER_MAGIC;
16466+#else
16467+ return 0;
16468+#endif
16469+}
16470+
16471+static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
16472+{
16473+#ifdef CONFIG_SYSFS
16474+ return sb->s_magic == SYSFS_MAGIC;
16475+#else
16476+ return 0;
16477+#endif
16478+}
16479+
16480+static inline int au_test_configfs(struct super_block *sb __maybe_unused)
16481+{
16482+#if IS_ENABLED(CONFIG_CONFIGFS_FS)
16483+ return sb->s_magic == CONFIGFS_MAGIC;
16484+#else
16485+ return 0;
16486+#endif
16487+}
16488+
16489+static inline int au_test_minix(struct super_block *sb __maybe_unused)
16490+{
16491+#if IS_ENABLED(CONFIG_MINIX_FS)
16492+ return sb->s_magic == MINIX3_SUPER_MAGIC
16493+ || sb->s_magic == MINIX2_SUPER_MAGIC
16494+ || sb->s_magic == MINIX2_SUPER_MAGIC2
16495+ || sb->s_magic == MINIX_SUPER_MAGIC
16496+ || sb->s_magic == MINIX_SUPER_MAGIC2;
16497+#else
16498+ return 0;
16499+#endif
16500+}
16501+
16502+static inline int au_test_fat(struct super_block *sb __maybe_unused)
16503+{
16504+#if IS_ENABLED(CONFIG_FAT_FS)
16505+ return sb->s_magic == MSDOS_SUPER_MAGIC;
16506+#else
16507+ return 0;
16508+#endif
16509+}
16510+
16511+static inline int au_test_msdos(struct super_block *sb)
16512+{
16513+ return au_test_fat(sb);
16514+}
16515+
16516+static inline int au_test_vfat(struct super_block *sb)
16517+{
16518+ return au_test_fat(sb);
16519+}
16520+
16521+static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
16522+{
16523+#ifdef CONFIG_SECURITYFS
16524+ return sb->s_magic == SECURITYFS_MAGIC;
16525+#else
16526+ return 0;
16527+#endif
16528+}
16529+
16530+static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
16531+{
16532+#if IS_ENABLED(CONFIG_SQUASHFS)
16533+ return sb->s_magic == SQUASHFS_MAGIC;
16534+#else
16535+ return 0;
16536+#endif
16537+}
16538+
16539+static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
16540+{
16541+#if IS_ENABLED(CONFIG_BTRFS_FS)
16542+ return sb->s_magic == BTRFS_SUPER_MAGIC;
16543+#else
16544+ return 0;
16545+#endif
16546+}
16547+
16548+static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
16549+{
16550+#if IS_ENABLED(CONFIG_XENFS)
16551+ return sb->s_magic == XENFS_SUPER_MAGIC;
16552+#else
16553+ return 0;
16554+#endif
16555+}
16556+
16557+static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
16558+{
16559+#ifdef CONFIG_DEBUG_FS
16560+ return sb->s_magic == DEBUGFS_MAGIC;
16561+#else
16562+ return 0;
16563+#endif
16564+}
16565+
16566+static inline int au_test_nilfs(struct super_block *sb __maybe_unused)
16567+{
16568+#if IS_ENABLED(CONFIG_NILFS)
16569+ return sb->s_magic == NILFS_SUPER_MAGIC;
16570+#else
16571+ return 0;
16572+#endif
16573+}
16574+
16575+static inline int au_test_hfsplus(struct super_block *sb __maybe_unused)
16576+{
16577+#if IS_ENABLED(CONFIG_HFSPLUS_FS)
16578+ return sb->s_magic == HFSPLUS_SUPER_MAGIC;
16579+#else
16580+ return 0;
16581+#endif
16582+}
16583+
16584+/* ---------------------------------------------------------------------- */
16585+/*
16586+ * they can't be an aufs branch.
16587+ */
16588+static inline int au_test_fs_unsuppoted(struct super_block *sb)
16589+{
16590+ return
16591+#ifndef CONFIG_AUFS_BR_RAMFS
16592+ au_test_ramfs(sb) ||
16593+#endif
16594+ au_test_procfs(sb)
16595+ || au_test_sysfs(sb)
16596+ || au_test_configfs(sb)
16597+ || au_test_debugfs(sb)
16598+ || au_test_securityfs(sb)
16599+ || au_test_xenfs(sb)
16600+ || au_test_ecryptfs(sb)
16601+ /* || !strcmp(au_sbtype(sb), "unionfs") */
16602+ || au_test_aufs(sb); /* will be supported in next version */
16603+}
16604+
16605+static inline int au_test_fs_remote(struct super_block *sb)
16606+{
16607+ return !au_test_tmpfs(sb)
16608+#ifdef CONFIG_AUFS_BR_RAMFS
16609+ && !au_test_ramfs(sb)
16610+#endif
16611+ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
16612+}
16613+
16614+/* ---------------------------------------------------------------------- */
16615+
16616+/*
16617+ * Note: these functions (below) are created after reading ->getattr() in all
16618+ * filesystems under linux/fs. it means we have to do so in every update...
16619+ */
16620+
16621+/*
16622+ * some filesystems require getattr to refresh the inode attributes before
16623+ * referencing.
16624+ * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
16625+ * and leave the work for d_revalidate()
16626+ */
16627+static inline int au_test_fs_refresh_iattr(struct super_block *sb)
16628+{
16629+ return au_test_nfs(sb)
16630+ || au_test_fuse(sb)
16631+ /* || au_test_btrfs(sb) */ /* untested */
16632+ ;
16633+}
16634+
16635+/*
16636+ * filesystems which don't maintain i_size or i_blocks.
16637+ */
16638+static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
16639+{
16640+ return au_test_xfs(sb)
16641+ || au_test_btrfs(sb)
16642+ || au_test_ubifs(sb)
16643+ || au_test_hfsplus(sb) /* maintained, but incorrect */
16644+ /* || au_test_minix(sb) */ /* untested */
16645+ ;
16646+}
16647+
16648+/*
16649+ * filesystems which don't store the correct value in some of their inode
16650+ * attributes.
16651+ */
16652+static inline int au_test_fs_bad_iattr(struct super_block *sb)
16653+{
16654+ return au_test_fs_bad_iattr_size(sb)
16655+ || au_test_fat(sb)
16656+ || au_test_msdos(sb)
16657+ || au_test_vfat(sb);
16658+}
16659+
16660+/* they don't check i_nlink in link(2) */
16661+static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
16662+{
16663+ return au_test_tmpfs(sb)
16664+#ifdef CONFIG_AUFS_BR_RAMFS
16665+ || au_test_ramfs(sb)
16666+#endif
16667+ || au_test_ubifs(sb)
16668+ || au_test_hfsplus(sb);
16669+}
16670+
16671+/*
16672+ * filesystems which sets S_NOATIME and S_NOCMTIME.
16673+ */
16674+static inline int au_test_fs_notime(struct super_block *sb)
16675+{
16676+ return au_test_nfs(sb)
16677+ || au_test_fuse(sb)
16678+ || au_test_ubifs(sb)
16679+ ;
16680+}
16681+
16682+/* temporary support for i#1 in cramfs */
16683+static inline int au_test_fs_unique_ino(struct inode *inode)
16684+{
16685+ if (au_test_cramfs(inode->i_sb))
16686+ return inode->i_ino != 1;
16687+ return 1;
16688+}
16689+
16690+/* ---------------------------------------------------------------------- */
16691+
16692+/*
16693+ * the filesystem where the xino files placed must support i/o after unlink and
16694+ * maintain i_size and i_blocks.
16695+ */
16696+static inline int au_test_fs_bad_xino(struct super_block *sb)
16697+{
16698+ return au_test_fs_remote(sb)
16699+ || au_test_fs_bad_iattr_size(sb)
16700+ /* don't want unnecessary work for xino */
16701+ || au_test_aufs(sb)
16702+ || au_test_ecryptfs(sb)
16703+ || au_test_nilfs(sb);
16704+}
16705+
16706+static inline int au_test_fs_trunc_xino(struct super_block *sb)
16707+{
16708+ return au_test_tmpfs(sb)
16709+ || au_test_ramfs(sb);
16710+}
16711+
16712+/*
16713+ * test if the @sb is real-readonly.
16714+ */
16715+static inline int au_test_fs_rr(struct super_block *sb)
16716+{
16717+ return au_test_squashfs(sb)
16718+ || au_test_iso9660(sb)
16719+ || au_test_cramfs(sb)
16720+ || au_test_romfs(sb);
16721+}
16722+
16723+/*
16724+ * test if the @inode is nfs with 'noacl' option
16725+ * NFS always sets SB_POSIXACL regardless its mount option 'noacl.'
16726+ */
16727+static inline int au_test_nfs_noacl(struct inode *inode)
16728+{
16729+ return au_test_nfs(inode->i_sb)
16730+ /* && IS_POSIXACL(inode) */
16731+ && !nfs_server_capable(inode, NFS_CAP_ACLS);
16732+}
16733+
16734+#endif /* __KERNEL__ */
16735+#endif /* __AUFS_FSTYPE_H__ */
16736diff -urN /usr/share/empty/fs/aufs/hbl.h linux/fs/aufs/hbl.h
16737--- /usr/share/empty/fs/aufs/hbl.h 1970-01-01 01:00:00.000000000 +0100
16738+++ linux/fs/aufs/hbl.h 2020-01-27 10:57:18.172204883 +0100
16739@@ -0,0 +1,65 @@
16740+/* SPDX-License-Identifier: GPL-2.0 */
16741+/*
16742+ * Copyright (C) 2017-2020 Junjiro R. Okajima
16743+ *
16744+ * This program, aufs is free software; you can redistribute it and/or modify
16745+ * it under the terms of the GNU General Public License as published by
16746+ * the Free Software Foundation; either version 2 of the License, or
16747+ * (at your option) any later version.
16748+ *
16749+ * This program is distributed in the hope that it will be useful,
16750+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16751+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16752+ * GNU General Public License for more details.
16753+ *
16754+ * You should have received a copy of the GNU General Public License
16755+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16756+ */
16757+
16758+/*
16759+ * helpers for hlist_bl.h
16760+ */
16761+
16762+#ifndef __AUFS_HBL_H__
16763+#define __AUFS_HBL_H__
16764+
16765+#ifdef __KERNEL__
16766+
16767+#include <linux/list_bl.h>
16768+
16769+static inline void au_hbl_add(struct hlist_bl_node *node,
16770+ struct hlist_bl_head *hbl)
16771+{
16772+ hlist_bl_lock(hbl);
16773+ hlist_bl_add_head(node, hbl);
16774+ hlist_bl_unlock(hbl);
16775+}
16776+
16777+static inline void au_hbl_del(struct hlist_bl_node *node,
16778+ struct hlist_bl_head *hbl)
16779+{
16780+ hlist_bl_lock(hbl);
16781+ hlist_bl_del(node);
16782+ hlist_bl_unlock(hbl);
16783+}
16784+
16785+#define au_hbl_for_each(pos, head) \
16786+ for (pos = hlist_bl_first(head); \
16787+ pos; \
16788+ pos = pos->next)
16789+
16790+static inline unsigned long au_hbl_count(struct hlist_bl_head *hbl)
16791+{
16792+ unsigned long cnt;
16793+ struct hlist_bl_node *pos;
16794+
16795+ cnt = 0;
16796+ hlist_bl_lock(hbl);
16797+ au_hbl_for_each(pos, hbl)
16798+ cnt++;
16799+ hlist_bl_unlock(hbl);
16800+ return cnt;
16801+}
16802+
16803+#endif /* __KERNEL__ */
16804+#endif /* __AUFS_HBL_H__ */
16805diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
16806--- /usr/share/empty/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100
16807+++ linux/fs/aufs/hfsnotify.c 2020-01-27 10:57:18.172204883 +0100
16808@@ -0,0 +1,288 @@
16809+// SPDX-License-Identifier: GPL-2.0
16810+/*
16811+ * Copyright (C) 2005-2020 Junjiro R. Okajima
16812+ *
16813+ * This program, aufs is free software; you can redistribute it and/or modify
16814+ * it under the terms of the GNU General Public License as published by
16815+ * the Free Software Foundation; either version 2 of the License, or
16816+ * (at your option) any later version.
16817+ *
16818+ * This program is distributed in the hope that it will be useful,
16819+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16820+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16821+ * GNU General Public License for more details.
16822+ *
16823+ * You should have received a copy of the GNU General Public License
16824+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16825+ */
16826+
16827+/*
16828+ * fsnotify for the lower directories
16829+ */
16830+
16831+#include "aufs.h"
16832+
16833+/* FS_IN_IGNORED is unnecessary */
16834+static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE
16835+ | FS_CREATE | FS_EVENT_ON_CHILD);
16836+static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
16837+static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0);
16838+
16839+static void au_hfsn_free_mark(struct fsnotify_mark *mark)
16840+{
16841+ struct au_hnotify *hn = container_of(mark, struct au_hnotify,
16842+ hn_mark);
16843+ /* AuDbg("here\n"); */
16844+ au_cache_free_hnotify(hn);
16845+ smp_mb__before_atomic(); /* for atomic64_dec */
16846+ if (atomic64_dec_and_test(&au_hfsn_ifree))
16847+ wake_up(&au_hfsn_wq);
16848+}
16849+
16850+static int au_hfsn_alloc(struct au_hinode *hinode)
16851+{
16852+ int err;
16853+ struct au_hnotify *hn;
16854+ struct super_block *sb;
16855+ struct au_branch *br;
16856+ struct fsnotify_mark *mark;
16857+ aufs_bindex_t bindex;
16858+
16859+ hn = hinode->hi_notify;
16860+ sb = hn->hn_aufs_inode->i_sb;
16861+ bindex = au_br_index(sb, hinode->hi_id);
16862+ br = au_sbr(sb, bindex);
16863+ AuDebugOn(!br->br_hfsn);
16864+
16865+ mark = &hn->hn_mark;
16866+ fsnotify_init_mark(mark, br->br_hfsn->hfsn_group);
16867+ mark->mask = AuHfsnMask;
16868+ /*
16869+ * by udba rename or rmdir, aufs assign a new inode to the known
16870+ * h_inode, so specify 1 to allow dups.
16871+ */
16872+ lockdep_off();
16873+ err = fsnotify_add_inode_mark(mark, hinode->hi_inode, /*allow_dups*/1);
16874+ lockdep_on();
16875+
16876+ return err;
16877+}
16878+
16879+static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn)
16880+{
16881+ struct fsnotify_mark *mark;
16882+ unsigned long long ull;
16883+ struct fsnotify_group *group;
16884+
16885+ ull = atomic64_inc_return(&au_hfsn_ifree);
16886+ BUG_ON(!ull);
16887+
16888+ mark = &hn->hn_mark;
16889+ spin_lock(&mark->lock);
16890+ group = mark->group;
16891+ fsnotify_get_group(group);
16892+ spin_unlock(&mark->lock);
16893+ lockdep_off();
16894+ fsnotify_destroy_mark(mark, group);
16895+ fsnotify_put_mark(mark);
16896+ fsnotify_put_group(group);
16897+ lockdep_on();
16898+
16899+ /* free hn by myself */
16900+ return 0;
16901+}
16902+
16903+/* ---------------------------------------------------------------------- */
16904+
16905+static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
16906+{
16907+ struct fsnotify_mark *mark;
16908+
16909+ mark = &hinode->hi_notify->hn_mark;
16910+ spin_lock(&mark->lock);
16911+ if (do_set) {
16912+ AuDebugOn(mark->mask & AuHfsnMask);
16913+ mark->mask |= AuHfsnMask;
16914+ } else {
16915+ AuDebugOn(!(mark->mask & AuHfsnMask));
16916+ mark->mask &= ~AuHfsnMask;
16917+ }
16918+ spin_unlock(&mark->lock);
16919+ /* fsnotify_recalc_inode_mask(hinode->hi_inode); */
16920+}
16921+
16922+/* ---------------------------------------------------------------------- */
16923+
16924+/* #define AuDbgHnotify */
16925+#ifdef AuDbgHnotify
16926+static char *au_hfsn_name(u32 mask)
16927+{
16928+#ifdef CONFIG_AUFS_DEBUG
16929+#define test_ret(flag) \
16930+ do { \
16931+ if (mask & flag) \
16932+ return #flag; \
16933+ } while (0)
16934+ test_ret(FS_ACCESS);
16935+ test_ret(FS_MODIFY);
16936+ test_ret(FS_ATTRIB);
16937+ test_ret(FS_CLOSE_WRITE);
16938+ test_ret(FS_CLOSE_NOWRITE);
16939+ test_ret(FS_OPEN);
16940+ test_ret(FS_MOVED_FROM);
16941+ test_ret(FS_MOVED_TO);
16942+ test_ret(FS_CREATE);
16943+ test_ret(FS_DELETE);
16944+ test_ret(FS_DELETE_SELF);
16945+ test_ret(FS_MOVE_SELF);
16946+ test_ret(FS_UNMOUNT);
16947+ test_ret(FS_Q_OVERFLOW);
16948+ test_ret(FS_IN_IGNORED);
16949+ test_ret(FS_ISDIR);
16950+ test_ret(FS_IN_ONESHOT);
16951+ test_ret(FS_EVENT_ON_CHILD);
16952+ return "";
16953+#undef test_ret
16954+#else
16955+ return "??";
16956+#endif
16957+}
16958+#endif
16959+
16960+/* ---------------------------------------------------------------------- */
16961+
16962+static void au_hfsn_free_group(struct fsnotify_group *group)
16963+{
16964+ struct au_br_hfsnotify *hfsn = group->private;
16965+
16966+ /* AuDbg("here\n"); */
16967+ au_kfree_try_rcu(hfsn);
16968+}
16969+
16970+static int au_hfsn_handle_event(struct fsnotify_group *group,
16971+ struct inode *inode,
16972+ u32 mask, const void *data, int data_type,
16973+ const struct qstr *file_name, u32 cookie,
16974+ struct fsnotify_iter_info *iter_info)
16975+{
16976+ int err;
16977+ struct au_hnotify *hnotify;
16978+ struct inode *h_dir, *h_inode;
16979+ struct fsnotify_mark *inode_mark;
16980+
16981+ AuDebugOn(data_type != FSNOTIFY_EVENT_INODE);
16982+
16983+ err = 0;
16984+ /* if FS_UNMOUNT happens, there must be another bug */
16985+ AuDebugOn(mask & FS_UNMOUNT);
16986+ if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
16987+ goto out;
16988+
16989+ h_dir = inode;
16990+ h_inode = NULL;
16991+#ifdef AuDbgHnotify
16992+ au_debug_on();
16993+ if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
16994+ || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
16995+ AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
16996+ h_dir->i_ino, mask, au_hfsn_name(mask),
16997+ AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
16998+ /* WARN_ON(1); */
16999+ }
17000+ au_debug_off();
17001+#endif
17002+
17003+ inode_mark = fsnotify_iter_inode_mark(iter_info);
17004+ AuDebugOn(!inode_mark);
17005+ hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
17006+ err = au_hnotify(h_dir, hnotify, mask, file_name, h_inode);
17007+
17008+out:
17009+ return err;
17010+}
17011+
17012+static struct fsnotify_ops au_hfsn_ops = {
17013+ .handle_event = au_hfsn_handle_event,
17014+ .free_group_priv = au_hfsn_free_group,
17015+ .free_mark = au_hfsn_free_mark
17016+};
17017+
17018+/* ---------------------------------------------------------------------- */
17019+
17020+static void au_hfsn_fin_br(struct au_branch *br)
17021+{
17022+ struct au_br_hfsnotify *hfsn;
17023+
17024+ hfsn = br->br_hfsn;
17025+ if (hfsn) {
17026+ lockdep_off();
17027+ fsnotify_put_group(hfsn->hfsn_group);
17028+ lockdep_on();
17029+ }
17030+}
17031+
17032+static int au_hfsn_init_br(struct au_branch *br, int perm)
17033+{
17034+ int err;
17035+ struct fsnotify_group *group;
17036+ struct au_br_hfsnotify *hfsn;
17037+
17038+ err = 0;
17039+ br->br_hfsn = NULL;
17040+ if (!au_br_hnotifyable(perm))
17041+ goto out;
17042+
17043+ err = -ENOMEM;
17044+ hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS);
17045+ if (unlikely(!hfsn))
17046+ goto out;
17047+
17048+ err = 0;
17049+ group = fsnotify_alloc_group(&au_hfsn_ops);
17050+ if (IS_ERR(group)) {
17051+ err = PTR_ERR(group);
17052+ pr_err("fsnotify_alloc_group() failed, %d\n", err);
17053+ goto out_hfsn;
17054+ }
17055+
17056+ group->private = hfsn;
17057+ hfsn->hfsn_group = group;
17058+ br->br_hfsn = hfsn;
17059+ goto out; /* success */
17060+
17061+out_hfsn:
17062+ au_kfree_try_rcu(hfsn);
17063+out:
17064+ return err;
17065+}
17066+
17067+static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm)
17068+{
17069+ int err;
17070+
17071+ err = 0;
17072+ if (!br->br_hfsn)
17073+ err = au_hfsn_init_br(br, perm);
17074+
17075+ return err;
17076+}
17077+
17078+/* ---------------------------------------------------------------------- */
17079+
17080+static void au_hfsn_fin(void)
17081+{
17082+ AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree));
17083+ wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree));
17084+}
17085+
17086+const struct au_hnotify_op au_hnotify_op = {
17087+ .ctl = au_hfsn_ctl,
17088+ .alloc = au_hfsn_alloc,
17089+ .free = au_hfsn_free,
17090+
17091+ .fin = au_hfsn_fin,
17092+
17093+ .reset_br = au_hfsn_reset_br,
17094+ .fin_br = au_hfsn_fin_br,
17095+ .init_br = au_hfsn_init_br
17096+};
17097diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c
17098--- /usr/share/empty/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100
17099+++ linux/fs/aufs/hfsplus.c 2020-01-27 10:57:18.172204883 +0100
17100@@ -0,0 +1,60 @@
17101+// SPDX-License-Identifier: GPL-2.0
17102+/*
17103+ * Copyright (C) 2010-2020 Junjiro R. Okajima
17104+ *
17105+ * This program, aufs is free software; you can redistribute it and/or modify
17106+ * it under the terms of the GNU General Public License as published by
17107+ * the Free Software Foundation; either version 2 of the License, or
17108+ * (at your option) any later version.
17109+ *
17110+ * This program is distributed in the hope that it will be useful,
17111+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17112+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17113+ * GNU General Public License for more details.
17114+ *
17115+ * You should have received a copy of the GNU General Public License
17116+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
17117+ */
17118+
17119+/*
17120+ * special support for filesystems which acquires an inode mutex
17121+ * at final closing a file, eg, hfsplus.
17122+ *
17123+ * This trick is very simple and stupid, just to open the file before really
17124+ * necessary open to tell hfsplus that this is not the final closing.
17125+ * The caller should call au_h_open_pre() after acquiring the inode mutex,
17126+ * and au_h_open_post() after releasing it.
17127+ */
17128+
17129+#include "aufs.h"
17130+
17131+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
17132+ int force_wr)
17133+{
17134+ struct file *h_file;
17135+ struct dentry *h_dentry;
17136+
17137+ h_dentry = au_h_dptr(dentry, bindex);
17138+ AuDebugOn(!h_dentry);
17139+ AuDebugOn(d_is_negative(h_dentry));
17140+
17141+ h_file = NULL;
17142+ if (au_test_hfsplus(h_dentry->d_sb)
17143+ && d_is_reg(h_dentry))
17144+ h_file = au_h_open(dentry, bindex,
17145+ O_RDONLY | O_NOATIME | O_LARGEFILE,
17146+ /*file*/NULL, force_wr);
17147+ return h_file;
17148+}
17149+
17150+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
17151+ struct file *h_file)
17152+{
17153+ struct au_branch *br;
17154+
17155+ if (h_file) {
17156+ fput(h_file);
17157+ br = au_sbr(dentry->d_sb, bindex);
17158+ au_lcnt_dec(&br->br_nfiles);
17159+ }
17160+}
17161diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
17162--- /usr/share/empty/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100
17163+++ linux/fs/aufs/hnotify.c 2020-01-27 10:57:18.172204883 +0100
17164@@ -0,0 +1,715 @@
17165+// SPDX-License-Identifier: GPL-2.0
17166+/*
17167+ * Copyright (C) 2005-2020 Junjiro R. Okajima
17168+ *
17169+ * This program, aufs is free software; you can redistribute it and/or modify
17170+ * it under the terms of the GNU General Public License as published by
17171+ * the Free Software Foundation; either version 2 of the License, or
17172+ * (at your option) any later version.
17173+ *
17174+ * This program is distributed in the hope that it will be useful,
17175+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17176+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17177+ * GNU General Public License for more details.
17178+ *
17179+ * You should have received a copy of the GNU General Public License
17180+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
17181+ */
17182+
17183+/*
17184+ * abstraction to notify the direct changes on lower directories
17185+ */
17186+
17187+/* #include <linux/iversion.h> */
17188+#include "aufs.h"
17189+
17190+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
17191+{
17192+ int err;
17193+ struct au_hnotify *hn;
17194+
17195+ err = -ENOMEM;
17196+ hn = au_cache_alloc_hnotify();
17197+ if (hn) {
17198+ hn->hn_aufs_inode = inode;
17199+ hinode->hi_notify = hn;
17200+ err = au_hnotify_op.alloc(hinode);
17201+ AuTraceErr(err);
17202+ if (unlikely(err)) {
17203+ hinode->hi_notify = NULL;
17204+ au_cache_free_hnotify(hn);
17205+ /*
17206+ * The upper dir was removed by udba, but the same named
17207+ * dir left. In this case, aufs assigns a new inode
17208+ * number and set the monitor again.
17209+ * For the lower dir, the old monitor is still left.
17210+ */
17211+ if (err == -EEXIST)
17212+ err = 0;
17213+ }
17214+ }
17215+
17216+ AuTraceErr(err);
17217+ return err;
17218+}
17219+
17220+void au_hn_free(struct au_hinode *hinode)
17221+{
17222+ struct au_hnotify *hn;
17223+
17224+ hn = hinode->hi_notify;
17225+ if (hn) {
17226+ hinode->hi_notify = NULL;
17227+ if (au_hnotify_op.free(hinode, hn))
17228+ au_cache_free_hnotify(hn);
17229+ }
17230+}
17231+
17232+/* ---------------------------------------------------------------------- */
17233+
17234+void au_hn_ctl(struct au_hinode *hinode, int do_set)
17235+{
17236+ if (hinode->hi_notify)
17237+ au_hnotify_op.ctl(hinode, do_set);
17238+}
17239+
17240+void au_hn_reset(struct inode *inode, unsigned int flags)
17241+{
17242+ aufs_bindex_t bindex, bbot;
17243+ struct inode *hi;
17244+ struct dentry *iwhdentry;
17245+
17246+ bbot = au_ibbot(inode);
17247+ for (bindex = au_ibtop(inode); bindex <= bbot; bindex++) {
17248+ hi = au_h_iptr(inode, bindex);
17249+ if (!hi)
17250+ continue;
17251+
17252+ /* inode_lock_nested(hi, AuLsc_I_CHILD); */
17253+ iwhdentry = au_hi_wh(inode, bindex);
17254+ if (iwhdentry)
17255+ dget(iwhdentry);
17256+ au_igrab(hi);
17257+ au_set_h_iptr(inode, bindex, NULL, 0);
17258+ au_set_h_iptr(inode, bindex, au_igrab(hi),
17259+ flags & ~AuHi_XINO);
17260+ iput(hi);
17261+ dput(iwhdentry);
17262+ /* inode_unlock(hi); */
17263+ }
17264+}
17265+
17266+/* ---------------------------------------------------------------------- */
17267+
17268+static int hn_xino(struct inode *inode, struct inode *h_inode)
17269+{
17270+ int err;
17271+ aufs_bindex_t bindex, bbot, bfound, btop;
17272+ struct inode *h_i;
17273+
17274+ err = 0;
17275+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
17276+ pr_warn("branch root dir was changed\n");
17277+ goto out;
17278+ }
17279+
17280+ bfound = -1;
17281+ bbot = au_ibbot(inode);
17282+ btop = au_ibtop(inode);
17283+#if 0 /* reserved for future use */
17284+ if (bindex == bbot) {
17285+ /* keep this ino in rename case */
17286+ goto out;
17287+ }
17288+#endif
17289+ for (bindex = btop; bindex <= bbot; bindex++)
17290+ if (au_h_iptr(inode, bindex) == h_inode) {
17291+ bfound = bindex;
17292+ break;
17293+ }
17294+ if (bfound < 0)
17295+ goto out;
17296+
17297+ for (bindex = btop; bindex <= bbot; bindex++) {
17298+ h_i = au_h_iptr(inode, bindex);
17299+ if (!h_i)
17300+ continue;
17301+
17302+ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
17303+ /* ignore this error */
17304+ /* bad action? */
17305+ }
17306+
17307+ /* children inode number will be broken */
17308+
17309+out:
17310+ AuTraceErr(err);
17311+ return err;
17312+}
17313+
17314+static int hn_gen_tree(struct dentry *dentry)
17315+{
17316+ int err, i, j, ndentry;
17317+ struct au_dcsub_pages dpages;
17318+ struct au_dpage *dpage;
17319+ struct dentry **dentries;
17320+
17321+ err = au_dpages_init(&dpages, GFP_NOFS);
17322+ if (unlikely(err))
17323+ goto out;
17324+ err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
17325+ if (unlikely(err))
17326+ goto out_dpages;
17327+
17328+ for (i = 0; i < dpages.ndpage; i++) {
17329+ dpage = dpages.dpages + i;
17330+ dentries = dpage->dentries;
17331+ ndentry = dpage->ndentry;
17332+ for (j = 0; j < ndentry; j++) {
17333+ struct dentry *d;
17334+
17335+ d = dentries[j];
17336+ if (IS_ROOT(d))
17337+ continue;
17338+
17339+ au_digen_dec(d);
17340+ if (d_really_is_positive(d))
17341+ /* todo: reset children xino?
17342+ cached children only? */
17343+ au_iigen_dec(d_inode(d));
17344+ }
17345+ }
17346+
17347+out_dpages:
17348+ au_dpages_free(&dpages);
17349+out:
17350+ return err;
17351+}
17352+
17353+/*
17354+ * return 0 if processed.
17355+ */
17356+static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
17357+ const unsigned int isdir)
17358+{
17359+ int err;
17360+ struct dentry *d;
17361+ struct qstr *dname;
17362+
17363+ err = 1;
17364+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
17365+ pr_warn("branch root dir was changed\n");
17366+ err = 0;
17367+ goto out;
17368+ }
17369+
17370+ if (!isdir) {
17371+ AuDebugOn(!name);
17372+ au_iigen_dec(inode);
17373+ spin_lock(&inode->i_lock);
17374+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
17375+ spin_lock(&d->d_lock);
17376+ dname = &d->d_name;
17377+ if (dname->len != nlen
17378+ && memcmp(dname->name, name, nlen)) {
17379+ spin_unlock(&d->d_lock);
17380+ continue;
17381+ }
17382+ err = 0;
17383+ au_digen_dec(d);
17384+ spin_unlock(&d->d_lock);
17385+ break;
17386+ }
17387+ spin_unlock(&inode->i_lock);
17388+ } else {
17389+ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
17390+ d = d_find_any_alias(inode);
17391+ if (!d) {
17392+ au_iigen_dec(inode);
17393+ goto out;
17394+ }
17395+
17396+ spin_lock(&d->d_lock);
17397+ dname = &d->d_name;
17398+ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
17399+ spin_unlock(&d->d_lock);
17400+ err = hn_gen_tree(d);
17401+ spin_lock(&d->d_lock);
17402+ }
17403+ spin_unlock(&d->d_lock);
17404+ dput(d);
17405+ }
17406+
17407+out:
17408+ AuTraceErr(err);
17409+ return err;
17410+}
17411+
17412+static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
17413+{
17414+ int err;
17415+
17416+ if (IS_ROOT(dentry)) {
17417+ pr_warn("branch root dir was changed\n");
17418+ return 0;
17419+ }
17420+
17421+ err = 0;
17422+ if (!isdir) {
17423+ au_digen_dec(dentry);
17424+ if (d_really_is_positive(dentry))
17425+ au_iigen_dec(d_inode(dentry));
17426+ } else {
17427+ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
17428+ if (d_really_is_positive(dentry))
17429+ err = hn_gen_tree(dentry);
17430+ }
17431+
17432+ AuTraceErr(err);
17433+ return err;
17434+}
17435+
17436+/* ---------------------------------------------------------------------- */
17437+
17438+/* hnotify job flags */
17439+#define AuHnJob_XINO0 1
17440+#define AuHnJob_GEN (1 << 1)
17441+#define AuHnJob_DIRENT (1 << 2)
17442+#define AuHnJob_ISDIR (1 << 3)
17443+#define AuHnJob_TRYXINO0 (1 << 4)
17444+#define AuHnJob_MNTPNT (1 << 5)
17445+#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name)
17446+#define au_fset_hnjob(flags, name) \
17447+ do { (flags) |= AuHnJob_##name; } while (0)
17448+#define au_fclr_hnjob(flags, name) \
17449+ do { (flags) &= ~AuHnJob_##name; } while (0)
17450+
17451+enum {
17452+ AuHn_CHILD,
17453+ AuHn_PARENT,
17454+ AuHnLast
17455+};
17456+
17457+struct au_hnotify_args {
17458+ struct inode *h_dir, *dir, *h_child_inode;
17459+ u32 mask;
17460+ unsigned int flags[AuHnLast];
17461+ unsigned int h_child_nlen;
17462+ char h_child_name[];
17463+};
17464+
17465+struct hn_job_args {
17466+ unsigned int flags;
17467+ struct inode *inode, *h_inode, *dir, *h_dir;
17468+ struct dentry *dentry;
17469+ char *h_name;
17470+ int h_nlen;
17471+};
17472+
17473+static int hn_job(struct hn_job_args *a)
17474+{
17475+ const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
17476+ int e;
17477+
17478+ /* reset xino */
17479+ if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
17480+ hn_xino(a->inode, a->h_inode); /* ignore this error */
17481+
17482+ if (au_ftest_hnjob(a->flags, TRYXINO0)
17483+ && a->inode
17484+ && a->h_inode) {
17485+ inode_lock_shared_nested(a->h_inode, AuLsc_I_CHILD);
17486+ if (!a->h_inode->i_nlink
17487+ && !(a->h_inode->i_state & I_LINKABLE))
17488+ hn_xino(a->inode, a->h_inode); /* ignore this error */
17489+ inode_unlock_shared(a->h_inode);
17490+ }
17491+
17492+ /* make the generation obsolete */
17493+ if (au_ftest_hnjob(a->flags, GEN)) {
17494+ e = -1;
17495+ if (a->inode)
17496+ e = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
17497+ isdir);
17498+ if (e && a->dentry)
17499+ hn_gen_by_name(a->dentry, isdir);
17500+ /* ignore this error */
17501+ }
17502+
17503+ /* make dir entries obsolete */
17504+ if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
17505+ struct au_vdir *vdir;
17506+
17507+ vdir = au_ivdir(a->inode);
17508+ if (vdir)
17509+ vdir->vd_jiffy = 0;
17510+ /* IMustLock(a->inode); */
17511+ /* inode_inc_iversion(a->inode); */
17512+ }
17513+
17514+ /* can do nothing but warn */
17515+ if (au_ftest_hnjob(a->flags, MNTPNT)
17516+ && a->dentry
17517+ && d_mountpoint(a->dentry))
17518+ pr_warn("mount-point %pd is removed or renamed\n", a->dentry);
17519+
17520+ return 0;
17521+}
17522+
17523+/* ---------------------------------------------------------------------- */
17524+
17525+static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
17526+ struct inode *dir)
17527+{
17528+ struct dentry *dentry, *d, *parent;
17529+ struct qstr *dname;
17530+
17531+ parent = d_find_any_alias(dir);
17532+ if (!parent)
17533+ return NULL;
17534+
17535+ dentry = NULL;
17536+ spin_lock(&parent->d_lock);
17537+ list_for_each_entry(d, &parent->d_subdirs, d_child) {
17538+ /* AuDbg("%pd\n", d); */
17539+ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
17540+ dname = &d->d_name;
17541+ if (dname->len != nlen || memcmp(dname->name, name, nlen))
17542+ goto cont_unlock;
17543+ if (au_di(d))
17544+ au_digen_dec(d);
17545+ else
17546+ goto cont_unlock;
17547+ if (au_dcount(d) > 0) {
17548+ dentry = dget_dlock(d);
17549+ spin_unlock(&d->d_lock);
17550+ break;
17551+ }
17552+
17553+cont_unlock:
17554+ spin_unlock(&d->d_lock);
17555+ }
17556+ spin_unlock(&parent->d_lock);
17557+ dput(parent);
17558+
17559+ if (dentry)
17560+ di_write_lock_child(dentry);
17561+
17562+ return dentry;
17563+}
17564+
17565+static struct inode *lookup_wlock_by_ino(struct super_block *sb,
17566+ aufs_bindex_t bindex, ino_t h_ino)
17567+{
17568+ struct inode *inode;
17569+ ino_t ino;
17570+ int err;
17571+
17572+ inode = NULL;
17573+ err = au_xino_read(sb, bindex, h_ino, &ino);
17574+ if (!err && ino)
17575+ inode = ilookup(sb, ino);
17576+ if (!inode)
17577+ goto out;
17578+
17579+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
17580+ pr_warn("wrong root branch\n");
17581+ iput(inode);
17582+ inode = NULL;
17583+ goto out;
17584+ }
17585+
17586+ ii_write_lock_child(inode);
17587+
17588+out:
17589+ return inode;
17590+}
17591+
17592+static void au_hn_bh(void *_args)
17593+{
17594+ struct au_hnotify_args *a = _args;
17595+ struct super_block *sb;
17596+ aufs_bindex_t bindex, bbot, bfound;
17597+ unsigned char xino, try_iput;
17598+ int err;
17599+ struct inode *inode;
17600+ ino_t h_ino;
17601+ struct hn_job_args args;
17602+ struct dentry *dentry;
17603+ struct au_sbinfo *sbinfo;
17604+
17605+ AuDebugOn(!_args);
17606+ AuDebugOn(!a->h_dir);
17607+ AuDebugOn(!a->dir);
17608+ AuDebugOn(!a->mask);
17609+ AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
17610+ a->mask, a->dir->i_ino, a->h_dir->i_ino,
17611+ a->h_child_inode ? a->h_child_inode->i_ino : 0);
17612+
17613+ inode = NULL;
17614+ dentry = NULL;
17615+ /*
17616+ * do not lock a->dir->i_mutex here
17617+ * because of d_revalidate() may cause a deadlock.
17618+ */
17619+ sb = a->dir->i_sb;
17620+ AuDebugOn(!sb);
17621+ sbinfo = au_sbi(sb);
17622+ AuDebugOn(!sbinfo);
17623+ si_write_lock(sb, AuLock_NOPLMW);
17624+
17625+ if (au_opt_test(sbinfo->si_mntflags, DIRREN))
17626+ switch (a->mask & FS_EVENTS_POSS_ON_CHILD) {
17627+ case FS_MOVED_FROM:
17628+ case FS_MOVED_TO:
17629+ AuWarn1("DIRREN with UDBA may not work correctly "
17630+ "for the direct rename(2)\n");
17631+ }
17632+
17633+ ii_read_lock_parent(a->dir);
17634+ bfound = -1;
17635+ bbot = au_ibbot(a->dir);
17636+ for (bindex = au_ibtop(a->dir); bindex <= bbot; bindex++)
17637+ if (au_h_iptr(a->dir, bindex) == a->h_dir) {
17638+ bfound = bindex;
17639+ break;
17640+ }
17641+ ii_read_unlock(a->dir);
17642+ if (unlikely(bfound < 0))
17643+ goto out;
17644+
17645+ xino = !!au_opt_test(au_mntflags(sb), XINO);
17646+ h_ino = 0;
17647+ if (a->h_child_inode)
17648+ h_ino = a->h_child_inode->i_ino;
17649+
17650+ if (a->h_child_nlen
17651+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
17652+ || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
17653+ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
17654+ a->dir);
17655+ try_iput = 0;
17656+ if (dentry && d_really_is_positive(dentry))
17657+ inode = d_inode(dentry);
17658+ if (xino && !inode && h_ino
17659+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
17660+ || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
17661+ || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
17662+ inode = lookup_wlock_by_ino(sb, bfound, h_ino);
17663+ try_iput = 1;
17664+ }
17665+
17666+ args.flags = a->flags[AuHn_CHILD];
17667+ args.dentry = dentry;
17668+ args.inode = inode;
17669+ args.h_inode = a->h_child_inode;
17670+ args.dir = a->dir;
17671+ args.h_dir = a->h_dir;
17672+ args.h_name = a->h_child_name;
17673+ args.h_nlen = a->h_child_nlen;
17674+ err = hn_job(&args);
17675+ if (dentry) {
17676+ if (au_di(dentry))
17677+ di_write_unlock(dentry);
17678+ dput(dentry);
17679+ }
17680+ if (inode && try_iput) {
17681+ ii_write_unlock(inode);
17682+ iput(inode);
17683+ }
17684+
17685+ ii_write_lock_parent(a->dir);
17686+ args.flags = a->flags[AuHn_PARENT];
17687+ args.dentry = NULL;
17688+ args.inode = a->dir;
17689+ args.h_inode = a->h_dir;
17690+ args.dir = NULL;
17691+ args.h_dir = NULL;
17692+ args.h_name = NULL;
17693+ args.h_nlen = 0;
17694+ err = hn_job(&args);
17695+ ii_write_unlock(a->dir);
17696+
17697+out:
17698+ iput(a->h_child_inode);
17699+ iput(a->h_dir);
17700+ iput(a->dir);
17701+ si_write_unlock(sb);
17702+ au_nwt_done(&sbinfo->si_nowait);
17703+ au_kfree_rcu(a);
17704+}
17705+
17706+/* ---------------------------------------------------------------------- */
17707+
17708+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
17709+ const struct qstr *h_child_qstr, struct inode *h_child_inode)
17710+{
17711+ int err, len;
17712+ unsigned int flags[AuHnLast], f;
17713+ unsigned char isdir, isroot, wh;
17714+ struct inode *dir;
17715+ struct au_hnotify_args *args;
17716+ char *p, *h_child_name;
17717+
17718+ err = 0;
17719+ AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
17720+ dir = igrab(hnotify->hn_aufs_inode);
17721+ if (!dir)
17722+ goto out;
17723+
17724+ isroot = (dir->i_ino == AUFS_ROOT_INO);
17725+ wh = 0;
17726+ h_child_name = (void *)h_child_qstr->name;
17727+ len = h_child_qstr->len;
17728+ if (h_child_name) {
17729+ if (len > AUFS_WH_PFX_LEN
17730+ && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
17731+ h_child_name += AUFS_WH_PFX_LEN;
17732+ len -= AUFS_WH_PFX_LEN;
17733+ wh = 1;
17734+ }
17735+ }
17736+
17737+ isdir = 0;
17738+ if (h_child_inode)
17739+ isdir = !!S_ISDIR(h_child_inode->i_mode);
17740+ flags[AuHn_PARENT] = AuHnJob_ISDIR;
17741+ flags[AuHn_CHILD] = 0;
17742+ if (isdir)
17743+ flags[AuHn_CHILD] = AuHnJob_ISDIR;
17744+ au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
17745+ au_fset_hnjob(flags[AuHn_CHILD], GEN);
17746+ switch (mask & ALL_FSNOTIFY_DIRENT_EVENTS) {
17747+ case FS_MOVED_FROM:
17748+ case FS_MOVED_TO:
17749+ au_fset_hnjob(flags[AuHn_CHILD], XINO0);
17750+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
17751+ /*FALLTHROUGH*/
17752+ case FS_CREATE:
17753+ AuDebugOn(!h_child_name);
17754+ break;
17755+
17756+ case FS_DELETE:
17757+ /*
17758+ * aufs never be able to get this child inode.
17759+ * revalidation should be in d_revalidate()
17760+ * by checking i_nlink, i_generation or d_unhashed().
17761+ */
17762+ AuDebugOn(!h_child_name);
17763+ au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
17764+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
17765+ break;
17766+
17767+ default:
17768+ AuDebugOn(1);
17769+ }
17770+
17771+ if (wh)
17772+ h_child_inode = NULL;
17773+
17774+ err = -ENOMEM;
17775+ /* iput() and kfree() will be called in au_hnotify() */
17776+ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
17777+ if (unlikely(!args)) {
17778+ AuErr1("no memory\n");
17779+ iput(dir);
17780+ goto out;
17781+ }
17782+ args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
17783+ args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
17784+ args->mask = mask;
17785+ args->dir = dir;
17786+ args->h_dir = igrab(h_dir);
17787+ if (h_child_inode)
17788+ h_child_inode = igrab(h_child_inode); /* can be NULL */
17789+ args->h_child_inode = h_child_inode;
17790+ args->h_child_nlen = len;
17791+ if (len) {
17792+ p = (void *)args;
17793+ p += sizeof(*args);
17794+ memcpy(p, h_child_name, len);
17795+ p[len] = 0;
17796+ }
17797+
17798+ /* NFS fires the event for silly-renamed one from kworker */
17799+ f = 0;
17800+ if (!dir->i_nlink
17801+ || (au_test_nfs(h_dir->i_sb) && (mask & FS_DELETE)))
17802+ f = AuWkq_NEST;
17803+ err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
17804+ if (unlikely(err)) {
17805+ pr_err("wkq %d\n", err);
17806+ iput(args->h_child_inode);
17807+ iput(args->h_dir);
17808+ iput(args->dir);
17809+ au_kfree_rcu(args);
17810+ }
17811+
17812+out:
17813+ return err;
17814+}
17815+
17816+/* ---------------------------------------------------------------------- */
17817+
17818+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
17819+{
17820+ int err;
17821+
17822+ AuDebugOn(!(udba & AuOptMask_UDBA));
17823+
17824+ err = 0;
17825+ if (au_hnotify_op.reset_br)
17826+ err = au_hnotify_op.reset_br(udba, br, perm);
17827+
17828+ return err;
17829+}
17830+
17831+int au_hnotify_init_br(struct au_branch *br, int perm)
17832+{
17833+ int err;
17834+
17835+ err = 0;
17836+ if (au_hnotify_op.init_br)
17837+ err = au_hnotify_op.init_br(br, perm);
17838+
17839+ return err;
17840+}
17841+
17842+void au_hnotify_fin_br(struct au_branch *br)
17843+{
17844+ if (au_hnotify_op.fin_br)
17845+ au_hnotify_op.fin_br(br);
17846+}
17847+
17848+static void au_hn_destroy_cache(void)
17849+{
17850+ kmem_cache_destroy(au_cache[AuCache_HNOTIFY]);
17851+ au_cache[AuCache_HNOTIFY] = NULL;
17852+}
17853+
17854+int __init au_hnotify_init(void)
17855+{
17856+ int err;
17857+
17858+ err = -ENOMEM;
17859+ au_cache[AuCache_HNOTIFY] = AuCache(au_hnotify);
17860+ if (au_cache[AuCache_HNOTIFY]) {
17861+ err = 0;
17862+ if (au_hnotify_op.init)
17863+ err = au_hnotify_op.init();
17864+ if (unlikely(err))
17865+ au_hn_destroy_cache();
17866+ }
17867+ AuTraceErr(err);
17868+ return err;
17869+}
17870+
17871+void au_hnotify_fin(void)
17872+{
17873+ if (au_hnotify_op.fin)
17874+ au_hnotify_op.fin();
17875+
17876+ /* cf. au_cache_fin() */
17877+ if (au_cache[AuCache_HNOTIFY])
17878+ au_hn_destroy_cache();
17879+}
17880diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
17881--- /usr/share/empty/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100
17882+++ linux/fs/aufs/iinfo.c 2020-01-27 10:57:18.175538316 +0100
17883@@ -0,0 +1,286 @@
17884+// SPDX-License-Identifier: GPL-2.0
17885+/*
17886+ * Copyright (C) 2005-2020 Junjiro R. Okajima
17887+ *
17888+ * This program, aufs is free software; you can redistribute it and/or modify
17889+ * it under the terms of the GNU General Public License as published by
17890+ * the Free Software Foundation; either version 2 of the License, or
17891+ * (at your option) any later version.
17892+ *
17893+ * This program is distributed in the hope that it will be useful,
17894+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17895+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17896+ * GNU General Public License for more details.
17897+ *
17898+ * You should have received a copy of the GNU General Public License
17899+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
17900+ */
17901+
17902+/*
17903+ * inode private data
17904+ */
17905+
17906+#include "aufs.h"
17907+
17908+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
17909+{
17910+ struct inode *h_inode;
17911+ struct au_hinode *hinode;
17912+
17913+ IiMustAnyLock(inode);
17914+
17915+ hinode = au_hinode(au_ii(inode), bindex);
17916+ h_inode = hinode->hi_inode;
17917+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
17918+ return h_inode;
17919+}
17920+
17921+/* todo: hard/soft set? */
17922+void au_hiput(struct au_hinode *hinode)
17923+{
17924+ au_hn_free(hinode);
17925+ dput(hinode->hi_whdentry);
17926+ iput(hinode->hi_inode);
17927+}
17928+
17929+unsigned int au_hi_flags(struct inode *inode, int isdir)
17930+{
17931+ unsigned int flags;
17932+ const unsigned int mnt_flags = au_mntflags(inode->i_sb);
17933+
17934+ flags = 0;
17935+ if (au_opt_test(mnt_flags, XINO))
17936+ au_fset_hi(flags, XINO);
17937+ if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY))
17938+ au_fset_hi(flags, HNOTIFY);
17939+ return flags;
17940+}
17941+
17942+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
17943+ struct inode *h_inode, unsigned int flags)
17944+{
17945+ struct au_hinode *hinode;
17946+ struct inode *hi;
17947+ struct au_iinfo *iinfo = au_ii(inode);
17948+
17949+ IiMustWriteLock(inode);
17950+
17951+ hinode = au_hinode(iinfo, bindex);
17952+ hi = hinode->hi_inode;
17953+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
17954+
17955+ if (hi)
17956+ au_hiput(hinode);
17957+ hinode->hi_inode = h_inode;
17958+ if (h_inode) {
17959+ int err;
17960+ struct super_block *sb = inode->i_sb;
17961+ struct au_branch *br;
17962+
17963+ AuDebugOn(inode->i_mode
17964+ && (h_inode->i_mode & S_IFMT)
17965+ != (inode->i_mode & S_IFMT));
17966+ if (bindex == iinfo->ii_btop)
17967+ au_cpup_igen(inode, h_inode);
17968+ br = au_sbr(sb, bindex);
17969+ hinode->hi_id = br->br_id;
17970+ if (au_ftest_hi(flags, XINO)) {
17971+ err = au_xino_write(sb, bindex, h_inode->i_ino,
17972+ inode->i_ino);
17973+ if (unlikely(err))
17974+ AuIOErr1("failed au_xino_write() %d\n", err);
17975+ }
17976+
17977+ if (au_ftest_hi(flags, HNOTIFY)
17978+ && au_br_hnotifyable(br->br_perm)) {
17979+ err = au_hn_alloc(hinode, inode);
17980+ if (unlikely(err))
17981+ AuIOErr1("au_hn_alloc() %d\n", err);
17982+ }
17983+ }
17984+}
17985+
17986+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
17987+ struct dentry *h_wh)
17988+{
17989+ struct au_hinode *hinode;
17990+
17991+ IiMustWriteLock(inode);
17992+
17993+ hinode = au_hinode(au_ii(inode), bindex);
17994+ AuDebugOn(hinode->hi_whdentry);
17995+ hinode->hi_whdentry = h_wh;
17996+}
17997+
17998+void au_update_iigen(struct inode *inode, int half)
17999+{
18000+ struct au_iinfo *iinfo;
18001+ struct au_iigen *iigen;
18002+ unsigned int sigen;
18003+
18004+ sigen = au_sigen(inode->i_sb);
18005+ iinfo = au_ii(inode);
18006+ iigen = &iinfo->ii_generation;
18007+ spin_lock(&iigen->ig_spin);
18008+ iigen->ig_generation = sigen;
18009+ if (half)
18010+ au_ig_fset(iigen->ig_flags, HALF_REFRESHED);
18011+ else
18012+ au_ig_fclr(iigen->ig_flags, HALF_REFRESHED);
18013+ spin_unlock(&iigen->ig_spin);
18014+}
18015+
18016+/* it may be called at remount time, too */
18017+void au_update_ibrange(struct inode *inode, int do_put_zero)
18018+{
18019+ struct au_iinfo *iinfo;
18020+ aufs_bindex_t bindex, bbot;
18021+
18022+ AuDebugOn(au_is_bad_inode(inode));
18023+ IiMustWriteLock(inode);
18024+
18025+ iinfo = au_ii(inode);
18026+ if (do_put_zero && iinfo->ii_btop >= 0) {
18027+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot;
18028+ bindex++) {
18029+ struct inode *h_i;
18030+
18031+ h_i = au_hinode(iinfo, bindex)->hi_inode;
18032+ if (h_i
18033+ && !h_i->i_nlink
18034+ && !(h_i->i_state & I_LINKABLE))
18035+ au_set_h_iptr(inode, bindex, NULL, 0);
18036+ }
18037+ }
18038+
18039+ iinfo->ii_btop = -1;
18040+ iinfo->ii_bbot = -1;
18041+ bbot = au_sbbot(inode->i_sb);
18042+ for (bindex = 0; bindex <= bbot; bindex++)
18043+ if (au_hinode(iinfo, bindex)->hi_inode) {
18044+ iinfo->ii_btop = bindex;
18045+ break;
18046+ }
18047+ if (iinfo->ii_btop >= 0)
18048+ for (bindex = bbot; bindex >= iinfo->ii_btop; bindex--)
18049+ if (au_hinode(iinfo, bindex)->hi_inode) {
18050+ iinfo->ii_bbot = bindex;
18051+ break;
18052+ }
18053+ AuDebugOn(iinfo->ii_btop > iinfo->ii_bbot);
18054+}
18055+
18056+/* ---------------------------------------------------------------------- */
18057+
18058+void au_icntnr_init_once(void *_c)
18059+{
18060+ struct au_icntnr *c = _c;
18061+ struct au_iinfo *iinfo = &c->iinfo;
18062+
18063+ spin_lock_init(&iinfo->ii_generation.ig_spin);
18064+ au_rw_init(&iinfo->ii_rwsem);
18065+ inode_init_once(&c->vfs_inode);
18066+}
18067+
18068+void au_hinode_init(struct au_hinode *hinode)
18069+{
18070+ hinode->hi_inode = NULL;
18071+ hinode->hi_id = -1;
18072+ au_hn_init(hinode);
18073+ hinode->hi_whdentry = NULL;
18074+}
18075+
18076+int au_iinfo_init(struct inode *inode)
18077+{
18078+ struct au_iinfo *iinfo;
18079+ struct super_block *sb;
18080+ struct au_hinode *hi;
18081+ int nbr, i;
18082+
18083+ sb = inode->i_sb;
18084+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
18085+ nbr = au_sbbot(sb) + 1;
18086+ if (unlikely(nbr <= 0))
18087+ nbr = 1;
18088+ hi = kmalloc_array(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
18089+ if (hi) {
18090+ au_lcnt_inc(&au_sbi(sb)->si_ninodes);
18091+
18092+ iinfo->ii_hinode = hi;
18093+ for (i = 0; i < nbr; i++, hi++)
18094+ au_hinode_init(hi);
18095+
18096+ iinfo->ii_generation.ig_generation = au_sigen(sb);
18097+ iinfo->ii_btop = -1;
18098+ iinfo->ii_bbot = -1;
18099+ iinfo->ii_vdir = NULL;
18100+ return 0;
18101+ }
18102+ return -ENOMEM;
18103+}
18104+
18105+int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink)
18106+{
18107+ int err, i;
18108+ struct au_hinode *hip;
18109+
18110+ AuRwMustWriteLock(&iinfo->ii_rwsem);
18111+
18112+ err = -ENOMEM;
18113+ hip = au_krealloc(iinfo->ii_hinode, sizeof(*hip) * nbr, GFP_NOFS,
18114+ may_shrink);
18115+ if (hip) {
18116+ iinfo->ii_hinode = hip;
18117+ i = iinfo->ii_bbot + 1;
18118+ hip += i;
18119+ for (; i < nbr; i++, hip++)
18120+ au_hinode_init(hip);
18121+ err = 0;
18122+ }
18123+
18124+ return err;
18125+}
18126+
18127+void au_iinfo_fin(struct inode *inode)
18128+{
18129+ struct au_iinfo *iinfo;
18130+ struct au_hinode *hi;
18131+ struct super_block *sb;
18132+ aufs_bindex_t bindex, bbot;
18133+ const unsigned char unlinked = !inode->i_nlink;
18134+
18135+ AuDebugOn(au_is_bad_inode(inode));
18136+
18137+ sb = inode->i_sb;
18138+ au_lcnt_dec(&au_sbi(sb)->si_ninodes);
18139+ if (si_pid_test(sb))
18140+ au_xino_delete_inode(inode, unlinked);
18141+ else {
18142+ /*
18143+ * it is safe to hide the dependency between sbinfo and
18144+ * sb->s_umount.
18145+ */
18146+ lockdep_off();
18147+ si_noflush_read_lock(sb);
18148+ au_xino_delete_inode(inode, unlinked);
18149+ si_read_unlock(sb);
18150+ lockdep_on();
18151+ }
18152+
18153+ iinfo = au_ii(inode);
18154+ if (iinfo->ii_vdir)
18155+ au_vdir_free(iinfo->ii_vdir);
18156+
18157+ bindex = iinfo->ii_btop;
18158+ if (bindex >= 0) {
18159+ hi = au_hinode(iinfo, bindex);
18160+ bbot = iinfo->ii_bbot;
18161+ while (bindex++ <= bbot) {
18162+ if (hi->hi_inode)
18163+ au_hiput(hi);
18164+ hi++;
18165+ }
18166+ }
18167+ au_kfree_rcu(iinfo->ii_hinode);
18168+ AuRwDestroy(&iinfo->ii_rwsem);
18169+}
18170diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
18171--- /usr/share/empty/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100
18172+++ linux/fs/aufs/inode.c 2020-01-27 10:57:18.175538316 +0100
18173@@ -0,0 +1,529 @@
18174+// SPDX-License-Identifier: GPL-2.0
18175+/*
18176+ * Copyright (C) 2005-2020 Junjiro R. Okajima
18177+ *
18178+ * This program, aufs is free software; you can redistribute it and/or modify
18179+ * it under the terms of the GNU General Public License as published by
18180+ * the Free Software Foundation; either version 2 of the License, or
18181+ * (at your option) any later version.
18182+ *
18183+ * This program is distributed in the hope that it will be useful,
18184+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18185+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18186+ * GNU General Public License for more details.
18187+ *
18188+ * You should have received a copy of the GNU General Public License
18189+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18190+ */
18191+
18192+/*
18193+ * inode functions
18194+ */
18195+
18196+#include <linux/iversion.h>
18197+#include "aufs.h"
18198+
18199+struct inode *au_igrab(struct inode *inode)
18200+{
18201+ if (inode) {
18202+ AuDebugOn(!atomic_read(&inode->i_count));
18203+ ihold(inode);
18204+ }
18205+ return inode;
18206+}
18207+
18208+static void au_refresh_hinode_attr(struct inode *inode, int do_version)
18209+{
18210+ au_cpup_attr_all(inode, /*force*/0);
18211+ au_update_iigen(inode, /*half*/1);
18212+ if (do_version)
18213+ inode_inc_iversion(inode);
18214+}
18215+
18216+static int au_ii_refresh(struct inode *inode, int *update)
18217+{
18218+ int err, e, nbr;
18219+ umode_t type;
18220+ aufs_bindex_t bindex, new_bindex;
18221+ struct super_block *sb;
18222+ struct au_iinfo *iinfo;
18223+ struct au_hinode *p, *q, tmp;
18224+
18225+ AuDebugOn(au_is_bad_inode(inode));
18226+ IiMustWriteLock(inode);
18227+
18228+ *update = 0;
18229+ sb = inode->i_sb;
18230+ nbr = au_sbbot(sb) + 1;
18231+ type = inode->i_mode & S_IFMT;
18232+ iinfo = au_ii(inode);
18233+ err = au_hinode_realloc(iinfo, nbr, /*may_shrink*/0);
18234+ if (unlikely(err))
18235+ goto out;
18236+
18237+ AuDebugOn(iinfo->ii_btop < 0);
18238+ p = au_hinode(iinfo, iinfo->ii_btop);
18239+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot;
18240+ bindex++, p++) {
18241+ if (!p->hi_inode)
18242+ continue;
18243+
18244+ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT));
18245+ new_bindex = au_br_index(sb, p->hi_id);
18246+ if (new_bindex == bindex)
18247+ continue;
18248+
18249+ if (new_bindex < 0) {
18250+ *update = 1;
18251+ au_hiput(p);
18252+ p->hi_inode = NULL;
18253+ continue;
18254+ }
18255+
18256+ if (new_bindex < iinfo->ii_btop)
18257+ iinfo->ii_btop = new_bindex;
18258+ if (iinfo->ii_bbot < new_bindex)
18259+ iinfo->ii_bbot = new_bindex;
18260+ /* swap two lower inode, and loop again */
18261+ q = au_hinode(iinfo, new_bindex);
18262+ tmp = *q;
18263+ *q = *p;
18264+ *p = tmp;
18265+ if (tmp.hi_inode) {
18266+ bindex--;
18267+ p--;
18268+ }
18269+ }
18270+ au_update_ibrange(inode, /*do_put_zero*/0);
18271+ au_hinode_realloc(iinfo, nbr, /*may_shrink*/1); /* harmless if err */
18272+ e = au_dy_irefresh(inode);
18273+ if (unlikely(e && !err))
18274+ err = e;
18275+
18276+out:
18277+ AuTraceErr(err);
18278+ return err;
18279+}
18280+
18281+void au_refresh_iop(struct inode *inode, int force_getattr)
18282+{
18283+ int type;
18284+ struct au_sbinfo *sbi = au_sbi(inode->i_sb);
18285+ const struct inode_operations *iop
18286+ = force_getattr ? aufs_iop : sbi->si_iop_array;
18287+
18288+ if (inode->i_op == iop)
18289+ return;
18290+
18291+ switch (inode->i_mode & S_IFMT) {
18292+ case S_IFDIR:
18293+ type = AuIop_DIR;
18294+ break;
18295+ case S_IFLNK:
18296+ type = AuIop_SYMLINK;
18297+ break;
18298+ default:
18299+ type = AuIop_OTHER;
18300+ break;
18301+ }
18302+
18303+ inode->i_op = iop + type;
18304+ /* unnecessary smp_wmb() */
18305+}
18306+
18307+int au_refresh_hinode_self(struct inode *inode)
18308+{
18309+ int err, update;
18310+
18311+ err = au_ii_refresh(inode, &update);
18312+ if (!err)
18313+ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
18314+
18315+ AuTraceErr(err);
18316+ return err;
18317+}
18318+
18319+int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
18320+{
18321+ int err, e, update;
18322+ unsigned int flags;
18323+ umode_t mode;
18324+ aufs_bindex_t bindex, bbot;
18325+ unsigned char isdir;
18326+ struct au_hinode *p;
18327+ struct au_iinfo *iinfo;
18328+
18329+ err = au_ii_refresh(inode, &update);
18330+ if (unlikely(err))
18331+ goto out;
18332+
18333+ update = 0;
18334+ iinfo = au_ii(inode);
18335+ p = au_hinode(iinfo, iinfo->ii_btop);
18336+ mode = (inode->i_mode & S_IFMT);
18337+ isdir = S_ISDIR(mode);
18338+ flags = au_hi_flags(inode, isdir);
18339+ bbot = au_dbbot(dentry);
18340+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++) {
18341+ struct inode *h_i, *h_inode;
18342+ struct dentry *h_d;
18343+
18344+ h_d = au_h_dptr(dentry, bindex);
18345+ if (!h_d || d_is_negative(h_d))
18346+ continue;
18347+
18348+ h_inode = d_inode(h_d);
18349+ AuDebugOn(mode != (h_inode->i_mode & S_IFMT));
18350+ if (iinfo->ii_btop <= bindex && bindex <= iinfo->ii_bbot) {
18351+ h_i = au_h_iptr(inode, bindex);
18352+ if (h_i) {
18353+ if (h_i == h_inode)
18354+ continue;
18355+ err = -EIO;
18356+ break;
18357+ }
18358+ }
18359+ if (bindex < iinfo->ii_btop)
18360+ iinfo->ii_btop = bindex;
18361+ if (iinfo->ii_bbot < bindex)
18362+ iinfo->ii_bbot = bindex;
18363+ au_set_h_iptr(inode, bindex, au_igrab(h_inode), flags);
18364+ update = 1;
18365+ }
18366+ au_update_ibrange(inode, /*do_put_zero*/0);
18367+ e = au_dy_irefresh(inode);
18368+ if (unlikely(e && !err))
18369+ err = e;
18370+ if (!err)
18371+ au_refresh_hinode_attr(inode, update && isdir);
18372+
18373+out:
18374+ AuTraceErr(err);
18375+ return err;
18376+}
18377+
18378+static int set_inode(struct inode *inode, struct dentry *dentry)
18379+{
18380+ int err;
18381+ unsigned int flags;
18382+ umode_t mode;
18383+ aufs_bindex_t bindex, btop, btail;
18384+ unsigned char isdir;
18385+ struct dentry *h_dentry;
18386+ struct inode *h_inode;
18387+ struct au_iinfo *iinfo;
18388+ const struct inode_operations *iop;
18389+
18390+ IiMustWriteLock(inode);
18391+
18392+ err = 0;
18393+ isdir = 0;
18394+ iop = au_sbi(inode->i_sb)->si_iop_array;
18395+ btop = au_dbtop(dentry);
18396+ h_dentry = au_h_dptr(dentry, btop);
18397+ h_inode = d_inode(h_dentry);
18398+ mode = h_inode->i_mode;
18399+ switch (mode & S_IFMT) {
18400+ case S_IFREG:
18401+ btail = au_dbtail(dentry);
18402+ inode->i_op = iop + AuIop_OTHER;
18403+ inode->i_fop = &aufs_file_fop;
18404+ err = au_dy_iaop(inode, btop, h_inode);
18405+ if (unlikely(err))
18406+ goto out;
18407+ break;
18408+ case S_IFDIR:
18409+ isdir = 1;
18410+ btail = au_dbtaildir(dentry);
18411+ inode->i_op = iop + AuIop_DIR;
18412+ inode->i_fop = &aufs_dir_fop;
18413+ break;
18414+ case S_IFLNK:
18415+ btail = au_dbtail(dentry);
18416+ inode->i_op = iop + AuIop_SYMLINK;
18417+ break;
18418+ case S_IFBLK:
18419+ case S_IFCHR:
18420+ case S_IFIFO:
18421+ case S_IFSOCK:
18422+ btail = au_dbtail(dentry);
18423+ inode->i_op = iop + AuIop_OTHER;
18424+ init_special_inode(inode, mode, h_inode->i_rdev);
18425+ break;
18426+ default:
18427+ AuIOErr("Unknown file type 0%o\n", mode);
18428+ err = -EIO;
18429+ goto out;
18430+ }
18431+
18432+ /* do not set hnotify for whiteouted dirs (SHWH mode) */
18433+ flags = au_hi_flags(inode, isdir);
18434+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
18435+ && au_ftest_hi(flags, HNOTIFY)
18436+ && dentry->d_name.len > AUFS_WH_PFX_LEN
18437+ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
18438+ au_fclr_hi(flags, HNOTIFY);
18439+ iinfo = au_ii(inode);
18440+ iinfo->ii_btop = btop;
18441+ iinfo->ii_bbot = btail;
18442+ for (bindex = btop; bindex <= btail; bindex++) {
18443+ h_dentry = au_h_dptr(dentry, bindex);
18444+ if (h_dentry)
18445+ au_set_h_iptr(inode, bindex,
18446+ au_igrab(d_inode(h_dentry)), flags);
18447+ }
18448+ au_cpup_attr_all(inode, /*force*/1);
18449+ /*
18450+ * to force calling aufs_get_acl() every time,
18451+ * do not call cache_no_acl() for aufs inode.
18452+ */
18453+
18454+out:
18455+ return err;
18456+}
18457+
18458+/*
18459+ * successful returns with iinfo write_locked
18460+ * minus: errno
18461+ * zero: success, matched
18462+ * plus: no error, but unmatched
18463+ */
18464+static int reval_inode(struct inode *inode, struct dentry *dentry)
18465+{
18466+ int err;
18467+ unsigned int gen, igflags;
18468+ aufs_bindex_t bindex, bbot;
18469+ struct inode *h_inode, *h_dinode;
18470+ struct dentry *h_dentry;
18471+
18472+ /*
18473+ * before this function, if aufs got any iinfo lock, it must be only
18474+ * one, the parent dir.
18475+ * it can happen by UDBA and the obsoleted inode number.
18476+ */
18477+ err = -EIO;
18478+ if (unlikely(inode->i_ino == parent_ino(dentry)))
18479+ goto out;
18480+
18481+ err = 1;
18482+ ii_write_lock_new_child(inode);
18483+ h_dentry = au_h_dptr(dentry, au_dbtop(dentry));
18484+ h_dinode = d_inode(h_dentry);
18485+ bbot = au_ibbot(inode);
18486+ for (bindex = au_ibtop(inode); bindex <= bbot; bindex++) {
18487+ h_inode = au_h_iptr(inode, bindex);
18488+ if (!h_inode || h_inode != h_dinode)
18489+ continue;
18490+
18491+ err = 0;
18492+ gen = au_iigen(inode, &igflags);
18493+ if (gen == au_digen(dentry)
18494+ && !au_ig_ftest(igflags, HALF_REFRESHED))
18495+ break;
18496+
18497+ /* fully refresh inode using dentry */
18498+ err = au_refresh_hinode(inode, dentry);
18499+ if (!err)
18500+ au_update_iigen(inode, /*half*/0);
18501+ break;
18502+ }
18503+
18504+ if (unlikely(err))
18505+ ii_write_unlock(inode);
18506+out:
18507+ return err;
18508+}
18509+
18510+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
18511+ unsigned int d_type, ino_t *ino)
18512+{
18513+ int err, idx;
18514+ const int isnondir = d_type != DT_DIR;
18515+
18516+ /* prevent hardlinked inode number from race condition */
18517+ if (isnondir) {
18518+ err = au_xinondir_enter(sb, bindex, h_ino, &idx);
18519+ if (unlikely(err))
18520+ goto out;
18521+ }
18522+
18523+ err = au_xino_read(sb, bindex, h_ino, ino);
18524+ if (unlikely(err))
18525+ goto out_xinondir;
18526+
18527+ if (!*ino) {
18528+ err = -EIO;
18529+ *ino = au_xino_new_ino(sb);
18530+ if (unlikely(!*ino))
18531+ goto out_xinondir;
18532+ err = au_xino_write(sb, bindex, h_ino, *ino);
18533+ if (unlikely(err))
18534+ goto out_xinondir;
18535+ }
18536+
18537+out_xinondir:
18538+ if (isnondir && idx >= 0)
18539+ au_xinondir_leave(sb, bindex, h_ino, idx);
18540+out:
18541+ return err;
18542+}
18543+
18544+/* successful returns with iinfo write_locked */
18545+/* todo: return with unlocked? */
18546+struct inode *au_new_inode(struct dentry *dentry, int must_new)
18547+{
18548+ struct inode *inode, *h_inode;
18549+ struct dentry *h_dentry;
18550+ struct super_block *sb;
18551+ ino_t h_ino, ino;
18552+ int err, idx, hlinked;
18553+ aufs_bindex_t btop;
18554+
18555+ sb = dentry->d_sb;
18556+ btop = au_dbtop(dentry);
18557+ h_dentry = au_h_dptr(dentry, btop);
18558+ h_inode = d_inode(h_dentry);
18559+ h_ino = h_inode->i_ino;
18560+ hlinked = !d_is_dir(h_dentry) && h_inode->i_nlink > 1;
18561+
18562+new_ino:
18563+ /*
18564+ * stop 'race'-ing between hardlinks under different
18565+ * parents.
18566+ */
18567+ if (hlinked) {
18568+ err = au_xinondir_enter(sb, btop, h_ino, &idx);
18569+ inode = ERR_PTR(err);
18570+ if (unlikely(err))
18571+ goto out;
18572+ }
18573+
18574+ err = au_xino_read(sb, btop, h_ino, &ino);
18575+ inode = ERR_PTR(err);
18576+ if (unlikely(err))
18577+ goto out_xinondir;
18578+
18579+ if (!ino) {
18580+ ino = au_xino_new_ino(sb);
18581+ if (unlikely(!ino)) {
18582+ inode = ERR_PTR(-EIO);
18583+ goto out_xinondir;
18584+ }
18585+ }
18586+
18587+ AuDbg("i%lu\n", (unsigned long)ino);
18588+ inode = au_iget_locked(sb, ino);
18589+ err = PTR_ERR(inode);
18590+ if (IS_ERR(inode))
18591+ goto out_xinondir;
18592+
18593+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
18594+ if (inode->i_state & I_NEW) {
18595+ ii_write_lock_new_child(inode);
18596+ err = set_inode(inode, dentry);
18597+ if (!err) {
18598+ unlock_new_inode(inode);
18599+ goto out_xinondir; /* success */
18600+ }
18601+
18602+ /*
18603+ * iget_failed() calls iput(), but we need to call
18604+ * ii_write_unlock() after iget_failed(). so dirty hack for
18605+ * i_count.
18606+ */
18607+ atomic_inc(&inode->i_count);
18608+ iget_failed(inode);
18609+ ii_write_unlock(inode);
18610+ au_xino_write(sb, btop, h_ino, /*ino*/0);
18611+ /* ignore this error */
18612+ goto out_iput;
18613+ } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) {
18614+ /*
18615+ * horrible race condition between lookup, readdir and copyup
18616+ * (or something).
18617+ */
18618+ if (hlinked && idx >= 0)
18619+ au_xinondir_leave(sb, btop, h_ino, idx);
18620+ err = reval_inode(inode, dentry);
18621+ if (unlikely(err < 0)) {
18622+ hlinked = 0;
18623+ goto out_iput;
18624+ }
18625+ if (!err)
18626+ goto out; /* success */
18627+ else if (hlinked && idx >= 0) {
18628+ err = au_xinondir_enter(sb, btop, h_ino, &idx);
18629+ if (unlikely(err)) {
18630+ iput(inode);
18631+ inode = ERR_PTR(err);
18632+ goto out;
18633+ }
18634+ }
18635+ }
18636+
18637+ if (unlikely(au_test_fs_unique_ino(h_inode)))
18638+ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
18639+ " b%d, %s, %pd, hi%lu, i%lu.\n",
18640+ btop, au_sbtype(h_dentry->d_sb), dentry,
18641+ (unsigned long)h_ino, (unsigned long)ino);
18642+ ino = 0;
18643+ err = au_xino_write(sb, btop, h_ino, /*ino*/0);
18644+ if (!err) {
18645+ iput(inode);
18646+ if (hlinked && idx >= 0)
18647+ au_xinondir_leave(sb, btop, h_ino, idx);
18648+ goto new_ino;
18649+ }
18650+
18651+out_iput:
18652+ iput(inode);
18653+ inode = ERR_PTR(err);
18654+out_xinondir:
18655+ if (hlinked && idx >= 0)
18656+ au_xinondir_leave(sb, btop, h_ino, idx);
18657+out:
18658+ return inode;
18659+}
18660+
18661+/* ---------------------------------------------------------------------- */
18662+
18663+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
18664+ struct inode *inode)
18665+{
18666+ int err;
18667+ struct inode *hi;
18668+
18669+ err = au_br_rdonly(au_sbr(sb, bindex));
18670+
18671+ /* pseudo-link after flushed may happen out of bounds */
18672+ if (!err
18673+ && inode
18674+ && au_ibtop(inode) <= bindex
18675+ && bindex <= au_ibbot(inode)) {
18676+ /*
18677+ * permission check is unnecessary since vfsub routine
18678+ * will be called later
18679+ */
18680+ hi = au_h_iptr(inode, bindex);
18681+ if (hi)
18682+ err = IS_IMMUTABLE(hi) ? -EROFS : 0;
18683+ }
18684+
18685+ return err;
18686+}
18687+
18688+int au_test_h_perm(struct inode *h_inode, int mask)
18689+{
18690+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
18691+ return 0;
18692+ return inode_permission(h_inode, mask);
18693+}
18694+
18695+int au_test_h_perm_sio(struct inode *h_inode, int mask)
18696+{
18697+ if (au_test_nfs(h_inode->i_sb)
18698+ && (mask & MAY_WRITE)
18699+ && S_ISDIR(h_inode->i_mode))
18700+ mask |= MAY_READ; /* force permission check */
18701+ return au_test_h_perm(h_inode, mask);
18702+}
18703diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
18704--- /usr/share/empty/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
18705+++ linux/fs/aufs/inode.h 2020-01-27 10:57:18.175538316 +0100
18706@@ -0,0 +1,698 @@
18707+/* SPDX-License-Identifier: GPL-2.0 */
18708+/*
18709+ * Copyright (C) 2005-2020 Junjiro R. Okajima
18710+ *
18711+ * This program, aufs is free software; you can redistribute it and/or modify
18712+ * it under the terms of the GNU General Public License as published by
18713+ * the Free Software Foundation; either version 2 of the License, or
18714+ * (at your option) any later version.
18715+ *
18716+ * This program is distributed in the hope that it will be useful,
18717+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18718+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18719+ * GNU General Public License for more details.
18720+ *
18721+ * You should have received a copy of the GNU General Public License
18722+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18723+ */
18724+
18725+/*
18726+ * inode operations
18727+ */
18728+
18729+#ifndef __AUFS_INODE_H__
18730+#define __AUFS_INODE_H__
18731+
18732+#ifdef __KERNEL__
18733+
18734+#include <linux/fsnotify.h>
18735+#include "rwsem.h"
18736+
18737+struct vfsmount;
18738+
18739+struct au_hnotify {
18740+#ifdef CONFIG_AUFS_HNOTIFY
18741+#ifdef CONFIG_AUFS_HFSNOTIFY
18742+ /* never use fsnotify_add_vfsmount_mark() */
18743+ struct fsnotify_mark hn_mark;
18744+#endif
18745+ struct inode *hn_aufs_inode; /* no get/put */
18746+ struct rcu_head rcu;
18747+#endif
18748+} ____cacheline_aligned_in_smp;
18749+
18750+struct au_hinode {
18751+ struct inode *hi_inode;
18752+ aufs_bindex_t hi_id;
18753+#ifdef CONFIG_AUFS_HNOTIFY
18754+ struct au_hnotify *hi_notify;
18755+#endif
18756+
18757+ /* reference to the copied-up whiteout with get/put */
18758+ struct dentry *hi_whdentry;
18759+};
18760+
18761+/* ig_flags */
18762+#define AuIG_HALF_REFRESHED 1
18763+#define au_ig_ftest(flags, name) ((flags) & AuIG_##name)
18764+#define au_ig_fset(flags, name) \
18765+ do { (flags) |= AuIG_##name; } while (0)
18766+#define au_ig_fclr(flags, name) \
18767+ do { (flags) &= ~AuIG_##name; } while (0)
18768+
18769+struct au_iigen {
18770+ spinlock_t ig_spin;
18771+ __u32 ig_generation, ig_flags;
18772+};
18773+
18774+struct au_vdir;
18775+struct au_iinfo {
18776+ struct au_iigen ii_generation;
18777+ struct super_block *ii_hsb1; /* no get/put */
18778+
18779+ struct au_rwsem ii_rwsem;
18780+ aufs_bindex_t ii_btop, ii_bbot;
18781+ __u32 ii_higen;
18782+ struct au_hinode *ii_hinode;
18783+ struct au_vdir *ii_vdir;
18784+};
18785+
18786+struct au_icntnr {
18787+ struct au_iinfo iinfo;
18788+ struct inode vfs_inode;
18789+ struct hlist_bl_node plink;
18790+ struct rcu_head rcu;
18791+} ____cacheline_aligned_in_smp;
18792+
18793+/* au_pin flags */
18794+#define AuPin_DI_LOCKED 1
18795+#define AuPin_MNT_WRITE (1 << 1)
18796+#define au_ftest_pin(flags, name) ((flags) & AuPin_##name)
18797+#define au_fset_pin(flags, name) \
18798+ do { (flags) |= AuPin_##name; } while (0)
18799+#define au_fclr_pin(flags, name) \
18800+ do { (flags) &= ~AuPin_##name; } while (0)
18801+
18802+struct au_pin {
18803+ /* input */
18804+ struct dentry *dentry;
18805+ unsigned int udba;
18806+ unsigned char lsc_di, lsc_hi, flags;
18807+ aufs_bindex_t bindex;
18808+
18809+ /* output */
18810+ struct dentry *parent;
18811+ struct au_hinode *hdir;
18812+ struct vfsmount *h_mnt;
18813+
18814+ /* temporary unlock/relock for copyup */
18815+ struct dentry *h_dentry, *h_parent;
18816+ struct au_branch *br;
18817+ struct task_struct *task;
18818+};
18819+
18820+void au_pin_hdir_unlock(struct au_pin *p);
18821+int au_pin_hdir_lock(struct au_pin *p);
18822+int au_pin_hdir_relock(struct au_pin *p);
18823+void au_pin_hdir_acquire_nest(struct au_pin *p);
18824+void au_pin_hdir_release(struct au_pin *p);
18825+
18826+/* ---------------------------------------------------------------------- */
18827+
18828+static inline struct au_iinfo *au_ii(struct inode *inode)
18829+{
18830+ BUG_ON(is_bad_inode(inode));
18831+ return &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
18832+}
18833+
18834+/* ---------------------------------------------------------------------- */
18835+
18836+/* inode.c */
18837+struct inode *au_igrab(struct inode *inode);
18838+void au_refresh_iop(struct inode *inode, int force_getattr);
18839+int au_refresh_hinode_self(struct inode *inode);
18840+int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
18841+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
18842+ unsigned int d_type, ino_t *ino);
18843+struct inode *au_new_inode(struct dentry *dentry, int must_new);
18844+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
18845+ struct inode *inode);
18846+int au_test_h_perm(struct inode *h_inode, int mask);
18847+int au_test_h_perm_sio(struct inode *h_inode, int mask);
18848+
18849+static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex,
18850+ ino_t h_ino, unsigned int d_type, ino_t *ino)
18851+{
18852+#ifdef CONFIG_AUFS_SHWH
18853+ return au_ino(sb, bindex, h_ino, d_type, ino);
18854+#else
18855+ return 0;
18856+#endif
18857+}
18858+
18859+/* i_op.c */
18860+enum {
18861+ AuIop_SYMLINK,
18862+ AuIop_DIR,
18863+ AuIop_OTHER,
18864+ AuIop_Last
18865+};
18866+extern struct inode_operations aufs_iop[AuIop_Last], /* not const */
18867+ aufs_iop_nogetattr[AuIop_Last];
18868+
18869+/* au_wr_dir flags */
18870+#define AuWrDir_ADD_ENTRY 1
18871+#define AuWrDir_ISDIR (1 << 1)
18872+#define AuWrDir_TMPFILE (1 << 2)
18873+#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
18874+#define au_fset_wrdir(flags, name) \
18875+ do { (flags) |= AuWrDir_##name; } while (0)
18876+#define au_fclr_wrdir(flags, name) \
18877+ do { (flags) &= ~AuWrDir_##name; } while (0)
18878+
18879+struct au_wr_dir_args {
18880+ aufs_bindex_t force_btgt;
18881+ unsigned char flags;
18882+};
18883+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
18884+ struct au_wr_dir_args *args);
18885+
18886+struct dentry *au_pinned_h_parent(struct au_pin *pin);
18887+void au_pin_init(struct au_pin *pin, struct dentry *dentry,
18888+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
18889+ unsigned int udba, unsigned char flags);
18890+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
18891+ unsigned int udba, unsigned char flags) __must_check;
18892+int au_do_pin(struct au_pin *pin) __must_check;
18893+void au_unpin(struct au_pin *pin);
18894+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen);
18895+
18896+#define AuIcpup_DID_CPUP 1
18897+#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
18898+#define au_fset_icpup(flags, name) \
18899+ do { (flags) |= AuIcpup_##name; } while (0)
18900+#define au_fclr_icpup(flags, name) \
18901+ do { (flags) &= ~AuIcpup_##name; } while (0)
18902+
18903+struct au_icpup_args {
18904+ unsigned char flags;
18905+ unsigned char pin_flags;
18906+ aufs_bindex_t btgt;
18907+ unsigned int udba;
18908+ struct au_pin pin;
18909+ struct path h_path;
18910+ struct inode *h_inode;
18911+};
18912+
18913+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
18914+ struct au_icpup_args *a);
18915+
18916+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path,
18917+ int locked);
18918+
18919+/* i_op_add.c */
18920+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
18921+ struct dentry *h_parent, int isdir);
18922+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
18923+ dev_t dev);
18924+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
18925+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
18926+ bool want_excl);
18927+struct vfsub_aopen_args;
18928+int au_aopen_or_create(struct inode *dir, struct dentry *dentry,
18929+ struct vfsub_aopen_args *args);
18930+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode);
18931+int aufs_link(struct dentry *src_dentry, struct inode *dir,
18932+ struct dentry *dentry);
18933+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
18934+
18935+/* i_op_del.c */
18936+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
18937+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
18938+ struct dentry *h_parent, int isdir);
18939+int aufs_unlink(struct inode *dir, struct dentry *dentry);
18940+int aufs_rmdir(struct inode *dir, struct dentry *dentry);
18941+
18942+/* i_op_ren.c */
18943+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
18944+int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
18945+ struct inode *dir, struct dentry *dentry,
18946+ unsigned int flags);
18947+
18948+/* iinfo.c */
18949+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
18950+void au_hiput(struct au_hinode *hinode);
18951+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
18952+ struct dentry *h_wh);
18953+unsigned int au_hi_flags(struct inode *inode, int isdir);
18954+
18955+/* hinode flags */
18956+#define AuHi_XINO 1
18957+#define AuHi_HNOTIFY (1 << 1)
18958+#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
18959+#define au_fset_hi(flags, name) \
18960+ do { (flags) |= AuHi_##name; } while (0)
18961+#define au_fclr_hi(flags, name) \
18962+ do { (flags) &= ~AuHi_##name; } while (0)
18963+
18964+#ifndef CONFIG_AUFS_HNOTIFY
18965+#undef AuHi_HNOTIFY
18966+#define AuHi_HNOTIFY 0
18967+#endif
18968+
18969+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
18970+ struct inode *h_inode, unsigned int flags);
18971+
18972+void au_update_iigen(struct inode *inode, int half);
18973+void au_update_ibrange(struct inode *inode, int do_put_zero);
18974+
18975+void au_icntnr_init_once(void *_c);
18976+void au_hinode_init(struct au_hinode *hinode);
18977+int au_iinfo_init(struct inode *inode);
18978+void au_iinfo_fin(struct inode *inode);
18979+int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink);
18980+
18981+#ifdef CONFIG_PROC_FS
18982+/* plink.c */
18983+int au_plink_maint(struct super_block *sb, int flags);
18984+struct au_sbinfo;
18985+void au_plink_maint_leave(struct au_sbinfo *sbinfo);
18986+int au_plink_maint_enter(struct super_block *sb);
18987+#ifdef CONFIG_AUFS_DEBUG
18988+void au_plink_list(struct super_block *sb);
18989+#else
18990+AuStubVoid(au_plink_list, struct super_block *sb)
18991+#endif
18992+int au_plink_test(struct inode *inode);
18993+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
18994+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
18995+ struct dentry *h_dentry);
18996+void au_plink_put(struct super_block *sb, int verbose);
18997+void au_plink_clean(struct super_block *sb, int verbose);
18998+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
18999+#else
19000+AuStubInt0(au_plink_maint, struct super_block *sb, int flags);
19001+AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo);
19002+AuStubInt0(au_plink_maint_enter, struct super_block *sb);
19003+AuStubVoid(au_plink_list, struct super_block *sb);
19004+AuStubInt0(au_plink_test, struct inode *inode);
19005+AuStub(struct dentry *, au_plink_lkup, return NULL,
19006+ struct inode *inode, aufs_bindex_t bindex);
19007+AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex,
19008+ struct dentry *h_dentry);
19009+AuStubVoid(au_plink_put, struct super_block *sb, int verbose);
19010+AuStubVoid(au_plink_clean, struct super_block *sb, int verbose);
19011+AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id);
19012+#endif /* CONFIG_PROC_FS */
19013+
19014+#ifdef CONFIG_AUFS_XATTR
19015+/* xattr.c */
19016+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags,
19017+ unsigned int verbose);
19018+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size);
19019+void au_xattr_init(struct super_block *sb);
19020+#else
19021+AuStubInt0(au_cpup_xattr, struct dentry *h_dst, struct dentry *h_src,
19022+ int ignore_flags, unsigned int verbose);
19023+AuStubVoid(au_xattr_init, struct super_block *sb);
19024+#endif
19025+
19026+#ifdef CONFIG_FS_POSIX_ACL
19027+struct posix_acl *aufs_get_acl(struct inode *inode, int type);
19028+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
19029+#endif
19030+
19031+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
19032+enum {
19033+ AU_XATTR_SET,
19034+ AU_ACL_SET
19035+};
19036+
19037+struct au_sxattr {
19038+ int type;
19039+ union {
19040+ struct {
19041+ const char *name;
19042+ const void *value;
19043+ size_t size;
19044+ int flags;
19045+ } set;
19046+ struct {
19047+ struct posix_acl *acl;
19048+ int type;
19049+ } acl_set;
19050+ } u;
19051+};
19052+ssize_t au_sxattr(struct dentry *dentry, struct inode *inode,
19053+ struct au_sxattr *arg);
19054+#endif
19055+
19056+/* ---------------------------------------------------------------------- */
19057+
19058+/* lock subclass for iinfo */
19059+enum {
19060+ AuLsc_II_CHILD, /* child first */
19061+ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */
19062+ AuLsc_II_CHILD3, /* copyup dirs */
19063+ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
19064+ AuLsc_II_PARENT2,
19065+ AuLsc_II_PARENT3, /* copyup dirs */
19066+ AuLsc_II_NEW_CHILD
19067+};
19068+
19069+/*
19070+ * ii_read_lock_child, ii_write_lock_child,
19071+ * ii_read_lock_child2, ii_write_lock_child2,
19072+ * ii_read_lock_child3, ii_write_lock_child3,
19073+ * ii_read_lock_parent, ii_write_lock_parent,
19074+ * ii_read_lock_parent2, ii_write_lock_parent2,
19075+ * ii_read_lock_parent3, ii_write_lock_parent3,
19076+ * ii_read_lock_new_child, ii_write_lock_new_child,
19077+ */
19078+#define AuReadLockFunc(name, lsc) \
19079+static inline void ii_read_lock_##name(struct inode *i) \
19080+{ \
19081+ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
19082+}
19083+
19084+#define AuWriteLockFunc(name, lsc) \
19085+static inline void ii_write_lock_##name(struct inode *i) \
19086+{ \
19087+ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
19088+}
19089+
19090+#define AuRWLockFuncs(name, lsc) \
19091+ AuReadLockFunc(name, lsc) \
19092+ AuWriteLockFunc(name, lsc)
19093+
19094+AuRWLockFuncs(child, CHILD);
19095+AuRWLockFuncs(child2, CHILD2);
19096+AuRWLockFuncs(child3, CHILD3);
19097+AuRWLockFuncs(parent, PARENT);
19098+AuRWLockFuncs(parent2, PARENT2);
19099+AuRWLockFuncs(parent3, PARENT3);
19100+AuRWLockFuncs(new_child, NEW_CHILD);
19101+
19102+#undef AuReadLockFunc
19103+#undef AuWriteLockFunc
19104+#undef AuRWLockFuncs
19105+
19106+#define ii_read_unlock(i) au_rw_read_unlock(&au_ii(i)->ii_rwsem)
19107+#define ii_write_unlock(i) au_rw_write_unlock(&au_ii(i)->ii_rwsem)
19108+#define ii_downgrade_lock(i) au_rw_dgrade_lock(&au_ii(i)->ii_rwsem)
19109+
19110+#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
19111+#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
19112+#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
19113+
19114+/* ---------------------------------------------------------------------- */
19115+
19116+static inline void au_icntnr_init(struct au_icntnr *c)
19117+{
19118+#ifdef CONFIG_AUFS_DEBUG
19119+ c->vfs_inode.i_mode = 0;
19120+#endif
19121+}
19122+
19123+static inline unsigned int au_iigen(struct inode *inode, unsigned int *igflags)
19124+{
19125+ unsigned int gen;
19126+ struct au_iinfo *iinfo;
19127+ struct au_iigen *iigen;
19128+
19129+ iinfo = au_ii(inode);
19130+ iigen = &iinfo->ii_generation;
19131+ spin_lock(&iigen->ig_spin);
19132+ if (igflags)
19133+ *igflags = iigen->ig_flags;
19134+ gen = iigen->ig_generation;
19135+ spin_unlock(&iigen->ig_spin);
19136+
19137+ return gen;
19138+}
19139+
19140+/* tiny test for inode number */
19141+/* tmpfs generation is too rough */
19142+static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
19143+{
19144+ struct au_iinfo *iinfo;
19145+
19146+ iinfo = au_ii(inode);
19147+ AuRwMustAnyLock(&iinfo->ii_rwsem);
19148+ return !(iinfo->ii_hsb1 == h_inode->i_sb
19149+ && iinfo->ii_higen == h_inode->i_generation);
19150+}
19151+
19152+static inline void au_iigen_dec(struct inode *inode)
19153+{
19154+ struct au_iinfo *iinfo;
19155+ struct au_iigen *iigen;
19156+
19157+ iinfo = au_ii(inode);
19158+ iigen = &iinfo->ii_generation;
19159+ spin_lock(&iigen->ig_spin);
19160+ iigen->ig_generation--;
19161+ spin_unlock(&iigen->ig_spin);
19162+}
19163+
19164+static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
19165+{
19166+ int err;
19167+
19168+ err = 0;
19169+ if (unlikely(inode && au_iigen(inode, NULL) != sigen))
19170+ err = -EIO;
19171+
19172+ return err;
19173+}
19174+
19175+/* ---------------------------------------------------------------------- */
19176+
19177+static inline struct au_hinode *au_hinode(struct au_iinfo *iinfo,
19178+ aufs_bindex_t bindex)
19179+{
19180+ return iinfo->ii_hinode + bindex;
19181+}
19182+
19183+static inline int au_is_bad_inode(struct inode *inode)
19184+{
19185+ return !!(is_bad_inode(inode) || !au_hinode(au_ii(inode), 0));
19186+}
19187+
19188+static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
19189+ aufs_bindex_t bindex)
19190+{
19191+ IiMustAnyLock(inode);
19192+ return au_hinode(au_ii(inode), bindex)->hi_id;
19193+}
19194+
19195+static inline aufs_bindex_t au_ibtop(struct inode *inode)
19196+{
19197+ IiMustAnyLock(inode);
19198+ return au_ii(inode)->ii_btop;
19199+}
19200+
19201+static inline aufs_bindex_t au_ibbot(struct inode *inode)
19202+{
19203+ IiMustAnyLock(inode);
19204+ return au_ii(inode)->ii_bbot;
19205+}
19206+
19207+static inline struct au_vdir *au_ivdir(struct inode *inode)
19208+{
19209+ IiMustAnyLock(inode);
19210+ return au_ii(inode)->ii_vdir;
19211+}
19212+
19213+static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
19214+{
19215+ IiMustAnyLock(inode);
19216+ return au_hinode(au_ii(inode), bindex)->hi_whdentry;
19217+}
19218+
19219+static inline void au_set_ibtop(struct inode *inode, aufs_bindex_t bindex)
19220+{
19221+ IiMustWriteLock(inode);
19222+ au_ii(inode)->ii_btop = bindex;
19223+}
19224+
19225+static inline void au_set_ibbot(struct inode *inode, aufs_bindex_t bindex)
19226+{
19227+ IiMustWriteLock(inode);
19228+ au_ii(inode)->ii_bbot = bindex;
19229+}
19230+
19231+static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
19232+{
19233+ IiMustWriteLock(inode);
19234+ au_ii(inode)->ii_vdir = vdir;
19235+}
19236+
19237+static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
19238+{
19239+ IiMustAnyLock(inode);
19240+ return au_hinode(au_ii(inode), bindex);
19241+}
19242+
19243+/* ---------------------------------------------------------------------- */
19244+
19245+static inline struct dentry *au_pinned_parent(struct au_pin *pin)
19246+{
19247+ if (pin)
19248+ return pin->parent;
19249+ return NULL;
19250+}
19251+
19252+static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
19253+{
19254+ if (pin && pin->hdir)
19255+ return pin->hdir->hi_inode;
19256+ return NULL;
19257+}
19258+
19259+static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
19260+{
19261+ if (pin)
19262+ return pin->hdir;
19263+ return NULL;
19264+}
19265+
19266+static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
19267+{
19268+ if (pin)
19269+ pin->dentry = dentry;
19270+}
19271+
19272+static inline void au_pin_set_parent_lflag(struct au_pin *pin,
19273+ unsigned char lflag)
19274+{
19275+ if (pin) {
19276+ if (lflag)
19277+ au_fset_pin(pin->flags, DI_LOCKED);
19278+ else
19279+ au_fclr_pin(pin->flags, DI_LOCKED);
19280+ }
19281+}
19282+
19283+#if 0 /* reserved */
19284+static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
19285+{
19286+ if (pin) {
19287+ dput(pin->parent);
19288+ pin->parent = dget(parent);
19289+ }
19290+}
19291+#endif
19292+
19293+/* ---------------------------------------------------------------------- */
19294+
19295+struct au_branch;
19296+#ifdef CONFIG_AUFS_HNOTIFY
19297+struct au_hnotify_op {
19298+ void (*ctl)(struct au_hinode *hinode, int do_set);
19299+ int (*alloc)(struct au_hinode *hinode);
19300+
19301+ /*
19302+ * if it returns true, the the caller should free hinode->hi_notify,
19303+ * otherwise ->free() frees it.
19304+ */
19305+ int (*free)(struct au_hinode *hinode,
19306+ struct au_hnotify *hn) __must_check;
19307+
19308+ void (*fin)(void);
19309+ int (*init)(void);
19310+
19311+ int (*reset_br)(unsigned int udba, struct au_branch *br, int perm);
19312+ void (*fin_br)(struct au_branch *br);
19313+ int (*init_br)(struct au_branch *br, int perm);
19314+};
19315+
19316+/* hnotify.c */
19317+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
19318+void au_hn_free(struct au_hinode *hinode);
19319+void au_hn_ctl(struct au_hinode *hinode, int do_set);
19320+void au_hn_reset(struct inode *inode, unsigned int flags);
19321+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
19322+ const struct qstr *h_child_qstr, struct inode *h_child_inode);
19323+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm);
19324+int au_hnotify_init_br(struct au_branch *br, int perm);
19325+void au_hnotify_fin_br(struct au_branch *br);
19326+int __init au_hnotify_init(void);
19327+void au_hnotify_fin(void);
19328+
19329+/* hfsnotify.c */
19330+extern const struct au_hnotify_op au_hnotify_op;
19331+
19332+static inline
19333+void au_hn_init(struct au_hinode *hinode)
19334+{
19335+ hinode->hi_notify = NULL;
19336+}
19337+
19338+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
19339+{
19340+ return hinode->hi_notify;
19341+}
19342+
19343+#else
19344+AuStub(int, au_hn_alloc, return -EOPNOTSUPP,
19345+ struct au_hinode *hinode __maybe_unused,
19346+ struct inode *inode __maybe_unused)
19347+AuStub(struct au_hnotify *, au_hn, return NULL, struct au_hinode *hinode)
19348+AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused)
19349+AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused,
19350+ int do_set __maybe_unused)
19351+AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused,
19352+ unsigned int flags __maybe_unused)
19353+AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused,
19354+ struct au_branch *br __maybe_unused,
19355+ int perm __maybe_unused)
19356+AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused,
19357+ int perm __maybe_unused)
19358+AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused)
19359+AuStubInt0(__init au_hnotify_init, void)
19360+AuStubVoid(au_hnotify_fin, void)
19361+AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused)
19362+#endif /* CONFIG_AUFS_HNOTIFY */
19363+
19364+static inline void au_hn_suspend(struct au_hinode *hdir)
19365+{
19366+ au_hn_ctl(hdir, /*do_set*/0);
19367+}
19368+
19369+static inline void au_hn_resume(struct au_hinode *hdir)
19370+{
19371+ au_hn_ctl(hdir, /*do_set*/1);
19372+}
19373+
19374+static inline void au_hn_inode_lock(struct au_hinode *hdir)
19375+{
19376+ inode_lock(hdir->hi_inode);
19377+ au_hn_suspend(hdir);
19378+}
19379+
19380+static inline void au_hn_inode_lock_nested(struct au_hinode *hdir,
19381+ unsigned int sc __maybe_unused)
19382+{
19383+ inode_lock_nested(hdir->hi_inode, sc);
19384+ au_hn_suspend(hdir);
19385+}
19386+
19387+#if 0 /* unused */
19388+#include "vfsub.h"
19389+static inline void au_hn_inode_lock_shared_nested(struct au_hinode *hdir,
19390+ unsigned int sc)
19391+{
19392+ inode_lock_shared_nested(hdir->hi_inode, sc);
19393+ au_hn_suspend(hdir);
19394+}
19395+#endif
19396+
19397+static inline void au_hn_inode_unlock(struct au_hinode *hdir)
19398+{
19399+ au_hn_resume(hdir);
19400+ inode_unlock(hdir->hi_inode);
19401+}
19402+
19403+#endif /* __KERNEL__ */
19404+#endif /* __AUFS_INODE_H__ */
19405diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c
19406--- /usr/share/empty/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100
19407+++ linux/fs/aufs/ioctl.c 2020-01-27 10:57:18.175538316 +0100
19408@@ -0,0 +1,220 @@
19409+// SPDX-License-Identifier: GPL-2.0
19410+/*
19411+ * Copyright (C) 2005-2020 Junjiro R. Okajima
19412+ *
19413+ * This program, aufs is free software; you can redistribute it and/or modify
19414+ * it under the terms of the GNU General Public License as published by
19415+ * the Free Software Foundation; either version 2 of the License, or
19416+ * (at your option) any later version.
19417+ *
19418+ * This program is distributed in the hope that it will be useful,
19419+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19420+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19421+ * GNU General Public License for more details.
19422+ *
19423+ * You should have received a copy of the GNU General Public License
19424+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19425+ */
19426+
19427+/*
19428+ * ioctl
19429+ * plink-management and readdir in userspace.
19430+ * assist the pathconf(3) wrapper library.
19431+ * move-down
19432+ * File-based Hierarchical Storage Management.
19433+ */
19434+
19435+#include <linux/compat.h>
19436+#include <linux/file.h>
19437+#include "aufs.h"
19438+
19439+static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
19440+{
19441+ int err, fd;
19442+ aufs_bindex_t wbi, bindex, bbot;
19443+ struct file *h_file;
19444+ struct super_block *sb;
19445+ struct dentry *root;
19446+ struct au_branch *br;
19447+ struct aufs_wbr_fd wbrfd = {
19448+ .oflags = au_dir_roflags,
19449+ .brid = -1
19450+ };
19451+ const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY
19452+ | O_NOATIME | O_CLOEXEC;
19453+
19454+ AuDebugOn(wbrfd.oflags & ~valid);
19455+
19456+ if (arg) {
19457+ err = copy_from_user(&wbrfd, arg, sizeof(wbrfd));
19458+ if (unlikely(err)) {
19459+ err = -EFAULT;
19460+ goto out;
19461+ }
19462+
19463+ err = -EINVAL;
19464+ AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid);
19465+ wbrfd.oflags |= au_dir_roflags;
19466+ AuDbg("0%o\n", wbrfd.oflags);
19467+ if (unlikely(wbrfd.oflags & ~valid))
19468+ goto out;
19469+ }
19470+
19471+ fd = get_unused_fd_flags(0);
19472+ err = fd;
19473+ if (unlikely(fd < 0))
19474+ goto out;
19475+
19476+ h_file = ERR_PTR(-EINVAL);
19477+ wbi = 0;
19478+ br = NULL;
19479+ sb = path->dentry->d_sb;
19480+ root = sb->s_root;
19481+ aufs_read_lock(root, AuLock_IR);
19482+ bbot = au_sbbot(sb);
19483+ if (wbrfd.brid >= 0) {
19484+ wbi = au_br_index(sb, wbrfd.brid);
19485+ if (unlikely(wbi < 0 || wbi > bbot))
19486+ goto out_unlock;
19487+ }
19488+
19489+ h_file = ERR_PTR(-ENOENT);
19490+ br = au_sbr(sb, wbi);
19491+ if (!au_br_writable(br->br_perm)) {
19492+ if (arg)
19493+ goto out_unlock;
19494+
19495+ bindex = wbi + 1;
19496+ wbi = -1;
19497+ for (; bindex <= bbot; bindex++) {
19498+ br = au_sbr(sb, bindex);
19499+ if (au_br_writable(br->br_perm)) {
19500+ wbi = bindex;
19501+ br = au_sbr(sb, wbi);
19502+ break;
19503+ }
19504+ }
19505+ }
19506+ AuDbg("wbi %d\n", wbi);
19507+ if (wbi >= 0)
19508+ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL,
19509+ /*force_wr*/0);
19510+
19511+out_unlock:
19512+ aufs_read_unlock(root, AuLock_IR);
19513+ err = PTR_ERR(h_file);
19514+ if (IS_ERR(h_file))
19515+ goto out_fd;
19516+
19517+ au_lcnt_dec(&br->br_nfiles); /* cf. au_h_open() */
19518+ fd_install(fd, h_file);
19519+ err = fd;
19520+ goto out; /* success */
19521+
19522+out_fd:
19523+ put_unused_fd(fd);
19524+out:
19525+ AuTraceErr(err);
19526+ return err;
19527+}
19528+
19529+/* ---------------------------------------------------------------------- */
19530+
19531+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
19532+{
19533+ long err;
19534+ struct dentry *dentry;
19535+
19536+ switch (cmd) {
19537+ case AUFS_CTL_RDU:
19538+ case AUFS_CTL_RDU_INO:
19539+ err = au_rdu_ioctl(file, cmd, arg);
19540+ break;
19541+
19542+ case AUFS_CTL_WBR_FD:
19543+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
19544+ break;
19545+
19546+ case AUFS_CTL_IBUSY:
19547+ err = au_ibusy_ioctl(file, arg);
19548+ break;
19549+
19550+ case AUFS_CTL_BRINFO:
19551+ err = au_brinfo_ioctl(file, arg);
19552+ break;
19553+
19554+ case AUFS_CTL_FHSM_FD:
19555+ dentry = file->f_path.dentry;
19556+ if (IS_ROOT(dentry))
19557+ err = au_fhsm_fd(dentry->d_sb, arg);
19558+ else
19559+ err = -ENOTTY;
19560+ break;
19561+
19562+ default:
19563+ /* do not call the lower */
19564+ AuDbg("0x%x\n", cmd);
19565+ err = -ENOTTY;
19566+ }
19567+
19568+ AuTraceErr(err);
19569+ return err;
19570+}
19571+
19572+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
19573+{
19574+ long err;
19575+
19576+ switch (cmd) {
19577+ case AUFS_CTL_MVDOWN:
19578+ err = au_mvdown(file->f_path.dentry, (void __user *)arg);
19579+ break;
19580+
19581+ case AUFS_CTL_WBR_FD:
19582+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
19583+ break;
19584+
19585+ default:
19586+ /* do not call the lower */
19587+ AuDbg("0x%x\n", cmd);
19588+ err = -ENOTTY;
19589+ }
19590+
19591+ AuTraceErr(err);
19592+ return err;
19593+}
19594+
19595+#ifdef CONFIG_COMPAT
19596+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
19597+ unsigned long arg)
19598+{
19599+ long err;
19600+
19601+ switch (cmd) {
19602+ case AUFS_CTL_RDU:
19603+ case AUFS_CTL_RDU_INO:
19604+ err = au_rdu_compat_ioctl(file, cmd, arg);
19605+ break;
19606+
19607+ case AUFS_CTL_IBUSY:
19608+ err = au_ibusy_compat_ioctl(file, arg);
19609+ break;
19610+
19611+ case AUFS_CTL_BRINFO:
19612+ err = au_brinfo_compat_ioctl(file, arg);
19613+ break;
19614+
19615+ default:
19616+ err = aufs_ioctl_dir(file, cmd, arg);
19617+ }
19618+
19619+ AuTraceErr(err);
19620+ return err;
19621+}
19622+
19623+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
19624+ unsigned long arg)
19625+{
19626+ return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg));
19627+}
19628+#endif
19629diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
19630--- /usr/share/empty/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
19631+++ linux/fs/aufs/i_op_add.c 2020-01-27 10:57:18.172204883 +0100
19632@@ -0,0 +1,936 @@
19633+// SPDX-License-Identifier: GPL-2.0
19634+/*
19635+ * Copyright (C) 2005-2020 Junjiro R. Okajima
19636+ *
19637+ * This program, aufs is free software; you can redistribute it and/or modify
19638+ * it under the terms of the GNU General Public License as published by
19639+ * the Free Software Foundation; either version 2 of the License, or
19640+ * (at your option) any later version.
19641+ *
19642+ * This program is distributed in the hope that it will be useful,
19643+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19644+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19645+ * GNU General Public License for more details.
19646+ *
19647+ * You should have received a copy of the GNU General Public License
19648+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19649+ */
19650+
19651+/*
19652+ * inode operations (add entry)
19653+ */
19654+
19655+#include <linux/iversion.h>
19656+#include "aufs.h"
19657+
19658+/*
19659+ * final procedure of adding a new entry, except link(2).
19660+ * remove whiteout, instantiate, copyup the parent dir's times and size
19661+ * and update version.
19662+ * if it failed, re-create the removed whiteout.
19663+ */
19664+static int epilog(struct inode *dir, aufs_bindex_t bindex,
19665+ struct dentry *wh_dentry, struct dentry *dentry)
19666+{
19667+ int err, rerr;
19668+ aufs_bindex_t bwh;
19669+ struct path h_path;
19670+ struct super_block *sb;
19671+ struct inode *inode, *h_dir;
19672+ struct dentry *wh;
19673+
19674+ bwh = -1;
19675+ sb = dir->i_sb;
19676+ if (wh_dentry) {
19677+ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */
19678+ IMustLock(h_dir);
19679+ AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
19680+ bwh = au_dbwh(dentry);
19681+ h_path.dentry = wh_dentry;
19682+ h_path.mnt = au_sbr_mnt(sb, bindex);
19683+ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
19684+ dentry);
19685+ if (unlikely(err))
19686+ goto out;
19687+ }
19688+
19689+ inode = au_new_inode(dentry, /*must_new*/1);
19690+ if (!IS_ERR(inode)) {
19691+ d_instantiate(dentry, inode);
19692+ dir = d_inode(dentry->d_parent); /* dir inode is locked */
19693+ IMustLock(dir);
19694+ au_dir_ts(dir, bindex);
19695+ inode_inc_iversion(dir);
19696+ au_fhsm_wrote(sb, bindex, /*force*/0);
19697+ return 0; /* success */
19698+ }
19699+
19700+ err = PTR_ERR(inode);
19701+ if (!wh_dentry)
19702+ goto out;
19703+
19704+ /* revert */
19705+ /* dir inode is locked */
19706+ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
19707+ rerr = PTR_ERR(wh);
19708+ if (IS_ERR(wh)) {
19709+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n",
19710+ dentry, err, rerr);
19711+ err = -EIO;
19712+ } else
19713+ dput(wh);
19714+
19715+out:
19716+ return err;
19717+}
19718+
19719+static int au_d_may_add(struct dentry *dentry)
19720+{
19721+ int err;
19722+
19723+ err = 0;
19724+ if (unlikely(d_unhashed(dentry)))
19725+ err = -ENOENT;
19726+ if (unlikely(d_really_is_positive(dentry)))
19727+ err = -EEXIST;
19728+ return err;
19729+}
19730+
19731+/*
19732+ * simple tests for the adding inode operations.
19733+ * following the checks in vfs, plus the parent-child relationship.
19734+ */
19735+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
19736+ struct dentry *h_parent, int isdir)
19737+{
19738+ int err;
19739+ umode_t h_mode;
19740+ struct dentry *h_dentry;
19741+ struct inode *h_inode;
19742+
19743+ err = -ENAMETOOLONG;
19744+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
19745+ goto out;
19746+
19747+ h_dentry = au_h_dptr(dentry, bindex);
19748+ if (d_really_is_negative(dentry)) {
19749+ err = -EEXIST;
19750+ if (unlikely(d_is_positive(h_dentry)))
19751+ goto out;
19752+ } else {
19753+ /* rename(2) case */
19754+ err = -EIO;
19755+ if (unlikely(d_is_negative(h_dentry)))
19756+ goto out;
19757+ h_inode = d_inode(h_dentry);
19758+ if (unlikely(!h_inode->i_nlink))
19759+ goto out;
19760+
19761+ h_mode = h_inode->i_mode;
19762+ if (!isdir) {
19763+ err = -EISDIR;
19764+ if (unlikely(S_ISDIR(h_mode)))
19765+ goto out;
19766+ } else if (unlikely(!S_ISDIR(h_mode))) {
19767+ err = -ENOTDIR;
19768+ goto out;
19769+ }
19770+ }
19771+
19772+ err = 0;
19773+ /* expected parent dir is locked */
19774+ if (unlikely(h_parent != h_dentry->d_parent))
19775+ err = -EIO;
19776+
19777+out:
19778+ AuTraceErr(err);
19779+ return err;
19780+}
19781+
19782+/*
19783+ * initial procedure of adding a new entry.
19784+ * prepare writable branch and the parent dir, lock it,
19785+ * and lookup whiteout for the new entry.
19786+ */
19787+static struct dentry*
19788+lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
19789+ struct dentry *src_dentry, struct au_pin *pin,
19790+ struct au_wr_dir_args *wr_dir_args)
19791+{
19792+ struct dentry *wh_dentry, *h_parent;
19793+ struct super_block *sb;
19794+ struct au_branch *br;
19795+ int err;
19796+ unsigned int udba;
19797+ aufs_bindex_t bcpup;
19798+
19799+ AuDbg("%pd\n", dentry);
19800+
19801+ err = au_wr_dir(dentry, src_dentry, wr_dir_args);
19802+ bcpup = err;
19803+ wh_dentry = ERR_PTR(err);
19804+ if (unlikely(err < 0))
19805+ goto out;
19806+
19807+ sb = dentry->d_sb;
19808+ udba = au_opt_udba(sb);
19809+ err = au_pin(pin, dentry, bcpup, udba,
19810+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
19811+ wh_dentry = ERR_PTR(err);
19812+ if (unlikely(err))
19813+ goto out;
19814+
19815+ h_parent = au_pinned_h_parent(pin);
19816+ if (udba != AuOpt_UDBA_NONE
19817+ && au_dbtop(dentry) == bcpup)
19818+ err = au_may_add(dentry, bcpup, h_parent,
19819+ au_ftest_wrdir(wr_dir_args->flags, ISDIR));
19820+ else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
19821+ err = -ENAMETOOLONG;
19822+ wh_dentry = ERR_PTR(err);
19823+ if (unlikely(err))
19824+ goto out_unpin;
19825+
19826+ br = au_sbr(sb, bcpup);
19827+ if (dt) {
19828+ struct path tmp = {
19829+ .dentry = h_parent,
19830+ .mnt = au_br_mnt(br)
19831+ };
19832+ au_dtime_store(dt, au_pinned_parent(pin), &tmp);
19833+ }
19834+
19835+ wh_dentry = NULL;
19836+ if (bcpup != au_dbwh(dentry))
19837+ goto out; /* success */
19838+
19839+ /*
19840+ * ENAMETOOLONG here means that if we allowed create such name, then it
19841+ * would not be able to removed in the future. So we don't allow such
19842+ * name here and we don't handle ENAMETOOLONG differently here.
19843+ */
19844+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
19845+
19846+out_unpin:
19847+ if (IS_ERR(wh_dentry))
19848+ au_unpin(pin);
19849+out:
19850+ return wh_dentry;
19851+}
19852+
19853+/* ---------------------------------------------------------------------- */
19854+
19855+enum { Mknod, Symlink, Creat };
19856+struct simple_arg {
19857+ int type;
19858+ union {
19859+ struct {
19860+ umode_t mode;
19861+ bool want_excl;
19862+ bool try_aopen;
19863+ struct vfsub_aopen_args *aopen;
19864+ } c;
19865+ struct {
19866+ const char *symname;
19867+ } s;
19868+ struct {
19869+ umode_t mode;
19870+ dev_t dev;
19871+ } m;
19872+ } u;
19873+};
19874+
19875+static int add_simple(struct inode *dir, struct dentry *dentry,
19876+ struct simple_arg *arg)
19877+{
19878+ int err, rerr;
19879+ aufs_bindex_t btop;
19880+ unsigned char created;
19881+ const unsigned char try_aopen
19882+ = (arg->type == Creat && arg->u.c.try_aopen);
19883+ struct vfsub_aopen_args *aopen = arg->u.c.aopen;
19884+ struct dentry *wh_dentry, *parent;
19885+ struct inode *h_dir;
19886+ struct super_block *sb;
19887+ struct au_branch *br;
19888+ /* to reduce stack size */
19889+ struct {
19890+ struct au_dtime dt;
19891+ struct au_pin pin;
19892+ struct path h_path;
19893+ struct au_wr_dir_args wr_dir_args;
19894+ } *a;
19895+
19896+ AuDbg("%pd\n", dentry);
19897+ IMustLock(dir);
19898+
19899+ err = -ENOMEM;
19900+ a = kmalloc(sizeof(*a), GFP_NOFS);
19901+ if (unlikely(!a))
19902+ goto out;
19903+ a->wr_dir_args.force_btgt = -1;
19904+ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY;
19905+
19906+ parent = dentry->d_parent; /* dir inode is locked */
19907+ if (!try_aopen) {
19908+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
19909+ if (unlikely(err))
19910+ goto out_free;
19911+ }
19912+ err = au_d_may_add(dentry);
19913+ if (unlikely(err))
19914+ goto out_unlock;
19915+ if (!try_aopen)
19916+ di_write_lock_parent(parent);
19917+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
19918+ &a->pin, &a->wr_dir_args);
19919+ err = PTR_ERR(wh_dentry);
19920+ if (IS_ERR(wh_dentry))
19921+ goto out_parent;
19922+
19923+ btop = au_dbtop(dentry);
19924+ sb = dentry->d_sb;
19925+ br = au_sbr(sb, btop);
19926+ a->h_path.dentry = au_h_dptr(dentry, btop);
19927+ a->h_path.mnt = au_br_mnt(br);
19928+ h_dir = au_pinned_h_dir(&a->pin);
19929+ switch (arg->type) {
19930+ case Creat:
19931+ if (!try_aopen || !h_dir->i_op->atomic_open) {
19932+ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode,
19933+ arg->u.c.want_excl);
19934+ created = !err;
19935+ if (!err && try_aopen)
19936+ aopen->file->f_mode |= FMODE_CREATED;
19937+ } else {
19938+ aopen->br = br;
19939+ err = vfsub_atomic_open(h_dir, a->h_path.dentry, aopen);
19940+ AuDbg("err %d\n", err);
19941+ AuDbgFile(aopen->file);
19942+ created = err >= 0
19943+ && !!(aopen->file->f_mode & FMODE_CREATED);
19944+ }
19945+ break;
19946+ case Symlink:
19947+ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname);
19948+ created = !err;
19949+ break;
19950+ case Mknod:
19951+ err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode,
19952+ arg->u.m.dev);
19953+ created = !err;
19954+ break;
19955+ default:
19956+ BUG();
19957+ }
19958+ if (unlikely(err < 0))
19959+ goto out_unpin;
19960+
19961+ err = epilog(dir, btop, wh_dentry, dentry);
19962+ if (!err)
19963+ goto out_unpin; /* success */
19964+
19965+ /* revert */
19966+ if (created /* && d_is_positive(a->h_path.dentry) */) {
19967+ /* no delegation since it is just created */
19968+ rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL,
19969+ /*force*/0);
19970+ if (rerr) {
19971+ AuIOErr("%pd revert failure(%d, %d)\n",
19972+ dentry, err, rerr);
19973+ err = -EIO;
19974+ }
19975+ au_dtime_revert(&a->dt);
19976+ }
19977+ if (try_aopen && h_dir->i_op->atomic_open
19978+ && (aopen->file->f_mode & FMODE_OPENED))
19979+ /* aopen->file is still opened */
19980+ au_lcnt_dec(&aopen->br->br_nfiles);
19981+
19982+out_unpin:
19983+ au_unpin(&a->pin);
19984+ dput(wh_dentry);
19985+out_parent:
19986+ if (!try_aopen)
19987+ di_write_unlock(parent);
19988+out_unlock:
19989+ if (unlikely(err)) {
19990+ au_update_dbtop(dentry);
19991+ d_drop(dentry);
19992+ }
19993+ if (!try_aopen)
19994+ aufs_read_unlock(dentry, AuLock_DW);
19995+out_free:
19996+ au_kfree_rcu(a);
19997+out:
19998+ return err;
19999+}
20000+
20001+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
20002+ dev_t dev)
20003+{
20004+ struct simple_arg arg = {
20005+ .type = Mknod,
20006+ .u.m = {
20007+ .mode = mode,
20008+ .dev = dev
20009+ }
20010+ };
20011+ return add_simple(dir, dentry, &arg);
20012+}
20013+
20014+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
20015+{
20016+ struct simple_arg arg = {
20017+ .type = Symlink,
20018+ .u.s.symname = symname
20019+ };
20020+ return add_simple(dir, dentry, &arg);
20021+}
20022+
20023+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
20024+ bool want_excl)
20025+{
20026+ struct simple_arg arg = {
20027+ .type = Creat,
20028+ .u.c = {
20029+ .mode = mode,
20030+ .want_excl = want_excl
20031+ }
20032+ };
20033+ return add_simple(dir, dentry, &arg);
20034+}
20035+
20036+int au_aopen_or_create(struct inode *dir, struct dentry *dentry,
20037+ struct vfsub_aopen_args *aopen_args)
20038+{
20039+ struct simple_arg arg = {
20040+ .type = Creat,
20041+ .u.c = {
20042+ .mode = aopen_args->create_mode,
20043+ .want_excl = aopen_args->open_flag & O_EXCL,
20044+ .try_aopen = true,
20045+ .aopen = aopen_args
20046+ }
20047+ };
20048+ return add_simple(dir, dentry, &arg);
20049+}
20050+
20051+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
20052+{
20053+ int err;
20054+ aufs_bindex_t bindex;
20055+ struct super_block *sb;
20056+ struct dentry *parent, *h_parent, *h_dentry;
20057+ struct inode *h_dir, *inode;
20058+ struct vfsmount *h_mnt;
20059+ struct au_wr_dir_args wr_dir_args = {
20060+ .force_btgt = -1,
20061+ .flags = AuWrDir_TMPFILE
20062+ };
20063+
20064+ /* copy-up may happen */
20065+ inode_lock(dir);
20066+
20067+ sb = dir->i_sb;
20068+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
20069+ if (unlikely(err))
20070+ goto out;
20071+
20072+ err = au_di_init(dentry);
20073+ if (unlikely(err))
20074+ goto out_si;
20075+
20076+ err = -EBUSY;
20077+ parent = d_find_any_alias(dir);
20078+ AuDebugOn(!parent);
20079+ di_write_lock_parent(parent);
20080+ if (unlikely(d_inode(parent) != dir))
20081+ goto out_parent;
20082+
20083+ err = au_digen_test(parent, au_sigen(sb));
20084+ if (unlikely(err))
20085+ goto out_parent;
20086+
20087+ bindex = au_dbtop(parent);
20088+ au_set_dbtop(dentry, bindex);
20089+ au_set_dbbot(dentry, bindex);
20090+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
20091+ bindex = err;
20092+ if (unlikely(err < 0))
20093+ goto out_parent;
20094+
20095+ err = -EOPNOTSUPP;
20096+ h_dir = au_h_iptr(dir, bindex);
20097+ if (unlikely(!h_dir->i_op->tmpfile))
20098+ goto out_parent;
20099+
20100+ h_mnt = au_sbr_mnt(sb, bindex);
20101+ err = vfsub_mnt_want_write(h_mnt);
20102+ if (unlikely(err))
20103+ goto out_parent;
20104+
20105+ h_parent = au_h_dptr(parent, bindex);
20106+ h_dentry = vfs_tmpfile(h_parent, mode, /*open_flag*/0);
20107+ if (IS_ERR(h_dentry)) {
20108+ err = PTR_ERR(h_dentry);
20109+ goto out_mnt;
20110+ }
20111+
20112+ au_set_dbtop(dentry, bindex);
20113+ au_set_dbbot(dentry, bindex);
20114+ au_set_h_dptr(dentry, bindex, dget(h_dentry));
20115+ inode = au_new_inode(dentry, /*must_new*/1);
20116+ if (IS_ERR(inode)) {
20117+ err = PTR_ERR(inode);
20118+ au_set_h_dptr(dentry, bindex, NULL);
20119+ au_set_dbtop(dentry, -1);
20120+ au_set_dbbot(dentry, -1);
20121+ } else {
20122+ if (!inode->i_nlink)
20123+ set_nlink(inode, 1);
20124+ d_tmpfile(dentry, inode);
20125+ au_di(dentry)->di_tmpfile = 1;
20126+
20127+ /* update without i_mutex */
20128+ if (au_ibtop(dir) == au_dbtop(dentry))
20129+ au_cpup_attr_timesizes(dir);
20130+ }
20131+ dput(h_dentry);
20132+
20133+out_mnt:
20134+ vfsub_mnt_drop_write(h_mnt);
20135+out_parent:
20136+ di_write_unlock(parent);
20137+ dput(parent);
20138+ di_write_unlock(dentry);
20139+ if (unlikely(err)) {
20140+ au_di_fin(dentry);
20141+ dentry->d_fsdata = NULL;
20142+ }
20143+out_si:
20144+ si_read_unlock(sb);
20145+out:
20146+ inode_unlock(dir);
20147+ return err;
20148+}
20149+
20150+/* ---------------------------------------------------------------------- */
20151+
20152+struct au_link_args {
20153+ aufs_bindex_t bdst, bsrc;
20154+ struct au_pin pin;
20155+ struct path h_path;
20156+ struct dentry *src_parent, *parent;
20157+};
20158+
20159+static int au_cpup_before_link(struct dentry *src_dentry,
20160+ struct au_link_args *a)
20161+{
20162+ int err;
20163+ struct dentry *h_src_dentry;
20164+ struct au_cp_generic cpg = {
20165+ .dentry = src_dentry,
20166+ .bdst = a->bdst,
20167+ .bsrc = a->bsrc,
20168+ .len = -1,
20169+ .pin = &a->pin,
20170+ .flags = AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */
20171+ };
20172+
20173+ di_read_lock_parent(a->src_parent, AuLock_IR);
20174+ err = au_test_and_cpup_dirs(src_dentry, a->bdst);
20175+ if (unlikely(err))
20176+ goto out;
20177+
20178+ h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
20179+ err = au_pin(&a->pin, src_dentry, a->bdst,
20180+ au_opt_udba(src_dentry->d_sb),
20181+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
20182+ if (unlikely(err))
20183+ goto out;
20184+
20185+ err = au_sio_cpup_simple(&cpg);
20186+ au_unpin(&a->pin);
20187+
20188+out:
20189+ di_read_unlock(a->src_parent, AuLock_IR);
20190+ return err;
20191+}
20192+
20193+static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry,
20194+ struct au_link_args *a)
20195+{
20196+ int err;
20197+ unsigned char plink;
20198+ aufs_bindex_t bbot;
20199+ struct dentry *h_src_dentry;
20200+ struct inode *h_inode, *inode, *delegated;
20201+ struct super_block *sb;
20202+ struct file *h_file;
20203+
20204+ plink = 0;
20205+ h_inode = NULL;
20206+ sb = src_dentry->d_sb;
20207+ inode = d_inode(src_dentry);
20208+ if (au_ibtop(inode) <= a->bdst)
20209+ h_inode = au_h_iptr(inode, a->bdst);
20210+ if (!h_inode || !h_inode->i_nlink) {
20211+ /* copyup src_dentry as the name of dentry. */
20212+ bbot = au_dbbot(dentry);
20213+ if (bbot < a->bsrc)
20214+ au_set_dbbot(dentry, a->bsrc);
20215+ au_set_h_dptr(dentry, a->bsrc,
20216+ dget(au_h_dptr(src_dentry, a->bsrc)));
20217+ dget(a->h_path.dentry);
20218+ au_set_h_dptr(dentry, a->bdst, NULL);
20219+ AuDbg("temporary d_inode...\n");
20220+ spin_lock(&dentry->d_lock);
20221+ dentry->d_inode = d_inode(src_dentry); /* tmp */
20222+ spin_unlock(&dentry->d_lock);
20223+ h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0);
20224+ if (IS_ERR(h_file))
20225+ err = PTR_ERR(h_file);
20226+ else {
20227+ struct au_cp_generic cpg = {
20228+ .dentry = dentry,
20229+ .bdst = a->bdst,
20230+ .bsrc = -1,
20231+ .len = -1,
20232+ .pin = &a->pin,
20233+ .flags = AuCpup_KEEPLINO
20234+ };
20235+ err = au_sio_cpup_simple(&cpg);
20236+ au_h_open_post(dentry, a->bsrc, h_file);
20237+ if (!err) {
20238+ dput(a->h_path.dentry);
20239+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
20240+ } else
20241+ au_set_h_dptr(dentry, a->bdst,
20242+ a->h_path.dentry);
20243+ }
20244+ spin_lock(&dentry->d_lock);
20245+ dentry->d_inode = NULL; /* restore */
20246+ spin_unlock(&dentry->d_lock);
20247+ AuDbg("temporary d_inode...done\n");
20248+ au_set_h_dptr(dentry, a->bsrc, NULL);
20249+ au_set_dbbot(dentry, bbot);
20250+ } else {
20251+ /* the inode of src_dentry already exists on a.bdst branch */
20252+ h_src_dentry = d_find_alias(h_inode);
20253+ if (!h_src_dentry && au_plink_test(inode)) {
20254+ plink = 1;
20255+ h_src_dentry = au_plink_lkup(inode, a->bdst);
20256+ err = PTR_ERR(h_src_dentry);
20257+ if (IS_ERR(h_src_dentry))
20258+ goto out;
20259+
20260+ if (unlikely(d_is_negative(h_src_dentry))) {
20261+ dput(h_src_dentry);
20262+ h_src_dentry = NULL;
20263+ }
20264+
20265+ }
20266+ if (h_src_dentry) {
20267+ delegated = NULL;
20268+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
20269+ &a->h_path, &delegated);
20270+ if (unlikely(err == -EWOULDBLOCK)) {
20271+ pr_warn("cannot retry for NFSv4 delegation"
20272+ " for an internal link\n");
20273+ iput(delegated);
20274+ }
20275+ dput(h_src_dentry);
20276+ } else {
20277+ AuIOErr("no dentry found for hi%lu on b%d\n",
20278+ h_inode->i_ino, a->bdst);
20279+ err = -EIO;
20280+ }
20281+ }
20282+
20283+ if (!err && !plink)
20284+ au_plink_append(inode, a->bdst, a->h_path.dentry);
20285+
20286+out:
20287+ AuTraceErr(err);
20288+ return err;
20289+}
20290+
20291+int aufs_link(struct dentry *src_dentry, struct inode *dir,
20292+ struct dentry *dentry)
20293+{
20294+ int err, rerr;
20295+ struct au_dtime dt;
20296+ struct au_link_args *a;
20297+ struct dentry *wh_dentry, *h_src_dentry;
20298+ struct inode *inode, *delegated;
20299+ struct super_block *sb;
20300+ struct au_wr_dir_args wr_dir_args = {
20301+ /* .force_btgt = -1, */
20302+ .flags = AuWrDir_ADD_ENTRY
20303+ };
20304+
20305+ IMustLock(dir);
20306+ inode = d_inode(src_dentry);
20307+ IMustLock(inode);
20308+
20309+ err = -ENOMEM;
20310+ a = kzalloc(sizeof(*a), GFP_NOFS);
20311+ if (unlikely(!a))
20312+ goto out;
20313+
20314+ a->parent = dentry->d_parent; /* dir inode is locked */
20315+ err = aufs_read_and_write_lock2(dentry, src_dentry,
20316+ AuLock_NOPLM | AuLock_GEN);
20317+ if (unlikely(err))
20318+ goto out_kfree;
20319+ err = au_d_linkable(src_dentry);
20320+ if (unlikely(err))
20321+ goto out_unlock;
20322+ err = au_d_may_add(dentry);
20323+ if (unlikely(err))
20324+ goto out_unlock;
20325+
20326+ a->src_parent = dget_parent(src_dentry);
20327+ wr_dir_args.force_btgt = au_ibtop(inode);
20328+
20329+ di_write_lock_parent(a->parent);
20330+ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
20331+ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
20332+ &wr_dir_args);
20333+ err = PTR_ERR(wh_dentry);
20334+ if (IS_ERR(wh_dentry))
20335+ goto out_parent;
20336+
20337+ err = 0;
20338+ sb = dentry->d_sb;
20339+ a->bdst = au_dbtop(dentry);
20340+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
20341+ a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
20342+ a->bsrc = au_ibtop(inode);
20343+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
20344+ if (!h_src_dentry && au_di(src_dentry)->di_tmpfile)
20345+ h_src_dentry = dget(au_hi_wh(inode, a->bsrc));
20346+ if (!h_src_dentry) {
20347+ a->bsrc = au_dbtop(src_dentry);
20348+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
20349+ AuDebugOn(!h_src_dentry);
20350+ } else if (IS_ERR(h_src_dentry)) {
20351+ err = PTR_ERR(h_src_dentry);
20352+ goto out_parent;
20353+ }
20354+
20355+ /*
20356+ * aufs doesn't touch the credential so
20357+ * security_dentry_create_files_as() is unnecessary.
20358+ */
20359+ if (au_opt_test(au_mntflags(sb), PLINK)) {
20360+ if (a->bdst < a->bsrc
20361+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
20362+ err = au_cpup_or_link(src_dentry, dentry, a);
20363+ else {
20364+ delegated = NULL;
20365+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
20366+ &a->h_path, &delegated);
20367+ if (unlikely(err == -EWOULDBLOCK)) {
20368+ pr_warn("cannot retry for NFSv4 delegation"
20369+ " for an internal link\n");
20370+ iput(delegated);
20371+ }
20372+ }
20373+ dput(h_src_dentry);
20374+ } else {
20375+ /*
20376+ * copyup src_dentry to the branch we process,
20377+ * and then link(2) to it.
20378+ */
20379+ dput(h_src_dentry);
20380+ if (a->bdst < a->bsrc
20381+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
20382+ au_unpin(&a->pin);
20383+ di_write_unlock(a->parent);
20384+ err = au_cpup_before_link(src_dentry, a);
20385+ di_write_lock_parent(a->parent);
20386+ if (!err)
20387+ err = au_pin(&a->pin, dentry, a->bdst,
20388+ au_opt_udba(sb),
20389+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
20390+ if (unlikely(err))
20391+ goto out_wh;
20392+ }
20393+ if (!err) {
20394+ h_src_dentry = au_h_dptr(src_dentry, a->bdst);
20395+ err = -ENOENT;
20396+ if (h_src_dentry && d_is_positive(h_src_dentry)) {
20397+ delegated = NULL;
20398+ err = vfsub_link(h_src_dentry,
20399+ au_pinned_h_dir(&a->pin),
20400+ &a->h_path, &delegated);
20401+ if (unlikely(err == -EWOULDBLOCK)) {
20402+ pr_warn("cannot retry"
20403+ " for NFSv4 delegation"
20404+ " for an internal link\n");
20405+ iput(delegated);
20406+ }
20407+ }
20408+ }
20409+ }
20410+ if (unlikely(err))
20411+ goto out_unpin;
20412+
20413+ if (wh_dentry) {
20414+ a->h_path.dentry = wh_dentry;
20415+ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
20416+ dentry);
20417+ if (unlikely(err))
20418+ goto out_revert;
20419+ }
20420+
20421+ au_dir_ts(dir, a->bdst);
20422+ inode_inc_iversion(dir);
20423+ inc_nlink(inode);
20424+ inode->i_ctime = dir->i_ctime;
20425+ d_instantiate(dentry, au_igrab(inode));
20426+ if (d_unhashed(a->h_path.dentry))
20427+ /* some filesystem calls d_drop() */
20428+ d_drop(dentry);
20429+ /* some filesystems consume an inode even hardlink */
20430+ au_fhsm_wrote(sb, a->bdst, /*force*/0);
20431+ goto out_unpin; /* success */
20432+
20433+out_revert:
20434+ /* no delegation since it is just created */
20435+ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path,
20436+ /*delegated*/NULL, /*force*/0);
20437+ if (unlikely(rerr)) {
20438+ AuIOErr("%pd reverting failed(%d, %d)\n", dentry, err, rerr);
20439+ err = -EIO;
20440+ }
20441+ au_dtime_revert(&dt);
20442+out_unpin:
20443+ au_unpin(&a->pin);
20444+out_wh:
20445+ dput(wh_dentry);
20446+out_parent:
20447+ di_write_unlock(a->parent);
20448+ dput(a->src_parent);
20449+out_unlock:
20450+ if (unlikely(err)) {
20451+ au_update_dbtop(dentry);
20452+ d_drop(dentry);
20453+ }
20454+ aufs_read_and_write_unlock2(dentry, src_dentry);
20455+out_kfree:
20456+ au_kfree_rcu(a);
20457+out:
20458+ AuTraceErr(err);
20459+ return err;
20460+}
20461+
20462+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
20463+{
20464+ int err, rerr;
20465+ aufs_bindex_t bindex;
20466+ unsigned char diropq;
20467+ struct path h_path;
20468+ struct dentry *wh_dentry, *parent, *opq_dentry;
20469+ struct inode *h_inode;
20470+ struct super_block *sb;
20471+ struct {
20472+ struct au_pin pin;
20473+ struct au_dtime dt;
20474+ } *a; /* reduce the stack usage */
20475+ struct au_wr_dir_args wr_dir_args = {
20476+ .force_btgt = -1,
20477+ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
20478+ };
20479+
20480+ IMustLock(dir);
20481+
20482+ err = -ENOMEM;
20483+ a = kmalloc(sizeof(*a), GFP_NOFS);
20484+ if (unlikely(!a))
20485+ goto out;
20486+
20487+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
20488+ if (unlikely(err))
20489+ goto out_free;
20490+ err = au_d_may_add(dentry);
20491+ if (unlikely(err))
20492+ goto out_unlock;
20493+
20494+ parent = dentry->d_parent; /* dir inode is locked */
20495+ di_write_lock_parent(parent);
20496+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
20497+ &a->pin, &wr_dir_args);
20498+ err = PTR_ERR(wh_dentry);
20499+ if (IS_ERR(wh_dentry))
20500+ goto out_parent;
20501+
20502+ sb = dentry->d_sb;
20503+ bindex = au_dbtop(dentry);
20504+ h_path.dentry = au_h_dptr(dentry, bindex);
20505+ h_path.mnt = au_sbr_mnt(sb, bindex);
20506+ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
20507+ if (unlikely(err))
20508+ goto out_unpin;
20509+
20510+ /* make the dir opaque */
20511+ diropq = 0;
20512+ h_inode = d_inode(h_path.dentry);
20513+ if (wh_dentry
20514+ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
20515+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
20516+ opq_dentry = au_diropq_create(dentry, bindex);
20517+ inode_unlock(h_inode);
20518+ err = PTR_ERR(opq_dentry);
20519+ if (IS_ERR(opq_dentry))
20520+ goto out_dir;
20521+ dput(opq_dentry);
20522+ diropq = 1;
20523+ }
20524+
20525+ err = epilog(dir, bindex, wh_dentry, dentry);
20526+ if (!err) {
20527+ inc_nlink(dir);
20528+ goto out_unpin; /* success */
20529+ }
20530+
20531+ /* revert */
20532+ if (diropq) {
20533+ AuLabel(revert opq);
20534+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
20535+ rerr = au_diropq_remove(dentry, bindex);
20536+ inode_unlock(h_inode);
20537+ if (rerr) {
20538+ AuIOErr("%pd reverting diropq failed(%d, %d)\n",
20539+ dentry, err, rerr);
20540+ err = -EIO;
20541+ }
20542+ }
20543+
20544+out_dir:
20545+ AuLabel(revert dir);
20546+ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
20547+ if (rerr) {
20548+ AuIOErr("%pd reverting dir failed(%d, %d)\n",
20549+ dentry, err, rerr);
20550+ err = -EIO;
20551+ }
20552+ au_dtime_revert(&a->dt);
20553+out_unpin:
20554+ au_unpin(&a->pin);
20555+ dput(wh_dentry);
20556+out_parent:
20557+ di_write_unlock(parent);
20558+out_unlock:
20559+ if (unlikely(err)) {
20560+ au_update_dbtop(dentry);
20561+ d_drop(dentry);
20562+ }
20563+ aufs_read_unlock(dentry, AuLock_DW);
20564+out_free:
20565+ au_kfree_rcu(a);
20566+out:
20567+ return err;
20568+}
20569diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
20570--- /usr/share/empty/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
20571+++ linux/fs/aufs/i_op.c 2020-04-03 08:16:47.547461775 +0200
20572@@ -0,0 +1,1498 @@
20573+// SPDX-License-Identifier: GPL-2.0
20574+/*
20575+ * Copyright (C) 2005-2020 Junjiro R. Okajima
20576+ *
20577+ * This program, aufs is free software; you can redistribute it and/or modify
20578+ * it under the terms of the GNU General Public License as published by
20579+ * the Free Software Foundation; either version 2 of the License, or
20580+ * (at your option) any later version.
20581+ *
20582+ * This program is distributed in the hope that it will be useful,
20583+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20584+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20585+ * GNU General Public License for more details.
20586+ *
20587+ * You should have received a copy of the GNU General Public License
20588+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20589+ */
20590+
20591+/*
20592+ * inode operations (except add/del/rename)
20593+ */
20594+
20595+#include <linux/device_cgroup.h>
20596+#include <linux/fs_stack.h>
20597+#include <linux/iversion.h>
20598+#include <linux/namei.h>
20599+#include <linux/security.h>
20600+#include "aufs.h"
20601+
20602+static int h_permission(struct inode *h_inode, int mask,
20603+ struct path *h_path, int brperm)
20604+{
20605+ int err;
20606+ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
20607+
20608+ err = -EPERM;
20609+ if (write_mask && IS_IMMUTABLE(h_inode))
20610+ goto out;
20611+
20612+ err = -EACCES;
20613+ if (((mask & MAY_EXEC)
20614+ && S_ISREG(h_inode->i_mode)
20615+ && (path_noexec(h_path)
20616+ || !(h_inode->i_mode & 0111))))
20617+ goto out;
20618+
20619+ /*
20620+ * - skip the lower fs test in the case of write to ro branch.
20621+ * - nfs dir permission write check is optimized, but a policy for
20622+ * link/rename requires a real check.
20623+ * - nfs always sets SB_POSIXACL regardless its mount option 'noacl.'
20624+ * in this case, generic_permission() returns -EOPNOTSUPP.
20625+ */
20626+ if ((write_mask && !au_br_writable(brperm))
20627+ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
20628+ && write_mask && !(mask & MAY_READ))
20629+ || !h_inode->i_op->permission) {
20630+ /* AuLabel(generic_permission); */
20631+ /* AuDbg("get_acl %ps\n", h_inode->i_op->get_acl); */
20632+ err = generic_permission(h_inode, mask);
20633+ if (err == -EOPNOTSUPP && au_test_nfs_noacl(h_inode))
20634+ err = h_inode->i_op->permission(h_inode, mask);
20635+ AuTraceErr(err);
20636+ } else {
20637+ /* AuLabel(h_inode->permission); */
20638+ err = h_inode->i_op->permission(h_inode, mask);
20639+ AuTraceErr(err);
20640+ }
20641+
20642+ if (!err)
20643+ err = devcgroup_inode_permission(h_inode, mask);
20644+ if (!err)
20645+ err = security_inode_permission(h_inode, mask);
20646+
20647+out:
20648+ return err;
20649+}
20650+
20651+static int aufs_permission(struct inode *inode, int mask)
20652+{
20653+ int err;
20654+ aufs_bindex_t bindex, bbot;
20655+ const unsigned char isdir = !!S_ISDIR(inode->i_mode),
20656+ write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
20657+ struct inode *h_inode;
20658+ struct super_block *sb;
20659+ struct au_branch *br;
20660+
20661+ /* todo: support rcu-walk? */
20662+ if (mask & MAY_NOT_BLOCK)
20663+ return -ECHILD;
20664+
20665+ sb = inode->i_sb;
20666+ si_read_lock(sb, AuLock_FLUSH);
20667+ ii_read_lock_child(inode);
20668+#if 0 /* reserved for future use */
20669+ /*
20670+ * This test may be rather 'too much' since the test is essentially done
20671+ * in the aufs_lookup(). Theoretically it is possible that the inode
20672+ * generation doesn't match to the superblock's here. But it isn't a
20673+ * big deal I suppose.
20674+ */
20675+ err = au_iigen_test(inode, au_sigen(sb));
20676+ if (unlikely(err))
20677+ goto out;
20678+#endif
20679+
20680+ if (!isdir
20681+ || write_mask
20682+ || au_opt_test(au_mntflags(sb), DIRPERM1)) {
20683+ err = au_busy_or_stale();
20684+ h_inode = au_h_iptr(inode, au_ibtop(inode));
20685+ if (unlikely(!h_inode
20686+ || (h_inode->i_mode & S_IFMT)
20687+ != (inode->i_mode & S_IFMT)))
20688+ goto out;
20689+
20690+ err = 0;
20691+ bindex = au_ibtop(inode);
20692+ br = au_sbr(sb, bindex);
20693+ err = h_permission(h_inode, mask, &br->br_path, br->br_perm);
20694+ if (write_mask
20695+ && !err
20696+ && !special_file(h_inode->i_mode)) {
20697+ /* test whether the upper writable branch exists */
20698+ err = -EROFS;
20699+ for (; bindex >= 0; bindex--)
20700+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
20701+ err = 0;
20702+ break;
20703+ }
20704+ }
20705+ goto out;
20706+ }
20707+
20708+ /* non-write to dir */
20709+ err = 0;
20710+ bbot = au_ibbot(inode);
20711+ for (bindex = au_ibtop(inode); !err && bindex <= bbot; bindex++) {
20712+ h_inode = au_h_iptr(inode, bindex);
20713+ if (h_inode) {
20714+ err = au_busy_or_stale();
20715+ if (unlikely(!S_ISDIR(h_inode->i_mode)))
20716+ break;
20717+
20718+ br = au_sbr(sb, bindex);
20719+ err = h_permission(h_inode, mask, &br->br_path,
20720+ br->br_perm);
20721+ }
20722+ }
20723+
20724+out:
20725+ ii_read_unlock(inode);
20726+ si_read_unlock(sb);
20727+ return err;
20728+}
20729+
20730+/* ---------------------------------------------------------------------- */
20731+
20732+static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
20733+ unsigned int flags)
20734+{
20735+ struct dentry *ret, *parent;
20736+ struct inode *inode;
20737+ struct super_block *sb;
20738+ int err, npositive;
20739+
20740+ IMustLock(dir);
20741+
20742+ /* todo: support rcu-walk? */
20743+ ret = ERR_PTR(-ECHILD);
20744+ if (flags & LOOKUP_RCU)
20745+ goto out;
20746+
20747+ ret = ERR_PTR(-ENAMETOOLONG);
20748+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
20749+ goto out;
20750+
20751+ sb = dir->i_sb;
20752+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
20753+ ret = ERR_PTR(err);
20754+ if (unlikely(err))
20755+ goto out;
20756+
20757+ err = au_di_init(dentry);
20758+ ret = ERR_PTR(err);
20759+ if (unlikely(err))
20760+ goto out_si;
20761+
20762+ inode = NULL;
20763+ npositive = 0; /* suppress a warning */
20764+ parent = dentry->d_parent; /* dir inode is locked */
20765+ di_read_lock_parent(parent, AuLock_IR);
20766+ err = au_alive_dir(parent);
20767+ if (!err)
20768+ err = au_digen_test(parent, au_sigen(sb));
20769+ if (!err) {
20770+ /* regardless LOOKUP_CREATE, always ALLOW_NEG */
20771+ npositive = au_lkup_dentry(dentry, au_dbtop(parent),
20772+ AuLkup_ALLOW_NEG);
20773+ err = npositive;
20774+ }
20775+ di_read_unlock(parent, AuLock_IR);
20776+ ret = ERR_PTR(err);
20777+ if (unlikely(err < 0))
20778+ goto out_unlock;
20779+
20780+ if (npositive) {
20781+ inode = au_new_inode(dentry, /*must_new*/0);
20782+ if (IS_ERR(inode)) {
20783+ ret = (void *)inode;
20784+ inode = NULL;
20785+ goto out_unlock;
20786+ }
20787+ }
20788+
20789+ if (inode)
20790+ atomic_inc(&inode->i_count);
20791+ ret = d_splice_alias(inode, dentry);
20792+#if 0 /* reserved for future use */
20793+ if (unlikely(d_need_lookup(dentry))) {
20794+ spin_lock(&dentry->d_lock);
20795+ dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
20796+ spin_unlock(&dentry->d_lock);
20797+ } else
20798+#endif
20799+ if (inode) {
20800+ if (!IS_ERR(ret)) {
20801+ iput(inode);
20802+ if (ret && ret != dentry)
20803+ ii_write_unlock(inode);
20804+ } else {
20805+ ii_write_unlock(inode);
20806+ iput(inode);
20807+ inode = NULL;
20808+ }
20809+ }
20810+
20811+out_unlock:
20812+ di_write_unlock(dentry);
20813+out_si:
20814+ si_read_unlock(sb);
20815+out:
20816+ return ret;
20817+}
20818+
20819+/* ---------------------------------------------------------------------- */
20820+
20821+/*
20822+ * very dirty and complicated aufs ->atomic_open().
20823+ * aufs_atomic_open()
20824+ * + au_aopen_or_create()
20825+ * + add_simple()
20826+ * + vfsub_atomic_open()
20827+ * + branch fs ->atomic_open()
20828+ * may call the actual 'open' for h_file
20829+ * + inc br_nfiles only if opened
20830+ * + au_aopen_no_open() or au_aopen_do_open()
20831+ *
20832+ * au_aopen_do_open()
20833+ * + finish_open()
20834+ * + au_do_aopen()
20835+ * + au_do_open() the body of all 'open'
20836+ * + au_do_open_nondir()
20837+ * set the passed h_file
20838+ *
20839+ * au_aopen_no_open()
20840+ * + finish_no_open()
20841+ */
20842+
20843+struct aopen_node {
20844+ struct hlist_bl_node hblist;
20845+ struct file *file, *h_file;
20846+};
20847+
20848+static int au_do_aopen(struct inode *inode, struct file *file)
20849+{
20850+ struct hlist_bl_head *aopen;
20851+ struct hlist_bl_node *pos;
20852+ struct aopen_node *node;
20853+ struct au_do_open_args args = {
20854+ .aopen = 1,
20855+ .open = au_do_open_nondir
20856+ };
20857+
20858+ aopen = &au_sbi(inode->i_sb)->si_aopen;
20859+ hlist_bl_lock(aopen);
20860+ hlist_bl_for_each_entry(node, pos, aopen, hblist)
20861+ if (node->file == file) {
20862+ args.h_file = node->h_file;
20863+ break;
20864+ }
20865+ hlist_bl_unlock(aopen);
20866+ /* AuDebugOn(!args.h_file); */
20867+
20868+ return au_do_open(file, &args);
20869+}
20870+
20871+static int au_aopen_do_open(struct file *file, struct dentry *dentry,
20872+ struct aopen_node *aopen_node)
20873+{
20874+ int err;
20875+ struct hlist_bl_head *aopen;
20876+
20877+ AuLabel(here);
20878+ aopen = &au_sbi(dentry->d_sb)->si_aopen;
20879+ au_hbl_add(&aopen_node->hblist, aopen);
20880+ err = finish_open(file, dentry, au_do_aopen);
20881+ au_hbl_del(&aopen_node->hblist, aopen);
20882+ /* AuDbgFile(file); */
20883+ AuDbg("%pd%s%s\n", dentry,
20884+ (file->f_mode & FMODE_CREATED) ? " created" : "",
20885+ (file->f_mode & FMODE_OPENED) ? " opened" : "");
20886+
20887+ AuTraceErr(err);
20888+ return err;
20889+}
20890+
20891+static int au_aopen_no_open(struct file *file, struct dentry *dentry)
20892+{
20893+ int err;
20894+
20895+ AuLabel(here);
20896+ dget(dentry);
20897+ err = finish_no_open(file, dentry);
20898+
20899+ AuTraceErr(err);
20900+ return err;
20901+}
20902+
20903+static int aufs_atomic_open(struct inode *dir, struct dentry *dentry,
20904+ struct file *file, unsigned int open_flag,
20905+ umode_t create_mode)
20906+{
20907+ int err, did_open;
20908+ unsigned int lkup_flags;
20909+ aufs_bindex_t bindex;
20910+ struct super_block *sb;
20911+ struct dentry *parent, *d;
20912+ struct vfsub_aopen_args args = {
20913+ .open_flag = open_flag,
20914+ .create_mode = create_mode
20915+ };
20916+ struct aopen_node aopen_node = {
20917+ .file = file
20918+ };
20919+
20920+ IMustLock(dir);
20921+ AuDbg("open_flag 0%o\n", open_flag);
20922+ AuDbgDentry(dentry);
20923+
20924+ err = 0;
20925+ if (!au_di(dentry)) {
20926+ lkup_flags = LOOKUP_OPEN;
20927+ if (open_flag & O_CREAT)
20928+ lkup_flags |= LOOKUP_CREATE;
20929+ d = aufs_lookup(dir, dentry, lkup_flags);
20930+ if (IS_ERR(d)) {
20931+ err = PTR_ERR(d);
20932+ AuTraceErr(err);
20933+ goto out;
20934+ } else if (d) {
20935+ /*
20936+ * obsoleted dentry found.
20937+ * another error will be returned later.
20938+ */
20939+ d_drop(d);
20940+ AuDbgDentry(d);
20941+ dput(d);
20942+ }
20943+ AuDbgDentry(dentry);
20944+ }
20945+
20946+ if (d_is_positive(dentry)
20947+ || d_unhashed(dentry)
20948+ || d_unlinked(dentry)
20949+ || !(open_flag & O_CREAT)) {
20950+ err = au_aopen_no_open(file, dentry);
20951+ goto out; /* success */
20952+ }
20953+
20954+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
20955+ if (unlikely(err))
20956+ goto out;
20957+
20958+ sb = dentry->d_sb;
20959+ parent = dentry->d_parent; /* dir is locked */
20960+ di_write_lock_parent(parent);
20961+ err = au_lkup_dentry(dentry, /*btop*/0, AuLkup_ALLOW_NEG);
20962+ if (unlikely(err < 0))
20963+ goto out_parent;
20964+
20965+ AuDbgDentry(dentry);
20966+ if (d_is_positive(dentry)) {
20967+ err = au_aopen_no_open(file, dentry);
20968+ goto out_parent; /* success */
20969+ }
20970+
20971+ args.file = alloc_empty_file(file->f_flags, current_cred());
20972+ err = PTR_ERR(args.file);
20973+ if (IS_ERR(args.file))
20974+ goto out_parent;
20975+
20976+ bindex = au_dbtop(dentry);
20977+ err = au_aopen_or_create(dir, dentry, &args);
20978+ AuTraceErr(err);
20979+ AuDbgFile(args.file);
20980+ file->f_mode = args.file->f_mode & ~FMODE_OPENED;
20981+ did_open = !!(args.file->f_mode & FMODE_OPENED);
20982+ if (!did_open) {
20983+ fput(args.file);
20984+ args.file = NULL;
20985+ }
20986+ di_write_unlock(parent);
20987+ di_write_unlock(dentry);
20988+ if (unlikely(err < 0)) {
20989+ if (args.file)
20990+ fput(args.file);
20991+ goto out_sb;
20992+ }
20993+
20994+ if (!did_open)
20995+ err = au_aopen_no_open(file, dentry);
20996+ else {
20997+ aopen_node.h_file = args.file;
20998+ err = au_aopen_do_open(file, dentry, &aopen_node);
20999+ }
21000+ if (unlikely(err < 0)) {
21001+ if (args.file)
21002+ fput(args.file);
21003+ if (did_open)
21004+ au_lcnt_dec(&args.br->br_nfiles);
21005+ }
21006+ goto out_sb; /* success */
21007+
21008+out_parent:
21009+ di_write_unlock(parent);
21010+ di_write_unlock(dentry);
21011+out_sb:
21012+ si_read_unlock(sb);
21013+out:
21014+ AuTraceErr(err);
21015+ AuDbgFile(file);
21016+ return err;
21017+}
21018+
21019+
21020+/* ---------------------------------------------------------------------- */
21021+
21022+static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
21023+ const unsigned char add_entry, aufs_bindex_t bcpup,
21024+ aufs_bindex_t btop)
21025+{
21026+ int err;
21027+ struct dentry *h_parent;
21028+ struct inode *h_dir;
21029+
21030+ if (add_entry)
21031+ IMustLock(d_inode(parent));
21032+ else
21033+ di_write_lock_parent(parent);
21034+
21035+ err = 0;
21036+ if (!au_h_dptr(parent, bcpup)) {
21037+ if (btop > bcpup)
21038+ err = au_cpup_dirs(dentry, bcpup);
21039+ else if (btop < bcpup)
21040+ err = au_cpdown_dirs(dentry, bcpup);
21041+ else
21042+ BUG();
21043+ }
21044+ if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) {
21045+ h_parent = au_h_dptr(parent, bcpup);
21046+ h_dir = d_inode(h_parent);
21047+ inode_lock_shared_nested(h_dir, AuLsc_I_PARENT);
21048+ err = au_lkup_neg(dentry, bcpup, /*wh*/0);
21049+ /* todo: no unlock here */
21050+ inode_unlock_shared(h_dir);
21051+
21052+ AuDbg("bcpup %d\n", bcpup);
21053+ if (!err) {
21054+ if (d_really_is_negative(dentry))
21055+ au_set_h_dptr(dentry, btop, NULL);
21056+ au_update_dbrange(dentry, /*do_put_zero*/0);
21057+ }
21058+ }
21059+
21060+ if (!add_entry)
21061+ di_write_unlock(parent);
21062+ if (!err)
21063+ err = bcpup; /* success */
21064+
21065+ AuTraceErr(err);
21066+ return err;
21067+}
21068+
21069+/*
21070+ * decide the branch and the parent dir where we will create a new entry.
21071+ * returns new bindex or an error.
21072+ * copyup the parent dir if needed.
21073+ */
21074+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
21075+ struct au_wr_dir_args *args)
21076+{
21077+ int err;
21078+ unsigned int flags;
21079+ aufs_bindex_t bcpup, btop, src_btop;
21080+ const unsigned char add_entry
21081+ = au_ftest_wrdir(args->flags, ADD_ENTRY)
21082+ | au_ftest_wrdir(args->flags, TMPFILE);
21083+ struct super_block *sb;
21084+ struct dentry *parent;
21085+ struct au_sbinfo *sbinfo;
21086+
21087+ sb = dentry->d_sb;
21088+ sbinfo = au_sbi(sb);
21089+ parent = dget_parent(dentry);
21090+ btop = au_dbtop(dentry);
21091+ bcpup = btop;
21092+ if (args->force_btgt < 0) {
21093+ if (src_dentry) {
21094+ src_btop = au_dbtop(src_dentry);
21095+ if (src_btop < btop)
21096+ bcpup = src_btop;
21097+ } else if (add_entry) {
21098+ flags = 0;
21099+ if (au_ftest_wrdir(args->flags, ISDIR))
21100+ au_fset_wbr(flags, DIR);
21101+ err = AuWbrCreate(sbinfo, dentry, flags);
21102+ bcpup = err;
21103+ }
21104+
21105+ if (bcpup < 0 || au_test_ro(sb, bcpup, d_inode(dentry))) {
21106+ if (add_entry)
21107+ err = AuWbrCopyup(sbinfo, dentry);
21108+ else {
21109+ if (!IS_ROOT(dentry)) {
21110+ di_read_lock_parent(parent, !AuLock_IR);
21111+ err = AuWbrCopyup(sbinfo, dentry);
21112+ di_read_unlock(parent, !AuLock_IR);
21113+ } else
21114+ err = AuWbrCopyup(sbinfo, dentry);
21115+ }
21116+ bcpup = err;
21117+ if (unlikely(err < 0))
21118+ goto out;
21119+ }
21120+ } else {
21121+ bcpup = args->force_btgt;
21122+ AuDebugOn(au_test_ro(sb, bcpup, d_inode(dentry)));
21123+ }
21124+
21125+ AuDbg("btop %d, bcpup %d\n", btop, bcpup);
21126+ err = bcpup;
21127+ if (bcpup == btop)
21128+ goto out; /* success */
21129+
21130+ /* copyup the new parent into the branch we process */
21131+ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, btop);
21132+ if (err >= 0) {
21133+ if (d_really_is_negative(dentry)) {
21134+ au_set_h_dptr(dentry, btop, NULL);
21135+ au_set_dbtop(dentry, bcpup);
21136+ au_set_dbbot(dentry, bcpup);
21137+ }
21138+ AuDebugOn(add_entry
21139+ && !au_ftest_wrdir(args->flags, TMPFILE)
21140+ && !au_h_dptr(dentry, bcpup));
21141+ }
21142+
21143+out:
21144+ dput(parent);
21145+ return err;
21146+}
21147+
21148+/* ---------------------------------------------------------------------- */
21149+
21150+void au_pin_hdir_unlock(struct au_pin *p)
21151+{
21152+ if (p->hdir)
21153+ au_hn_inode_unlock(p->hdir);
21154+}
21155+
21156+int au_pin_hdir_lock(struct au_pin *p)
21157+{
21158+ int err;
21159+
21160+ err = 0;
21161+ if (!p->hdir)
21162+ goto out;
21163+
21164+ /* even if an error happens later, keep this lock */
21165+ au_hn_inode_lock_nested(p->hdir, p->lsc_hi);
21166+
21167+ err = -EBUSY;
21168+ if (unlikely(p->hdir->hi_inode != d_inode(p->h_parent)))
21169+ goto out;
21170+
21171+ err = 0;
21172+ if (p->h_dentry)
21173+ err = au_h_verify(p->h_dentry, p->udba, p->hdir->hi_inode,
21174+ p->h_parent, p->br);
21175+
21176+out:
21177+ return err;
21178+}
21179+
21180+int au_pin_hdir_relock(struct au_pin *p)
21181+{
21182+ int err, i;
21183+ struct inode *h_i;
21184+ struct dentry *h_d[] = {
21185+ p->h_dentry,
21186+ p->h_parent
21187+ };
21188+
21189+ err = au_pin_hdir_lock(p);
21190+ if (unlikely(err))
21191+ goto out;
21192+
21193+ for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) {
21194+ if (!h_d[i])
21195+ continue;
21196+ if (d_is_positive(h_d[i])) {
21197+ h_i = d_inode(h_d[i]);
21198+ err = !h_i->i_nlink;
21199+ }
21200+ }
21201+
21202+out:
21203+ return err;
21204+}
21205+
21206+static void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task)
21207+{
21208+ atomic_long_set(&p->hdir->hi_inode->i_rwsem.owner, (long)task);
21209+}
21210+
21211+void au_pin_hdir_acquire_nest(struct au_pin *p)
21212+{
21213+ if (p->hdir) {
21214+ rwsem_acquire_nest(&p->hdir->hi_inode->i_rwsem.dep_map,
21215+ p->lsc_hi, 0, NULL, _RET_IP_);
21216+ au_pin_hdir_set_owner(p, current);
21217+ }
21218+}
21219+
21220+void au_pin_hdir_release(struct au_pin *p)
21221+{
21222+ if (p->hdir) {
21223+ au_pin_hdir_set_owner(p, p->task);
21224+ rwsem_release(&p->hdir->hi_inode->i_rwsem.dep_map, 1, _RET_IP_);
21225+ }
21226+}
21227+
21228+struct dentry *au_pinned_h_parent(struct au_pin *pin)
21229+{
21230+ if (pin && pin->parent)
21231+ return au_h_dptr(pin->parent, pin->bindex);
21232+ return NULL;
21233+}
21234+
21235+void au_unpin(struct au_pin *p)
21236+{
21237+ if (p->hdir)
21238+ au_pin_hdir_unlock(p);
21239+ if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE))
21240+ vfsub_mnt_drop_write(p->h_mnt);
21241+ if (!p->hdir)
21242+ return;
21243+
21244+ if (!au_ftest_pin(p->flags, DI_LOCKED))
21245+ di_read_unlock(p->parent, AuLock_IR);
21246+ iput(p->hdir->hi_inode);
21247+ dput(p->parent);
21248+ p->parent = NULL;
21249+ p->hdir = NULL;
21250+ p->h_mnt = NULL;
21251+ /* do not clear p->task */
21252+}
21253+
21254+int au_do_pin(struct au_pin *p)
21255+{
21256+ int err;
21257+ struct super_block *sb;
21258+ struct inode *h_dir;
21259+
21260+ err = 0;
21261+ sb = p->dentry->d_sb;
21262+ p->br = au_sbr(sb, p->bindex);
21263+ if (IS_ROOT(p->dentry)) {
21264+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
21265+ p->h_mnt = au_br_mnt(p->br);
21266+ err = vfsub_mnt_want_write(p->h_mnt);
21267+ if (unlikely(err)) {
21268+ au_fclr_pin(p->flags, MNT_WRITE);
21269+ goto out_err;
21270+ }
21271+ }
21272+ goto out;
21273+ }
21274+
21275+ p->h_dentry = NULL;
21276+ if (p->bindex <= au_dbbot(p->dentry))
21277+ p->h_dentry = au_h_dptr(p->dentry, p->bindex);
21278+
21279+ p->parent = dget_parent(p->dentry);
21280+ if (!au_ftest_pin(p->flags, DI_LOCKED))
21281+ di_read_lock(p->parent, AuLock_IR, p->lsc_di);
21282+
21283+ h_dir = NULL;
21284+ p->h_parent = au_h_dptr(p->parent, p->bindex);
21285+ p->hdir = au_hi(d_inode(p->parent), p->bindex);
21286+ if (p->hdir)
21287+ h_dir = p->hdir->hi_inode;
21288+
21289+ /*
21290+ * udba case, or
21291+ * if DI_LOCKED is not set, then p->parent may be different
21292+ * and h_parent can be NULL.
21293+ */
21294+ if (unlikely(!p->hdir || !h_dir || !p->h_parent)) {
21295+ err = -EBUSY;
21296+ if (!au_ftest_pin(p->flags, DI_LOCKED))
21297+ di_read_unlock(p->parent, AuLock_IR);
21298+ dput(p->parent);
21299+ p->parent = NULL;
21300+ goto out_err;
21301+ }
21302+
21303+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
21304+ p->h_mnt = au_br_mnt(p->br);
21305+ err = vfsub_mnt_want_write(p->h_mnt);
21306+ if (unlikely(err)) {
21307+ au_fclr_pin(p->flags, MNT_WRITE);
21308+ if (!au_ftest_pin(p->flags, DI_LOCKED))
21309+ di_read_unlock(p->parent, AuLock_IR);
21310+ dput(p->parent);
21311+ p->parent = NULL;
21312+ goto out_err;
21313+ }
21314+ }
21315+
21316+ au_igrab(h_dir);
21317+ err = au_pin_hdir_lock(p);
21318+ if (!err)
21319+ goto out; /* success */
21320+
21321+ au_unpin(p);
21322+
21323+out_err:
21324+ pr_err("err %d\n", err);
21325+ err = au_busy_or_stale();
21326+out:
21327+ return err;
21328+}
21329+
21330+void au_pin_init(struct au_pin *p, struct dentry *dentry,
21331+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
21332+ unsigned int udba, unsigned char flags)
21333+{
21334+ p->dentry = dentry;
21335+ p->udba = udba;
21336+ p->lsc_di = lsc_di;
21337+ p->lsc_hi = lsc_hi;
21338+ p->flags = flags;
21339+ p->bindex = bindex;
21340+
21341+ p->parent = NULL;
21342+ p->hdir = NULL;
21343+ p->h_mnt = NULL;
21344+
21345+ p->h_dentry = NULL;
21346+ p->h_parent = NULL;
21347+ p->br = NULL;
21348+ p->task = current;
21349+}
21350+
21351+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
21352+ unsigned int udba, unsigned char flags)
21353+{
21354+ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
21355+ udba, flags);
21356+ return au_do_pin(pin);
21357+}
21358+
21359+/* ---------------------------------------------------------------------- */
21360+
21361+/*
21362+ * ->setattr() and ->getattr() are called in various cases.
21363+ * chmod, stat: dentry is revalidated.
21364+ * fchmod, fstat: file and dentry are not revalidated, additionally they may be
21365+ * unhashed.
21366+ * for ->setattr(), ia->ia_file is passed from ftruncate only.
21367+ */
21368+/* todo: consolidate with do_refresh() and simple_reval_dpath() */
21369+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
21370+{
21371+ int err;
21372+ struct dentry *parent;
21373+
21374+ err = 0;
21375+ if (au_digen_test(dentry, sigen)) {
21376+ parent = dget_parent(dentry);
21377+ di_read_lock_parent(parent, AuLock_IR);
21378+ err = au_refresh_dentry(dentry, parent);
21379+ di_read_unlock(parent, AuLock_IR);
21380+ dput(parent);
21381+ }
21382+
21383+ AuTraceErr(err);
21384+ return err;
21385+}
21386+
21387+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
21388+ struct au_icpup_args *a)
21389+{
21390+ int err;
21391+ loff_t sz;
21392+ aufs_bindex_t btop, ibtop;
21393+ struct dentry *hi_wh, *parent;
21394+ struct inode *inode;
21395+ struct au_wr_dir_args wr_dir_args = {
21396+ .force_btgt = -1,
21397+ .flags = 0
21398+ };
21399+
21400+ if (d_is_dir(dentry))
21401+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
21402+ /* plink or hi_wh() case */
21403+ btop = au_dbtop(dentry);
21404+ inode = d_inode(dentry);
21405+ ibtop = au_ibtop(inode);
21406+ if (btop != ibtop && !au_test_ro(inode->i_sb, ibtop, inode))
21407+ wr_dir_args.force_btgt = ibtop;
21408+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
21409+ if (unlikely(err < 0))
21410+ goto out;
21411+ a->btgt = err;
21412+ if (err != btop)
21413+ au_fset_icpup(a->flags, DID_CPUP);
21414+
21415+ err = 0;
21416+ a->pin_flags = AuPin_MNT_WRITE;
21417+ parent = NULL;
21418+ if (!IS_ROOT(dentry)) {
21419+ au_fset_pin(a->pin_flags, DI_LOCKED);
21420+ parent = dget_parent(dentry);
21421+ di_write_lock_parent(parent);
21422+ }
21423+
21424+ err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags);
21425+ if (unlikely(err))
21426+ goto out_parent;
21427+
21428+ sz = -1;
21429+ a->h_path.dentry = au_h_dptr(dentry, btop);
21430+ a->h_inode = d_inode(a->h_path.dentry);
21431+ if (ia && (ia->ia_valid & ATTR_SIZE)) {
21432+ inode_lock_shared_nested(a->h_inode, AuLsc_I_CHILD);
21433+ if (ia->ia_size < i_size_read(a->h_inode))
21434+ sz = ia->ia_size;
21435+ inode_unlock_shared(a->h_inode);
21436+ }
21437+
21438+ hi_wh = NULL;
21439+ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) {
21440+ hi_wh = au_hi_wh(inode, a->btgt);
21441+ if (!hi_wh) {
21442+ struct au_cp_generic cpg = {
21443+ .dentry = dentry,
21444+ .bdst = a->btgt,
21445+ .bsrc = -1,
21446+ .len = sz,
21447+ .pin = &a->pin
21448+ };
21449+ err = au_sio_cpup_wh(&cpg, /*file*/NULL);
21450+ if (unlikely(err))
21451+ goto out_unlock;
21452+ hi_wh = au_hi_wh(inode, a->btgt);
21453+ /* todo: revalidate hi_wh? */
21454+ }
21455+ }
21456+
21457+ if (parent) {
21458+ au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
21459+ di_downgrade_lock(parent, AuLock_IR);
21460+ dput(parent);
21461+ parent = NULL;
21462+ }
21463+ if (!au_ftest_icpup(a->flags, DID_CPUP))
21464+ goto out; /* success */
21465+
21466+ if (!d_unhashed(dentry)) {
21467+ struct au_cp_generic cpg = {
21468+ .dentry = dentry,
21469+ .bdst = a->btgt,
21470+ .bsrc = btop,
21471+ .len = sz,
21472+ .pin = &a->pin,
21473+ .flags = AuCpup_DTIME | AuCpup_HOPEN
21474+ };
21475+ err = au_sio_cpup_simple(&cpg);
21476+ if (!err)
21477+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
21478+ } else if (!hi_wh)
21479+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
21480+ else
21481+ a->h_path.dentry = hi_wh; /* do not dget here */
21482+
21483+out_unlock:
21484+ a->h_inode = d_inode(a->h_path.dentry);
21485+ if (!err)
21486+ goto out; /* success */
21487+ au_unpin(&a->pin);
21488+out_parent:
21489+ if (parent) {
21490+ di_write_unlock(parent);
21491+ dput(parent);
21492+ }
21493+out:
21494+ if (!err)
21495+ inode_lock_nested(a->h_inode, AuLsc_I_CHILD);
21496+ return err;
21497+}
21498+
21499+static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
21500+{
21501+ int err;
21502+ struct inode *inode, *delegated;
21503+ struct super_block *sb;
21504+ struct file *file;
21505+ struct au_icpup_args *a;
21506+
21507+ inode = d_inode(dentry);
21508+ IMustLock(inode);
21509+
21510+ err = setattr_prepare(dentry, ia);
21511+ if (unlikely(err))
21512+ goto out;
21513+
21514+ err = -ENOMEM;
21515+ a = kzalloc(sizeof(*a), GFP_NOFS);
21516+ if (unlikely(!a))
21517+ goto out;
21518+
21519+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
21520+ ia->ia_valid &= ~ATTR_MODE;
21521+
21522+ file = NULL;
21523+ sb = dentry->d_sb;
21524+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
21525+ if (unlikely(err))
21526+ goto out_kfree;
21527+
21528+ if (ia->ia_valid & ATTR_FILE) {
21529+ /* currently ftruncate(2) only */
21530+ AuDebugOn(!d_is_reg(dentry));
21531+ file = ia->ia_file;
21532+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1,
21533+ /*fi_lsc*/0);
21534+ if (unlikely(err))
21535+ goto out_si;
21536+ ia->ia_file = au_hf_top(file);
21537+ a->udba = AuOpt_UDBA_NONE;
21538+ } else {
21539+ /* fchmod() doesn't pass ia_file */
21540+ a->udba = au_opt_udba(sb);
21541+ di_write_lock_child(dentry);
21542+ /* no d_unlinked(), to set UDBA_NONE for root */
21543+ if (d_unhashed(dentry))
21544+ a->udba = AuOpt_UDBA_NONE;
21545+ if (a->udba != AuOpt_UDBA_NONE) {
21546+ AuDebugOn(IS_ROOT(dentry));
21547+ err = au_reval_for_attr(dentry, au_sigen(sb));
21548+ if (unlikely(err))
21549+ goto out_dentry;
21550+ }
21551+ }
21552+
21553+ err = au_pin_and_icpup(dentry, ia, a);
21554+ if (unlikely(err < 0))
21555+ goto out_dentry;
21556+ if (au_ftest_icpup(a->flags, DID_CPUP)) {
21557+ ia->ia_file = NULL;
21558+ ia->ia_valid &= ~ATTR_FILE;
21559+ }
21560+
21561+ a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
21562+ if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME))
21563+ == (ATTR_MODE | ATTR_CTIME)) {
21564+ err = security_path_chmod(&a->h_path, ia->ia_mode);
21565+ if (unlikely(err))
21566+ goto out_unlock;
21567+ } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
21568+ && (ia->ia_valid & ATTR_CTIME)) {
21569+ err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid);
21570+ if (unlikely(err))
21571+ goto out_unlock;
21572+ }
21573+
21574+ if (ia->ia_valid & ATTR_SIZE) {
21575+ struct file *f;
21576+
21577+ if (ia->ia_size < i_size_read(inode))
21578+ /* unmap only */
21579+ truncate_setsize(inode, ia->ia_size);
21580+
21581+ f = NULL;
21582+ if (ia->ia_valid & ATTR_FILE)
21583+ f = ia->ia_file;
21584+ inode_unlock(a->h_inode);
21585+ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
21586+ inode_lock_nested(a->h_inode, AuLsc_I_CHILD);
21587+ } else {
21588+ delegated = NULL;
21589+ while (1) {
21590+ err = vfsub_notify_change(&a->h_path, ia, &delegated);
21591+ if (delegated) {
21592+ err = break_deleg_wait(&delegated);
21593+ if (!err)
21594+ continue;
21595+ }
21596+ break;
21597+ }
21598+ }
21599+ /*
21600+ * regardless aufs 'acl' option setting.
21601+ * why don't all acl-aware fs call this func from their ->setattr()?
21602+ */
21603+ if (!err && (ia->ia_valid & ATTR_MODE))
21604+ err = vfsub_acl_chmod(a->h_inode, ia->ia_mode);
21605+ if (!err)
21606+ au_cpup_attr_changeable(inode);
21607+
21608+out_unlock:
21609+ inode_unlock(a->h_inode);
21610+ au_unpin(&a->pin);
21611+ if (unlikely(err))
21612+ au_update_dbtop(dentry);
21613+out_dentry:
21614+ di_write_unlock(dentry);
21615+ if (file) {
21616+ fi_write_unlock(file);
21617+ ia->ia_file = file;
21618+ ia->ia_valid |= ATTR_FILE;
21619+ }
21620+out_si:
21621+ si_read_unlock(sb);
21622+out_kfree:
21623+ au_kfree_rcu(a);
21624+out:
21625+ AuTraceErr(err);
21626+ return err;
21627+}
21628+
21629+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
21630+static int au_h_path_to_set_attr(struct dentry *dentry,
21631+ struct au_icpup_args *a, struct path *h_path)
21632+{
21633+ int err;
21634+ struct super_block *sb;
21635+
21636+ sb = dentry->d_sb;
21637+ a->udba = au_opt_udba(sb);
21638+ /* no d_unlinked(), to set UDBA_NONE for root */
21639+ if (d_unhashed(dentry))
21640+ a->udba = AuOpt_UDBA_NONE;
21641+ if (a->udba != AuOpt_UDBA_NONE) {
21642+ AuDebugOn(IS_ROOT(dentry));
21643+ err = au_reval_for_attr(dentry, au_sigen(sb));
21644+ if (unlikely(err))
21645+ goto out;
21646+ }
21647+ err = au_pin_and_icpup(dentry, /*ia*/NULL, a);
21648+ if (unlikely(err < 0))
21649+ goto out;
21650+
21651+ h_path->dentry = a->h_path.dentry;
21652+ h_path->mnt = au_sbr_mnt(sb, a->btgt);
21653+
21654+out:
21655+ return err;
21656+}
21657+
21658+ssize_t au_sxattr(struct dentry *dentry, struct inode *inode,
21659+ struct au_sxattr *arg)
21660+{
21661+ int err;
21662+ struct path h_path;
21663+ struct super_block *sb;
21664+ struct au_icpup_args *a;
21665+ struct inode *h_inode;
21666+
21667+ IMustLock(inode);
21668+
21669+ err = -ENOMEM;
21670+ a = kzalloc(sizeof(*a), GFP_NOFS);
21671+ if (unlikely(!a))
21672+ goto out;
21673+
21674+ sb = dentry->d_sb;
21675+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
21676+ if (unlikely(err))
21677+ goto out_kfree;
21678+
21679+ h_path.dentry = NULL; /* silence gcc */
21680+ di_write_lock_child(dentry);
21681+ err = au_h_path_to_set_attr(dentry, a, &h_path);
21682+ if (unlikely(err))
21683+ goto out_di;
21684+
21685+ inode_unlock(a->h_inode);
21686+ switch (arg->type) {
21687+ case AU_XATTR_SET:
21688+ AuDebugOn(d_is_negative(h_path.dentry));
21689+ err = vfsub_setxattr(h_path.dentry,
21690+ arg->u.set.name, arg->u.set.value,
21691+ arg->u.set.size, arg->u.set.flags);
21692+ break;
21693+ case AU_ACL_SET:
21694+ err = -EOPNOTSUPP;
21695+ h_inode = d_inode(h_path.dentry);
21696+ if (h_inode->i_op->set_acl)
21697+ /* this will call posix_acl_update_mode */
21698+ err = h_inode->i_op->set_acl(h_inode,
21699+ arg->u.acl_set.acl,
21700+ arg->u.acl_set.type);
21701+ break;
21702+ }
21703+ if (!err)
21704+ au_cpup_attr_timesizes(inode);
21705+
21706+ au_unpin(&a->pin);
21707+ if (unlikely(err))
21708+ au_update_dbtop(dentry);
21709+
21710+out_di:
21711+ di_write_unlock(dentry);
21712+ si_read_unlock(sb);
21713+out_kfree:
21714+ au_kfree_rcu(a);
21715+out:
21716+ AuTraceErr(err);
21717+ return err;
21718+}
21719+#endif
21720+
21721+static void au_refresh_iattr(struct inode *inode, struct kstat *st,
21722+ unsigned int nlink)
21723+{
21724+ unsigned int n;
21725+
21726+ inode->i_mode = st->mode;
21727+ /* don't i_[ug]id_write() here */
21728+ inode->i_uid = st->uid;
21729+ inode->i_gid = st->gid;
21730+ inode->i_atime = st->atime;
21731+ inode->i_mtime = st->mtime;
21732+ inode->i_ctime = st->ctime;
21733+
21734+ au_cpup_attr_nlink(inode, /*force*/0);
21735+ if (S_ISDIR(inode->i_mode)) {
21736+ n = inode->i_nlink;
21737+ n -= nlink;
21738+ n += st->nlink;
21739+ smp_mb(); /* for i_nlink */
21740+ /* 0 can happen */
21741+ set_nlink(inode, n);
21742+ }
21743+
21744+ spin_lock(&inode->i_lock);
21745+ inode->i_blocks = st->blocks;
21746+ i_size_write(inode, st->size);
21747+ spin_unlock(&inode->i_lock);
21748+}
21749+
21750+/*
21751+ * common routine for aufs_getattr() and au_getxattr().
21752+ * returns zero or negative (an error).
21753+ * @dentry will be read-locked in success.
21754+ */
21755+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path,
21756+ int locked)
21757+{
21758+ int err;
21759+ unsigned int mnt_flags, sigen;
21760+ unsigned char udba_none;
21761+ aufs_bindex_t bindex;
21762+ struct super_block *sb, *h_sb;
21763+ struct inode *inode;
21764+
21765+ h_path->mnt = NULL;
21766+ h_path->dentry = NULL;
21767+
21768+ err = 0;
21769+ sb = dentry->d_sb;
21770+ mnt_flags = au_mntflags(sb);
21771+ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
21772+
21773+ if (unlikely(locked))
21774+ goto body; /* skip locking dinfo */
21775+
21776+ /* support fstat(2) */
21777+ if (!d_unlinked(dentry) && !udba_none) {
21778+ sigen = au_sigen(sb);
21779+ err = au_digen_test(dentry, sigen);
21780+ if (!err) {
21781+ di_read_lock_child(dentry, AuLock_IR);
21782+ err = au_dbrange_test(dentry);
21783+ if (unlikely(err)) {
21784+ di_read_unlock(dentry, AuLock_IR);
21785+ goto out;
21786+ }
21787+ } else {
21788+ AuDebugOn(IS_ROOT(dentry));
21789+ di_write_lock_child(dentry);
21790+ err = au_dbrange_test(dentry);
21791+ if (!err)
21792+ err = au_reval_for_attr(dentry, sigen);
21793+ if (!err)
21794+ di_downgrade_lock(dentry, AuLock_IR);
21795+ else {
21796+ di_write_unlock(dentry);
21797+ goto out;
21798+ }
21799+ }
21800+ } else
21801+ di_read_lock_child(dentry, AuLock_IR);
21802+
21803+body:
21804+ inode = d_inode(dentry);
21805+ bindex = au_ibtop(inode);
21806+ h_path->mnt = au_sbr_mnt(sb, bindex);
21807+ h_sb = h_path->mnt->mnt_sb;
21808+ if (!force
21809+ && !au_test_fs_bad_iattr(h_sb)
21810+ && udba_none)
21811+ goto out; /* success */
21812+
21813+ if (au_dbtop(dentry) == bindex)
21814+ h_path->dentry = au_h_dptr(dentry, bindex);
21815+ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
21816+ h_path->dentry = au_plink_lkup(inode, bindex);
21817+ if (IS_ERR(h_path->dentry))
21818+ /* pretending success */
21819+ h_path->dentry = NULL;
21820+ else
21821+ dput(h_path->dentry);
21822+ }
21823+
21824+out:
21825+ return err;
21826+}
21827+
21828+static int aufs_getattr(const struct path *path, struct kstat *st,
21829+ u32 request, unsigned int query)
21830+{
21831+ int err;
21832+ unsigned char positive;
21833+ struct path h_path;
21834+ struct dentry *dentry;
21835+ struct inode *inode;
21836+ struct super_block *sb;
21837+
21838+ dentry = path->dentry;
21839+ inode = d_inode(dentry);
21840+ sb = dentry->d_sb;
21841+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
21842+ if (unlikely(err))
21843+ goto out;
21844+ err = au_h_path_getattr(dentry, /*force*/0, &h_path, /*locked*/0);
21845+ if (unlikely(err))
21846+ goto out_si;
21847+ if (unlikely(!h_path.dentry))
21848+ /* illegally overlapped or something */
21849+ goto out_fill; /* pretending success */
21850+
21851+ positive = d_is_positive(h_path.dentry);
21852+ if (positive)
21853+ /* no vfsub version */
21854+ err = vfs_getattr(&h_path, st, request, query);
21855+ if (!err) {
21856+ if (positive)
21857+ au_refresh_iattr(inode, st,
21858+ d_inode(h_path.dentry)->i_nlink);
21859+ goto out_fill; /* success */
21860+ }
21861+ AuTraceErr(err);
21862+ goto out_di;
21863+
21864+out_fill:
21865+ generic_fillattr(inode, st);
21866+out_di:
21867+ di_read_unlock(dentry, AuLock_IR);
21868+out_si:
21869+ si_read_unlock(sb);
21870+out:
21871+ AuTraceErr(err);
21872+ return err;
21873+}
21874+
21875+/* ---------------------------------------------------------------------- */
21876+
21877+static const char *aufs_get_link(struct dentry *dentry, struct inode *inode,
21878+ struct delayed_call *done)
21879+{
21880+ const char *ret;
21881+ struct dentry *h_dentry;
21882+ struct inode *h_inode;
21883+ int err;
21884+ aufs_bindex_t bindex;
21885+
21886+ ret = NULL; /* suppress a warning */
21887+ err = -ECHILD;
21888+ if (!dentry)
21889+ goto out;
21890+
21891+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
21892+ if (unlikely(err))
21893+ goto out;
21894+
21895+ err = au_d_hashed_positive(dentry);
21896+ if (unlikely(err))
21897+ goto out_unlock;
21898+
21899+ err = -EINVAL;
21900+ inode = d_inode(dentry);
21901+ bindex = au_ibtop(inode);
21902+ h_inode = au_h_iptr(inode, bindex);
21903+ if (unlikely(!h_inode->i_op->get_link))
21904+ goto out_unlock;
21905+
21906+ err = -EBUSY;
21907+ h_dentry = NULL;
21908+ if (au_dbtop(dentry) <= bindex) {
21909+ h_dentry = au_h_dptr(dentry, bindex);
21910+ if (h_dentry)
21911+ dget(h_dentry);
21912+ }
21913+ if (!h_dentry) {
21914+ h_dentry = d_find_any_alias(h_inode);
21915+ if (IS_ERR(h_dentry)) {
21916+ err = PTR_ERR(h_dentry);
21917+ goto out_unlock;
21918+ }
21919+ }
21920+ if (unlikely(!h_dentry))
21921+ goto out_unlock;
21922+
21923+ err = 0;
21924+ AuDbg("%ps\n", h_inode->i_op->get_link);
21925+ AuDbgDentry(h_dentry);
21926+ ret = vfs_get_link(h_dentry, done);
21927+ dput(h_dentry);
21928+ if (IS_ERR(ret))
21929+ err = PTR_ERR(ret);
21930+
21931+out_unlock:
21932+ aufs_read_unlock(dentry, AuLock_IR);
21933+out:
21934+ if (unlikely(err))
21935+ ret = ERR_PTR(err);
21936+ AuTraceErrPtr(ret);
21937+ return ret;
21938+}
21939+
21940+/* ---------------------------------------------------------------------- */
21941+
21942+static int au_is_special(struct inode *inode)
21943+{
21944+ return (inode->i_mode & (S_IFBLK | S_IFCHR | S_IFIFO | S_IFSOCK));
21945+}
21946+
21947+static int aufs_update_time(struct inode *inode, struct timespec64 *ts,
21948+ int flags)
21949+{
21950+ int err;
21951+ aufs_bindex_t bindex;
21952+ struct super_block *sb;
21953+ struct inode *h_inode;
21954+ struct vfsmount *h_mnt;
21955+
21956+ sb = inode->i_sb;
21957+ WARN_ONCE((flags & S_ATIME) && !IS_NOATIME(inode),
21958+ "unexpected s_flags 0x%lx", sb->s_flags);
21959+
21960+ /* mmap_sem might be acquired already, cf. aufs_mmap() */
21961+ lockdep_off();
21962+ si_read_lock(sb, AuLock_FLUSH);
21963+ ii_write_lock_child(inode);
21964+
21965+ err = 0;
21966+ bindex = au_ibtop(inode);
21967+ h_inode = au_h_iptr(inode, bindex);
21968+ if (!au_test_ro(sb, bindex, inode)) {
21969+ h_mnt = au_sbr_mnt(sb, bindex);
21970+ err = vfsub_mnt_want_write(h_mnt);
21971+ if (!err) {
21972+ err = vfsub_update_time(h_inode, ts, flags);
21973+ vfsub_mnt_drop_write(h_mnt);
21974+ }
21975+ } else if (au_is_special(h_inode)) {
21976+ /*
21977+ * Never copy-up here.
21978+ * These special files may already be opened and used for
21979+ * communicating. If we copied it up, then the communication
21980+ * would be corrupted.
21981+ */
21982+ AuWarn1("timestamps for i%lu are ignored "
21983+ "since it is on readonly branch (hi%lu).\n",
21984+ inode->i_ino, h_inode->i_ino);
21985+ } else if (flags & ~S_ATIME) {
21986+ err = -EIO;
21987+ AuIOErr1("unexpected flags 0x%x\n", flags);
21988+ AuDebugOn(1);
21989+ }
21990+
21991+ if (!err)
21992+ au_cpup_attr_timesizes(inode);
21993+ ii_write_unlock(inode);
21994+ si_read_unlock(sb);
21995+ lockdep_on();
21996+
21997+ if (!err && (flags & S_VERSION))
21998+ inode_inc_iversion(inode);
21999+
22000+ return err;
22001+}
22002+
22003+/* ---------------------------------------------------------------------- */
22004+
22005+/* no getattr version will be set by module.c:aufs_init() */
22006+struct inode_operations aufs_iop_nogetattr[AuIop_Last],
22007+ aufs_iop[] = {
22008+ [AuIop_SYMLINK] = {
22009+ .permission = aufs_permission,
22010+#ifdef CONFIG_FS_POSIX_ACL
22011+ .get_acl = aufs_get_acl,
22012+ .set_acl = aufs_set_acl, /* unsupport for symlink? */
22013+#endif
22014+
22015+ .setattr = aufs_setattr,
22016+ .getattr = aufs_getattr,
22017+
22018+#ifdef CONFIG_AUFS_XATTR
22019+ .listxattr = aufs_listxattr,
22020+#endif
22021+
22022+ .get_link = aufs_get_link,
22023+
22024+ /* .update_time = aufs_update_time */
22025+ },
22026+ [AuIop_DIR] = {
22027+ .create = aufs_create,
22028+ .lookup = aufs_lookup,
22029+ .link = aufs_link,
22030+ .unlink = aufs_unlink,
22031+ .symlink = aufs_symlink,
22032+ .mkdir = aufs_mkdir,
22033+ .rmdir = aufs_rmdir,
22034+ .mknod = aufs_mknod,
22035+ .rename = aufs_rename,
22036+
22037+ .permission = aufs_permission,
22038+#ifdef CONFIG_FS_POSIX_ACL
22039+ .get_acl = aufs_get_acl,
22040+ .set_acl = aufs_set_acl,
22041+#endif
22042+
22043+ .setattr = aufs_setattr,
22044+ .getattr = aufs_getattr,
22045+
22046+#ifdef CONFIG_AUFS_XATTR
22047+ .listxattr = aufs_listxattr,
22048+#endif
22049+
22050+ .update_time = aufs_update_time,
22051+ .atomic_open = aufs_atomic_open,
22052+ .tmpfile = aufs_tmpfile
22053+ },
22054+ [AuIop_OTHER] = {
22055+ .permission = aufs_permission,
22056+#ifdef CONFIG_FS_POSIX_ACL
22057+ .get_acl = aufs_get_acl,
22058+ .set_acl = aufs_set_acl,
22059+#endif
22060+
22061+ .setattr = aufs_setattr,
22062+ .getattr = aufs_getattr,
22063+
22064+#ifdef CONFIG_AUFS_XATTR
22065+ .listxattr = aufs_listxattr,
22066+#endif
22067+
22068+ .update_time = aufs_update_time
22069+ }
22070+};
22071diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
22072--- /usr/share/empty/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
22073+++ linux/fs/aufs/i_op_del.c 2020-01-27 10:57:18.172204883 +0100
22074@@ -0,0 +1,513 @@
22075+// SPDX-License-Identifier: GPL-2.0
22076+/*
22077+ * Copyright (C) 2005-2020 Junjiro R. Okajima
22078+ *
22079+ * This program, aufs is free software; you can redistribute it and/or modify
22080+ * it under the terms of the GNU General Public License as published by
22081+ * the Free Software Foundation; either version 2 of the License, or
22082+ * (at your option) any later version.
22083+ *
22084+ * This program is distributed in the hope that it will be useful,
22085+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22086+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22087+ * GNU General Public License for more details.
22088+ *
22089+ * You should have received a copy of the GNU General Public License
22090+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
22091+ */
22092+
22093+/*
22094+ * inode operations (del entry)
22095+ */
22096+
22097+#include <linux/iversion.h>
22098+#include "aufs.h"
22099+
22100+/*
22101+ * decide if a new whiteout for @dentry is necessary or not.
22102+ * when it is necessary, prepare the parent dir for the upper branch whose
22103+ * branch index is @bcpup for creation. the actual creation of the whiteout will
22104+ * be done by caller.
22105+ * return value:
22106+ * 0: wh is unnecessary
22107+ * plus: wh is necessary
22108+ * minus: error
22109+ */
22110+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
22111+{
22112+ int need_wh, err;
22113+ aufs_bindex_t btop;
22114+ struct super_block *sb;
22115+
22116+ sb = dentry->d_sb;
22117+ btop = au_dbtop(dentry);
22118+ if (*bcpup < 0) {
22119+ *bcpup = btop;
22120+ if (au_test_ro(sb, btop, d_inode(dentry))) {
22121+ err = AuWbrCopyup(au_sbi(sb), dentry);
22122+ *bcpup = err;
22123+ if (unlikely(err < 0))
22124+ goto out;
22125+ }
22126+ } else
22127+ AuDebugOn(btop < *bcpup
22128+ || au_test_ro(sb, *bcpup, d_inode(dentry)));
22129+ AuDbg("bcpup %d, btop %d\n", *bcpup, btop);
22130+
22131+ if (*bcpup != btop) {
22132+ err = au_cpup_dirs(dentry, *bcpup);
22133+ if (unlikely(err))
22134+ goto out;
22135+ need_wh = 1;
22136+ } else {
22137+ struct au_dinfo *dinfo, *tmp;
22138+
22139+ need_wh = -ENOMEM;
22140+ dinfo = au_di(dentry);
22141+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
22142+ if (tmp) {
22143+ au_di_cp(tmp, dinfo);
22144+ au_di_swap(tmp, dinfo);
22145+ /* returns the number of positive dentries */
22146+ need_wh = au_lkup_dentry(dentry, btop + 1,
22147+ /* AuLkup_IGNORE_PERM */ 0);
22148+ au_di_swap(tmp, dinfo);
22149+ au_rw_write_unlock(&tmp->di_rwsem);
22150+ au_di_free(tmp);
22151+ }
22152+ }
22153+ AuDbg("need_wh %d\n", need_wh);
22154+ err = need_wh;
22155+
22156+out:
22157+ return err;
22158+}
22159+
22160+/*
22161+ * simple tests for the del-entry operations.
22162+ * following the checks in vfs, plus the parent-child relationship.
22163+ */
22164+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
22165+ struct dentry *h_parent, int isdir)
22166+{
22167+ int err;
22168+ umode_t h_mode;
22169+ struct dentry *h_dentry, *h_latest;
22170+ struct inode *h_inode;
22171+
22172+ h_dentry = au_h_dptr(dentry, bindex);
22173+ if (d_really_is_positive(dentry)) {
22174+ err = -ENOENT;
22175+ if (unlikely(d_is_negative(h_dentry)))
22176+ goto out;
22177+ h_inode = d_inode(h_dentry);
22178+ if (unlikely(!h_inode->i_nlink))
22179+ goto out;
22180+
22181+ h_mode = h_inode->i_mode;
22182+ if (!isdir) {
22183+ err = -EISDIR;
22184+ if (unlikely(S_ISDIR(h_mode)))
22185+ goto out;
22186+ } else if (unlikely(!S_ISDIR(h_mode))) {
22187+ err = -ENOTDIR;
22188+ goto out;
22189+ }
22190+ } else {
22191+ /* rename(2) case */
22192+ err = -EIO;
22193+ if (unlikely(d_is_positive(h_dentry)))
22194+ goto out;
22195+ }
22196+
22197+ err = -ENOENT;
22198+ /* expected parent dir is locked */
22199+ if (unlikely(h_parent != h_dentry->d_parent))
22200+ goto out;
22201+ err = 0;
22202+
22203+ /*
22204+ * rmdir a dir may break the consistency on some filesystem.
22205+ * let's try heavy test.
22206+ */
22207+ err = -EACCES;
22208+ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1)
22209+ && au_test_h_perm(d_inode(h_parent),
22210+ MAY_EXEC | MAY_WRITE)))
22211+ goto out;
22212+
22213+ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent);
22214+ err = -EIO;
22215+ if (IS_ERR(h_latest))
22216+ goto out;
22217+ if (h_latest == h_dentry)
22218+ err = 0;
22219+ dput(h_latest);
22220+
22221+out:
22222+ return err;
22223+}
22224+
22225+/*
22226+ * decide the branch where we operate for @dentry. the branch index will be set
22227+ * @rbcpup. after deciding it, 'pin' it and store the timestamps of the parent
22228+ * dir for reverting.
22229+ * when a new whiteout is necessary, create it.
22230+ */
22231+static struct dentry*
22232+lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
22233+ struct au_dtime *dt, struct au_pin *pin)
22234+{
22235+ struct dentry *wh_dentry;
22236+ struct super_block *sb;
22237+ struct path h_path;
22238+ int err, need_wh;
22239+ unsigned int udba;
22240+ aufs_bindex_t bcpup;
22241+
22242+ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
22243+ wh_dentry = ERR_PTR(need_wh);
22244+ if (unlikely(need_wh < 0))
22245+ goto out;
22246+
22247+ sb = dentry->d_sb;
22248+ udba = au_opt_udba(sb);
22249+ bcpup = *rbcpup;
22250+ err = au_pin(pin, dentry, bcpup, udba,
22251+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
22252+ wh_dentry = ERR_PTR(err);
22253+ if (unlikely(err))
22254+ goto out;
22255+
22256+ h_path.dentry = au_pinned_h_parent(pin);
22257+ if (udba != AuOpt_UDBA_NONE
22258+ && au_dbtop(dentry) == bcpup) {
22259+ err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
22260+ wh_dentry = ERR_PTR(err);
22261+ if (unlikely(err))
22262+ goto out_unpin;
22263+ }
22264+
22265+ h_path.mnt = au_sbr_mnt(sb, bcpup);
22266+ au_dtime_store(dt, au_pinned_parent(pin), &h_path);
22267+ wh_dentry = NULL;
22268+ if (!need_wh)
22269+ goto out; /* success, no need to create whiteout */
22270+
22271+ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
22272+ if (IS_ERR(wh_dentry))
22273+ goto out_unpin;
22274+
22275+ /* returns with the parent is locked and wh_dentry is dget-ed */
22276+ goto out; /* success */
22277+
22278+out_unpin:
22279+ au_unpin(pin);
22280+out:
22281+ return wh_dentry;
22282+}
22283+
22284+/*
22285+ * when removing a dir, rename it to a unique temporary whiteout-ed name first
22286+ * in order to be revertible and save time for removing many child whiteouts
22287+ * under the dir.
22288+ * returns 1 when there are too many child whiteout and caller should remove
22289+ * them asynchronously. returns 0 when the number of children is enough small to
22290+ * remove now or the branch fs is a remote fs.
22291+ * otherwise return an error.
22292+ */
22293+static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
22294+ struct au_nhash *whlist, struct inode *dir)
22295+{
22296+ int rmdir_later, err, dirwh;
22297+ struct dentry *h_dentry;
22298+ struct super_block *sb;
22299+ struct inode *inode;
22300+
22301+ sb = dentry->d_sb;
22302+ SiMustAnyLock(sb);
22303+ h_dentry = au_h_dptr(dentry, bindex);
22304+ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
22305+ if (unlikely(err))
22306+ goto out;
22307+
22308+ /* stop monitoring */
22309+ inode = d_inode(dentry);
22310+ au_hn_free(au_hi(inode, bindex));
22311+
22312+ if (!au_test_fs_remote(h_dentry->d_sb)) {
22313+ dirwh = au_sbi(sb)->si_dirwh;
22314+ rmdir_later = (dirwh <= 1);
22315+ if (!rmdir_later)
22316+ rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
22317+ dirwh);
22318+ if (rmdir_later)
22319+ return rmdir_later;
22320+ }
22321+
22322+ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
22323+ if (unlikely(err)) {
22324+ AuIOErr("rmdir %pd, b%d failed, %d. ignored\n",
22325+ h_dentry, bindex, err);
22326+ err = 0;
22327+ }
22328+
22329+out:
22330+ AuTraceErr(err);
22331+ return err;
22332+}
22333+
22334+/*
22335+ * final procedure for deleting a entry.
22336+ * maintain dentry and iattr.
22337+ */
22338+static void epilog(struct inode *dir, struct dentry *dentry,
22339+ aufs_bindex_t bindex)
22340+{
22341+ struct inode *inode;
22342+
22343+ inode = d_inode(dentry);
22344+ d_drop(dentry);
22345+ inode->i_ctime = dir->i_ctime;
22346+
22347+ au_dir_ts(dir, bindex);
22348+ inode_inc_iversion(dir);
22349+}
22350+
22351+/*
22352+ * when an error happened, remove the created whiteout and revert everything.
22353+ */
22354+static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex,
22355+ aufs_bindex_t bwh, struct dentry *wh_dentry,
22356+ struct dentry *dentry, struct au_dtime *dt)
22357+{
22358+ int rerr;
22359+ struct path h_path = {
22360+ .dentry = wh_dentry,
22361+ .mnt = au_sbr_mnt(dir->i_sb, bindex)
22362+ };
22363+
22364+ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
22365+ if (!rerr) {
22366+ au_set_dbwh(dentry, bwh);
22367+ au_dtime_revert(dt);
22368+ return 0;
22369+ }
22370+
22371+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", dentry, err, rerr);
22372+ return -EIO;
22373+}
22374+
22375+/* ---------------------------------------------------------------------- */
22376+
22377+int aufs_unlink(struct inode *dir, struct dentry *dentry)
22378+{
22379+ int err;
22380+ aufs_bindex_t bwh, bindex, btop;
22381+ struct inode *inode, *h_dir, *delegated;
22382+ struct dentry *parent, *wh_dentry;
22383+ /* to reduce stack size */
22384+ struct {
22385+ struct au_dtime dt;
22386+ struct au_pin pin;
22387+ struct path h_path;
22388+ } *a;
22389+
22390+ IMustLock(dir);
22391+
22392+ err = -ENOMEM;
22393+ a = kmalloc(sizeof(*a), GFP_NOFS);
22394+ if (unlikely(!a))
22395+ goto out;
22396+
22397+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
22398+ if (unlikely(err))
22399+ goto out_free;
22400+ err = au_d_hashed_positive(dentry);
22401+ if (unlikely(err))
22402+ goto out_unlock;
22403+ inode = d_inode(dentry);
22404+ IMustLock(inode);
22405+ err = -EISDIR;
22406+ if (unlikely(d_is_dir(dentry)))
22407+ goto out_unlock; /* possible? */
22408+
22409+ btop = au_dbtop(dentry);
22410+ bwh = au_dbwh(dentry);
22411+ bindex = -1;
22412+ parent = dentry->d_parent; /* dir inode is locked */
22413+ di_write_lock_parent(parent);
22414+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &a->dt,
22415+ &a->pin);
22416+ err = PTR_ERR(wh_dentry);
22417+ if (IS_ERR(wh_dentry))
22418+ goto out_parent;
22419+
22420+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, btop);
22421+ a->h_path.dentry = au_h_dptr(dentry, btop);
22422+ dget(a->h_path.dentry);
22423+ if (bindex == btop) {
22424+ h_dir = au_pinned_h_dir(&a->pin);
22425+ delegated = NULL;
22426+ err = vfsub_unlink(h_dir, &a->h_path, &delegated, /*force*/0);
22427+ if (unlikely(err == -EWOULDBLOCK)) {
22428+ pr_warn("cannot retry for NFSv4 delegation"
22429+ " for an internal unlink\n");
22430+ iput(delegated);
22431+ }
22432+ } else {
22433+ /* dir inode is locked */
22434+ h_dir = d_inode(wh_dentry->d_parent);
22435+ IMustLock(h_dir);
22436+ err = 0;
22437+ }
22438+
22439+ if (!err) {
22440+ vfsub_drop_nlink(inode);
22441+ epilog(dir, dentry, bindex);
22442+
22443+ /* update target timestamps */
22444+ if (bindex == btop) {
22445+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL);
22446+ /*ignore*/
22447+ inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
22448+ } else
22449+ /* todo: this timestamp may be reverted later */
22450+ inode->i_ctime = h_dir->i_ctime;
22451+ goto out_unpin; /* success */
22452+ }
22453+
22454+ /* revert */
22455+ if (wh_dentry) {
22456+ int rerr;
22457+
22458+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
22459+ &a->dt);
22460+ if (rerr)
22461+ err = rerr;
22462+ }
22463+
22464+out_unpin:
22465+ au_unpin(&a->pin);
22466+ dput(wh_dentry);
22467+ dput(a->h_path.dentry);
22468+out_parent:
22469+ di_write_unlock(parent);
22470+out_unlock:
22471+ aufs_read_unlock(dentry, AuLock_DW);
22472+out_free:
22473+ au_kfree_rcu(a);
22474+out:
22475+ return err;
22476+}
22477+
22478+int aufs_rmdir(struct inode *dir, struct dentry *dentry)
22479+{
22480+ int err, rmdir_later;
22481+ aufs_bindex_t bwh, bindex, btop;
22482+ struct inode *inode;
22483+ struct dentry *parent, *wh_dentry, *h_dentry;
22484+ struct au_whtmp_rmdir *args;
22485+ /* to reduce stack size */
22486+ struct {
22487+ struct au_dtime dt;
22488+ struct au_pin pin;
22489+ } *a;
22490+
22491+ IMustLock(dir);
22492+
22493+ err = -ENOMEM;
22494+ a = kmalloc(sizeof(*a), GFP_NOFS);
22495+ if (unlikely(!a))
22496+ goto out;
22497+
22498+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
22499+ if (unlikely(err))
22500+ goto out_free;
22501+ err = au_alive_dir(dentry);
22502+ if (unlikely(err))
22503+ goto out_unlock;
22504+ inode = d_inode(dentry);
22505+ IMustLock(inode);
22506+ err = -ENOTDIR;
22507+ if (unlikely(!d_is_dir(dentry)))
22508+ goto out_unlock; /* possible? */
22509+
22510+ err = -ENOMEM;
22511+ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
22512+ if (unlikely(!args))
22513+ goto out_unlock;
22514+
22515+ parent = dentry->d_parent; /* dir inode is locked */
22516+ di_write_lock_parent(parent);
22517+ err = au_test_empty(dentry, &args->whlist);
22518+ if (unlikely(err))
22519+ goto out_parent;
22520+
22521+ btop = au_dbtop(dentry);
22522+ bwh = au_dbwh(dentry);
22523+ bindex = -1;
22524+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &a->dt,
22525+ &a->pin);
22526+ err = PTR_ERR(wh_dentry);
22527+ if (IS_ERR(wh_dentry))
22528+ goto out_parent;
22529+
22530+ h_dentry = au_h_dptr(dentry, btop);
22531+ dget(h_dentry);
22532+ rmdir_later = 0;
22533+ if (bindex == btop) {
22534+ err = renwh_and_rmdir(dentry, btop, &args->whlist, dir);
22535+ if (err > 0) {
22536+ rmdir_later = err;
22537+ err = 0;
22538+ }
22539+ } else {
22540+ /* stop monitoring */
22541+ au_hn_free(au_hi(inode, btop));
22542+
22543+ /* dir inode is locked */
22544+ IMustLock(d_inode(wh_dentry->d_parent));
22545+ err = 0;
22546+ }
22547+
22548+ if (!err) {
22549+ vfsub_dead_dir(inode);
22550+ au_set_dbdiropq(dentry, -1);
22551+ epilog(dir, dentry, bindex);
22552+
22553+ if (rmdir_later) {
22554+ au_whtmp_kick_rmdir(dir, btop, h_dentry, args);
22555+ args = NULL;
22556+ }
22557+
22558+ goto out_unpin; /* success */
22559+ }
22560+
22561+ /* revert */
22562+ AuLabel(revert);
22563+ if (wh_dentry) {
22564+ int rerr;
22565+
22566+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
22567+ &a->dt);
22568+ if (rerr)
22569+ err = rerr;
22570+ }
22571+
22572+out_unpin:
22573+ au_unpin(&a->pin);
22574+ dput(wh_dentry);
22575+ dput(h_dentry);
22576+out_parent:
22577+ di_write_unlock(parent);
22578+ if (args)
22579+ au_whtmp_rmdir_free(args);
22580+out_unlock:
22581+ aufs_read_unlock(dentry, AuLock_DW);
22582+out_free:
22583+ au_kfree_rcu(a);
22584+out:
22585+ AuTraceErr(err);
22586+ return err;
22587+}
22588diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
22589--- /usr/share/empty/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
22590+++ linux/fs/aufs/i_op_ren.c 2020-01-27 10:57:18.172204883 +0100
22591@@ -0,0 +1,1250 @@
22592+// SPDX-License-Identifier: GPL-2.0
22593+/*
22594+ * Copyright (C) 2005-2020 Junjiro R. Okajima
22595+ *
22596+ * This program, aufs is free software; you can redistribute it and/or modify
22597+ * it under the terms of the GNU General Public License as published by
22598+ * the Free Software Foundation; either version 2 of the License, or
22599+ * (at your option) any later version.
22600+ *
22601+ * This program is distributed in the hope that it will be useful,
22602+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22603+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22604+ * GNU General Public License for more details.
22605+ *
22606+ * You should have received a copy of the GNU General Public License
22607+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
22608+ */
22609+
22610+/*
22611+ * inode operation (rename entry)
22612+ * todo: this is crazy monster
22613+ */
22614+
22615+#include <linux/iversion.h>
22616+#include "aufs.h"
22617+
22618+enum { AuSRC, AuDST, AuSrcDst };
22619+enum { AuPARENT, AuCHILD, AuParentChild };
22620+
22621+#define AuRen_ISDIR_SRC 1
22622+#define AuRen_ISDIR_DST (1 << 1)
22623+#define AuRen_ISSAMEDIR (1 << 2)
22624+#define AuRen_WHSRC (1 << 3)
22625+#define AuRen_WHDST (1 << 4)
22626+#define AuRen_MNT_WRITE (1 << 5)
22627+#define AuRen_DT_DSTDIR (1 << 6)
22628+#define AuRen_DIROPQ_SRC (1 << 7)
22629+#define AuRen_DIROPQ_DST (1 << 8)
22630+#define AuRen_DIRREN (1 << 9)
22631+#define AuRen_DROPPED_SRC (1 << 10)
22632+#define AuRen_DROPPED_DST (1 << 11)
22633+#define au_ftest_ren(flags, name) ((flags) & AuRen_##name)
22634+#define au_fset_ren(flags, name) \
22635+ do { (flags) |= AuRen_##name; } while (0)
22636+#define au_fclr_ren(flags, name) \
22637+ do { (flags) &= ~AuRen_##name; } while (0)
22638+
22639+#ifndef CONFIG_AUFS_DIRREN
22640+#undef AuRen_DIRREN
22641+#define AuRen_DIRREN 0
22642+#endif
22643+
22644+struct au_ren_args {
22645+ struct {
22646+ struct dentry *dentry, *h_dentry, *parent, *h_parent,
22647+ *wh_dentry;
22648+ struct inode *dir, *inode;
22649+ struct au_hinode *hdir, *hinode;
22650+ struct au_dtime dt[AuParentChild];
22651+ aufs_bindex_t btop, bdiropq;
22652+ } sd[AuSrcDst];
22653+
22654+#define src_dentry sd[AuSRC].dentry
22655+#define src_dir sd[AuSRC].dir
22656+#define src_inode sd[AuSRC].inode
22657+#define src_h_dentry sd[AuSRC].h_dentry
22658+#define src_parent sd[AuSRC].parent
22659+#define src_h_parent sd[AuSRC].h_parent
22660+#define src_wh_dentry sd[AuSRC].wh_dentry
22661+#define src_hdir sd[AuSRC].hdir
22662+#define src_hinode sd[AuSRC].hinode
22663+#define src_h_dir sd[AuSRC].hdir->hi_inode
22664+#define src_dt sd[AuSRC].dt
22665+#define src_btop sd[AuSRC].btop
22666+#define src_bdiropq sd[AuSRC].bdiropq
22667+
22668+#define dst_dentry sd[AuDST].dentry
22669+#define dst_dir sd[AuDST].dir
22670+#define dst_inode sd[AuDST].inode
22671+#define dst_h_dentry sd[AuDST].h_dentry
22672+#define dst_parent sd[AuDST].parent
22673+#define dst_h_parent sd[AuDST].h_parent
22674+#define dst_wh_dentry sd[AuDST].wh_dentry
22675+#define dst_hdir sd[AuDST].hdir
22676+#define dst_hinode sd[AuDST].hinode
22677+#define dst_h_dir sd[AuDST].hdir->hi_inode
22678+#define dst_dt sd[AuDST].dt
22679+#define dst_btop sd[AuDST].btop
22680+#define dst_bdiropq sd[AuDST].bdiropq
22681+
22682+ struct dentry *h_trap;
22683+ struct au_branch *br;
22684+ struct path h_path;
22685+ struct au_nhash whlist;
22686+ aufs_bindex_t btgt, src_bwh;
22687+
22688+ struct {
22689+ unsigned short auren_flags;
22690+ unsigned char flags; /* syscall parameter */
22691+ unsigned char exchange;
22692+ } __packed;
22693+
22694+ struct au_whtmp_rmdir *thargs;
22695+ struct dentry *h_dst;
22696+ struct au_hinode *h_root;
22697+};
22698+
22699+/* ---------------------------------------------------------------------- */
22700+
22701+/*
22702+ * functions for reverting.
22703+ * when an error happened in a single rename systemcall, we should revert
22704+ * everything as if nothing happened.
22705+ * we don't need to revert the copied-up/down the parent dir since they are
22706+ * harmless.
22707+ */
22708+
22709+#define RevertFailure(fmt, ...) do { \
22710+ AuIOErr("revert failure: " fmt " (%d, %d)\n", \
22711+ ##__VA_ARGS__, err, rerr); \
22712+ err = -EIO; \
22713+} while (0)
22714+
22715+static void au_ren_do_rev_diropq(int err, struct au_ren_args *a, int idx)
22716+{
22717+ int rerr;
22718+ struct dentry *d;
22719+#define src_or_dst(member) a->sd[idx].member
22720+
22721+ d = src_or_dst(dentry); /* {src,dst}_dentry */
22722+ au_hn_inode_lock_nested(src_or_dst(hinode), AuLsc_I_CHILD);
22723+ rerr = au_diropq_remove(d, a->btgt);
22724+ au_hn_inode_unlock(src_or_dst(hinode));
22725+ au_set_dbdiropq(d, src_or_dst(bdiropq));
22726+ if (rerr)
22727+ RevertFailure("remove diropq %pd", d);
22728+
22729+#undef src_or_dst_
22730+}
22731+
22732+static void au_ren_rev_diropq(int err, struct au_ren_args *a)
22733+{
22734+ if (au_ftest_ren(a->auren_flags, DIROPQ_SRC))
22735+ au_ren_do_rev_diropq(err, a, AuSRC);
22736+ if (au_ftest_ren(a->auren_flags, DIROPQ_DST))
22737+ au_ren_do_rev_diropq(err, a, AuDST);
22738+}
22739+
22740+static void au_ren_rev_rename(int err, struct au_ren_args *a)
22741+{
22742+ int rerr;
22743+ struct inode *delegated;
22744+
22745+ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name,
22746+ a->src_h_parent);
22747+ rerr = PTR_ERR(a->h_path.dentry);
22748+ if (IS_ERR(a->h_path.dentry)) {
22749+ RevertFailure("lkup one %pd", a->src_dentry);
22750+ return;
22751+ }
22752+
22753+ delegated = NULL;
22754+ rerr = vfsub_rename(a->dst_h_dir,
22755+ au_h_dptr(a->src_dentry, a->btgt),
22756+ a->src_h_dir, &a->h_path, &delegated, a->flags);
22757+ if (unlikely(rerr == -EWOULDBLOCK)) {
22758+ pr_warn("cannot retry for NFSv4 delegation"
22759+ " for an internal rename\n");
22760+ iput(delegated);
22761+ }
22762+ d_drop(a->h_path.dentry);
22763+ dput(a->h_path.dentry);
22764+ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
22765+ if (rerr)
22766+ RevertFailure("rename %pd", a->src_dentry);
22767+}
22768+
22769+static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
22770+{
22771+ int rerr;
22772+ struct inode *delegated;
22773+
22774+ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name,
22775+ a->dst_h_parent);
22776+ rerr = PTR_ERR(a->h_path.dentry);
22777+ if (IS_ERR(a->h_path.dentry)) {
22778+ RevertFailure("lkup one %pd", a->dst_dentry);
22779+ return;
22780+ }
22781+ if (d_is_positive(a->h_path.dentry)) {
22782+ d_drop(a->h_path.dentry);
22783+ dput(a->h_path.dentry);
22784+ return;
22785+ }
22786+
22787+ delegated = NULL;
22788+ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path,
22789+ &delegated, a->flags);
22790+ if (unlikely(rerr == -EWOULDBLOCK)) {
22791+ pr_warn("cannot retry for NFSv4 delegation"
22792+ " for an internal rename\n");
22793+ iput(delegated);
22794+ }
22795+ d_drop(a->h_path.dentry);
22796+ dput(a->h_path.dentry);
22797+ if (!rerr)
22798+ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
22799+ else
22800+ RevertFailure("rename %pd", a->h_dst);
22801+}
22802+
22803+static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
22804+{
22805+ int rerr;
22806+
22807+ a->h_path.dentry = a->src_wh_dentry;
22808+ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
22809+ au_set_dbwh(a->src_dentry, a->src_bwh);
22810+ if (rerr)
22811+ RevertFailure("unlink %pd", a->src_wh_dentry);
22812+}
22813+#undef RevertFailure
22814+
22815+/* ---------------------------------------------------------------------- */
22816+
22817+/*
22818+ * when we have to copyup the renaming entry, do it with the rename-target name
22819+ * in order to minimize the cost (the later actual rename is unnecessary).
22820+ * otherwise rename it on the target branch.
22821+ */
22822+static int au_ren_or_cpup(struct au_ren_args *a)
22823+{
22824+ int err;
22825+ struct dentry *d;
22826+ struct inode *delegated;
22827+
22828+ d = a->src_dentry;
22829+ if (au_dbtop(d) == a->btgt) {
22830+ a->h_path.dentry = a->dst_h_dentry;
22831+ AuDebugOn(au_dbtop(d) != a->btgt);
22832+ delegated = NULL;
22833+ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
22834+ a->dst_h_dir, &a->h_path, &delegated,
22835+ a->flags);
22836+ if (unlikely(err == -EWOULDBLOCK)) {
22837+ pr_warn("cannot retry for NFSv4 delegation"
22838+ " for an internal rename\n");
22839+ iput(delegated);
22840+ }
22841+ } else
22842+ BUG();
22843+
22844+ if (!err && a->h_dst)
22845+ /* it will be set to dinfo later */
22846+ dget(a->h_dst);
22847+
22848+ return err;
22849+}
22850+
22851+/* cf. aufs_rmdir() */
22852+static int au_ren_del_whtmp(struct au_ren_args *a)
22853+{
22854+ int err;
22855+ struct inode *dir;
22856+
22857+ dir = a->dst_dir;
22858+ SiMustAnyLock(dir->i_sb);
22859+ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
22860+ au_sbi(dir->i_sb)->si_dirwh)
22861+ || au_test_fs_remote(a->h_dst->d_sb)) {
22862+ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
22863+ if (unlikely(err))
22864+ pr_warn("failed removing whtmp dir %pd (%d), "
22865+ "ignored.\n", a->h_dst, err);
22866+ } else {
22867+ au_nhash_wh_free(&a->thargs->whlist);
22868+ a->thargs->whlist = a->whlist;
22869+ a->whlist.nh_num = 0;
22870+ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
22871+ dput(a->h_dst);
22872+ a->thargs = NULL;
22873+ }
22874+
22875+ return 0;
22876+}
22877+
22878+/* make it 'opaque' dir. */
22879+static int au_ren_do_diropq(struct au_ren_args *a, int idx)
22880+{
22881+ int err;
22882+ struct dentry *d, *diropq;
22883+#define src_or_dst(member) a->sd[idx].member
22884+
22885+ err = 0;
22886+ d = src_or_dst(dentry); /* {src,dst}_dentry */
22887+ src_or_dst(bdiropq) = au_dbdiropq(d);
22888+ src_or_dst(hinode) = au_hi(src_or_dst(inode), a->btgt);
22889+ au_hn_inode_lock_nested(src_or_dst(hinode), AuLsc_I_CHILD);
22890+ diropq = au_diropq_create(d, a->btgt);
22891+ au_hn_inode_unlock(src_or_dst(hinode));
22892+ if (IS_ERR(diropq))
22893+ err = PTR_ERR(diropq);
22894+ else
22895+ dput(diropq);
22896+
22897+#undef src_or_dst_
22898+ return err;
22899+}
22900+
22901+static int au_ren_diropq(struct au_ren_args *a)
22902+{
22903+ int err;
22904+ unsigned char always;
22905+ struct dentry *d;
22906+
22907+ err = 0;
22908+ d = a->dst_dentry; /* already renamed on the branch */
22909+ always = !!au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ);
22910+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)
22911+ && !au_ftest_ren(a->auren_flags, DIRREN)
22912+ && a->btgt != au_dbdiropq(a->src_dentry)
22913+ && (a->dst_wh_dentry
22914+ || a->btgt <= au_dbdiropq(d)
22915+ /* hide the lower to keep xino */
22916+ /* the lowers may not be a dir, but we hide them anyway */
22917+ || a->btgt < au_dbbot(d)
22918+ || always)) {
22919+ AuDbg("here\n");
22920+ err = au_ren_do_diropq(a, AuSRC);
22921+ if (unlikely(err))
22922+ goto out;
22923+ au_fset_ren(a->auren_flags, DIROPQ_SRC);
22924+ }
22925+ if (!a->exchange)
22926+ goto out; /* success */
22927+
22928+ d = a->src_dentry; /* already renamed on the branch */
22929+ if (au_ftest_ren(a->auren_flags, ISDIR_DST)
22930+ && a->btgt != au_dbdiropq(a->dst_dentry)
22931+ && (a->btgt < au_dbdiropq(d)
22932+ || a->btgt < au_dbbot(d)
22933+ || always)) {
22934+ AuDbgDentry(a->src_dentry);
22935+ AuDbgDentry(a->dst_dentry);
22936+ err = au_ren_do_diropq(a, AuDST);
22937+ if (unlikely(err))
22938+ goto out_rev_src;
22939+ au_fset_ren(a->auren_flags, DIROPQ_DST);
22940+ }
22941+ goto out; /* success */
22942+
22943+out_rev_src:
22944+ AuDbg("err %d, reverting src\n", err);
22945+ au_ren_rev_diropq(err, a);
22946+out:
22947+ return err;
22948+}
22949+
22950+static int do_rename(struct au_ren_args *a)
22951+{
22952+ int err;
22953+ struct dentry *d, *h_d;
22954+
22955+ if (!a->exchange) {
22956+ /* prepare workqueue args for asynchronous rmdir */
22957+ h_d = a->dst_h_dentry;
22958+ if (au_ftest_ren(a->auren_flags, ISDIR_DST)
22959+ /* && !au_ftest_ren(a->auren_flags, DIRREN) */
22960+ && d_is_positive(h_d)) {
22961+ err = -ENOMEM;
22962+ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb,
22963+ GFP_NOFS);
22964+ if (unlikely(!a->thargs))
22965+ goto out;
22966+ a->h_dst = dget(h_d);
22967+ }
22968+
22969+ /* create whiteout for src_dentry */
22970+ if (au_ftest_ren(a->auren_flags, WHSRC)) {
22971+ a->src_bwh = au_dbwh(a->src_dentry);
22972+ AuDebugOn(a->src_bwh >= 0);
22973+ a->src_wh_dentry = au_wh_create(a->src_dentry, a->btgt,
22974+ a->src_h_parent);
22975+ err = PTR_ERR(a->src_wh_dentry);
22976+ if (IS_ERR(a->src_wh_dentry))
22977+ goto out_thargs;
22978+ }
22979+
22980+ /* lookup whiteout for dentry */
22981+ if (au_ftest_ren(a->auren_flags, WHDST)) {
22982+ h_d = au_wh_lkup(a->dst_h_parent,
22983+ &a->dst_dentry->d_name, a->br);
22984+ err = PTR_ERR(h_d);
22985+ if (IS_ERR(h_d))
22986+ goto out_whsrc;
22987+ if (d_is_negative(h_d))
22988+ dput(h_d);
22989+ else
22990+ a->dst_wh_dentry = h_d;
22991+ }
22992+
22993+ /* rename dentry to tmpwh */
22994+ if (a->thargs) {
22995+ err = au_whtmp_ren(a->dst_h_dentry, a->br);
22996+ if (unlikely(err))
22997+ goto out_whdst;
22998+
22999+ d = a->dst_dentry;
23000+ au_set_h_dptr(d, a->btgt, NULL);
23001+ err = au_lkup_neg(d, a->btgt, /*wh*/0);
23002+ if (unlikely(err))
23003+ goto out_whtmp;
23004+ a->dst_h_dentry = au_h_dptr(d, a->btgt);
23005+ }
23006+ }
23007+
23008+ BUG_ON(d_is_positive(a->dst_h_dentry) && a->src_btop != a->btgt);
23009+#if 0 /* debugging */
23010+ BUG_ON(!au_ftest_ren(a->auren_flags, DIRREN)
23011+ && d_is_positive(a->dst_h_dentry)
23012+ && a->src_btop != a->btgt);
23013+#endif
23014+
23015+ /* rename by vfs_rename or cpup */
23016+ err = au_ren_or_cpup(a);
23017+ if (unlikely(err))
23018+ /* leave the copied-up one */
23019+ goto out_whtmp;
23020+
23021+ /* make dir opaque */
23022+ err = au_ren_diropq(a);
23023+ if (unlikely(err))
23024+ goto out_rename;
23025+
23026+ /* update target timestamps */
23027+ if (a->exchange) {
23028+ AuDebugOn(au_dbtop(a->dst_dentry) != a->btgt);
23029+ a->h_path.dentry = au_h_dptr(a->dst_dentry, a->btgt);
23030+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
23031+ a->dst_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
23032+ }
23033+ AuDebugOn(au_dbtop(a->src_dentry) != a->btgt);
23034+ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
23035+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
23036+ a->src_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
23037+
23038+ if (!a->exchange) {
23039+ /* remove whiteout for dentry */
23040+ if (a->dst_wh_dentry) {
23041+ a->h_path.dentry = a->dst_wh_dentry;
23042+ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
23043+ a->dst_dentry);
23044+ if (unlikely(err))
23045+ goto out_diropq;
23046+ }
23047+
23048+ /* remove whtmp */
23049+ if (a->thargs)
23050+ au_ren_del_whtmp(a); /* ignore this error */
23051+
23052+ au_fhsm_wrote(a->src_dentry->d_sb, a->btgt, /*force*/0);
23053+ }
23054+ err = 0;
23055+ goto out_success;
23056+
23057+out_diropq:
23058+ au_ren_rev_diropq(err, a);
23059+out_rename:
23060+ au_ren_rev_rename(err, a);
23061+ dput(a->h_dst);
23062+out_whtmp:
23063+ if (a->thargs)
23064+ au_ren_rev_whtmp(err, a);
23065+out_whdst:
23066+ dput(a->dst_wh_dentry);
23067+ a->dst_wh_dentry = NULL;
23068+out_whsrc:
23069+ if (a->src_wh_dentry)
23070+ au_ren_rev_whsrc(err, a);
23071+out_success:
23072+ dput(a->src_wh_dentry);
23073+ dput(a->dst_wh_dentry);
23074+out_thargs:
23075+ if (a->thargs) {
23076+ dput(a->h_dst);
23077+ au_whtmp_rmdir_free(a->thargs);
23078+ a->thargs = NULL;
23079+ }
23080+out:
23081+ return err;
23082+}
23083+
23084+/* ---------------------------------------------------------------------- */
23085+
23086+/*
23087+ * test if @dentry dir can be rename destination or not.
23088+ * success means, it is a logically empty dir.
23089+ */
23090+static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
23091+{
23092+ return au_test_empty(dentry, whlist);
23093+}
23094+
23095+/*
23096+ * test if @a->src_dentry dir can be rename source or not.
23097+ * if it can, return 0.
23098+ * success means,
23099+ * - it is a logically empty dir.
23100+ * - or, it exists on writable branch and has no children including whiteouts
23101+ * on the lower branch unless DIRREN is on.
23102+ */
23103+static int may_rename_srcdir(struct au_ren_args *a)
23104+{
23105+ int err;
23106+ unsigned int rdhash;
23107+ aufs_bindex_t btop, btgt;
23108+ struct dentry *dentry;
23109+ struct super_block *sb;
23110+ struct au_sbinfo *sbinfo;
23111+
23112+ dentry = a->src_dentry;
23113+ sb = dentry->d_sb;
23114+ sbinfo = au_sbi(sb);
23115+ if (au_opt_test(sbinfo->si_mntflags, DIRREN))
23116+ au_fset_ren(a->auren_flags, DIRREN);
23117+
23118+ btgt = a->btgt;
23119+ btop = au_dbtop(dentry);
23120+ if (btop != btgt) {
23121+ struct au_nhash whlist;
23122+
23123+ SiMustAnyLock(sb);
23124+ rdhash = sbinfo->si_rdhash;
23125+ if (!rdhash)
23126+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL,
23127+ dentry));
23128+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
23129+ if (unlikely(err))
23130+ goto out;
23131+ err = au_test_empty(dentry, &whlist);
23132+ au_nhash_wh_free(&whlist);
23133+ goto out;
23134+ }
23135+
23136+ if (btop == au_dbtaildir(dentry))
23137+ return 0; /* success */
23138+
23139+ err = au_test_empty_lower(dentry);
23140+
23141+out:
23142+ if (err == -ENOTEMPTY) {
23143+ if (au_ftest_ren(a->auren_flags, DIRREN)) {
23144+ err = 0;
23145+ } else {
23146+ AuWarn1("renaming dir who has child(ren) on multiple "
23147+ "branches, is not supported\n");
23148+ err = -EXDEV;
23149+ }
23150+ }
23151+ return err;
23152+}
23153+
23154+/* side effect: sets whlist and h_dentry */
23155+static int au_ren_may_dir(struct au_ren_args *a)
23156+{
23157+ int err;
23158+ unsigned int rdhash;
23159+ struct dentry *d;
23160+
23161+ d = a->dst_dentry;
23162+ SiMustAnyLock(d->d_sb);
23163+
23164+ err = 0;
23165+ if (au_ftest_ren(a->auren_flags, ISDIR_DST) && a->dst_inode) {
23166+ rdhash = au_sbi(d->d_sb)->si_rdhash;
23167+ if (!rdhash)
23168+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d));
23169+ err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS);
23170+ if (unlikely(err))
23171+ goto out;
23172+
23173+ if (!a->exchange) {
23174+ au_set_dbtop(d, a->dst_btop);
23175+ err = may_rename_dstdir(d, &a->whlist);
23176+ au_set_dbtop(d, a->btgt);
23177+ } else
23178+ err = may_rename_srcdir(a);
23179+ }
23180+ a->dst_h_dentry = au_h_dptr(d, au_dbtop(d));
23181+ if (unlikely(err))
23182+ goto out;
23183+
23184+ d = a->src_dentry;
23185+ a->src_h_dentry = au_h_dptr(d, au_dbtop(d));
23186+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)) {
23187+ err = may_rename_srcdir(a);
23188+ if (unlikely(err)) {
23189+ au_nhash_wh_free(&a->whlist);
23190+ a->whlist.nh_num = 0;
23191+ }
23192+ }
23193+out:
23194+ return err;
23195+}
23196+
23197+/* ---------------------------------------------------------------------- */
23198+
23199+/*
23200+ * simple tests for rename.
23201+ * following the checks in vfs, plus the parent-child relationship.
23202+ */
23203+static int au_may_ren(struct au_ren_args *a)
23204+{
23205+ int err, isdir;
23206+ struct inode *h_inode;
23207+
23208+ if (a->src_btop == a->btgt) {
23209+ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
23210+ au_ftest_ren(a->auren_flags, ISDIR_SRC));
23211+ if (unlikely(err))
23212+ goto out;
23213+ err = -EINVAL;
23214+ if (unlikely(a->src_h_dentry == a->h_trap))
23215+ goto out;
23216+ }
23217+
23218+ err = 0;
23219+ if (a->dst_btop != a->btgt)
23220+ goto out;
23221+
23222+ err = -ENOTEMPTY;
23223+ if (unlikely(a->dst_h_dentry == a->h_trap))
23224+ goto out;
23225+
23226+ err = -EIO;
23227+ isdir = !!au_ftest_ren(a->auren_flags, ISDIR_DST);
23228+ if (d_really_is_negative(a->dst_dentry)) {
23229+ if (d_is_negative(a->dst_h_dentry))
23230+ err = au_may_add(a->dst_dentry, a->btgt,
23231+ a->dst_h_parent, isdir);
23232+ } else {
23233+ if (unlikely(d_is_negative(a->dst_h_dentry)))
23234+ goto out;
23235+ h_inode = d_inode(a->dst_h_dentry);
23236+ if (h_inode->i_nlink)
23237+ err = au_may_del(a->dst_dentry, a->btgt,
23238+ a->dst_h_parent, isdir);
23239+ }
23240+
23241+out:
23242+ if (unlikely(err == -ENOENT || err == -EEXIST))
23243+ err = -EIO;
23244+ AuTraceErr(err);
23245+ return err;
23246+}
23247+
23248+/* ---------------------------------------------------------------------- */
23249+
23250+/*
23251+ * locking order
23252+ * (VFS)
23253+ * - src_dir and dir by lock_rename()
23254+ * - inode if exists
23255+ * (aufs)
23256+ * - lock all
23257+ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
23258+ * + si_read_lock
23259+ * + di_write_lock2_child()
23260+ * + di_write_lock_child()
23261+ * + ii_write_lock_child()
23262+ * + di_write_lock_child2()
23263+ * + ii_write_lock_child2()
23264+ * + src_parent and parent
23265+ * + di_write_lock_parent()
23266+ * + ii_write_lock_parent()
23267+ * + di_write_lock_parent2()
23268+ * + ii_write_lock_parent2()
23269+ * + lower src_dir and dir by vfsub_lock_rename()
23270+ * + verify the every relationships between child and parent. if any
23271+ * of them failed, unlock all and return -EBUSY.
23272+ */
23273+static void au_ren_unlock(struct au_ren_args *a)
23274+{
23275+ vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
23276+ a->dst_h_parent, a->dst_hdir);
23277+ if (au_ftest_ren(a->auren_flags, DIRREN)
23278+ && a->h_root)
23279+ au_hn_inode_unlock(a->h_root);
23280+ if (au_ftest_ren(a->auren_flags, MNT_WRITE))
23281+ vfsub_mnt_drop_write(au_br_mnt(a->br));
23282+}
23283+
23284+static int au_ren_lock(struct au_ren_args *a)
23285+{
23286+ int err;
23287+ unsigned int udba;
23288+
23289+ err = 0;
23290+ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
23291+ a->src_hdir = au_hi(a->src_dir, a->btgt);
23292+ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
23293+ a->dst_hdir = au_hi(a->dst_dir, a->btgt);
23294+
23295+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
23296+ if (unlikely(err))
23297+ goto out;
23298+ au_fset_ren(a->auren_flags, MNT_WRITE);
23299+ if (au_ftest_ren(a->auren_flags, DIRREN)) {
23300+ struct dentry *root;
23301+ struct inode *dir;
23302+
23303+ /*
23304+ * sbinfo is already locked, so this ii_read_lock is
23305+ * unnecessary. but our debugging feature checks it.
23306+ */
23307+ root = a->src_inode->i_sb->s_root;
23308+ if (root != a->src_parent && root != a->dst_parent) {
23309+ dir = d_inode(root);
23310+ ii_read_lock_parent3(dir);
23311+ a->h_root = au_hi(dir, a->btgt);
23312+ ii_read_unlock(dir);
23313+ au_hn_inode_lock_nested(a->h_root, AuLsc_I_PARENT3);
23314+ }
23315+ }
23316+ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
23317+ a->dst_h_parent, a->dst_hdir);
23318+ udba = au_opt_udba(a->src_dentry->d_sb);
23319+ if (unlikely(a->src_hdir->hi_inode != d_inode(a->src_h_parent)
23320+ || a->dst_hdir->hi_inode != d_inode(a->dst_h_parent)))
23321+ err = au_busy_or_stale();
23322+ if (!err && au_dbtop(a->src_dentry) == a->btgt)
23323+ err = au_h_verify(a->src_h_dentry, udba,
23324+ d_inode(a->src_h_parent), a->src_h_parent,
23325+ a->br);
23326+ if (!err && au_dbtop(a->dst_dentry) == a->btgt)
23327+ err = au_h_verify(a->dst_h_dentry, udba,
23328+ d_inode(a->dst_h_parent), a->dst_h_parent,
23329+ a->br);
23330+ if (!err)
23331+ goto out; /* success */
23332+
23333+ err = au_busy_or_stale();
23334+ au_ren_unlock(a);
23335+
23336+out:
23337+ return err;
23338+}
23339+
23340+/* ---------------------------------------------------------------------- */
23341+
23342+static void au_ren_refresh_dir(struct au_ren_args *a)
23343+{
23344+ struct inode *dir;
23345+
23346+ dir = a->dst_dir;
23347+ inode_inc_iversion(dir);
23348+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)) {
23349+ /* is this updating defined in POSIX? */
23350+ au_cpup_attr_timesizes(a->src_inode);
23351+ au_cpup_attr_nlink(dir, /*force*/1);
23352+ }
23353+ au_dir_ts(dir, a->btgt);
23354+
23355+ if (a->exchange) {
23356+ dir = a->src_dir;
23357+ inode_inc_iversion(dir);
23358+ if (au_ftest_ren(a->auren_flags, ISDIR_DST)) {
23359+ /* is this updating defined in POSIX? */
23360+ au_cpup_attr_timesizes(a->dst_inode);
23361+ au_cpup_attr_nlink(dir, /*force*/1);
23362+ }
23363+ au_dir_ts(dir, a->btgt);
23364+ }
23365+
23366+ if (au_ftest_ren(a->auren_flags, ISSAMEDIR))
23367+ return;
23368+
23369+ dir = a->src_dir;
23370+ inode_inc_iversion(dir);
23371+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC))
23372+ au_cpup_attr_nlink(dir, /*force*/1);
23373+ au_dir_ts(dir, a->btgt);
23374+}
23375+
23376+static void au_ren_refresh(struct au_ren_args *a)
23377+{
23378+ aufs_bindex_t bbot, bindex;
23379+ struct dentry *d, *h_d;
23380+ struct inode *i, *h_i;
23381+ struct super_block *sb;
23382+
23383+ d = a->dst_dentry;
23384+ d_drop(d);
23385+ if (a->h_dst)
23386+ /* already dget-ed by au_ren_or_cpup() */
23387+ au_set_h_dptr(d, a->btgt, a->h_dst);
23388+
23389+ i = a->dst_inode;
23390+ if (i) {
23391+ if (!a->exchange) {
23392+ if (!au_ftest_ren(a->auren_flags, ISDIR_DST))
23393+ vfsub_drop_nlink(i);
23394+ else {
23395+ vfsub_dead_dir(i);
23396+ au_cpup_attr_timesizes(i);
23397+ }
23398+ au_update_dbrange(d, /*do_put_zero*/1);
23399+ } else
23400+ au_cpup_attr_nlink(i, /*force*/1);
23401+ } else {
23402+ bbot = a->btgt;
23403+ for (bindex = au_dbtop(d); bindex < bbot; bindex++)
23404+ au_set_h_dptr(d, bindex, NULL);
23405+ bbot = au_dbbot(d);
23406+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++)
23407+ au_set_h_dptr(d, bindex, NULL);
23408+ au_update_dbrange(d, /*do_put_zero*/0);
23409+ }
23410+
23411+ if (a->exchange
23412+ || au_ftest_ren(a->auren_flags, DIRREN)) {
23413+ d_drop(a->src_dentry);
23414+ if (au_ftest_ren(a->auren_flags, DIRREN))
23415+ au_set_dbwh(a->src_dentry, -1);
23416+ return;
23417+ }
23418+
23419+ d = a->src_dentry;
23420+ au_set_dbwh(d, -1);
23421+ bbot = au_dbbot(d);
23422+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++) {
23423+ h_d = au_h_dptr(d, bindex);
23424+ if (h_d)
23425+ au_set_h_dptr(d, bindex, NULL);
23426+ }
23427+ au_set_dbbot(d, a->btgt);
23428+
23429+ sb = d->d_sb;
23430+ i = a->src_inode;
23431+ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
23432+ return; /* success */
23433+
23434+ bbot = au_ibbot(i);
23435+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++) {
23436+ h_i = au_h_iptr(i, bindex);
23437+ if (h_i) {
23438+ au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
23439+ /* ignore this error */
23440+ au_set_h_iptr(i, bindex, NULL, 0);
23441+ }
23442+ }
23443+ au_set_ibbot(i, a->btgt);
23444+}
23445+
23446+/* ---------------------------------------------------------------------- */
23447+
23448+/* mainly for link(2) and rename(2) */
23449+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
23450+{
23451+ aufs_bindex_t bdiropq, bwh;
23452+ struct dentry *parent;
23453+ struct au_branch *br;
23454+
23455+ parent = dentry->d_parent;
23456+ IMustLock(d_inode(parent)); /* dir is locked */
23457+
23458+ bdiropq = au_dbdiropq(parent);
23459+ bwh = au_dbwh(dentry);
23460+ br = au_sbr(dentry->d_sb, btgt);
23461+ if (au_br_rdonly(br)
23462+ || (0 <= bdiropq && bdiropq < btgt)
23463+ || (0 <= bwh && bwh < btgt))
23464+ btgt = -1;
23465+
23466+ AuDbg("btgt %d\n", btgt);
23467+ return btgt;
23468+}
23469+
23470+/* sets src_btop, dst_btop and btgt */
23471+static int au_ren_wbr(struct au_ren_args *a)
23472+{
23473+ int err;
23474+ struct au_wr_dir_args wr_dir_args = {
23475+ /* .force_btgt = -1, */
23476+ .flags = AuWrDir_ADD_ENTRY
23477+ };
23478+
23479+ a->src_btop = au_dbtop(a->src_dentry);
23480+ a->dst_btop = au_dbtop(a->dst_dentry);
23481+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)
23482+ || au_ftest_ren(a->auren_flags, ISDIR_DST))
23483+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
23484+ wr_dir_args.force_btgt = a->src_btop;
23485+ if (a->dst_inode && a->dst_btop < a->src_btop)
23486+ wr_dir_args.force_btgt = a->dst_btop;
23487+ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
23488+ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
23489+ a->btgt = err;
23490+ if (a->exchange)
23491+ au_update_dbtop(a->dst_dentry);
23492+
23493+ return err;
23494+}
23495+
23496+static void au_ren_dt(struct au_ren_args *a)
23497+{
23498+ a->h_path.dentry = a->src_h_parent;
23499+ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
23500+ if (!au_ftest_ren(a->auren_flags, ISSAMEDIR)) {
23501+ a->h_path.dentry = a->dst_h_parent;
23502+ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
23503+ }
23504+
23505+ au_fclr_ren(a->auren_flags, DT_DSTDIR);
23506+ if (!au_ftest_ren(a->auren_flags, ISDIR_SRC)
23507+ && !a->exchange)
23508+ return;
23509+
23510+ a->h_path.dentry = a->src_h_dentry;
23511+ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
23512+ if (d_is_positive(a->dst_h_dentry)) {
23513+ au_fset_ren(a->auren_flags, DT_DSTDIR);
23514+ a->h_path.dentry = a->dst_h_dentry;
23515+ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
23516+ }
23517+}
23518+
23519+static void au_ren_rev_dt(int err, struct au_ren_args *a)
23520+{
23521+ struct dentry *h_d;
23522+ struct inode *h_inode;
23523+
23524+ au_dtime_revert(a->src_dt + AuPARENT);
23525+ if (!au_ftest_ren(a->auren_flags, ISSAMEDIR))
23526+ au_dtime_revert(a->dst_dt + AuPARENT);
23527+
23528+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC) && err != -EIO) {
23529+ h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
23530+ h_inode = d_inode(h_d);
23531+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
23532+ au_dtime_revert(a->src_dt + AuCHILD);
23533+ inode_unlock(h_inode);
23534+
23535+ if (au_ftest_ren(a->auren_flags, DT_DSTDIR)) {
23536+ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
23537+ h_inode = d_inode(h_d);
23538+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
23539+ au_dtime_revert(a->dst_dt + AuCHILD);
23540+ inode_unlock(h_inode);
23541+ }
23542+ }
23543+}
23544+
23545+/* ---------------------------------------------------------------------- */
23546+
23547+int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
23548+ struct inode *_dst_dir, struct dentry *_dst_dentry,
23549+ unsigned int _flags)
23550+{
23551+ int err, lock_flags;
23552+ void *rev;
23553+ /* reduce stack space */
23554+ struct au_ren_args *a;
23555+ struct au_pin pin;
23556+
23557+ AuDbg("%pd, %pd, 0x%x\n", _src_dentry, _dst_dentry, _flags);
23558+ IMustLock(_src_dir);
23559+ IMustLock(_dst_dir);
23560+
23561+ err = -EINVAL;
23562+ if (unlikely(_flags & RENAME_WHITEOUT))
23563+ goto out;
23564+
23565+ err = -ENOMEM;
23566+ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
23567+ a = kzalloc(sizeof(*a), GFP_NOFS);
23568+ if (unlikely(!a))
23569+ goto out;
23570+
23571+ a->flags = _flags;
23572+ BUILD_BUG_ON(sizeof(a->exchange) == sizeof(u8)
23573+ && RENAME_EXCHANGE > U8_MAX);
23574+ a->exchange = _flags & RENAME_EXCHANGE;
23575+ a->src_dir = _src_dir;
23576+ a->src_dentry = _src_dentry;
23577+ a->src_inode = NULL;
23578+ if (d_really_is_positive(a->src_dentry))
23579+ a->src_inode = d_inode(a->src_dentry);
23580+ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
23581+ a->dst_dir = _dst_dir;
23582+ a->dst_dentry = _dst_dentry;
23583+ a->dst_inode = NULL;
23584+ if (d_really_is_positive(a->dst_dentry))
23585+ a->dst_inode = d_inode(a->dst_dentry);
23586+ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
23587+ if (a->dst_inode) {
23588+ /*
23589+ * if EXCHANGE && src is non-dir && dst is dir,
23590+ * dst is not locked.
23591+ */
23592+ /* IMustLock(a->dst_inode); */
23593+ au_igrab(a->dst_inode);
23594+ }
23595+
23596+ err = -ENOTDIR;
23597+ lock_flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
23598+ if (d_is_dir(a->src_dentry)) {
23599+ au_fset_ren(a->auren_flags, ISDIR_SRC);
23600+ if (unlikely(!a->exchange
23601+ && d_really_is_positive(a->dst_dentry)
23602+ && !d_is_dir(a->dst_dentry)))
23603+ goto out_free;
23604+ lock_flags |= AuLock_DIRS;
23605+ }
23606+ if (a->dst_inode && d_is_dir(a->dst_dentry)) {
23607+ au_fset_ren(a->auren_flags, ISDIR_DST);
23608+ if (unlikely(!a->exchange
23609+ && d_really_is_positive(a->src_dentry)
23610+ && !d_is_dir(a->src_dentry)))
23611+ goto out_free;
23612+ lock_flags |= AuLock_DIRS;
23613+ }
23614+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
23615+ lock_flags);
23616+ if (unlikely(err))
23617+ goto out_free;
23618+
23619+ err = au_d_hashed_positive(a->src_dentry);
23620+ if (unlikely(err))
23621+ goto out_unlock;
23622+ err = -ENOENT;
23623+ if (a->dst_inode) {
23624+ /*
23625+ * If it is a dir, VFS unhash it before this
23626+ * function. It means we cannot rely upon d_unhashed().
23627+ */
23628+ if (unlikely(!a->dst_inode->i_nlink))
23629+ goto out_unlock;
23630+ if (!au_ftest_ren(a->auren_flags, ISDIR_DST)) {
23631+ err = au_d_hashed_positive(a->dst_dentry);
23632+ if (unlikely(err && !a->exchange))
23633+ goto out_unlock;
23634+ } else if (unlikely(IS_DEADDIR(a->dst_inode)))
23635+ goto out_unlock;
23636+ } else if (unlikely(d_unhashed(a->dst_dentry)))
23637+ goto out_unlock;
23638+
23639+ /*
23640+ * is it possible?
23641+ * yes, it happened (in linux-3.3-rcN) but I don't know why.
23642+ * there may exist a problem somewhere else.
23643+ */
23644+ err = -EINVAL;
23645+ if (unlikely(d_inode(a->dst_parent) == d_inode(a->src_dentry)))
23646+ goto out_unlock;
23647+
23648+ au_fset_ren(a->auren_flags, ISSAMEDIR); /* temporary */
23649+ di_write_lock_parent(a->dst_parent);
23650+
23651+ /* which branch we process */
23652+ err = au_ren_wbr(a);
23653+ if (unlikely(err < 0))
23654+ goto out_parent;
23655+ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
23656+ a->h_path.mnt = au_br_mnt(a->br);
23657+
23658+ /* are they available to be renamed */
23659+ err = au_ren_may_dir(a);
23660+ if (unlikely(err))
23661+ goto out_children;
23662+
23663+ /* prepare the writable parent dir on the same branch */
23664+ if (a->dst_btop == a->btgt) {
23665+ au_fset_ren(a->auren_flags, WHDST);
23666+ } else {
23667+ err = au_cpup_dirs(a->dst_dentry, a->btgt);
23668+ if (unlikely(err))
23669+ goto out_children;
23670+ }
23671+
23672+ err = 0;
23673+ if (!a->exchange) {
23674+ if (a->src_dir != a->dst_dir) {
23675+ /*
23676+ * this temporary unlock is safe,
23677+ * because both dir->i_mutex are locked.
23678+ */
23679+ di_write_unlock(a->dst_parent);
23680+ di_write_lock_parent(a->src_parent);
23681+ err = au_wr_dir_need_wh(a->src_dentry,
23682+ au_ftest_ren(a->auren_flags,
23683+ ISDIR_SRC),
23684+ &a->btgt);
23685+ di_write_unlock(a->src_parent);
23686+ di_write_lock2_parent(a->src_parent, a->dst_parent,
23687+ /*isdir*/1);
23688+ au_fclr_ren(a->auren_flags, ISSAMEDIR);
23689+ } else
23690+ err = au_wr_dir_need_wh(a->src_dentry,
23691+ au_ftest_ren(a->auren_flags,
23692+ ISDIR_SRC),
23693+ &a->btgt);
23694+ }
23695+ if (unlikely(err < 0))
23696+ goto out_children;
23697+ if (err)
23698+ au_fset_ren(a->auren_flags, WHSRC);
23699+
23700+ /* cpup src */
23701+ if (a->src_btop != a->btgt) {
23702+ err = au_pin(&pin, a->src_dentry, a->btgt,
23703+ au_opt_udba(a->src_dentry->d_sb),
23704+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
23705+ if (!err) {
23706+ struct au_cp_generic cpg = {
23707+ .dentry = a->src_dentry,
23708+ .bdst = a->btgt,
23709+ .bsrc = a->src_btop,
23710+ .len = -1,
23711+ .pin = &pin,
23712+ .flags = AuCpup_DTIME | AuCpup_HOPEN
23713+ };
23714+ AuDebugOn(au_dbtop(a->src_dentry) != a->src_btop);
23715+ err = au_sio_cpup_simple(&cpg);
23716+ au_unpin(&pin);
23717+ }
23718+ if (unlikely(err))
23719+ goto out_children;
23720+ a->src_btop = a->btgt;
23721+ a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt);
23722+ if (!a->exchange)
23723+ au_fset_ren(a->auren_flags, WHSRC);
23724+ }
23725+
23726+ /* cpup dst */
23727+ if (a->exchange && a->dst_inode
23728+ && a->dst_btop != a->btgt) {
23729+ err = au_pin(&pin, a->dst_dentry, a->btgt,
23730+ au_opt_udba(a->dst_dentry->d_sb),
23731+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
23732+ if (!err) {
23733+ struct au_cp_generic cpg = {
23734+ .dentry = a->dst_dentry,
23735+ .bdst = a->btgt,
23736+ .bsrc = a->dst_btop,
23737+ .len = -1,
23738+ .pin = &pin,
23739+ .flags = AuCpup_DTIME | AuCpup_HOPEN
23740+ };
23741+ err = au_sio_cpup_simple(&cpg);
23742+ au_unpin(&pin);
23743+ }
23744+ if (unlikely(err))
23745+ goto out_children;
23746+ a->dst_btop = a->btgt;
23747+ a->dst_h_dentry = au_h_dptr(a->dst_dentry, a->btgt);
23748+ }
23749+
23750+ /* lock them all */
23751+ err = au_ren_lock(a);
23752+ if (unlikely(err))
23753+ /* leave the copied-up one */
23754+ goto out_children;
23755+
23756+ if (!a->exchange) {
23757+ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE))
23758+ err = au_may_ren(a);
23759+ else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN))
23760+ err = -ENAMETOOLONG;
23761+ if (unlikely(err))
23762+ goto out_hdir;
23763+ }
23764+
23765+ /* store timestamps to be revertible */
23766+ au_ren_dt(a);
23767+
23768+ /* store dirren info */
23769+ if (au_ftest_ren(a->auren_flags, DIRREN)) {
23770+ err = au_dr_rename(a->src_dentry, a->btgt,
23771+ &a->dst_dentry->d_name, &rev);
23772+ AuTraceErr(err);
23773+ if (unlikely(err))
23774+ goto out_dt;
23775+ }
23776+
23777+ /* here we go */
23778+ err = do_rename(a);
23779+ if (unlikely(err))
23780+ goto out_dirren;
23781+
23782+ if (au_ftest_ren(a->auren_flags, DIRREN))
23783+ au_dr_rename_fin(a->src_dentry, a->btgt, rev);
23784+
23785+ /* update dir attributes */
23786+ au_ren_refresh_dir(a);
23787+
23788+ /* dput/iput all lower dentries */
23789+ au_ren_refresh(a);
23790+
23791+ goto out_hdir; /* success */
23792+
23793+out_dirren:
23794+ if (au_ftest_ren(a->auren_flags, DIRREN))
23795+ au_dr_rename_rev(a->src_dentry, a->btgt, rev);
23796+out_dt:
23797+ au_ren_rev_dt(err, a);
23798+out_hdir:
23799+ au_ren_unlock(a);
23800+out_children:
23801+ au_nhash_wh_free(&a->whlist);
23802+ if (err && a->dst_inode && a->dst_btop != a->btgt) {
23803+ AuDbg("btop %d, btgt %d\n", a->dst_btop, a->btgt);
23804+ au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
23805+ au_set_dbtop(a->dst_dentry, a->dst_btop);
23806+ }
23807+out_parent:
23808+ if (!err) {
23809+ if (d_unhashed(a->src_dentry))
23810+ au_fset_ren(a->auren_flags, DROPPED_SRC);
23811+ if (d_unhashed(a->dst_dentry))
23812+ au_fset_ren(a->auren_flags, DROPPED_DST);
23813+ if (!a->exchange)
23814+ d_move(a->src_dentry, a->dst_dentry);
23815+ else {
23816+ d_exchange(a->src_dentry, a->dst_dentry);
23817+ if (au_ftest_ren(a->auren_flags, DROPPED_DST))
23818+ d_drop(a->dst_dentry);
23819+ }
23820+ if (au_ftest_ren(a->auren_flags, DROPPED_SRC))
23821+ d_drop(a->src_dentry);
23822+ } else {
23823+ au_update_dbtop(a->dst_dentry);
23824+ if (!a->dst_inode)
23825+ d_drop(a->dst_dentry);
23826+ }
23827+ if (au_ftest_ren(a->auren_flags, ISSAMEDIR))
23828+ di_write_unlock(a->dst_parent);
23829+ else
23830+ di_write_unlock2(a->src_parent, a->dst_parent);
23831+out_unlock:
23832+ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
23833+out_free:
23834+ iput(a->dst_inode);
23835+ if (a->thargs)
23836+ au_whtmp_rmdir_free(a->thargs);
23837+ au_kfree_rcu(a);
23838+out:
23839+ AuTraceErr(err);
23840+ return err;
23841+}
23842diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
23843--- /usr/share/empty/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100
23844+++ linux/fs/aufs/Kconfig 2019-07-11 15:42:14.458904362 +0200
23845@@ -0,0 +1,199 @@
23846+# SPDX-License-Identifier: GPL-2.0
23847+config AUFS_FS
23848+ tristate "Aufs (Advanced multi layered unification filesystem) support"
23849+ help
23850+ Aufs is a stackable unification filesystem such as Unionfs,
23851+ which unifies several directories and provides a merged single
23852+ directory.
23853+ In the early days, aufs was entirely re-designed and
23854+ re-implemented Unionfs Version 1.x series. Introducing many
23855+ original ideas, approaches and improvements, it becomes totally
23856+ different from Unionfs while keeping the basic features.
23857+
23858+if AUFS_FS
23859+choice
23860+ prompt "Maximum number of branches"
23861+ default AUFS_BRANCH_MAX_127
23862+ help
23863+ Specifies the maximum number of branches (or member directories)
23864+ in a single aufs. The larger value consumes more system
23865+ resources and has a minor impact to performance.
23866+config AUFS_BRANCH_MAX_127
23867+ bool "127"
23868+ help
23869+ Specifies the maximum number of branches (or member directories)
23870+ in a single aufs. The larger value consumes more system
23871+ resources and has a minor impact to performance.
23872+config AUFS_BRANCH_MAX_511
23873+ bool "511"
23874+ help
23875+ Specifies the maximum number of branches (or member directories)
23876+ in a single aufs. The larger value consumes more system
23877+ resources and has a minor impact to performance.
23878+config AUFS_BRANCH_MAX_1023
23879+ bool "1023"
23880+ help
23881+ Specifies the maximum number of branches (or member directories)
23882+ in a single aufs. The larger value consumes more system
23883+ resources and has a minor impact to performance.
23884+config AUFS_BRANCH_MAX_32767
23885+ bool "32767"
23886+ help
23887+ Specifies the maximum number of branches (or member directories)
23888+ in a single aufs. The larger value consumes more system
23889+ resources and has a minor impact to performance.
23890+endchoice
23891+
23892+config AUFS_SBILIST
23893+ bool
23894+ depends on AUFS_MAGIC_SYSRQ || PROC_FS
23895+ default y
23896+ help
23897+ Automatic configuration for internal use.
23898+ When aufs supports Magic SysRq or /proc, enabled automatically.
23899+
23900+config AUFS_HNOTIFY
23901+ bool "Detect direct branch access (bypassing aufs)"
23902+ help
23903+ If you want to modify files on branches directly, eg. bypassing aufs,
23904+ and want aufs to detect the changes of them fully, then enable this
23905+ option and use 'udba=notify' mount option.
23906+ Currently there is only one available configuration, "fsnotify".
23907+ It will have a negative impact to the performance.
23908+ See detail in aufs.5.
23909+
23910+choice
23911+ prompt "method" if AUFS_HNOTIFY
23912+ default AUFS_HFSNOTIFY
23913+config AUFS_HFSNOTIFY
23914+ bool "fsnotify"
23915+ select FSNOTIFY
23916+endchoice
23917+
23918+config AUFS_EXPORT
23919+ bool "NFS-exportable aufs"
23920+ depends on EXPORTFS
23921+ help
23922+ If you want to export your mounted aufs via NFS, then enable this
23923+ option. There are several requirements for this configuration.
23924+ See detail in aufs.5.
23925+
23926+config AUFS_INO_T_64
23927+ bool
23928+ depends on AUFS_EXPORT
23929+ depends on 64BIT && !(ALPHA || S390)
23930+ default y
23931+ help
23932+ Automatic configuration for internal use.
23933+ /* typedef unsigned long/int __kernel_ino_t */
23934+ /* alpha and s390x are int */
23935+
23936+config AUFS_XATTR
23937+ bool "support for XATTR/EA (including Security Labels)"
23938+ help
23939+ If your branch fs supports XATTR/EA and you want to make them
23940+ available in aufs too, then enable this opsion and specify the
23941+ branch attributes for EA.
23942+ See detail in aufs.5.
23943+
23944+config AUFS_FHSM
23945+ bool "File-based Hierarchical Storage Management"
23946+ help
23947+ Hierarchical Storage Management (or HSM) is a well-known feature
23948+ in the storage world. Aufs provides this feature as file-based.
23949+ with multiple branches.
23950+ These multiple branches are prioritized, ie. the topmost one
23951+ should be the fastest drive and be used heavily.
23952+
23953+config AUFS_RDU
23954+ bool "Readdir in userspace"
23955+ help
23956+ Aufs has two methods to provide a merged view for a directory,
23957+ by a user-space library and by kernel-space natively. The latter
23958+ is always enabled but sometimes large and slow.
23959+ If you enable this option, install the library in aufs2-util
23960+ package, and set some environment variables for your readdir(3),
23961+ then the work will be handled in user-space which generally
23962+ shows better performance in most cases.
23963+ See detail in aufs.5.
23964+
23965+config AUFS_DIRREN
23966+ bool "Workaround for rename(2)-ing a directory"
23967+ help
23968+ By default, aufs returns EXDEV error in renameing a dir who has
23969+ his child on the lower branch, since it is a bad idea to issue
23970+ rename(2) internally for every lower branch. But user may not
23971+ accept this behaviour. So here is a workaround to allow such
23972+ rename(2) and store some extra infromation on the writable
23973+ branch. Obviously this costs high (and I don't like it).
23974+ To use this feature, you need to enable this configuration AND
23975+ to specify the mount option `dirren.'
23976+ See details in aufs.5 and the design documents.
23977+
23978+config AUFS_SHWH
23979+ bool "Show whiteouts"
23980+ help
23981+ If you want to make the whiteouts in aufs visible, then enable
23982+ this option and specify 'shwh' mount option. Although it may
23983+ sounds like philosophy or something, but in technically it
23984+ simply shows the name of whiteout with keeping its behaviour.
23985+
23986+config AUFS_BR_RAMFS
23987+ bool "Ramfs (initramfs/rootfs) as an aufs branch"
23988+ help
23989+ If you want to use ramfs as an aufs branch fs, then enable this
23990+ option. Generally tmpfs is recommended.
23991+ Aufs prohibited them to be a branch fs by default, because
23992+ initramfs becomes unusable after switch_root or something
23993+ generally. If you sets initramfs as an aufs branch and boot your
23994+ system by switch_root, you will meet a problem easily since the
23995+ files in initramfs may be inaccessible.
23996+ Unless you are going to use ramfs as an aufs branch fs without
23997+ switch_root or something, leave it N.
23998+
23999+config AUFS_BR_FUSE
24000+ bool "Fuse fs as an aufs branch"
24001+ depends on FUSE_FS
24002+ select AUFS_POLL
24003+ help
24004+ If you want to use fuse-based userspace filesystem as an aufs
24005+ branch fs, then enable this option.
24006+ It implements the internal poll(2) operation which is
24007+ implemented by fuse only (curretnly).
24008+
24009+config AUFS_POLL
24010+ bool
24011+ help
24012+ Automatic configuration for internal use.
24013+
24014+config AUFS_BR_HFSPLUS
24015+ bool "Hfsplus as an aufs branch"
24016+ depends on HFSPLUS_FS
24017+ default y
24018+ help
24019+ If you want to use hfsplus fs as an aufs branch fs, then enable
24020+ this option. This option introduces a small overhead at
24021+ copying-up a file on hfsplus.
24022+
24023+config AUFS_BDEV_LOOP
24024+ bool
24025+ depends on BLK_DEV_LOOP
24026+ default y
24027+ help
24028+ Automatic configuration for internal use.
24029+ Convert =[ym] into =y.
24030+
24031+config AUFS_DEBUG
24032+ bool "Debug aufs"
24033+ help
24034+ Enable this to compile aufs internal debug code.
24035+ It will have a negative impact to the performance.
24036+
24037+config AUFS_MAGIC_SYSRQ
24038+ bool
24039+ depends on AUFS_DEBUG && MAGIC_SYSRQ
24040+ default y
24041+ help
24042+ Automatic configuration for internal use.
24043+ When aufs supports Magic SysRq, enabled automatically.
24044+endif
24045diff -urN /usr/share/empty/fs/aufs/lcnt.h linux/fs/aufs/lcnt.h
24046--- /usr/share/empty/fs/aufs/lcnt.h 1970-01-01 01:00:00.000000000 +0100
24047+++ linux/fs/aufs/lcnt.h 2020-01-27 10:57:18.175538316 +0100
24048@@ -0,0 +1,186 @@
24049+/* SPDX-License-Identifier: GPL-2.0 */
24050+/*
24051+ * Copyright (C) 2018-2020 Junjiro R. Okajima
24052+ *
24053+ * This program, aufs is free software; you can redistribute it and/or modify
24054+ * it under the terms of the GNU General Public License as published by
24055+ * the Free Software Foundation; either version 2 of the License, or
24056+ * (at your option) any later version.
24057+ *
24058+ * This program is distributed in the hope that it will be useful,
24059+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24060+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24061+ * GNU General Public License for more details.
24062+ *
24063+ * You should have received a copy of the GNU General Public License
24064+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
24065+ */
24066+
24067+/*
24068+ * simple long counter wrapper
24069+ */
24070+
24071+#ifndef __AUFS_LCNT_H__
24072+#define __AUFS_LCNT_H__
24073+
24074+#ifdef __KERNEL__
24075+
24076+#include "debug.h"
24077+
24078+#define AuLCntATOMIC 1
24079+#define AuLCntPCPUCNT 2
24080+/*
24081+ * why does percpu_refcount require extra synchronize_rcu()s in
24082+ * au_br_do_free()
24083+ */
24084+#define AuLCntPCPUREF 3
24085+
24086+/* #define AuLCntChosen AuLCntATOMIC */
24087+#define AuLCntChosen AuLCntPCPUCNT
24088+/* #define AuLCntChosen AuLCntPCPUREF */
24089+
24090+#if AuLCntChosen == AuLCntATOMIC
24091+#include <linux/atomic.h>
24092+
24093+typedef atomic_long_t au_lcnt_t;
24094+
24095+static inline int au_lcnt_init(au_lcnt_t *cnt, void *release __maybe_unused)
24096+{
24097+ atomic_long_set(cnt, 0);
24098+ return 0;
24099+}
24100+
24101+static inline void au_lcnt_wait_for_fin(au_lcnt_t *cnt __maybe_unused)
24102+{
24103+ /* empty */
24104+}
24105+
24106+static inline void au_lcnt_fin(au_lcnt_t *cnt __maybe_unused,
24107+ int do_sync __maybe_unused)
24108+{
24109+ /* empty */
24110+}
24111+
24112+static inline void au_lcnt_inc(au_lcnt_t *cnt)
24113+{
24114+ atomic_long_inc(cnt);
24115+}
24116+
24117+static inline void au_lcnt_dec(au_lcnt_t *cnt)
24118+{
24119+ atomic_long_dec(cnt);
24120+}
24121+
24122+static inline long au_lcnt_read(au_lcnt_t *cnt, int do_rev __maybe_unused)
24123+{
24124+ return atomic_long_read(cnt);
24125+}
24126+#endif
24127+
24128+#if AuLCntChosen == AuLCntPCPUCNT
24129+#include <linux/percpu_counter.h>
24130+
24131+typedef struct percpu_counter au_lcnt_t;
24132+
24133+static inline int au_lcnt_init(au_lcnt_t *cnt, void *release __maybe_unused)
24134+{
24135+ return percpu_counter_init(cnt, 0, GFP_NOFS);
24136+}
24137+
24138+static inline void au_lcnt_wait_for_fin(au_lcnt_t *cnt __maybe_unused)
24139+{
24140+ /* empty */
24141+}
24142+
24143+static inline void au_lcnt_fin(au_lcnt_t *cnt, int do_sync __maybe_unused)
24144+{
24145+ percpu_counter_destroy(cnt);
24146+}
24147+
24148+static inline void au_lcnt_inc(au_lcnt_t *cnt)
24149+{
24150+ percpu_counter_inc(cnt);
24151+}
24152+
24153+static inline void au_lcnt_dec(au_lcnt_t *cnt)
24154+{
24155+ percpu_counter_dec(cnt);
24156+}
24157+
24158+static inline long au_lcnt_read(au_lcnt_t *cnt, int do_rev __maybe_unused)
24159+{
24160+ s64 n;
24161+
24162+ n = percpu_counter_sum(cnt);
24163+ BUG_ON(n < 0);
24164+ if (LONG_MAX != LLONG_MAX
24165+ && n > LONG_MAX)
24166+ AuWarn1("%s\n", "wrap-around");
24167+
24168+ return n;
24169+}
24170+#endif
24171+
24172+#if AuLCntChosen == AuLCntPCPUREF
24173+#include <linux/percpu-refcount.h>
24174+
24175+typedef struct percpu_ref au_lcnt_t;
24176+
24177+static inline int au_lcnt_init(au_lcnt_t *cnt, percpu_ref_func_t *release)
24178+{
24179+ if (!release)
24180+ release = percpu_ref_exit;
24181+ return percpu_ref_init(cnt, release, /*percpu mode*/0, GFP_NOFS);
24182+}
24183+
24184+static inline void au_lcnt_wait_for_fin(au_lcnt_t *cnt __maybe_unused)
24185+{
24186+ synchronize_rcu();
24187+}
24188+
24189+static inline void au_lcnt_fin(au_lcnt_t *cnt, int do_sync)
24190+{
24191+ percpu_ref_kill(cnt);
24192+ if (do_sync)
24193+ au_lcnt_wait_for_fin(cnt);
24194+}
24195+
24196+static inline void au_lcnt_inc(au_lcnt_t *cnt)
24197+{
24198+ percpu_ref_get(cnt);
24199+}
24200+
24201+static inline void au_lcnt_dec(au_lcnt_t *cnt)
24202+{
24203+ percpu_ref_put(cnt);
24204+}
24205+
24206+/*
24207+ * avoid calling this func as possible.
24208+ */
24209+static inline long au_lcnt_read(au_lcnt_t *cnt, int do_rev)
24210+{
24211+ long l;
24212+
24213+ percpu_ref_switch_to_atomic_sync(cnt);
24214+ l = atomic_long_read(&cnt->count);
24215+ if (do_rev)
24216+ percpu_ref_switch_to_percpu(cnt);
24217+
24218+ /* percpu_ref is initialized by 1 instead of 0 */
24219+ return l - 1;
24220+}
24221+#endif
24222+
24223+#ifdef CONFIG_AUFS_DEBUG
24224+#define AuLCntZero(val) do { \
24225+ long l = val; \
24226+ if (l) \
24227+ AuDbg("%s = %ld\n", #val, l); \
24228+} while (0)
24229+#else
24230+#define AuLCntZero(val) do {} while (0)
24231+#endif
24232+
24233+#endif /* __KERNEL__ */
24234+#endif /* __AUFS_LCNT_H__ */
24235diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
24236--- /usr/share/empty/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100
24237+++ linux/fs/aufs/loop.c 2020-01-27 10:57:18.175538316 +0100
24238@@ -0,0 +1,148 @@
24239+// SPDX-License-Identifier: GPL-2.0
24240+/*
24241+ * Copyright (C) 2005-2020 Junjiro R. Okajima
24242+ *
24243+ * This program, aufs is free software; you can redistribute it and/or modify
24244+ * it under the terms of the GNU General Public License as published by
24245+ * the Free Software Foundation; either version 2 of the License, or
24246+ * (at your option) any later version.
24247+ *
24248+ * This program is distributed in the hope that it will be useful,
24249+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24250+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24251+ * GNU General Public License for more details.
24252+ *
24253+ * You should have received a copy of the GNU General Public License
24254+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
24255+ */
24256+
24257+/*
24258+ * support for loopback block device as a branch
24259+ */
24260+
24261+#include "aufs.h"
24262+
24263+/* added into drivers/block/loop.c */
24264+static struct file *(*backing_file_func)(struct super_block *sb);
24265+
24266+/*
24267+ * test if two lower dentries have overlapping branches.
24268+ */
24269+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
24270+{
24271+ struct super_block *h_sb;
24272+ struct file *backing_file;
24273+
24274+ if (unlikely(!backing_file_func)) {
24275+ /* don't load "loop" module here */
24276+ backing_file_func = symbol_get(loop_backing_file);
24277+ if (unlikely(!backing_file_func))
24278+ /* "loop" module is not loaded */
24279+ return 0;
24280+ }
24281+
24282+ h_sb = h_adding->d_sb;
24283+ backing_file = backing_file_func(h_sb);
24284+ if (!backing_file)
24285+ return 0;
24286+
24287+ h_adding = backing_file->f_path.dentry;
24288+ /*
24289+ * h_adding can be local NFS.
24290+ * in this case aufs cannot detect the loop.
24291+ */
24292+ if (unlikely(h_adding->d_sb == sb))
24293+ return 1;
24294+ return !!au_test_subdir(h_adding, sb->s_root);
24295+}
24296+
24297+/* true if a kernel thread named 'loop[0-9].*' accesses a file */
24298+int au_test_loopback_kthread(void)
24299+{
24300+ int ret;
24301+ struct task_struct *tsk = current;
24302+ char c, comm[sizeof(tsk->comm)];
24303+
24304+ ret = 0;
24305+ if (tsk->flags & PF_KTHREAD) {
24306+ get_task_comm(comm, tsk);
24307+ c = comm[4];
24308+ ret = ('0' <= c && c <= '9'
24309+ && !strncmp(comm, "loop", 4));
24310+ }
24311+
24312+ return ret;
24313+}
24314+
24315+/* ---------------------------------------------------------------------- */
24316+
24317+#define au_warn_loopback_step 16
24318+static int au_warn_loopback_nelem = au_warn_loopback_step;
24319+static unsigned long *au_warn_loopback_array;
24320+
24321+void au_warn_loopback(struct super_block *h_sb)
24322+{
24323+ int i, new_nelem;
24324+ unsigned long *a, magic;
24325+ static DEFINE_SPINLOCK(spin);
24326+
24327+ magic = h_sb->s_magic;
24328+ spin_lock(&spin);
24329+ a = au_warn_loopback_array;
24330+ for (i = 0; i < au_warn_loopback_nelem && *a; i++)
24331+ if (a[i] == magic) {
24332+ spin_unlock(&spin);
24333+ return;
24334+ }
24335+
24336+ /* h_sb is new to us, print it */
24337+ if (i < au_warn_loopback_nelem) {
24338+ a[i] = magic;
24339+ goto pr;
24340+ }
24341+
24342+ /* expand the array */
24343+ new_nelem = au_warn_loopback_nelem + au_warn_loopback_step;
24344+ a = au_kzrealloc(au_warn_loopback_array,
24345+ au_warn_loopback_nelem * sizeof(unsigned long),
24346+ new_nelem * sizeof(unsigned long), GFP_ATOMIC,
24347+ /*may_shrink*/0);
24348+ if (a) {
24349+ au_warn_loopback_nelem = new_nelem;
24350+ au_warn_loopback_array = a;
24351+ a[i] = magic;
24352+ goto pr;
24353+ }
24354+
24355+ spin_unlock(&spin);
24356+ AuWarn1("realloc failed, ignored\n");
24357+ return;
24358+
24359+pr:
24360+ spin_unlock(&spin);
24361+ pr_warn("you may want to try another patch for loopback file "
24362+ "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic);
24363+}
24364+
24365+int au_loopback_init(void)
24366+{
24367+ int err;
24368+ struct super_block *sb __maybe_unused;
24369+
24370+ BUILD_BUG_ON(sizeof(sb->s_magic) != sizeof(*au_warn_loopback_array));
24371+
24372+ err = 0;
24373+ au_warn_loopback_array = kcalloc(au_warn_loopback_step,
24374+ sizeof(unsigned long), GFP_NOFS);
24375+ if (unlikely(!au_warn_loopback_array))
24376+ err = -ENOMEM;
24377+
24378+ return err;
24379+}
24380+
24381+void au_loopback_fin(void)
24382+{
24383+ if (backing_file_func)
24384+ symbol_put(loop_backing_file);
24385+ au_kfree_try_rcu(au_warn_loopback_array);
24386+}
24387diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
24388--- /usr/share/empty/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
24389+++ linux/fs/aufs/loop.h 2020-01-27 10:57:18.175538316 +0100
24390@@ -0,0 +1,55 @@
24391+/* SPDX-License-Identifier: GPL-2.0 */
24392+/*
24393+ * Copyright (C) 2005-2020 Junjiro R. Okajima
24394+ *
24395+ * This program, aufs is free software; you can redistribute it and/or modify
24396+ * it under the terms of the GNU General Public License as published by
24397+ * the Free Software Foundation; either version 2 of the License, or
24398+ * (at your option) any later version.
24399+ *
24400+ * This program is distributed in the hope that it will be useful,
24401+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24402+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24403+ * GNU General Public License for more details.
24404+ *
24405+ * You should have received a copy of the GNU General Public License
24406+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
24407+ */
24408+
24409+/*
24410+ * support for loopback mount as a branch
24411+ */
24412+
24413+#ifndef __AUFS_LOOP_H__
24414+#define __AUFS_LOOP_H__
24415+
24416+#ifdef __KERNEL__
24417+
24418+struct dentry;
24419+struct super_block;
24420+
24421+#ifdef CONFIG_AUFS_BDEV_LOOP
24422+/* drivers/block/loop.c */
24423+struct file *loop_backing_file(struct super_block *sb);
24424+
24425+/* loop.c */
24426+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding);
24427+int au_test_loopback_kthread(void);
24428+void au_warn_loopback(struct super_block *h_sb);
24429+
24430+int au_loopback_init(void);
24431+void au_loopback_fin(void);
24432+#else
24433+AuStub(struct file *, loop_backing_file, return NULL, struct super_block *sb)
24434+
24435+AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
24436+ struct dentry *h_adding)
24437+AuStubInt0(au_test_loopback_kthread, void)
24438+AuStubVoid(au_warn_loopback, struct super_block *h_sb)
24439+
24440+AuStubInt0(au_loopback_init, void)
24441+AuStubVoid(au_loopback_fin, void)
24442+#endif /* BLK_DEV_LOOP */
24443+
24444+#endif /* __KERNEL__ */
24445+#endif /* __AUFS_LOOP_H__ */
24446diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
24447--- /usr/share/empty/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100
24448+++ linux/fs/aufs/magic.mk 2019-07-11 15:42:14.468904634 +0200
24449@@ -0,0 +1,31 @@
24450+# SPDX-License-Identifier: GPL-2.0
24451+
24452+# defined in ${srctree}/fs/fuse/inode.c
24453+# tristate
24454+ifdef CONFIG_FUSE_FS
24455+ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
24456+endif
24457+
24458+# defined in ${srctree}/fs/xfs/xfs_sb.h
24459+# tristate
24460+ifdef CONFIG_XFS_FS
24461+ccflags-y += -DXFS_SB_MAGIC=0x58465342
24462+endif
24463+
24464+# defined in ${srctree}/fs/configfs/mount.c
24465+# tristate
24466+ifdef CONFIG_CONFIGFS_FS
24467+ccflags-y += -DCONFIGFS_MAGIC=0x62656570
24468+endif
24469+
24470+# defined in ${srctree}/fs/ubifs/ubifs.h
24471+# tristate
24472+ifdef CONFIG_UBIFS_FS
24473+ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
24474+endif
24475+
24476+# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h
24477+# tristate
24478+ifdef CONFIG_HFSPLUS_FS
24479+ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b
24480+endif
24481diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
24482--- /usr/share/empty/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100
24483+++ linux/fs/aufs/Makefile 2019-07-11 15:42:14.462237786 +0200
24484@@ -0,0 +1,46 @@
24485+# SPDX-License-Identifier: GPL-2.0
24486+
24487+include ${src}/magic.mk
24488+ifeq (${CONFIG_AUFS_FS},m)
24489+include ${src}/conf.mk
24490+endif
24491+-include ${src}/priv_def.mk
24492+
24493+# cf. include/linux/kernel.h
24494+# enable pr_debug
24495+ccflags-y += -DDEBUG
24496+# sparse requires the full pathname
24497+ifdef M
24498+ccflags-y += -include ${M}/../../include/uapi/linux/aufs_type.h
24499+else
24500+ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h
24501+endif
24502+
24503+obj-$(CONFIG_AUFS_FS) += aufs.o
24504+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
24505+ wkq.o vfsub.o dcsub.o \
24506+ cpup.o whout.o wbr_policy.o \
24507+ dinfo.o dentry.o \
24508+ dynop.o \
24509+ finfo.o file.o f_op.o \
24510+ dir.o vdir.o \
24511+ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
24512+ mvdown.o ioctl.o
24513+
24514+# all are boolean
24515+aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
24516+aufs-$(CONFIG_SYSFS) += sysfs.o
24517+aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
24518+aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
24519+aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
24520+aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
24521+aufs-$(CONFIG_AUFS_EXPORT) += export.o
24522+aufs-$(CONFIG_AUFS_XATTR) += xattr.o
24523+aufs-$(CONFIG_FS_POSIX_ACL) += posix_acl.o
24524+aufs-$(CONFIG_AUFS_DIRREN) += dirren.o
24525+aufs-$(CONFIG_AUFS_FHSM) += fhsm.o
24526+aufs-$(CONFIG_AUFS_POLL) += poll.o
24527+aufs-$(CONFIG_AUFS_RDU) += rdu.o
24528+aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
24529+aufs-$(CONFIG_AUFS_DEBUG) += debug.o
24530+aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
24531diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
24532--- /usr/share/empty/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100
24533+++ linux/fs/aufs/module.c 2020-01-27 10:57:18.175538316 +0100
24534@@ -0,0 +1,273 @@
24535+// SPDX-License-Identifier: GPL-2.0
24536+/*
24537+ * Copyright (C) 2005-2020 Junjiro R. Okajima
24538+ *
24539+ * This program, aufs is free software; you can redistribute it and/or modify
24540+ * it under the terms of the GNU General Public License as published by
24541+ * the Free Software Foundation; either version 2 of the License, or
24542+ * (at your option) any later version.
24543+ *
24544+ * This program is distributed in the hope that it will be useful,
24545+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24546+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24547+ * GNU General Public License for more details.
24548+ *
24549+ * You should have received a copy of the GNU General Public License
24550+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
24551+ */
24552+
24553+/*
24554+ * module global variables and operations
24555+ */
24556+
24557+#include <linux/module.h>
24558+#include <linux/seq_file.h>
24559+#include "aufs.h"
24560+
24561+/* shrinkable realloc */
24562+void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink)
24563+{
24564+ size_t sz;
24565+ int diff;
24566+
24567+ sz = 0;
24568+ diff = -1;
24569+ if (p) {
24570+#if 0 /* unused */
24571+ if (!new_sz) {
24572+ au_kfree_rcu(p);
24573+ p = NULL;
24574+ goto out;
24575+ }
24576+#else
24577+ AuDebugOn(!new_sz);
24578+#endif
24579+ sz = ksize(p);
24580+ diff = au_kmidx_sub(sz, new_sz);
24581+ }
24582+ if (sz && !diff)
24583+ goto out;
24584+
24585+ if (sz < new_sz)
24586+ /* expand or SLOB */
24587+ p = krealloc(p, new_sz, gfp);
24588+ else if (new_sz < sz && may_shrink) {
24589+ /* shrink */
24590+ void *q;
24591+
24592+ q = kmalloc(new_sz, gfp);
24593+ if (q) {
24594+ if (p) {
24595+ memcpy(q, p, new_sz);
24596+ au_kfree_try_rcu(p);
24597+ }
24598+ p = q;
24599+ } else
24600+ p = NULL;
24601+ }
24602+
24603+out:
24604+ return p;
24605+}
24606+
24607+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp,
24608+ int may_shrink)
24609+{
24610+ p = au_krealloc(p, new_sz, gfp, may_shrink);
24611+ if (p && new_sz > nused)
24612+ memset(p + nused, 0, new_sz - nused);
24613+ return p;
24614+}
24615+
24616+/* ---------------------------------------------------------------------- */
24617+/*
24618+ * aufs caches
24619+ */
24620+struct kmem_cache *au_cache[AuCache_Last];
24621+
24622+static void au_cache_fin(void)
24623+{
24624+ int i;
24625+
24626+ /*
24627+ * Make sure all delayed rcu free inodes are flushed before we
24628+ * destroy cache.
24629+ */
24630+ rcu_barrier();
24631+
24632+ /* excluding AuCache_HNOTIFY */
24633+ BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
24634+ for (i = 0; i < AuCache_HNOTIFY; i++) {
24635+ kmem_cache_destroy(au_cache[i]);
24636+ au_cache[i] = NULL;
24637+ }
24638+}
24639+
24640+static int __init au_cache_init(void)
24641+{
24642+ au_cache[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
24643+ if (au_cache[AuCache_DINFO])
24644+ /* SLAB_DESTROY_BY_RCU */
24645+ au_cache[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
24646+ au_icntnr_init_once);
24647+ if (au_cache[AuCache_ICNTNR])
24648+ au_cache[AuCache_FINFO] = AuCacheCtor(au_finfo,
24649+ au_fi_init_once);
24650+ if (au_cache[AuCache_FINFO])
24651+ au_cache[AuCache_VDIR] = AuCache(au_vdir);
24652+ if (au_cache[AuCache_VDIR])
24653+ au_cache[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
24654+ if (au_cache[AuCache_DEHSTR])
24655+ return 0;
24656+
24657+ au_cache_fin();
24658+ return -ENOMEM;
24659+}
24660+
24661+/* ---------------------------------------------------------------------- */
24662+
24663+int au_dir_roflags;
24664+
24665+#ifdef CONFIG_AUFS_SBILIST
24666+/*
24667+ * iterate_supers_type() doesn't protect us from
24668+ * remounting (branch management)
24669+ */
24670+struct hlist_bl_head au_sbilist;
24671+#endif
24672+
24673+/*
24674+ * functions for module interface.
24675+ */
24676+MODULE_LICENSE("GPL");
24677+/* MODULE_LICENSE("GPL v2"); */
24678+MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
24679+MODULE_DESCRIPTION(AUFS_NAME
24680+ " -- Advanced multi layered unification filesystem");
24681+MODULE_VERSION(AUFS_VERSION);
24682+MODULE_ALIAS_FS(AUFS_NAME);
24683+
24684+/* this module parameter has no meaning when SYSFS is disabled */
24685+int sysaufs_brs = 1;
24686+MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
24687+module_param_named(brs, sysaufs_brs, int, 0444);
24688+
24689+/* this module parameter has no meaning when USER_NS is disabled */
24690+bool au_userns;
24691+MODULE_PARM_DESC(allow_userns, "allow unprivileged to mount under userns");
24692+module_param_named(allow_userns, au_userns, bool, 0444);
24693+
24694+/* ---------------------------------------------------------------------- */
24695+
24696+static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
24697+
24698+int au_seq_path(struct seq_file *seq, struct path *path)
24699+{
24700+ int err;
24701+
24702+ err = seq_path(seq, path, au_esc_chars);
24703+ if (err >= 0)
24704+ err = 0;
24705+ else
24706+ err = -ENOMEM;
24707+
24708+ return err;
24709+}
24710+
24711+/* ---------------------------------------------------------------------- */
24712+
24713+static int __init aufs_init(void)
24714+{
24715+ int err, i;
24716+ char *p;
24717+
24718+ p = au_esc_chars;
24719+ for (i = 1; i <= ' '; i++)
24720+ *p++ = i;
24721+ *p++ = '\\';
24722+ *p++ = '\x7f';
24723+ *p = 0;
24724+
24725+ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
24726+
24727+ memcpy(aufs_iop_nogetattr, aufs_iop, sizeof(aufs_iop));
24728+ for (i = 0; i < AuIop_Last; i++)
24729+ aufs_iop_nogetattr[i].getattr = NULL;
24730+
24731+ memset(au_cache, 0, sizeof(au_cache)); /* including hnotify */
24732+
24733+ au_sbilist_init();
24734+ sysaufs_brs_init();
24735+ au_debug_init();
24736+ au_dy_init();
24737+ err = sysaufs_init();
24738+ if (unlikely(err))
24739+ goto out;
24740+ err = dbgaufs_init();
24741+ if (unlikely(err))
24742+ goto out_sysaufs;
24743+ err = au_procfs_init();
24744+ if (unlikely(err))
24745+ goto out_dbgaufs;
24746+ err = au_wkq_init();
24747+ if (unlikely(err))
24748+ goto out_procfs;
24749+ err = au_loopback_init();
24750+ if (unlikely(err))
24751+ goto out_wkq;
24752+ err = au_hnotify_init();
24753+ if (unlikely(err))
24754+ goto out_loopback;
24755+ err = au_sysrq_init();
24756+ if (unlikely(err))
24757+ goto out_hin;
24758+ err = au_cache_init();
24759+ if (unlikely(err))
24760+ goto out_sysrq;
24761+
24762+ aufs_fs_type.fs_flags |= au_userns ? FS_USERNS_MOUNT : 0;
24763+ err = register_filesystem(&aufs_fs_type);
24764+ if (unlikely(err))
24765+ goto out_cache;
24766+
24767+ /* since we define pr_fmt, call printk directly */
24768+ printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
24769+ goto out; /* success */
24770+
24771+out_cache:
24772+ au_cache_fin();
24773+out_sysrq:
24774+ au_sysrq_fin();
24775+out_hin:
24776+ au_hnotify_fin();
24777+out_loopback:
24778+ au_loopback_fin();
24779+out_wkq:
24780+ au_wkq_fin();
24781+out_procfs:
24782+ au_procfs_fin();
24783+out_dbgaufs:
24784+ dbgaufs_fin();
24785+out_sysaufs:
24786+ sysaufs_fin();
24787+ au_dy_fin();
24788+out:
24789+ return err;
24790+}
24791+
24792+static void __exit aufs_exit(void)
24793+{
24794+ unregister_filesystem(&aufs_fs_type);
24795+ au_cache_fin();
24796+ au_sysrq_fin();
24797+ au_hnotify_fin();
24798+ au_loopback_fin();
24799+ au_wkq_fin();
24800+ au_procfs_fin();
24801+ dbgaufs_fin();
24802+ sysaufs_fin();
24803+ au_dy_fin();
24804+}
24805+
24806+module_init(aufs_init);
24807+module_exit(aufs_exit);
24808diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
24809--- /usr/share/empty/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100
24810+++ linux/fs/aufs/module.h 2020-01-27 10:57:18.175538316 +0100
24811@@ -0,0 +1,166 @@
24812+/* SPDX-License-Identifier: GPL-2.0 */
24813+/*
24814+ * Copyright (C) 2005-2020 Junjiro R. Okajima
24815+ *
24816+ * This program, aufs is free software; you can redistribute it and/or modify
24817+ * it under the terms of the GNU General Public License as published by
24818+ * the Free Software Foundation; either version 2 of the License, or
24819+ * (at your option) any later version.
24820+ *
24821+ * This program is distributed in the hope that it will be useful,
24822+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24823+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24824+ * GNU General Public License for more details.
24825+ *
24826+ * You should have received a copy of the GNU General Public License
24827+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
24828+ */
24829+
24830+/*
24831+ * module initialization and module-global
24832+ */
24833+
24834+#ifndef __AUFS_MODULE_H__
24835+#define __AUFS_MODULE_H__
24836+
24837+#ifdef __KERNEL__
24838+
24839+#include <linux/slab.h>
24840+#include "debug.h"
24841+#include "dentry.h"
24842+#include "dir.h"
24843+#include "file.h"
24844+#include "inode.h"
24845+
24846+struct path;
24847+struct seq_file;
24848+
24849+/* module parameters */
24850+extern int sysaufs_brs;
24851+extern bool au_userns;
24852+
24853+/* ---------------------------------------------------------------------- */
24854+
24855+extern int au_dir_roflags;
24856+
24857+void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink);
24858+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp,
24859+ int may_shrink);
24860+
24861+/*
24862+ * Comparing the size of the object with sizeof(struct rcu_head)
24863+ * case 1: object is always larger
24864+ * --> au_kfree_rcu() or au_kfree_do_rcu()
24865+ * case 2: object is always smaller
24866+ * --> au_kfree_small()
24867+ * case 3: object can be any size
24868+ * --> au_kfree_try_rcu()
24869+ */
24870+
24871+static inline void au_kfree_do_rcu(const void *p)
24872+{
24873+ struct {
24874+ struct rcu_head rcu;
24875+ } *a = (void *)p;
24876+
24877+ kfree_rcu(a, rcu);
24878+}
24879+
24880+#define au_kfree_rcu(_p) do { \
24881+ typeof(_p) p = (_p); \
24882+ BUILD_BUG_ON(sizeof(*p) < sizeof(struct rcu_head)); \
24883+ if (p) \
24884+ au_kfree_do_rcu(p); \
24885+ } while (0)
24886+
24887+#define au_kfree_do_sz_test(sz) (sz >= sizeof(struct rcu_head))
24888+#define au_kfree_sz_test(p) (p && au_kfree_do_sz_test(ksize(p)))
24889+
24890+static inline void au_kfree_try_rcu(const void *p)
24891+{
24892+ if (!p)
24893+ return;
24894+ if (au_kfree_sz_test(p))
24895+ au_kfree_do_rcu(p);
24896+ else
24897+ kfree(p);
24898+}
24899+
24900+static inline void au_kfree_small(const void *p)
24901+{
24902+ if (!p)
24903+ return;
24904+ AuDebugOn(au_kfree_sz_test(p));
24905+ kfree(p);
24906+}
24907+
24908+static inline int au_kmidx_sub(size_t sz, size_t new_sz)
24909+{
24910+#ifndef CONFIG_SLOB
24911+ return kmalloc_index(sz) - kmalloc_index(new_sz);
24912+#else
24913+ return -1; /* SLOB is untested */
24914+#endif
24915+}
24916+
24917+int au_seq_path(struct seq_file *seq, struct path *path);
24918+
24919+#ifdef CONFIG_PROC_FS
24920+/* procfs.c */
24921+int __init au_procfs_init(void);
24922+void au_procfs_fin(void);
24923+#else
24924+AuStubInt0(au_procfs_init, void);
24925+AuStubVoid(au_procfs_fin, void);
24926+#endif
24927+
24928+/* ---------------------------------------------------------------------- */
24929+
24930+/* kmem cache */
24931+enum {
24932+ AuCache_DINFO,
24933+ AuCache_ICNTNR,
24934+ AuCache_FINFO,
24935+ AuCache_VDIR,
24936+ AuCache_DEHSTR,
24937+ AuCache_HNOTIFY, /* must be last */
24938+ AuCache_Last
24939+};
24940+
24941+extern struct kmem_cache *au_cache[AuCache_Last];
24942+
24943+#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
24944+#define AuCache(type) KMEM_CACHE(type, AuCacheFlags)
24945+#define AuCacheCtor(type, ctor) \
24946+ kmem_cache_create(#type, sizeof(struct type), \
24947+ __alignof__(struct type), AuCacheFlags, ctor)
24948+
24949+#define AuCacheFuncs(name, index) \
24950+ static inline struct au_##name *au_cache_alloc_##name(void) \
24951+ { return kmem_cache_alloc(au_cache[AuCache_##index], GFP_NOFS); } \
24952+ static inline void au_cache_free_##name##_norcu(struct au_##name *p) \
24953+ { kmem_cache_free(au_cache[AuCache_##index], p); } \
24954+ \
24955+ static inline void au_cache_free_##name##_rcu_cb(struct rcu_head *rcu) \
24956+ { void *p = rcu; \
24957+ p -= offsetof(struct au_##name, rcu); \
24958+ kmem_cache_free(au_cache[AuCache_##index], p); } \
24959+ static inline void au_cache_free_##name##_rcu(struct au_##name *p) \
24960+ { BUILD_BUG_ON(sizeof(struct au_##name) < sizeof(struct rcu_head)); \
24961+ call_rcu(&p->rcu, au_cache_free_##name##_rcu_cb); } \
24962+ \
24963+ static inline void au_cache_free_##name(struct au_##name *p) \
24964+ { /* au_cache_free_##name##_norcu(p); */ \
24965+ au_cache_free_##name##_rcu(p); }
24966+
24967+AuCacheFuncs(dinfo, DINFO);
24968+AuCacheFuncs(icntnr, ICNTNR);
24969+AuCacheFuncs(finfo, FINFO);
24970+AuCacheFuncs(vdir, VDIR);
24971+AuCacheFuncs(vdir_dehstr, DEHSTR);
24972+#ifdef CONFIG_AUFS_HNOTIFY
24973+AuCacheFuncs(hnotify, HNOTIFY);
24974+#endif
24975+
24976+#endif /* __KERNEL__ */
24977+#endif /* __AUFS_MODULE_H__ */
24978diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
24979--- /usr/share/empty/fs/aufs/mvdown.c 1970-01-01 01:00:00.000000000 +0100
24980+++ linux/fs/aufs/mvdown.c 2020-01-27 10:57:18.175538316 +0100
24981@@ -0,0 +1,706 @@
24982+// SPDX-License-Identifier: GPL-2.0
24983+/*
24984+ * Copyright (C) 2011-2020 Junjiro R. Okajima
24985+ *
24986+ * This program, aufs is free software; you can redistribute it and/or modify
24987+ * it under the terms of the GNU General Public License as published by
24988+ * the Free Software Foundation; either version 2 of the License, or
24989+ * (at your option) any later version.
24990+ *
24991+ * This program is distributed in the hope that it will be useful,
24992+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24993+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24994+ * GNU General Public License for more details.
24995+ *
24996+ * You should have received a copy of the GNU General Public License
24997+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
24998+ */
24999+
25000+/*
25001+ * move-down, opposite of copy-up
25002+ */
25003+
25004+#include "aufs.h"
25005+
25006+struct au_mvd_args {
25007+ struct {
25008+ struct super_block *h_sb;
25009+ struct dentry *h_parent;
25010+ struct au_hinode *hdir;
25011+ struct inode *h_dir, *h_inode;
25012+ struct au_pin pin;
25013+ } info[AUFS_MVDOWN_NARRAY];
25014+
25015+ struct aufs_mvdown mvdown;
25016+ struct dentry *dentry, *parent;
25017+ struct inode *inode, *dir;
25018+ struct super_block *sb;
25019+ aufs_bindex_t bopq, bwh, bfound;
25020+ unsigned char rename_lock;
25021+};
25022+
25023+#define mvd_errno mvdown.au_errno
25024+#define mvd_bsrc mvdown.stbr[AUFS_MVDOWN_UPPER].bindex
25025+#define mvd_src_brid mvdown.stbr[AUFS_MVDOWN_UPPER].brid
25026+#define mvd_bdst mvdown.stbr[AUFS_MVDOWN_LOWER].bindex
25027+#define mvd_dst_brid mvdown.stbr[AUFS_MVDOWN_LOWER].brid
25028+
25029+#define mvd_h_src_sb info[AUFS_MVDOWN_UPPER].h_sb
25030+#define mvd_h_src_parent info[AUFS_MVDOWN_UPPER].h_parent
25031+#define mvd_hdir_src info[AUFS_MVDOWN_UPPER].hdir
25032+#define mvd_h_src_dir info[AUFS_MVDOWN_UPPER].h_dir
25033+#define mvd_h_src_inode info[AUFS_MVDOWN_UPPER].h_inode
25034+#define mvd_pin_src info[AUFS_MVDOWN_UPPER].pin
25035+
25036+#define mvd_h_dst_sb info[AUFS_MVDOWN_LOWER].h_sb
25037+#define mvd_h_dst_parent info[AUFS_MVDOWN_LOWER].h_parent
25038+#define mvd_hdir_dst info[AUFS_MVDOWN_LOWER].hdir
25039+#define mvd_h_dst_dir info[AUFS_MVDOWN_LOWER].h_dir
25040+#define mvd_h_dst_inode info[AUFS_MVDOWN_LOWER].h_inode
25041+#define mvd_pin_dst info[AUFS_MVDOWN_LOWER].pin
25042+
25043+#define AU_MVD_PR(flag, ...) do { \
25044+ if (flag) \
25045+ pr_err(__VA_ARGS__); \
25046+ } while (0)
25047+
25048+static int find_lower_writable(struct au_mvd_args *a)
25049+{
25050+ struct super_block *sb;
25051+ aufs_bindex_t bindex, bbot;
25052+ struct au_branch *br;
25053+
25054+ sb = a->sb;
25055+ bindex = a->mvd_bsrc;
25056+ bbot = au_sbbot(sb);
25057+ if (a->mvdown.flags & AUFS_MVDOWN_FHSM_LOWER)
25058+ for (bindex++; bindex <= bbot; bindex++) {
25059+ br = au_sbr(sb, bindex);
25060+ if (au_br_fhsm(br->br_perm)
25061+ && !sb_rdonly(au_br_sb(br)))
25062+ return bindex;
25063+ }
25064+ else if (!(a->mvdown.flags & AUFS_MVDOWN_ROLOWER))
25065+ for (bindex++; bindex <= bbot; bindex++) {
25066+ br = au_sbr(sb, bindex);
25067+ if (!au_br_rdonly(br))
25068+ return bindex;
25069+ }
25070+ else
25071+ for (bindex++; bindex <= bbot; bindex++) {
25072+ br = au_sbr(sb, bindex);
25073+ if (!sb_rdonly(au_br_sb(br))) {
25074+ if (au_br_rdonly(br))
25075+ a->mvdown.flags
25076+ |= AUFS_MVDOWN_ROLOWER_R;
25077+ return bindex;
25078+ }
25079+ }
25080+
25081+ return -1;
25082+}
25083+
25084+/* make the parent dir on bdst */
25085+static int au_do_mkdir(const unsigned char dmsg, struct au_mvd_args *a)
25086+{
25087+ int err;
25088+
25089+ err = 0;
25090+ a->mvd_hdir_src = au_hi(a->dir, a->mvd_bsrc);
25091+ a->mvd_hdir_dst = au_hi(a->dir, a->mvd_bdst);
25092+ a->mvd_h_src_parent = au_h_dptr(a->parent, a->mvd_bsrc);
25093+ a->mvd_h_dst_parent = NULL;
25094+ if (au_dbbot(a->parent) >= a->mvd_bdst)
25095+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
25096+ if (!a->mvd_h_dst_parent) {
25097+ err = au_cpdown_dirs(a->dentry, a->mvd_bdst);
25098+ if (unlikely(err)) {
25099+ AU_MVD_PR(dmsg, "cpdown_dirs failed\n");
25100+ goto out;
25101+ }
25102+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
25103+ }
25104+
25105+out:
25106+ AuTraceErr(err);
25107+ return err;
25108+}
25109+
25110+/* lock them all */
25111+static int au_do_lock(const unsigned char dmsg, struct au_mvd_args *a)
25112+{
25113+ int err;
25114+ struct dentry *h_trap;
25115+
25116+ a->mvd_h_src_sb = au_sbr_sb(a->sb, a->mvd_bsrc);
25117+ a->mvd_h_dst_sb = au_sbr_sb(a->sb, a->mvd_bdst);
25118+ err = au_pin(&a->mvd_pin_dst, a->dentry, a->mvd_bdst,
25119+ au_opt_udba(a->sb),
25120+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
25121+ AuTraceErr(err);
25122+ if (unlikely(err)) {
25123+ AU_MVD_PR(dmsg, "pin_dst failed\n");
25124+ goto out;
25125+ }
25126+
25127+ if (a->mvd_h_src_sb != a->mvd_h_dst_sb) {
25128+ a->rename_lock = 0;
25129+ au_pin_init(&a->mvd_pin_src, a->dentry, a->mvd_bsrc,
25130+ AuLsc_DI_PARENT, AuLsc_I_PARENT3,
25131+ au_opt_udba(a->sb),
25132+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
25133+ err = au_do_pin(&a->mvd_pin_src);
25134+ AuTraceErr(err);
25135+ a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent);
25136+ if (unlikely(err)) {
25137+ AU_MVD_PR(dmsg, "pin_src failed\n");
25138+ goto out_dst;
25139+ }
25140+ goto out; /* success */
25141+ }
25142+
25143+ a->rename_lock = 1;
25144+ au_pin_hdir_unlock(&a->mvd_pin_dst);
25145+ err = au_pin(&a->mvd_pin_src, a->dentry, a->mvd_bsrc,
25146+ au_opt_udba(a->sb),
25147+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
25148+ AuTraceErr(err);
25149+ a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent);
25150+ if (unlikely(err)) {
25151+ AU_MVD_PR(dmsg, "pin_src failed\n");
25152+ au_pin_hdir_lock(&a->mvd_pin_dst);
25153+ goto out_dst;
25154+ }
25155+ au_pin_hdir_unlock(&a->mvd_pin_src);
25156+ h_trap = vfsub_lock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
25157+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
25158+ if (h_trap) {
25159+ err = (h_trap != a->mvd_h_src_parent);
25160+ if (err)
25161+ err = (h_trap != a->mvd_h_dst_parent);
25162+ }
25163+ BUG_ON(err); /* it should never happen */
25164+ if (unlikely(a->mvd_h_src_dir != au_pinned_h_dir(&a->mvd_pin_src))) {
25165+ err = -EBUSY;
25166+ AuTraceErr(err);
25167+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
25168+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
25169+ au_pin_hdir_lock(&a->mvd_pin_src);
25170+ au_unpin(&a->mvd_pin_src);
25171+ au_pin_hdir_lock(&a->mvd_pin_dst);
25172+ goto out_dst;
25173+ }
25174+ goto out; /* success */
25175+
25176+out_dst:
25177+ au_unpin(&a->mvd_pin_dst);
25178+out:
25179+ AuTraceErr(err);
25180+ return err;
25181+}
25182+
25183+static void au_do_unlock(const unsigned char dmsg, struct au_mvd_args *a)
25184+{
25185+ if (!a->rename_lock)
25186+ au_unpin(&a->mvd_pin_src);
25187+ else {
25188+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
25189+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
25190+ au_pin_hdir_lock(&a->mvd_pin_src);
25191+ au_unpin(&a->mvd_pin_src);
25192+ au_pin_hdir_lock(&a->mvd_pin_dst);
25193+ }
25194+ au_unpin(&a->mvd_pin_dst);
25195+}
25196+
25197+/* copy-down the file */
25198+static int au_do_cpdown(const unsigned char dmsg, struct au_mvd_args *a)
25199+{
25200+ int err;
25201+ struct au_cp_generic cpg = {
25202+ .dentry = a->dentry,
25203+ .bdst = a->mvd_bdst,
25204+ .bsrc = a->mvd_bsrc,
25205+ .len = -1,
25206+ .pin = &a->mvd_pin_dst,
25207+ .flags = AuCpup_DTIME | AuCpup_HOPEN
25208+ };
25209+
25210+ AuDbg("b%d, b%d\n", cpg.bsrc, cpg.bdst);
25211+ if (a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
25212+ au_fset_cpup(cpg.flags, OVERWRITE);
25213+ if (a->mvdown.flags & AUFS_MVDOWN_ROLOWER)
25214+ au_fset_cpup(cpg.flags, RWDST);
25215+ err = au_sio_cpdown_simple(&cpg);
25216+ if (unlikely(err))
25217+ AU_MVD_PR(dmsg, "cpdown failed\n");
25218+
25219+ AuTraceErr(err);
25220+ return err;
25221+}
25222+
25223+/*
25224+ * unlink the whiteout on bdst if exist which may be created by UDBA while we
25225+ * were sleeping
25226+ */
25227+static int au_do_unlink_wh(const unsigned char dmsg, struct au_mvd_args *a)
25228+{
25229+ int err;
25230+ struct path h_path;
25231+ struct au_branch *br;
25232+ struct inode *delegated;
25233+
25234+ br = au_sbr(a->sb, a->mvd_bdst);
25235+ h_path.dentry = au_wh_lkup(a->mvd_h_dst_parent, &a->dentry->d_name, br);
25236+ err = PTR_ERR(h_path.dentry);
25237+ if (IS_ERR(h_path.dentry)) {
25238+ AU_MVD_PR(dmsg, "wh_lkup failed\n");
25239+ goto out;
25240+ }
25241+
25242+ err = 0;
25243+ if (d_is_positive(h_path.dentry)) {
25244+ h_path.mnt = au_br_mnt(br);
25245+ delegated = NULL;
25246+ err = vfsub_unlink(d_inode(a->mvd_h_dst_parent), &h_path,
25247+ &delegated, /*force*/0);
25248+ if (unlikely(err == -EWOULDBLOCK)) {
25249+ pr_warn("cannot retry for NFSv4 delegation"
25250+ " for an internal unlink\n");
25251+ iput(delegated);
25252+ }
25253+ if (unlikely(err))
25254+ AU_MVD_PR(dmsg, "wh_unlink failed\n");
25255+ }
25256+ dput(h_path.dentry);
25257+
25258+out:
25259+ AuTraceErr(err);
25260+ return err;
25261+}
25262+
25263+/*
25264+ * unlink the topmost h_dentry
25265+ */
25266+static int au_do_unlink(const unsigned char dmsg, struct au_mvd_args *a)
25267+{
25268+ int err;
25269+ struct path h_path;
25270+ struct inode *delegated;
25271+
25272+ h_path.mnt = au_sbr_mnt(a->sb, a->mvd_bsrc);
25273+ h_path.dentry = au_h_dptr(a->dentry, a->mvd_bsrc);
25274+ delegated = NULL;
25275+ err = vfsub_unlink(a->mvd_h_src_dir, &h_path, &delegated, /*force*/0);
25276+ if (unlikely(err == -EWOULDBLOCK)) {
25277+ pr_warn("cannot retry for NFSv4 delegation"
25278+ " for an internal unlink\n");
25279+ iput(delegated);
25280+ }
25281+ if (unlikely(err))
25282+ AU_MVD_PR(dmsg, "unlink failed\n");
25283+
25284+ AuTraceErr(err);
25285+ return err;
25286+}
25287+
25288+/* Since mvdown succeeded, we ignore an error of this function */
25289+static void au_do_stfs(const unsigned char dmsg, struct au_mvd_args *a)
25290+{
25291+ int err;
25292+ struct au_branch *br;
25293+
25294+ a->mvdown.flags |= AUFS_MVDOWN_STFS_FAILED;
25295+ br = au_sbr(a->sb, a->mvd_bsrc);
25296+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_UPPER].stfs);
25297+ if (!err) {
25298+ br = au_sbr(a->sb, a->mvd_bdst);
25299+ a->mvdown.stbr[AUFS_MVDOWN_LOWER].brid = br->br_id;
25300+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_LOWER].stfs);
25301+ }
25302+ if (!err)
25303+ a->mvdown.flags &= ~AUFS_MVDOWN_STFS_FAILED;
25304+ else
25305+ AU_MVD_PR(dmsg, "statfs failed (%d), ignored\n", err);
25306+}
25307+
25308+/*
25309+ * copy-down the file and unlink the bsrc file.
25310+ * - unlink the bdst whout if exist
25311+ * - copy-down the file (with whtmp name and rename)
25312+ * - unlink the bsrc file
25313+ */
25314+static int au_do_mvdown(const unsigned char dmsg, struct au_mvd_args *a)
25315+{
25316+ int err;
25317+
25318+ err = au_do_mkdir(dmsg, a);
25319+ if (!err)
25320+ err = au_do_lock(dmsg, a);
25321+ if (unlikely(err))
25322+ goto out;
25323+
25324+ /*
25325+ * do not revert the activities we made on bdst since they should be
25326+ * harmless in aufs.
25327+ */
25328+
25329+ err = au_do_cpdown(dmsg, a);
25330+ if (!err)
25331+ err = au_do_unlink_wh(dmsg, a);
25332+ if (!err && !(a->mvdown.flags & AUFS_MVDOWN_KUPPER))
25333+ err = au_do_unlink(dmsg, a);
25334+ if (unlikely(err))
25335+ goto out_unlock;
25336+
25337+ AuDbg("%pd2, 0x%x, %d --> %d\n",
25338+ a->dentry, a->mvdown.flags, a->mvd_bsrc, a->mvd_bdst);
25339+ if (find_lower_writable(a) < 0)
25340+ a->mvdown.flags |= AUFS_MVDOWN_BOTTOM;
25341+
25342+ if (a->mvdown.flags & AUFS_MVDOWN_STFS)
25343+ au_do_stfs(dmsg, a);
25344+
25345+ /* maintain internal array */
25346+ if (!(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) {
25347+ au_set_h_dptr(a->dentry, a->mvd_bsrc, NULL);
25348+ au_set_dbtop(a->dentry, a->mvd_bdst);
25349+ au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0);
25350+ au_set_ibtop(a->inode, a->mvd_bdst);
25351+ } else {
25352+ /* hide the lower */
25353+ au_set_h_dptr(a->dentry, a->mvd_bdst, NULL);
25354+ au_set_dbbot(a->dentry, a->mvd_bsrc);
25355+ au_set_h_iptr(a->inode, a->mvd_bdst, NULL, /*flags*/0);
25356+ au_set_ibbot(a->inode, a->mvd_bsrc);
25357+ }
25358+ if (au_dbbot(a->dentry) < a->mvd_bdst)
25359+ au_set_dbbot(a->dentry, a->mvd_bdst);
25360+ if (au_ibbot(a->inode) < a->mvd_bdst)
25361+ au_set_ibbot(a->inode, a->mvd_bdst);
25362+
25363+out_unlock:
25364+ au_do_unlock(dmsg, a);
25365+out:
25366+ AuTraceErr(err);
25367+ return err;
25368+}
25369+
25370+/* ---------------------------------------------------------------------- */
25371+
25372+/* make sure the file is idle */
25373+static int au_mvd_args_busy(const unsigned char dmsg, struct au_mvd_args *a)
25374+{
25375+ int err, plinked;
25376+
25377+ err = 0;
25378+ plinked = !!au_opt_test(au_mntflags(a->sb), PLINK);
25379+ if (au_dbtop(a->dentry) == a->mvd_bsrc
25380+ && au_dcount(a->dentry) == 1
25381+ && atomic_read(&a->inode->i_count) == 1
25382+ /* && a->mvd_h_src_inode->i_nlink == 1 */
25383+ && (!plinked || !au_plink_test(a->inode))
25384+ && a->inode->i_nlink == 1)
25385+ goto out;
25386+
25387+ err = -EBUSY;
25388+ AU_MVD_PR(dmsg,
25389+ "b%d, d{b%d, c%d?}, i{c%d?, l%u}, hi{l%u}, p{%d, %d}\n",
25390+ a->mvd_bsrc, au_dbtop(a->dentry), au_dcount(a->dentry),
25391+ atomic_read(&a->inode->i_count), a->inode->i_nlink,
25392+ a->mvd_h_src_inode->i_nlink,
25393+ plinked, plinked ? au_plink_test(a->inode) : 0);
25394+
25395+out:
25396+ AuTraceErr(err);
25397+ return err;
25398+}
25399+
25400+/* make sure the parent dir is fine */
25401+static int au_mvd_args_parent(const unsigned char dmsg,
25402+ struct au_mvd_args *a)
25403+{
25404+ int err;
25405+ aufs_bindex_t bindex;
25406+
25407+ err = 0;
25408+ if (unlikely(au_alive_dir(a->parent))) {
25409+ err = -ENOENT;
25410+ AU_MVD_PR(dmsg, "parent dir is dead\n");
25411+ goto out;
25412+ }
25413+
25414+ a->bopq = au_dbdiropq(a->parent);
25415+ bindex = au_wbr_nonopq(a->dentry, a->mvd_bdst);
25416+ AuDbg("b%d\n", bindex);
25417+ if (unlikely((bindex >= 0 && bindex < a->mvd_bdst)
25418+ || (a->bopq != -1 && a->bopq < a->mvd_bdst))) {
25419+ err = -EINVAL;
25420+ a->mvd_errno = EAU_MVDOWN_OPAQUE;
25421+ AU_MVD_PR(dmsg, "ancestor is opaque b%d, b%d\n",
25422+ a->bopq, a->mvd_bdst);
25423+ }
25424+
25425+out:
25426+ AuTraceErr(err);
25427+ return err;
25428+}
25429+
25430+static int au_mvd_args_intermediate(const unsigned char dmsg,
25431+ struct au_mvd_args *a)
25432+{
25433+ int err;
25434+ struct au_dinfo *dinfo, *tmp;
25435+
25436+ /* lookup the next lower positive entry */
25437+ err = -ENOMEM;
25438+ tmp = au_di_alloc(a->sb, AuLsc_DI_TMP);
25439+ if (unlikely(!tmp))
25440+ goto out;
25441+
25442+ a->bfound = -1;
25443+ a->bwh = -1;
25444+ dinfo = au_di(a->dentry);
25445+ au_di_cp(tmp, dinfo);
25446+ au_di_swap(tmp, dinfo);
25447+
25448+ /* returns the number of positive dentries */
25449+ err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1,
25450+ /* AuLkup_IGNORE_PERM */ 0);
25451+ if (!err)
25452+ a->bwh = au_dbwh(a->dentry);
25453+ else if (err > 0)
25454+ a->bfound = au_dbtop(a->dentry);
25455+
25456+ au_di_swap(tmp, dinfo);
25457+ au_rw_write_unlock(&tmp->di_rwsem);
25458+ au_di_free(tmp);
25459+ if (unlikely(err < 0))
25460+ AU_MVD_PR(dmsg, "failed look-up lower\n");
25461+
25462+ /*
25463+ * here, we have these cases.
25464+ * bfound == -1
25465+ * no positive dentry under bsrc. there are more sub-cases.
25466+ * bwh < 0
25467+ * there no whiteout, we can safely move-down.
25468+ * bwh <= bsrc
25469+ * impossible
25470+ * bsrc < bwh && bwh < bdst
25471+ * there is a whiteout on RO branch. cannot proceed.
25472+ * bwh == bdst
25473+ * there is a whiteout on the RW target branch. it should
25474+ * be removed.
25475+ * bdst < bwh
25476+ * there is a whiteout somewhere unrelated branch.
25477+ * -1 < bfound && bfound <= bsrc
25478+ * impossible.
25479+ * bfound < bdst
25480+ * found, but it is on RO branch between bsrc and bdst. cannot
25481+ * proceed.
25482+ * bfound == bdst
25483+ * found, replace it if AUFS_MVDOWN_FORCE is set. otherwise return
25484+ * error.
25485+ * bdst < bfound
25486+ * found, after we create the file on bdst, it will be hidden.
25487+ */
25488+
25489+ AuDebugOn(a->bfound == -1
25490+ && a->bwh != -1
25491+ && a->bwh <= a->mvd_bsrc);
25492+ AuDebugOn(-1 < a->bfound
25493+ && a->bfound <= a->mvd_bsrc);
25494+
25495+ err = -EINVAL;
25496+ if (a->bfound == -1
25497+ && a->mvd_bsrc < a->bwh
25498+ && a->bwh != -1
25499+ && a->bwh < a->mvd_bdst) {
25500+ a->mvd_errno = EAU_MVDOWN_WHITEOUT;
25501+ AU_MVD_PR(dmsg, "bsrc %d, bdst %d, bfound %d, bwh %d\n",
25502+ a->mvd_bsrc, a->mvd_bdst, a->bfound, a->bwh);
25503+ goto out;
25504+ } else if (a->bfound != -1 && a->bfound < a->mvd_bdst) {
25505+ a->mvd_errno = EAU_MVDOWN_UPPER;
25506+ AU_MVD_PR(dmsg, "bdst %d, bfound %d\n",
25507+ a->mvd_bdst, a->bfound);
25508+ goto out;
25509+ }
25510+
25511+ err = 0; /* success */
25512+
25513+out:
25514+ AuTraceErr(err);
25515+ return err;
25516+}
25517+
25518+static int au_mvd_args_exist(const unsigned char dmsg, struct au_mvd_args *a)
25519+{
25520+ int err;
25521+
25522+ err = 0;
25523+ if (!(a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
25524+ && a->bfound == a->mvd_bdst)
25525+ err = -EEXIST;
25526+ AuTraceErr(err);
25527+ return err;
25528+}
25529+
25530+static int au_mvd_args(const unsigned char dmsg, struct au_mvd_args *a)
25531+{
25532+ int err;
25533+ struct au_branch *br;
25534+
25535+ err = -EISDIR;
25536+ if (unlikely(S_ISDIR(a->inode->i_mode)))
25537+ goto out;
25538+
25539+ err = -EINVAL;
25540+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_UPPER))
25541+ a->mvd_bsrc = au_ibtop(a->inode);
25542+ else {
25543+ a->mvd_bsrc = au_br_index(a->sb, a->mvd_src_brid);
25544+ if (unlikely(a->mvd_bsrc < 0
25545+ || (a->mvd_bsrc < au_dbtop(a->dentry)
25546+ || au_dbbot(a->dentry) < a->mvd_bsrc
25547+ || !au_h_dptr(a->dentry, a->mvd_bsrc))
25548+ || (a->mvd_bsrc < au_ibtop(a->inode)
25549+ || au_ibbot(a->inode) < a->mvd_bsrc
25550+ || !au_h_iptr(a->inode, a->mvd_bsrc)))) {
25551+ a->mvd_errno = EAU_MVDOWN_NOUPPER;
25552+ AU_MVD_PR(dmsg, "no upper\n");
25553+ goto out;
25554+ }
25555+ }
25556+ if (unlikely(a->mvd_bsrc == au_sbbot(a->sb))) {
25557+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
25558+ AU_MVD_PR(dmsg, "on the bottom\n");
25559+ goto out;
25560+ }
25561+ a->mvd_h_src_inode = au_h_iptr(a->inode, a->mvd_bsrc);
25562+ br = au_sbr(a->sb, a->mvd_bsrc);
25563+ err = au_br_rdonly(br);
25564+ if (!(a->mvdown.flags & AUFS_MVDOWN_ROUPPER)) {
25565+ if (unlikely(err))
25566+ goto out;
25567+ } else if (!(vfsub_native_ro(a->mvd_h_src_inode)
25568+ || IS_APPEND(a->mvd_h_src_inode))) {
25569+ if (err)
25570+ a->mvdown.flags |= AUFS_MVDOWN_ROUPPER_R;
25571+ /* go on */
25572+ } else
25573+ goto out;
25574+
25575+ err = -EINVAL;
25576+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_LOWER)) {
25577+ a->mvd_bdst = find_lower_writable(a);
25578+ if (unlikely(a->mvd_bdst < 0)) {
25579+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
25580+ AU_MVD_PR(dmsg, "no writable lower branch\n");
25581+ goto out;
25582+ }
25583+ } else {
25584+ a->mvd_bdst = au_br_index(a->sb, a->mvd_dst_brid);
25585+ if (unlikely(a->mvd_bdst < 0
25586+ || au_sbbot(a->sb) < a->mvd_bdst)) {
25587+ a->mvd_errno = EAU_MVDOWN_NOLOWERBR;
25588+ AU_MVD_PR(dmsg, "no lower brid\n");
25589+ goto out;
25590+ }
25591+ }
25592+
25593+ err = au_mvd_args_busy(dmsg, a);
25594+ if (!err)
25595+ err = au_mvd_args_parent(dmsg, a);
25596+ if (!err)
25597+ err = au_mvd_args_intermediate(dmsg, a);
25598+ if (!err)
25599+ err = au_mvd_args_exist(dmsg, a);
25600+ if (!err)
25601+ AuDbg("b%d, b%d\n", a->mvd_bsrc, a->mvd_bdst);
25602+
25603+out:
25604+ AuTraceErr(err);
25605+ return err;
25606+}
25607+
25608+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg)
25609+{
25610+ int err, e;
25611+ unsigned char dmsg;
25612+ struct au_mvd_args *args;
25613+ struct inode *inode;
25614+
25615+ inode = d_inode(dentry);
25616+ err = -EPERM;
25617+ if (unlikely(!capable(CAP_SYS_ADMIN)))
25618+ goto out;
25619+
25620+ err = -ENOMEM;
25621+ args = kmalloc(sizeof(*args), GFP_NOFS);
25622+ if (unlikely(!args))
25623+ goto out;
25624+
25625+ err = copy_from_user(&args->mvdown, uarg, sizeof(args->mvdown));
25626+ if (!err)
25627+ /* VERIFY_WRITE */
25628+ err = !access_ok(uarg, sizeof(*uarg));
25629+ if (unlikely(err)) {
25630+ err = -EFAULT;
25631+ AuTraceErr(err);
25632+ goto out_free;
25633+ }
25634+ AuDbg("flags 0x%x\n", args->mvdown.flags);
25635+ args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R);
25636+ args->mvdown.au_errno = 0;
25637+ args->dentry = dentry;
25638+ args->inode = inode;
25639+ args->sb = dentry->d_sb;
25640+
25641+ err = -ENOENT;
25642+ dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG);
25643+ args->parent = dget_parent(dentry);
25644+ args->dir = d_inode(args->parent);
25645+ inode_lock_nested(args->dir, I_MUTEX_PARENT);
25646+ dput(args->parent);
25647+ if (unlikely(args->parent != dentry->d_parent)) {
25648+ AU_MVD_PR(dmsg, "parent dir is moved\n");
25649+ goto out_dir;
25650+ }
25651+
25652+ inode_lock_nested(inode, I_MUTEX_CHILD);
25653+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_NOPLMW);
25654+ if (unlikely(err))
25655+ goto out_inode;
25656+
25657+ di_write_lock_parent(args->parent);
25658+ err = au_mvd_args(dmsg, args);
25659+ if (unlikely(err))
25660+ goto out_parent;
25661+
25662+ err = au_do_mvdown(dmsg, args);
25663+ if (unlikely(err))
25664+ goto out_parent;
25665+
25666+ au_cpup_attr_timesizes(args->dir);
25667+ au_cpup_attr_timesizes(inode);
25668+ if (!(args->mvdown.flags & AUFS_MVDOWN_KUPPER))
25669+ au_cpup_igen(inode, au_h_iptr(inode, args->mvd_bdst));
25670+ /* au_digen_dec(dentry); */
25671+
25672+out_parent:
25673+ di_write_unlock(args->parent);
25674+ aufs_read_unlock(dentry, AuLock_DW);
25675+out_inode:
25676+ inode_unlock(inode);
25677+out_dir:
25678+ inode_unlock(args->dir);
25679+out_free:
25680+ e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown));
25681+ if (unlikely(e))
25682+ err = -EFAULT;
25683+ au_kfree_rcu(args);
25684+out:
25685+ AuTraceErr(err);
25686+ return err;
25687+}
25688diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
25689--- /usr/share/empty/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100
25690+++ linux/fs/aufs/opts.c 2020-01-27 10:57:18.175538316 +0100
25691@@ -0,0 +1,1880 @@
25692+// SPDX-License-Identifier: GPL-2.0
25693+/*
25694+ * Copyright (C) 2005-2020 Junjiro R. Okajima
25695+ *
25696+ * This program, aufs is free software; you can redistribute it and/or modify
25697+ * it under the terms of the GNU General Public License as published by
25698+ * the Free Software Foundation; either version 2 of the License, or
25699+ * (at your option) any later version.
25700+ *
25701+ * This program is distributed in the hope that it will be useful,
25702+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25703+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25704+ * GNU General Public License for more details.
25705+ *
25706+ * You should have received a copy of the GNU General Public License
25707+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
25708+ */
25709+
25710+/*
25711+ * mount options/flags
25712+ */
25713+
25714+#include <linux/namei.h>
25715+#include <linux/types.h> /* a distribution requires */
25716+#include <linux/parser.h>
25717+#include "aufs.h"
25718+
25719+/* ---------------------------------------------------------------------- */
25720+
25721+enum {
25722+ Opt_br,
25723+ Opt_add, Opt_del, Opt_mod, Opt_append, Opt_prepend,
25724+ Opt_idel, Opt_imod,
25725+ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash,
25726+ Opt_rdblk_def, Opt_rdhash_def,
25727+ Opt_xino, Opt_noxino,
25728+ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
25729+ Opt_trunc_xino_path, Opt_itrunc_xino,
25730+ Opt_trunc_xib, Opt_notrunc_xib,
25731+ Opt_shwh, Opt_noshwh,
25732+ Opt_plink, Opt_noplink, Opt_list_plink,
25733+ Opt_udba,
25734+ Opt_dio, Opt_nodio,
25735+ Opt_diropq_a, Opt_diropq_w,
25736+ Opt_warn_perm, Opt_nowarn_perm,
25737+ Opt_wbr_copyup, Opt_wbr_create,
25738+ Opt_fhsm_sec,
25739+ Opt_verbose, Opt_noverbose,
25740+ Opt_sum, Opt_nosum, Opt_wsum,
25741+ Opt_dirperm1, Opt_nodirperm1,
25742+ Opt_dirren, Opt_nodirren,
25743+ Opt_acl, Opt_noacl,
25744+ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
25745+};
25746+
25747+static match_table_t options = {
25748+ {Opt_br, "br=%s"},
25749+ {Opt_br, "br:%s"},
25750+
25751+ {Opt_add, "add=%d:%s"},
25752+ {Opt_add, "add:%d:%s"},
25753+ {Opt_add, "ins=%d:%s"},
25754+ {Opt_add, "ins:%d:%s"},
25755+ {Opt_append, "append=%s"},
25756+ {Opt_append, "append:%s"},
25757+ {Opt_prepend, "prepend=%s"},
25758+ {Opt_prepend, "prepend:%s"},
25759+
25760+ {Opt_del, "del=%s"},
25761+ {Opt_del, "del:%s"},
25762+ /* {Opt_idel, "idel:%d"}, */
25763+ {Opt_mod, "mod=%s"},
25764+ {Opt_mod, "mod:%s"},
25765+ /* {Opt_imod, "imod:%d:%s"}, */
25766+
25767+ {Opt_dirwh, "dirwh=%d"},
25768+
25769+ {Opt_xino, "xino=%s"},
25770+ {Opt_noxino, "noxino"},
25771+ {Opt_trunc_xino, "trunc_xino"},
25772+ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
25773+ {Opt_notrunc_xino, "notrunc_xino"},
25774+ {Opt_trunc_xino_path, "trunc_xino=%s"},
25775+ {Opt_itrunc_xino, "itrunc_xino=%d"},
25776+ /* {Opt_zxino, "zxino=%s"}, */
25777+ {Opt_trunc_xib, "trunc_xib"},
25778+ {Opt_notrunc_xib, "notrunc_xib"},
25779+
25780+#ifdef CONFIG_PROC_FS
25781+ {Opt_plink, "plink"},
25782+#else
25783+ {Opt_ignore_silent, "plink"},
25784+#endif
25785+
25786+ {Opt_noplink, "noplink"},
25787+
25788+#ifdef CONFIG_AUFS_DEBUG
25789+ {Opt_list_plink, "list_plink"},
25790+#endif
25791+
25792+ {Opt_udba, "udba=%s"},
25793+
25794+ {Opt_dio, "dio"},
25795+ {Opt_nodio, "nodio"},
25796+
25797+#ifdef CONFIG_AUFS_DIRREN
25798+ {Opt_dirren, "dirren"},
25799+ {Opt_nodirren, "nodirren"},
25800+#else
25801+ {Opt_ignore, "dirren"},
25802+ {Opt_ignore_silent, "nodirren"},
25803+#endif
25804+
25805+#ifdef CONFIG_AUFS_FHSM
25806+ {Opt_fhsm_sec, "fhsm_sec=%d"},
25807+#else
25808+ {Opt_ignore, "fhsm_sec=%d"},
25809+#endif
25810+
25811+ {Opt_diropq_a, "diropq=always"},
25812+ {Opt_diropq_a, "diropq=a"},
25813+ {Opt_diropq_w, "diropq=whiteouted"},
25814+ {Opt_diropq_w, "diropq=w"},
25815+
25816+ {Opt_warn_perm, "warn_perm"},
25817+ {Opt_nowarn_perm, "nowarn_perm"},
25818+
25819+ /* keep them temporary */
25820+ {Opt_ignore_silent, "nodlgt"},
25821+ {Opt_ignore, "clean_plink"},
25822+
25823+#ifdef CONFIG_AUFS_SHWH
25824+ {Opt_shwh, "shwh"},
25825+#endif
25826+ {Opt_noshwh, "noshwh"},
25827+
25828+ {Opt_dirperm1, "dirperm1"},
25829+ {Opt_nodirperm1, "nodirperm1"},
25830+
25831+ {Opt_verbose, "verbose"},
25832+ {Opt_verbose, "v"},
25833+ {Opt_noverbose, "noverbose"},
25834+ {Opt_noverbose, "quiet"},
25835+ {Opt_noverbose, "q"},
25836+ {Opt_noverbose, "silent"},
25837+
25838+ {Opt_sum, "sum"},
25839+ {Opt_nosum, "nosum"},
25840+ {Opt_wsum, "wsum"},
25841+
25842+ {Opt_rdcache, "rdcache=%d"},
25843+ {Opt_rdblk, "rdblk=%d"},
25844+ {Opt_rdblk_def, "rdblk=def"},
25845+ {Opt_rdhash, "rdhash=%d"},
25846+ {Opt_rdhash_def, "rdhash=def"},
25847+
25848+ {Opt_wbr_create, "create=%s"},
25849+ {Opt_wbr_create, "create_policy=%s"},
25850+ {Opt_wbr_copyup, "cpup=%s"},
25851+ {Opt_wbr_copyup, "copyup=%s"},
25852+ {Opt_wbr_copyup, "copyup_policy=%s"},
25853+
25854+ /* generic VFS flag */
25855+#ifdef CONFIG_FS_POSIX_ACL
25856+ {Opt_acl, "acl"},
25857+ {Opt_noacl, "noacl"},
25858+#else
25859+ {Opt_ignore, "acl"},
25860+ {Opt_ignore_silent, "noacl"},
25861+#endif
25862+
25863+ /* internal use for the scripts */
25864+ {Opt_ignore_silent, "si=%s"},
25865+
25866+ {Opt_br, "dirs=%s"},
25867+ {Opt_ignore, "debug=%d"},
25868+ {Opt_ignore, "delete=whiteout"},
25869+ {Opt_ignore, "delete=all"},
25870+ {Opt_ignore, "imap=%s"},
25871+
25872+ /* temporary workaround, due to old mount(8)? */
25873+ {Opt_ignore_silent, "relatime"},
25874+
25875+ {Opt_err, NULL}
25876+};
25877+
25878+/* ---------------------------------------------------------------------- */
25879+
25880+static const char *au_parser_pattern(int val, match_table_t tbl)
25881+{
25882+ struct match_token *p;
25883+
25884+ p = tbl;
25885+ while (p->pattern) {
25886+ if (p->token == val)
25887+ return p->pattern;
25888+ p++;
25889+ }
25890+ BUG();
25891+ return "??";
25892+}
25893+
25894+static const char *au_optstr(int *val, match_table_t tbl)
25895+{
25896+ struct match_token *p;
25897+ int v;
25898+
25899+ v = *val;
25900+ if (!v)
25901+ goto out;
25902+ p = tbl;
25903+ while (p->pattern) {
25904+ if (p->token
25905+ && (v & p->token) == p->token) {
25906+ *val &= ~p->token;
25907+ return p->pattern;
25908+ }
25909+ p++;
25910+ }
25911+
25912+out:
25913+ return NULL;
25914+}
25915+
25916+/* ---------------------------------------------------------------------- */
25917+
25918+static match_table_t brperm = {
25919+ {AuBrPerm_RO, AUFS_BRPERM_RO},
25920+ {AuBrPerm_RR, AUFS_BRPERM_RR},
25921+ {AuBrPerm_RW, AUFS_BRPERM_RW},
25922+ {0, NULL}
25923+};
25924+
25925+static match_table_t brattr = {
25926+ /* general */
25927+ {AuBrAttr_COO_REG, AUFS_BRATTR_COO_REG},
25928+ {AuBrAttr_COO_ALL, AUFS_BRATTR_COO_ALL},
25929+ /* 'unpin' attrib is meaningless since linux-3.18-rc1 */
25930+ {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN},
25931+#ifdef CONFIG_AUFS_FHSM
25932+ {AuBrAttr_FHSM, AUFS_BRATTR_FHSM},
25933+#endif
25934+#ifdef CONFIG_AUFS_XATTR
25935+ {AuBrAttr_ICEX, AUFS_BRATTR_ICEX},
25936+ {AuBrAttr_ICEX_SEC, AUFS_BRATTR_ICEX_SEC},
25937+ {AuBrAttr_ICEX_SYS, AUFS_BRATTR_ICEX_SYS},
25938+ {AuBrAttr_ICEX_TR, AUFS_BRATTR_ICEX_TR},
25939+ {AuBrAttr_ICEX_USR, AUFS_BRATTR_ICEX_USR},
25940+ {AuBrAttr_ICEX_OTH, AUFS_BRATTR_ICEX_OTH},
25941+#endif
25942+
25943+ /* ro/rr branch */
25944+ {AuBrRAttr_WH, AUFS_BRRATTR_WH},
25945+
25946+ /* rw branch */
25947+ {AuBrWAttr_MOO, AUFS_BRWATTR_MOO},
25948+ {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
25949+
25950+ {0, NULL}
25951+};
25952+
25953+static int br_attr_val(char *str, match_table_t table, substring_t args[])
25954+{
25955+ int attr, v;
25956+ char *p;
25957+
25958+ attr = 0;
25959+ do {
25960+ p = strchr(str, '+');
25961+ if (p)
25962+ *p = 0;
25963+ v = match_token(str, table, args);
25964+ if (v) {
25965+ if (v & AuBrAttr_CMOO_Mask)
25966+ attr &= ~AuBrAttr_CMOO_Mask;
25967+ attr |= v;
25968+ } else {
25969+ if (p)
25970+ *p = '+';
25971+ pr_warn("ignored branch attribute %s\n", str);
25972+ break;
25973+ }
25974+ if (p)
25975+ str = p + 1;
25976+ } while (p);
25977+
25978+ return attr;
25979+}
25980+
25981+static int au_do_optstr_br_attr(au_br_perm_str_t *str, int perm)
25982+{
25983+ int sz;
25984+ const char *p;
25985+ char *q;
25986+
25987+ q = str->a;
25988+ *q = 0;
25989+ p = au_optstr(&perm, brattr);
25990+ if (p) {
25991+ sz = strlen(p);
25992+ memcpy(q, p, sz + 1);
25993+ q += sz;
25994+ } else
25995+ goto out;
25996+
25997+ do {
25998+ p = au_optstr(&perm, brattr);
25999+ if (p) {
26000+ *q++ = '+';
26001+ sz = strlen(p);
26002+ memcpy(q, p, sz + 1);
26003+ q += sz;
26004+ }
26005+ } while (p);
26006+
26007+out:
26008+ return q - str->a;
26009+}
26010+
26011+static int noinline_for_stack br_perm_val(char *perm)
26012+{
26013+ int val, bad, sz;
26014+ char *p;
26015+ substring_t args[MAX_OPT_ARGS];
26016+ au_br_perm_str_t attr;
26017+
26018+ p = strchr(perm, '+');
26019+ if (p)
26020+ *p = 0;
26021+ val = match_token(perm, brperm, args);
26022+ if (!val) {
26023+ if (p)
26024+ *p = '+';
26025+ pr_warn("ignored branch permission %s\n", perm);
26026+ val = AuBrPerm_RO;
26027+ goto out;
26028+ }
26029+ if (!p)
26030+ goto out;
26031+
26032+ val |= br_attr_val(p + 1, brattr, args);
26033+
26034+ bad = 0;
26035+ switch (val & AuBrPerm_Mask) {
26036+ case AuBrPerm_RO:
26037+ case AuBrPerm_RR:
26038+ bad = val & AuBrWAttr_Mask;
26039+ val &= ~AuBrWAttr_Mask;
26040+ break;
26041+ case AuBrPerm_RW:
26042+ bad = val & AuBrRAttr_Mask;
26043+ val &= ~AuBrRAttr_Mask;
26044+ break;
26045+ }
26046+
26047+ /*
26048+ * 'unpin' attrib becomes meaningless since linux-3.18-rc1, but aufs
26049+ * does not treat it as an error, just warning.
26050+ * this is a tiny guard for the user operation.
26051+ */
26052+ if (val & AuBrAttr_UNPIN) {
26053+ bad |= AuBrAttr_UNPIN;
26054+ val &= ~AuBrAttr_UNPIN;
26055+ }
26056+
26057+ if (unlikely(bad)) {
26058+ sz = au_do_optstr_br_attr(&attr, bad);
26059+ AuDebugOn(!sz);
26060+ pr_warn("ignored branch attribute %s\n", attr.a);
26061+ }
26062+
26063+out:
26064+ return val;
26065+}
26066+
26067+void au_optstr_br_perm(au_br_perm_str_t *str, int perm)
26068+{
26069+ au_br_perm_str_t attr;
26070+ const char *p;
26071+ char *q;
26072+ int sz;
26073+
26074+ q = str->a;
26075+ p = au_optstr(&perm, brperm);
26076+ AuDebugOn(!p || !*p);
26077+ sz = strlen(p);
26078+ memcpy(q, p, sz + 1);
26079+ q += sz;
26080+
26081+ sz = au_do_optstr_br_attr(&attr, perm);
26082+ if (sz) {
26083+ *q++ = '+';
26084+ memcpy(q, attr.a, sz + 1);
26085+ }
26086+
26087+ AuDebugOn(strlen(str->a) >= sizeof(str->a));
26088+}
26089+
26090+/* ---------------------------------------------------------------------- */
26091+
26092+static match_table_t udbalevel = {
26093+ {AuOpt_UDBA_REVAL, "reval"},
26094+ {AuOpt_UDBA_NONE, "none"},
26095+#ifdef CONFIG_AUFS_HNOTIFY
26096+ {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
26097+#ifdef CONFIG_AUFS_HFSNOTIFY
26098+ {AuOpt_UDBA_HNOTIFY, "fsnotify"},
26099+#endif
26100+#endif
26101+ {-1, NULL}
26102+};
26103+
26104+static int noinline_for_stack udba_val(char *str)
26105+{
26106+ substring_t args[MAX_OPT_ARGS];
26107+
26108+ return match_token(str, udbalevel, args);
26109+}
26110+
26111+const char *au_optstr_udba(int udba)
26112+{
26113+ return au_parser_pattern(udba, udbalevel);
26114+}
26115+
26116+/* ---------------------------------------------------------------------- */
26117+
26118+static match_table_t au_wbr_create_policy = {
26119+ {AuWbrCreate_TDP, "tdp"},
26120+ {AuWbrCreate_TDP, "top-down-parent"},
26121+ {AuWbrCreate_RR, "rr"},
26122+ {AuWbrCreate_RR, "round-robin"},
26123+ {AuWbrCreate_MFS, "mfs"},
26124+ {AuWbrCreate_MFS, "most-free-space"},
26125+ {AuWbrCreate_MFSV, "mfs:%d"},
26126+ {AuWbrCreate_MFSV, "most-free-space:%d"},
26127+
26128+ /* top-down regardless the parent, and then mfs */
26129+ {AuWbrCreate_TDMFS, "tdmfs:%d"},
26130+ {AuWbrCreate_TDMFSV, "tdmfs:%d:%d"},
26131+
26132+ {AuWbrCreate_MFSRR, "mfsrr:%d"},
26133+ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
26134+ {AuWbrCreate_PMFS, "pmfs"},
26135+ {AuWbrCreate_PMFSV, "pmfs:%d"},
26136+ {AuWbrCreate_PMFSRR, "pmfsrr:%d"},
26137+ {AuWbrCreate_PMFSRRV, "pmfsrr:%d:%d"},
26138+
26139+ {-1, NULL}
26140+};
26141+
26142+static int au_wbr_mfs_wmark(substring_t *arg, char *str,
26143+ struct au_opt_wbr_create *create)
26144+{
26145+ int err;
26146+ unsigned long long ull;
26147+
26148+ err = 0;
26149+ if (!match_u64(arg, &ull))
26150+ create->mfsrr_watermark = ull;
26151+ else {
26152+ pr_err("bad integer in %s\n", str);
26153+ err = -EINVAL;
26154+ }
26155+
26156+ return err;
26157+}
26158+
26159+static int au_wbr_mfs_sec(substring_t *arg, char *str,
26160+ struct au_opt_wbr_create *create)
26161+{
26162+ int n, err;
26163+
26164+ err = 0;
26165+ if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
26166+ create->mfs_second = n;
26167+ else {
26168+ pr_err("bad integer in %s\n", str);
26169+ err = -EINVAL;
26170+ }
26171+
26172+ return err;
26173+}
26174+
26175+static int noinline_for_stack
26176+au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
26177+{
26178+ int err, e;
26179+ substring_t args[MAX_OPT_ARGS];
26180+
26181+ err = match_token(str, au_wbr_create_policy, args);
26182+ create->wbr_create = err;
26183+ switch (err) {
26184+ case AuWbrCreate_MFSRRV:
26185+ case AuWbrCreate_TDMFSV:
26186+ case AuWbrCreate_PMFSRRV:
26187+ e = au_wbr_mfs_wmark(&args[0], str, create);
26188+ if (!e)
26189+ e = au_wbr_mfs_sec(&args[1], str, create);
26190+ if (unlikely(e))
26191+ err = e;
26192+ break;
26193+ case AuWbrCreate_MFSRR:
26194+ case AuWbrCreate_TDMFS:
26195+ case AuWbrCreate_PMFSRR:
26196+ e = au_wbr_mfs_wmark(&args[0], str, create);
26197+ if (unlikely(e)) {
26198+ err = e;
26199+ break;
26200+ }
26201+ /*FALLTHROUGH*/
26202+ case AuWbrCreate_MFS:
26203+ case AuWbrCreate_PMFS:
26204+ create->mfs_second = AUFS_MFS_DEF_SEC;
26205+ break;
26206+ case AuWbrCreate_MFSV:
26207+ case AuWbrCreate_PMFSV:
26208+ e = au_wbr_mfs_sec(&args[0], str, create);
26209+ if (unlikely(e))
26210+ err = e;
26211+ break;
26212+ }
26213+
26214+ return err;
26215+}
26216+
26217+const char *au_optstr_wbr_create(int wbr_create)
26218+{
26219+ return au_parser_pattern(wbr_create, au_wbr_create_policy);
26220+}
26221+
26222+static match_table_t au_wbr_copyup_policy = {
26223+ {AuWbrCopyup_TDP, "tdp"},
26224+ {AuWbrCopyup_TDP, "top-down-parent"},
26225+ {AuWbrCopyup_BUP, "bup"},
26226+ {AuWbrCopyup_BUP, "bottom-up-parent"},
26227+ {AuWbrCopyup_BU, "bu"},
26228+ {AuWbrCopyup_BU, "bottom-up"},
26229+ {-1, NULL}
26230+};
26231+
26232+static int noinline_for_stack au_wbr_copyup_val(char *str)
26233+{
26234+ substring_t args[MAX_OPT_ARGS];
26235+
26236+ return match_token(str, au_wbr_copyup_policy, args);
26237+}
26238+
26239+const char *au_optstr_wbr_copyup(int wbr_copyup)
26240+{
26241+ return au_parser_pattern(wbr_copyup, au_wbr_copyup_policy);
26242+}
26243+
26244+/* ---------------------------------------------------------------------- */
26245+
26246+static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
26247+
26248+static void dump_opts(struct au_opts *opts)
26249+{
26250+#ifdef CONFIG_AUFS_DEBUG
26251+ /* reduce stack space */
26252+ union {
26253+ struct au_opt_add *add;
26254+ struct au_opt_del *del;
26255+ struct au_opt_mod *mod;
26256+ struct au_opt_xino *xino;
26257+ struct au_opt_xino_itrunc *xino_itrunc;
26258+ struct au_opt_wbr_create *create;
26259+ } u;
26260+ struct au_opt *opt;
26261+
26262+ opt = opts->opt;
26263+ while (opt->type != Opt_tail) {
26264+ switch (opt->type) {
26265+ case Opt_add:
26266+ u.add = &opt->add;
26267+ AuDbg("add {b%d, %s, 0x%x, %p}\n",
26268+ u.add->bindex, u.add->pathname, u.add->perm,
26269+ u.add->path.dentry);
26270+ break;
26271+ case Opt_del:
26272+ case Opt_idel:
26273+ u.del = &opt->del;
26274+ AuDbg("del {%s, %p}\n",
26275+ u.del->pathname, u.del->h_path.dentry);
26276+ break;
26277+ case Opt_mod:
26278+ case Opt_imod:
26279+ u.mod = &opt->mod;
26280+ AuDbg("mod {%s, 0x%x, %p}\n",
26281+ u.mod->path, u.mod->perm, u.mod->h_root);
26282+ break;
26283+ case Opt_append:
26284+ u.add = &opt->add;
26285+ AuDbg("append {b%d, %s, 0x%x, %p}\n",
26286+ u.add->bindex, u.add->pathname, u.add->perm,
26287+ u.add->path.dentry);
26288+ break;
26289+ case Opt_prepend:
26290+ u.add = &opt->add;
26291+ AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
26292+ u.add->bindex, u.add->pathname, u.add->perm,
26293+ u.add->path.dentry);
26294+ break;
26295+ case Opt_dirwh:
26296+ AuDbg("dirwh %d\n", opt->dirwh);
26297+ break;
26298+ case Opt_rdcache:
26299+ AuDbg("rdcache %d\n", opt->rdcache);
26300+ break;
26301+ case Opt_rdblk:
26302+ AuDbg("rdblk %u\n", opt->rdblk);
26303+ break;
26304+ case Opt_rdblk_def:
26305+ AuDbg("rdblk_def\n");
26306+ break;
26307+ case Opt_rdhash:
26308+ AuDbg("rdhash %u\n", opt->rdhash);
26309+ break;
26310+ case Opt_rdhash_def:
26311+ AuDbg("rdhash_def\n");
26312+ break;
26313+ case Opt_xino:
26314+ u.xino = &opt->xino;
26315+ AuDbg("xino {%s %pD}\n", u.xino->path, u.xino->file);
26316+ break;
26317+ case Opt_trunc_xino:
26318+ AuLabel(trunc_xino);
26319+ break;
26320+ case Opt_notrunc_xino:
26321+ AuLabel(notrunc_xino);
26322+ break;
26323+ case Opt_trunc_xino_path:
26324+ case Opt_itrunc_xino:
26325+ u.xino_itrunc = &opt->xino_itrunc;
26326+ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
26327+ break;
26328+ case Opt_noxino:
26329+ AuLabel(noxino);
26330+ break;
26331+ case Opt_trunc_xib:
26332+ AuLabel(trunc_xib);
26333+ break;
26334+ case Opt_notrunc_xib:
26335+ AuLabel(notrunc_xib);
26336+ break;
26337+ case Opt_shwh:
26338+ AuLabel(shwh);
26339+ break;
26340+ case Opt_noshwh:
26341+ AuLabel(noshwh);
26342+ break;
26343+ case Opt_dirperm1:
26344+ AuLabel(dirperm1);
26345+ break;
26346+ case Opt_nodirperm1:
26347+ AuLabel(nodirperm1);
26348+ break;
26349+ case Opt_plink:
26350+ AuLabel(plink);
26351+ break;
26352+ case Opt_noplink:
26353+ AuLabel(noplink);
26354+ break;
26355+ case Opt_list_plink:
26356+ AuLabel(list_plink);
26357+ break;
26358+ case Opt_udba:
26359+ AuDbg("udba %d, %s\n",
26360+ opt->udba, au_optstr_udba(opt->udba));
26361+ break;
26362+ case Opt_dio:
26363+ AuLabel(dio);
26364+ break;
26365+ case Opt_nodio:
26366+ AuLabel(nodio);
26367+ break;
26368+ case Opt_diropq_a:
26369+ AuLabel(diropq_a);
26370+ break;
26371+ case Opt_diropq_w:
26372+ AuLabel(diropq_w);
26373+ break;
26374+ case Opt_warn_perm:
26375+ AuLabel(warn_perm);
26376+ break;
26377+ case Opt_nowarn_perm:
26378+ AuLabel(nowarn_perm);
26379+ break;
26380+ case Opt_verbose:
26381+ AuLabel(verbose);
26382+ break;
26383+ case Opt_noverbose:
26384+ AuLabel(noverbose);
26385+ break;
26386+ case Opt_sum:
26387+ AuLabel(sum);
26388+ break;
26389+ case Opt_nosum:
26390+ AuLabel(nosum);
26391+ break;
26392+ case Opt_wsum:
26393+ AuLabel(wsum);
26394+ break;
26395+ case Opt_wbr_create:
26396+ u.create = &opt->wbr_create;
26397+ AuDbg("create %d, %s\n", u.create->wbr_create,
26398+ au_optstr_wbr_create(u.create->wbr_create));
26399+ switch (u.create->wbr_create) {
26400+ case AuWbrCreate_MFSV:
26401+ case AuWbrCreate_PMFSV:
26402+ AuDbg("%d sec\n", u.create->mfs_second);
26403+ break;
26404+ case AuWbrCreate_MFSRR:
26405+ case AuWbrCreate_TDMFS:
26406+ AuDbg("%llu watermark\n",
26407+ u.create->mfsrr_watermark);
26408+ break;
26409+ case AuWbrCreate_MFSRRV:
26410+ case AuWbrCreate_TDMFSV:
26411+ case AuWbrCreate_PMFSRRV:
26412+ AuDbg("%llu watermark, %d sec\n",
26413+ u.create->mfsrr_watermark,
26414+ u.create->mfs_second);
26415+ break;
26416+ }
26417+ break;
26418+ case Opt_wbr_copyup:
26419+ AuDbg("copyup %d, %s\n", opt->wbr_copyup,
26420+ au_optstr_wbr_copyup(opt->wbr_copyup));
26421+ break;
26422+ case Opt_fhsm_sec:
26423+ AuDbg("fhsm_sec %u\n", opt->fhsm_second);
26424+ break;
26425+ case Opt_dirren:
26426+ AuLabel(dirren);
26427+ break;
26428+ case Opt_nodirren:
26429+ AuLabel(nodirren);
26430+ break;
26431+ case Opt_acl:
26432+ AuLabel(acl);
26433+ break;
26434+ case Opt_noacl:
26435+ AuLabel(noacl);
26436+ break;
26437+ default:
26438+ BUG();
26439+ }
26440+ opt++;
26441+ }
26442+#endif
26443+}
26444+
26445+void au_opts_free(struct au_opts *opts)
26446+{
26447+ struct au_opt *opt;
26448+
26449+ opt = opts->opt;
26450+ while (opt->type != Opt_tail) {
26451+ switch (opt->type) {
26452+ case Opt_add:
26453+ case Opt_append:
26454+ case Opt_prepend:
26455+ path_put(&opt->add.path);
26456+ break;
26457+ case Opt_del:
26458+ case Opt_idel:
26459+ path_put(&opt->del.h_path);
26460+ break;
26461+ case Opt_mod:
26462+ case Opt_imod:
26463+ dput(opt->mod.h_root);
26464+ break;
26465+ case Opt_xino:
26466+ fput(opt->xino.file);
26467+ break;
26468+ }
26469+ opt++;
26470+ }
26471+}
26472+
26473+static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
26474+ aufs_bindex_t bindex)
26475+{
26476+ int err;
26477+ struct au_opt_add *add = &opt->add;
26478+ char *p;
26479+
26480+ add->bindex = bindex;
26481+ add->perm = AuBrPerm_RO;
26482+ add->pathname = opt_str;
26483+ p = strchr(opt_str, '=');
26484+ if (p) {
26485+ *p++ = 0;
26486+ if (*p)
26487+ add->perm = br_perm_val(p);
26488+ }
26489+
26490+ err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
26491+ if (!err) {
26492+ if (!p) {
26493+ add->perm = AuBrPerm_RO;
26494+ if (au_test_fs_rr(add->path.dentry->d_sb))
26495+ add->perm = AuBrPerm_RR;
26496+ else if (!bindex && !(sb_flags & SB_RDONLY))
26497+ add->perm = AuBrPerm_RW;
26498+ }
26499+ opt->type = Opt_add;
26500+ goto out;
26501+ }
26502+ pr_err("lookup failed %s (%d)\n", add->pathname, err);
26503+ err = -EINVAL;
26504+
26505+out:
26506+ return err;
26507+}
26508+
26509+static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
26510+{
26511+ int err;
26512+
26513+ del->pathname = args[0].from;
26514+ AuDbg("del path %s\n", del->pathname);
26515+
26516+ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
26517+ if (unlikely(err))
26518+ pr_err("lookup failed %s (%d)\n", del->pathname, err);
26519+
26520+ return err;
26521+}
26522+
26523+#if 0 /* reserved for future use */
26524+static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
26525+ struct au_opt_del *del, substring_t args[])
26526+{
26527+ int err;
26528+ struct dentry *root;
26529+
26530+ err = -EINVAL;
26531+ root = sb->s_root;
26532+ aufs_read_lock(root, AuLock_FLUSH);
26533+ if (bindex < 0 || au_sbbot(sb) < bindex) {
26534+ pr_err("out of bounds, %d\n", bindex);
26535+ goto out;
26536+ }
26537+
26538+ err = 0;
26539+ del->h_path.dentry = dget(au_h_dptr(root, bindex));
26540+ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
26541+
26542+out:
26543+ aufs_read_unlock(root, !AuLock_IR);
26544+ return err;
26545+}
26546+#endif
26547+
26548+static int noinline_for_stack
26549+au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
26550+{
26551+ int err;
26552+ struct path path;
26553+ char *p;
26554+
26555+ err = -EINVAL;
26556+ mod->path = args[0].from;
26557+ p = strchr(mod->path, '=');
26558+ if (unlikely(!p)) {
26559+ pr_err("no permission %s\n", args[0].from);
26560+ goto out;
26561+ }
26562+
26563+ *p++ = 0;
26564+ err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
26565+ if (unlikely(err)) {
26566+ pr_err("lookup failed %s (%d)\n", mod->path, err);
26567+ goto out;
26568+ }
26569+
26570+ mod->perm = br_perm_val(p);
26571+ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
26572+ mod->h_root = dget(path.dentry);
26573+ path_put(&path);
26574+
26575+out:
26576+ return err;
26577+}
26578+
26579+#if 0 /* reserved for future use */
26580+static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
26581+ struct au_opt_mod *mod, substring_t args[])
26582+{
26583+ int err;
26584+ struct dentry *root;
26585+
26586+ err = -EINVAL;
26587+ root = sb->s_root;
26588+ aufs_read_lock(root, AuLock_FLUSH);
26589+ if (bindex < 0 || au_sbbot(sb) < bindex) {
26590+ pr_err("out of bounds, %d\n", bindex);
26591+ goto out;
26592+ }
26593+
26594+ err = 0;
26595+ mod->perm = br_perm_val(args[1].from);
26596+ AuDbg("mod path %s, perm 0x%x, %s\n",
26597+ mod->path, mod->perm, args[1].from);
26598+ mod->h_root = dget(au_h_dptr(root, bindex));
26599+
26600+out:
26601+ aufs_read_unlock(root, !AuLock_IR);
26602+ return err;
26603+}
26604+#endif
26605+
26606+static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
26607+ substring_t args[])
26608+{
26609+ int err;
26610+ struct file *file;
26611+
26612+ file = au_xino_create(sb, args[0].from, /*silent*/0, /*wbrtop*/0);
26613+ err = PTR_ERR(file);
26614+ if (IS_ERR(file))
26615+ goto out;
26616+
26617+ err = -EINVAL;
26618+ if (unlikely(file->f_path.dentry->d_sb == sb)) {
26619+ fput(file);
26620+ pr_err("%s must be outside\n", args[0].from);
26621+ goto out;
26622+ }
26623+
26624+ err = 0;
26625+ xino->file = file;
26626+ xino->path = args[0].from;
26627+
26628+out:
26629+ return err;
26630+}
26631+
26632+static int noinline_for_stack
26633+au_opts_parse_xino_itrunc_path(struct super_block *sb,
26634+ struct au_opt_xino_itrunc *xino_itrunc,
26635+ substring_t args[])
26636+{
26637+ int err;
26638+ aufs_bindex_t bbot, bindex;
26639+ struct path path;
26640+ struct dentry *root;
26641+
26642+ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
26643+ if (unlikely(err)) {
26644+ pr_err("lookup failed %s (%d)\n", args[0].from, err);
26645+ goto out;
26646+ }
26647+
26648+ xino_itrunc->bindex = -1;
26649+ root = sb->s_root;
26650+ aufs_read_lock(root, AuLock_FLUSH);
26651+ bbot = au_sbbot(sb);
26652+ for (bindex = 0; bindex <= bbot; bindex++) {
26653+ if (au_h_dptr(root, bindex) == path.dentry) {
26654+ xino_itrunc->bindex = bindex;
26655+ break;
26656+ }
26657+ }
26658+ aufs_read_unlock(root, !AuLock_IR);
26659+ path_put(&path);
26660+
26661+ if (unlikely(xino_itrunc->bindex < 0)) {
26662+ pr_err("no such branch %s\n", args[0].from);
26663+ err = -EINVAL;
26664+ }
26665+
26666+out:
26667+ return err;
26668+}
26669+
26670+/* called without aufs lock */
26671+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
26672+{
26673+ int err, n, token;
26674+ aufs_bindex_t bindex;
26675+ unsigned char skipped;
26676+ struct dentry *root;
26677+ struct au_opt *opt, *opt_tail;
26678+ char *opt_str;
26679+ /* reduce the stack space */
26680+ union {
26681+ struct au_opt_xino_itrunc *xino_itrunc;
26682+ struct au_opt_wbr_create *create;
26683+ } u;
26684+ struct {
26685+ substring_t args[MAX_OPT_ARGS];
26686+ } *a;
26687+
26688+ err = -ENOMEM;
26689+ a = kmalloc(sizeof(*a), GFP_NOFS);
26690+ if (unlikely(!a))
26691+ goto out;
26692+
26693+ root = sb->s_root;
26694+ err = 0;
26695+ bindex = 0;
26696+ opt = opts->opt;
26697+ opt_tail = opt + opts->max_opt - 1;
26698+ opt->type = Opt_tail;
26699+ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
26700+ err = -EINVAL;
26701+ skipped = 0;
26702+ token = match_token(opt_str, options, a->args);
26703+ switch (token) {
26704+ case Opt_br:
26705+ err = 0;
26706+ while (!err && (opt_str = strsep(&a->args[0].from, ":"))
26707+ && *opt_str) {
26708+ err = opt_add(opt, opt_str, opts->sb_flags,
26709+ bindex++);
26710+ if (unlikely(!err && ++opt > opt_tail)) {
26711+ err = -E2BIG;
26712+ break;
26713+ }
26714+ opt->type = Opt_tail;
26715+ skipped = 1;
26716+ }
26717+ break;
26718+ case Opt_add:
26719+ if (unlikely(match_int(&a->args[0], &n))) {
26720+ pr_err("bad integer in %s\n", opt_str);
26721+ break;
26722+ }
26723+ bindex = n;
26724+ err = opt_add(opt, a->args[1].from, opts->sb_flags,
26725+ bindex);
26726+ if (!err)
26727+ opt->type = token;
26728+ break;
26729+ case Opt_append:
26730+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
26731+ /*dummy bindex*/1);
26732+ if (!err)
26733+ opt->type = token;
26734+ break;
26735+ case Opt_prepend:
26736+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
26737+ /*bindex*/0);
26738+ if (!err)
26739+ opt->type = token;
26740+ break;
26741+ case Opt_del:
26742+ err = au_opts_parse_del(&opt->del, a->args);
26743+ if (!err)
26744+ opt->type = token;
26745+ break;
26746+#if 0 /* reserved for future use */
26747+ case Opt_idel:
26748+ del->pathname = "(indexed)";
26749+ if (unlikely(match_int(&args[0], &n))) {
26750+ pr_err("bad integer in %s\n", opt_str);
26751+ break;
26752+ }
26753+ err = au_opts_parse_idel(sb, n, &opt->del, a->args);
26754+ if (!err)
26755+ opt->type = token;
26756+ break;
26757+#endif
26758+ case Opt_mod:
26759+ err = au_opts_parse_mod(&opt->mod, a->args);
26760+ if (!err)
26761+ opt->type = token;
26762+ break;
26763+#ifdef IMOD /* reserved for future use */
26764+ case Opt_imod:
26765+ u.mod->path = "(indexed)";
26766+ if (unlikely(match_int(&a->args[0], &n))) {
26767+ pr_err("bad integer in %s\n", opt_str);
26768+ break;
26769+ }
26770+ err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
26771+ if (!err)
26772+ opt->type = token;
26773+ break;
26774+#endif
26775+ case Opt_xino:
26776+ err = au_opts_parse_xino(sb, &opt->xino, a->args);
26777+ if (!err)
26778+ opt->type = token;
26779+ break;
26780+
26781+ case Opt_trunc_xino_path:
26782+ err = au_opts_parse_xino_itrunc_path
26783+ (sb, &opt->xino_itrunc, a->args);
26784+ if (!err)
26785+ opt->type = token;
26786+ break;
26787+
26788+ case Opt_itrunc_xino:
26789+ u.xino_itrunc = &opt->xino_itrunc;
26790+ if (unlikely(match_int(&a->args[0], &n))) {
26791+ pr_err("bad integer in %s\n", opt_str);
26792+ break;
26793+ }
26794+ u.xino_itrunc->bindex = n;
26795+ aufs_read_lock(root, AuLock_FLUSH);
26796+ if (n < 0 || au_sbbot(sb) < n) {
26797+ pr_err("out of bounds, %d\n", n);
26798+ aufs_read_unlock(root, !AuLock_IR);
26799+ break;
26800+ }
26801+ aufs_read_unlock(root, !AuLock_IR);
26802+ err = 0;
26803+ opt->type = token;
26804+ break;
26805+
26806+ case Opt_dirwh:
26807+ if (unlikely(match_int(&a->args[0], &opt->dirwh)))
26808+ break;
26809+ err = 0;
26810+ opt->type = token;
26811+ break;
26812+
26813+ case Opt_rdcache:
26814+ if (unlikely(match_int(&a->args[0], &n))) {
26815+ pr_err("bad integer in %s\n", opt_str);
26816+ break;
26817+ }
26818+ if (unlikely(n > AUFS_RDCACHE_MAX)) {
26819+ pr_err("rdcache must be smaller than %d\n",
26820+ AUFS_RDCACHE_MAX);
26821+ break;
26822+ }
26823+ opt->rdcache = n;
26824+ err = 0;
26825+ opt->type = token;
26826+ break;
26827+ case Opt_rdblk:
26828+ if (unlikely(match_int(&a->args[0], &n)
26829+ || n < 0
26830+ || n > KMALLOC_MAX_SIZE)) {
26831+ pr_err("bad integer in %s\n", opt_str);
26832+ break;
26833+ }
26834+ if (unlikely(n && n < NAME_MAX)) {
26835+ pr_err("rdblk must be larger than %d\n",
26836+ NAME_MAX);
26837+ break;
26838+ }
26839+ opt->rdblk = n;
26840+ err = 0;
26841+ opt->type = token;
26842+ break;
26843+ case Opt_rdhash:
26844+ if (unlikely(match_int(&a->args[0], &n)
26845+ || n < 0
26846+ || n * sizeof(struct hlist_head)
26847+ > KMALLOC_MAX_SIZE)) {
26848+ pr_err("bad integer in %s\n", opt_str);
26849+ break;
26850+ }
26851+ opt->rdhash = n;
26852+ err = 0;
26853+ opt->type = token;
26854+ break;
26855+
26856+ case Opt_trunc_xino:
26857+ case Opt_notrunc_xino:
26858+ case Opt_noxino:
26859+ case Opt_trunc_xib:
26860+ case Opt_notrunc_xib:
26861+ case Opt_shwh:
26862+ case Opt_noshwh:
26863+ case Opt_dirperm1:
26864+ case Opt_nodirperm1:
26865+ case Opt_plink:
26866+ case Opt_noplink:
26867+ case Opt_list_plink:
26868+ case Opt_dio:
26869+ case Opt_nodio:
26870+ case Opt_diropq_a:
26871+ case Opt_diropq_w:
26872+ case Opt_warn_perm:
26873+ case Opt_nowarn_perm:
26874+ case Opt_verbose:
26875+ case Opt_noverbose:
26876+ case Opt_sum:
26877+ case Opt_nosum:
26878+ case Opt_wsum:
26879+ case Opt_rdblk_def:
26880+ case Opt_rdhash_def:
26881+ case Opt_dirren:
26882+ case Opt_nodirren:
26883+ case Opt_acl:
26884+ case Opt_noacl:
26885+ err = 0;
26886+ opt->type = token;
26887+ break;
26888+
26889+ case Opt_udba:
26890+ opt->udba = udba_val(a->args[0].from);
26891+ if (opt->udba >= 0) {
26892+ err = 0;
26893+ opt->type = token;
26894+ } else
26895+ pr_err("wrong value, %s\n", opt_str);
26896+ break;
26897+
26898+ case Opt_wbr_create:
26899+ u.create = &opt->wbr_create;
26900+ u.create->wbr_create
26901+ = au_wbr_create_val(a->args[0].from, u.create);
26902+ if (u.create->wbr_create >= 0) {
26903+ err = 0;
26904+ opt->type = token;
26905+ } else
26906+ pr_err("wrong value, %s\n", opt_str);
26907+ break;
26908+ case Opt_wbr_copyup:
26909+ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
26910+ if (opt->wbr_copyup >= 0) {
26911+ err = 0;
26912+ opt->type = token;
26913+ } else
26914+ pr_err("wrong value, %s\n", opt_str);
26915+ break;
26916+
26917+ case Opt_fhsm_sec:
26918+ if (unlikely(match_int(&a->args[0], &n)
26919+ || n < 0)) {
26920+ pr_err("bad integer in %s\n", opt_str);
26921+ break;
26922+ }
26923+ if (sysaufs_brs) {
26924+ opt->fhsm_second = n;
26925+ opt->type = token;
26926+ } else
26927+ pr_warn("ignored %s\n", opt_str);
26928+ err = 0;
26929+ break;
26930+
26931+ case Opt_ignore:
26932+ pr_warn("ignored %s\n", opt_str);
26933+ /*FALLTHROUGH*/
26934+ case Opt_ignore_silent:
26935+ skipped = 1;
26936+ err = 0;
26937+ break;
26938+ case Opt_err:
26939+ pr_err("unknown option %s\n", opt_str);
26940+ break;
26941+ }
26942+
26943+ if (!err && !skipped) {
26944+ if (unlikely(++opt > opt_tail)) {
26945+ err = -E2BIG;
26946+ opt--;
26947+ opt->type = Opt_tail;
26948+ break;
26949+ }
26950+ opt->type = Opt_tail;
26951+ }
26952+ }
26953+
26954+ au_kfree_rcu(a);
26955+ dump_opts(opts);
26956+ if (unlikely(err))
26957+ au_opts_free(opts);
26958+
26959+out:
26960+ return err;
26961+}
26962+
26963+static int au_opt_wbr_create(struct super_block *sb,
26964+ struct au_opt_wbr_create *create)
26965+{
26966+ int err;
26967+ struct au_sbinfo *sbinfo;
26968+
26969+ SiMustWriteLock(sb);
26970+
26971+ err = 1; /* handled */
26972+ sbinfo = au_sbi(sb);
26973+ if (sbinfo->si_wbr_create_ops->fin) {
26974+ err = sbinfo->si_wbr_create_ops->fin(sb);
26975+ if (!err)
26976+ err = 1;
26977+ }
26978+
26979+ sbinfo->si_wbr_create = create->wbr_create;
26980+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
26981+ switch (create->wbr_create) {
26982+ case AuWbrCreate_MFSRRV:
26983+ case AuWbrCreate_MFSRR:
26984+ case AuWbrCreate_TDMFS:
26985+ case AuWbrCreate_TDMFSV:
26986+ case AuWbrCreate_PMFSRR:
26987+ case AuWbrCreate_PMFSRRV:
26988+ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
26989+ /*FALLTHROUGH*/
26990+ case AuWbrCreate_MFS:
26991+ case AuWbrCreate_MFSV:
26992+ case AuWbrCreate_PMFS:
26993+ case AuWbrCreate_PMFSV:
26994+ sbinfo->si_wbr_mfs.mfs_expire
26995+ = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
26996+ break;
26997+ }
26998+
26999+ if (sbinfo->si_wbr_create_ops->init)
27000+ sbinfo->si_wbr_create_ops->init(sb); /* ignore */
27001+
27002+ return err;
27003+}
27004+
27005+/*
27006+ * returns,
27007+ * plus: processed without an error
27008+ * zero: unprocessed
27009+ */
27010+static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
27011+ struct au_opts *opts)
27012+{
27013+ int err;
27014+ struct au_sbinfo *sbinfo;
27015+
27016+ SiMustWriteLock(sb);
27017+
27018+ err = 1; /* handled */
27019+ sbinfo = au_sbi(sb);
27020+ switch (opt->type) {
27021+ case Opt_udba:
27022+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
27023+ sbinfo->si_mntflags |= opt->udba;
27024+ opts->given_udba |= opt->udba;
27025+ break;
27026+
27027+ case Opt_plink:
27028+ au_opt_set(sbinfo->si_mntflags, PLINK);
27029+ break;
27030+ case Opt_noplink:
27031+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
27032+ au_plink_put(sb, /*verbose*/1);
27033+ au_opt_clr(sbinfo->si_mntflags, PLINK);
27034+ break;
27035+ case Opt_list_plink:
27036+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
27037+ au_plink_list(sb);
27038+ break;
27039+
27040+ case Opt_dio:
27041+ au_opt_set(sbinfo->si_mntflags, DIO);
27042+ au_fset_opts(opts->flags, REFRESH_DYAOP);
27043+ break;
27044+ case Opt_nodio:
27045+ au_opt_clr(sbinfo->si_mntflags, DIO);
27046+ au_fset_opts(opts->flags, REFRESH_DYAOP);
27047+ break;
27048+
27049+ case Opt_fhsm_sec:
27050+ au_fhsm_set(sbinfo, opt->fhsm_second);
27051+ break;
27052+
27053+ case Opt_diropq_a:
27054+ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
27055+ break;
27056+ case Opt_diropq_w:
27057+ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
27058+ break;
27059+
27060+ case Opt_warn_perm:
27061+ au_opt_set(sbinfo->si_mntflags, WARN_PERM);
27062+ break;
27063+ case Opt_nowarn_perm:
27064+ au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
27065+ break;
27066+
27067+ case Opt_verbose:
27068+ au_opt_set(sbinfo->si_mntflags, VERBOSE);
27069+ break;
27070+ case Opt_noverbose:
27071+ au_opt_clr(sbinfo->si_mntflags, VERBOSE);
27072+ break;
27073+
27074+ case Opt_sum:
27075+ au_opt_set(sbinfo->si_mntflags, SUM);
27076+ break;
27077+ case Opt_wsum:
27078+ au_opt_clr(sbinfo->si_mntflags, SUM);
27079+ au_opt_set(sbinfo->si_mntflags, SUM_W);
27080+ break;
27081+ case Opt_nosum:
27082+ au_opt_clr(sbinfo->si_mntflags, SUM);
27083+ au_opt_clr(sbinfo->si_mntflags, SUM_W);
27084+ break;
27085+
27086+ case Opt_wbr_create:
27087+ err = au_opt_wbr_create(sb, &opt->wbr_create);
27088+ break;
27089+ case Opt_wbr_copyup:
27090+ sbinfo->si_wbr_copyup = opt->wbr_copyup;
27091+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
27092+ break;
27093+
27094+ case Opt_dirwh:
27095+ sbinfo->si_dirwh = opt->dirwh;
27096+ break;
27097+
27098+ case Opt_rdcache:
27099+ sbinfo->si_rdcache
27100+ = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
27101+ break;
27102+ case Opt_rdblk:
27103+ sbinfo->si_rdblk = opt->rdblk;
27104+ break;
27105+ case Opt_rdblk_def:
27106+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
27107+ break;
27108+ case Opt_rdhash:
27109+ sbinfo->si_rdhash = opt->rdhash;
27110+ break;
27111+ case Opt_rdhash_def:
27112+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
27113+ break;
27114+
27115+ case Opt_shwh:
27116+ au_opt_set(sbinfo->si_mntflags, SHWH);
27117+ break;
27118+ case Opt_noshwh:
27119+ au_opt_clr(sbinfo->si_mntflags, SHWH);
27120+ break;
27121+
27122+ case Opt_dirperm1:
27123+ au_opt_set(sbinfo->si_mntflags, DIRPERM1);
27124+ break;
27125+ case Opt_nodirperm1:
27126+ au_opt_clr(sbinfo->si_mntflags, DIRPERM1);
27127+ break;
27128+
27129+ case Opt_trunc_xino:
27130+ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
27131+ break;
27132+ case Opt_notrunc_xino:
27133+ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
27134+ break;
27135+
27136+ case Opt_trunc_xino_path:
27137+ case Opt_itrunc_xino:
27138+ err = au_xino_trunc(sb, opt->xino_itrunc.bindex,
27139+ /*idx_begin*/0);
27140+ if (!err)
27141+ err = 1;
27142+ break;
27143+
27144+ case Opt_trunc_xib:
27145+ au_fset_opts(opts->flags, TRUNC_XIB);
27146+ break;
27147+ case Opt_notrunc_xib:
27148+ au_fclr_opts(opts->flags, TRUNC_XIB);
27149+ break;
27150+
27151+ case Opt_dirren:
27152+ err = 1;
27153+ if (!au_opt_test(sbinfo->si_mntflags, DIRREN)) {
27154+ err = au_dr_opt_set(sb);
27155+ if (!err)
27156+ err = 1;
27157+ }
27158+ if (err == 1)
27159+ au_opt_set(sbinfo->si_mntflags, DIRREN);
27160+ break;
27161+ case Opt_nodirren:
27162+ err = 1;
27163+ if (au_opt_test(sbinfo->si_mntflags, DIRREN)) {
27164+ err = au_dr_opt_clr(sb, au_ftest_opts(opts->flags,
27165+ DR_FLUSHED));
27166+ if (!err)
27167+ err = 1;
27168+ }
27169+ if (err == 1)
27170+ au_opt_clr(sbinfo->si_mntflags, DIRREN);
27171+ break;
27172+
27173+ case Opt_acl:
27174+ sb->s_flags |= SB_POSIXACL;
27175+ break;
27176+ case Opt_noacl:
27177+ sb->s_flags &= ~SB_POSIXACL;
27178+ break;
27179+
27180+ default:
27181+ err = 0;
27182+ break;
27183+ }
27184+
27185+ return err;
27186+}
27187+
27188+/*
27189+ * returns tri-state.
27190+ * plus: processed without an error
27191+ * zero: unprocessed
27192+ * minus: error
27193+ */
27194+static int au_opt_br(struct super_block *sb, struct au_opt *opt,
27195+ struct au_opts *opts)
27196+{
27197+ int err, do_refresh;
27198+
27199+ err = 0;
27200+ switch (opt->type) {
27201+ case Opt_append:
27202+ opt->add.bindex = au_sbbot(sb) + 1;
27203+ if (opt->add.bindex < 0)
27204+ opt->add.bindex = 0;
27205+ goto add;
27206+ /* Always goto add, not fallthrough */
27207+ case Opt_prepend:
27208+ opt->add.bindex = 0;
27209+ /* fallthrough */
27210+ add: /* indented label */
27211+ case Opt_add:
27212+ err = au_br_add(sb, &opt->add,
27213+ au_ftest_opts(opts->flags, REMOUNT));
27214+ if (!err) {
27215+ err = 1;
27216+ au_fset_opts(opts->flags, REFRESH);
27217+ }
27218+ break;
27219+
27220+ case Opt_del:
27221+ case Opt_idel:
27222+ err = au_br_del(sb, &opt->del,
27223+ au_ftest_opts(opts->flags, REMOUNT));
27224+ if (!err) {
27225+ err = 1;
27226+ au_fset_opts(opts->flags, TRUNC_XIB);
27227+ au_fset_opts(opts->flags, REFRESH);
27228+ }
27229+ break;
27230+
27231+ case Opt_mod:
27232+ case Opt_imod:
27233+ err = au_br_mod(sb, &opt->mod,
27234+ au_ftest_opts(opts->flags, REMOUNT),
27235+ &do_refresh);
27236+ if (!err) {
27237+ err = 1;
27238+ if (do_refresh)
27239+ au_fset_opts(opts->flags, REFRESH);
27240+ }
27241+ break;
27242+ }
27243+ return err;
27244+}
27245+
27246+static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
27247+ struct au_opt_xino **opt_xino,
27248+ struct au_opts *opts)
27249+{
27250+ int err;
27251+
27252+ err = 0;
27253+ switch (opt->type) {
27254+ case Opt_xino:
27255+ err = au_xino_set(sb, &opt->xino,
27256+ !!au_ftest_opts(opts->flags, REMOUNT));
27257+ if (unlikely(err))
27258+ break;
27259+
27260+ *opt_xino = &opt->xino;
27261+ break;
27262+
27263+ case Opt_noxino:
27264+ au_xino_clr(sb);
27265+ *opt_xino = (void *)-1;
27266+ break;
27267+ }
27268+
27269+ return err;
27270+}
27271+
27272+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
27273+ unsigned int pending)
27274+{
27275+ int err, fhsm;
27276+ aufs_bindex_t bindex, bbot;
27277+ unsigned char do_plink, skip, do_free, can_no_dreval;
27278+ struct au_branch *br;
27279+ struct au_wbr *wbr;
27280+ struct dentry *root, *dentry;
27281+ struct inode *dir, *h_dir;
27282+ struct au_sbinfo *sbinfo;
27283+ struct au_hinode *hdir;
27284+
27285+ SiMustAnyLock(sb);
27286+
27287+ sbinfo = au_sbi(sb);
27288+ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
27289+
27290+ if (!(sb_flags & SB_RDONLY)) {
27291+ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
27292+ pr_warn("first branch should be rw\n");
27293+ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
27294+ pr_warn_once("shwh should be used with ro\n");
27295+ }
27296+
27297+ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
27298+ && !au_opt_test(sbinfo->si_mntflags, XINO))
27299+ pr_warn_once("udba=*notify requires xino\n");
27300+
27301+ if (au_opt_test(sbinfo->si_mntflags, DIRPERM1))
27302+ pr_warn_once("dirperm1 breaks the protection"
27303+ " by the permission bits on the lower branch\n");
27304+
27305+ err = 0;
27306+ fhsm = 0;
27307+ root = sb->s_root;
27308+ dir = d_inode(root);
27309+ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
27310+ can_no_dreval = !!au_opt_test((sbinfo->si_mntflags | pending),
27311+ UDBA_NONE);
27312+ bbot = au_sbbot(sb);
27313+ for (bindex = 0; !err && bindex <= bbot; bindex++) {
27314+ skip = 0;
27315+ h_dir = au_h_iptr(dir, bindex);
27316+ br = au_sbr(sb, bindex);
27317+
27318+ if ((br->br_perm & AuBrAttr_ICEX)
27319+ && !h_dir->i_op->listxattr)
27320+ br->br_perm &= ~AuBrAttr_ICEX;
27321+#if 0 /* untested */
27322+ if ((br->br_perm & AuBrAttr_ICEX_SEC)
27323+ && (au_br_sb(br)->s_flags & SB_NOSEC))
27324+ br->br_perm &= ~AuBrAttr_ICEX_SEC;
27325+#endif
27326+
27327+ do_free = 0;
27328+ wbr = br->br_wbr;
27329+ if (wbr)
27330+ wbr_wh_read_lock(wbr);
27331+
27332+ if (!au_br_writable(br->br_perm)) {
27333+ do_free = !!wbr;
27334+ skip = (!wbr
27335+ || (!wbr->wbr_whbase
27336+ && !wbr->wbr_plink
27337+ && !wbr->wbr_orph));
27338+ } else if (!au_br_wh_linkable(br->br_perm)) {
27339+ /* skip = (!br->br_whbase && !br->br_orph); */
27340+ skip = (!wbr || !wbr->wbr_whbase);
27341+ if (skip && wbr) {
27342+ if (do_plink)
27343+ skip = !!wbr->wbr_plink;
27344+ else
27345+ skip = !wbr->wbr_plink;
27346+ }
27347+ } else {
27348+ /* skip = (br->br_whbase && br->br_ohph); */
27349+ skip = (wbr && wbr->wbr_whbase);
27350+ if (skip) {
27351+ if (do_plink)
27352+ skip = !!wbr->wbr_plink;
27353+ else
27354+ skip = !wbr->wbr_plink;
27355+ }
27356+ }
27357+ if (wbr)
27358+ wbr_wh_read_unlock(wbr);
27359+
27360+ if (can_no_dreval) {
27361+ dentry = br->br_path.dentry;
27362+ spin_lock(&dentry->d_lock);
27363+ if (dentry->d_flags &
27364+ (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE))
27365+ can_no_dreval = 0;
27366+ spin_unlock(&dentry->d_lock);
27367+ }
27368+
27369+ if (au_br_fhsm(br->br_perm)) {
27370+ fhsm++;
27371+ AuDebugOn(!br->br_fhsm);
27372+ }
27373+
27374+ if (skip)
27375+ continue;
27376+
27377+ hdir = au_hi(dir, bindex);
27378+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
27379+ if (wbr)
27380+ wbr_wh_write_lock(wbr);
27381+ err = au_wh_init(br, sb);
27382+ if (wbr)
27383+ wbr_wh_write_unlock(wbr);
27384+ au_hn_inode_unlock(hdir);
27385+
27386+ if (!err && do_free) {
27387+ au_kfree_rcu(wbr);
27388+ br->br_wbr = NULL;
27389+ }
27390+ }
27391+
27392+ if (can_no_dreval)
27393+ au_fset_si(sbinfo, NO_DREVAL);
27394+ else
27395+ au_fclr_si(sbinfo, NO_DREVAL);
27396+
27397+ if (fhsm >= 2) {
27398+ au_fset_si(sbinfo, FHSM);
27399+ for (bindex = bbot; bindex >= 0; bindex--) {
27400+ br = au_sbr(sb, bindex);
27401+ if (au_br_fhsm(br->br_perm)) {
27402+ au_fhsm_set_bottom(sb, bindex);
27403+ break;
27404+ }
27405+ }
27406+ } else {
27407+ au_fclr_si(sbinfo, FHSM);
27408+ au_fhsm_set_bottom(sb, -1);
27409+ }
27410+
27411+ return err;
27412+}
27413+
27414+int au_opts_mount(struct super_block *sb, struct au_opts *opts)
27415+{
27416+ int err;
27417+ unsigned int tmp;
27418+ aufs_bindex_t bindex, bbot;
27419+ struct au_opt *opt;
27420+ struct au_opt_xino *opt_xino, xino;
27421+ struct au_sbinfo *sbinfo;
27422+ struct au_branch *br;
27423+ struct inode *dir;
27424+
27425+ SiMustWriteLock(sb);
27426+
27427+ err = 0;
27428+ opt_xino = NULL;
27429+ opt = opts->opt;
27430+ while (err >= 0 && opt->type != Opt_tail)
27431+ err = au_opt_simple(sb, opt++, opts);
27432+ if (err > 0)
27433+ err = 0;
27434+ else if (unlikely(err < 0))
27435+ goto out;
27436+
27437+ /* disable xino and udba temporary */
27438+ sbinfo = au_sbi(sb);
27439+ tmp = sbinfo->si_mntflags;
27440+ au_opt_clr(sbinfo->si_mntflags, XINO);
27441+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
27442+
27443+ opt = opts->opt;
27444+ while (err >= 0 && opt->type != Opt_tail)
27445+ err = au_opt_br(sb, opt++, opts);
27446+ if (err > 0)
27447+ err = 0;
27448+ else if (unlikely(err < 0))
27449+ goto out;
27450+
27451+ bbot = au_sbbot(sb);
27452+ if (unlikely(bbot < 0)) {
27453+ err = -EINVAL;
27454+ pr_err("no branches\n");
27455+ goto out;
27456+ }
27457+
27458+ if (au_opt_test(tmp, XINO))
27459+ au_opt_set(sbinfo->si_mntflags, XINO);
27460+ opt = opts->opt;
27461+ while (!err && opt->type != Opt_tail)
27462+ err = au_opt_xino(sb, opt++, &opt_xino, opts);
27463+ if (unlikely(err))
27464+ goto out;
27465+
27466+ err = au_opts_verify(sb, sb->s_flags, tmp);
27467+ if (unlikely(err))
27468+ goto out;
27469+
27470+ /* restore xino */
27471+ if (au_opt_test(tmp, XINO) && !opt_xino) {
27472+ xino.file = au_xino_def(sb);
27473+ err = PTR_ERR(xino.file);
27474+ if (IS_ERR(xino.file))
27475+ goto out;
27476+
27477+ err = au_xino_set(sb, &xino, /*remount*/0);
27478+ fput(xino.file);
27479+ if (unlikely(err))
27480+ goto out;
27481+ }
27482+
27483+ /* restore udba */
27484+ tmp &= AuOptMask_UDBA;
27485+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
27486+ sbinfo->si_mntflags |= tmp;
27487+ bbot = au_sbbot(sb);
27488+ for (bindex = 0; bindex <= bbot; bindex++) {
27489+ br = au_sbr(sb, bindex);
27490+ err = au_hnotify_reset_br(tmp, br, br->br_perm);
27491+ if (unlikely(err))
27492+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
27493+ bindex, err);
27494+ /* go on even if err */
27495+ }
27496+ if (au_opt_test(tmp, UDBA_HNOTIFY)) {
27497+ dir = d_inode(sb->s_root);
27498+ au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
27499+ }
27500+
27501+out:
27502+ return err;
27503+}
27504+
27505+int au_opts_remount(struct super_block *sb, struct au_opts *opts)
27506+{
27507+ int err, rerr;
27508+ unsigned char no_dreval;
27509+ struct inode *dir;
27510+ struct au_opt_xino *opt_xino;
27511+ struct au_opt *opt;
27512+ struct au_sbinfo *sbinfo;
27513+
27514+ SiMustWriteLock(sb);
27515+
27516+ err = au_dr_opt_flush(sb);
27517+ if (unlikely(err))
27518+ goto out;
27519+ au_fset_opts(opts->flags, DR_FLUSHED);
27520+
27521+ dir = d_inode(sb->s_root);
27522+ sbinfo = au_sbi(sb);
27523+ opt_xino = NULL;
27524+ opt = opts->opt;
27525+ while (err >= 0 && opt->type != Opt_tail) {
27526+ err = au_opt_simple(sb, opt, opts);
27527+ if (!err)
27528+ err = au_opt_br(sb, opt, opts);
27529+ if (!err)
27530+ err = au_opt_xino(sb, opt, &opt_xino, opts);
27531+ opt++;
27532+ }
27533+ if (err > 0)
27534+ err = 0;
27535+ AuTraceErr(err);
27536+ /* go on even err */
27537+
27538+ no_dreval = !!au_ftest_si(sbinfo, NO_DREVAL);
27539+ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
27540+ if (unlikely(rerr && !err))
27541+ err = rerr;
27542+
27543+ if (no_dreval != !!au_ftest_si(sbinfo, NO_DREVAL))
27544+ au_fset_opts(opts->flags, REFRESH_IDOP);
27545+
27546+ if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
27547+ rerr = au_xib_trunc(sb);
27548+ if (unlikely(rerr && !err))
27549+ err = rerr;
27550+ }
27551+
27552+ /* will be handled by the caller */
27553+ if (!au_ftest_opts(opts->flags, REFRESH)
27554+ && (opts->given_udba
27555+ || au_opt_test(sbinfo->si_mntflags, XINO)
27556+ || au_ftest_opts(opts->flags, REFRESH_IDOP)
27557+ ))
27558+ au_fset_opts(opts->flags, REFRESH);
27559+
27560+ AuDbg("status 0x%x\n", opts->flags);
27561+
27562+out:
27563+ return err;
27564+}
27565+
27566+/* ---------------------------------------------------------------------- */
27567+
27568+unsigned int au_opt_udba(struct super_block *sb)
27569+{
27570+ return au_mntflags(sb) & AuOptMask_UDBA;
27571+}
27572diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
27573--- /usr/share/empty/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100
27574+++ linux/fs/aufs/opts.h 2020-01-27 10:57:18.175538316 +0100
27575@@ -0,0 +1,225 @@
27576+/* SPDX-License-Identifier: GPL-2.0 */
27577+/*
27578+ * Copyright (C) 2005-2020 Junjiro R. Okajima
27579+ *
27580+ * This program, aufs is free software; you can redistribute it and/or modify
27581+ * it under the terms of the GNU General Public License as published by
27582+ * the Free Software Foundation; either version 2 of the License, or
27583+ * (at your option) any later version.
27584+ *
27585+ * This program is distributed in the hope that it will be useful,
27586+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27587+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27588+ * GNU General Public License for more details.
27589+ *
27590+ * You should have received a copy of the GNU General Public License
27591+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
27592+ */
27593+
27594+/*
27595+ * mount options/flags
27596+ */
27597+
27598+#ifndef __AUFS_OPTS_H__
27599+#define __AUFS_OPTS_H__
27600+
27601+#ifdef __KERNEL__
27602+
27603+#include <linux/path.h>
27604+
27605+struct file;
27606+
27607+/* ---------------------------------------------------------------------- */
27608+
27609+/* mount flags */
27610+#define AuOpt_XINO 1 /* external inode number bitmap
27611+ and translation table */
27612+#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */
27613+#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */
27614+#define AuOpt_UDBA_REVAL (1 << 3)
27615+#define AuOpt_UDBA_HNOTIFY (1 << 4)
27616+#define AuOpt_SHWH (1 << 5) /* show whiteout */
27617+#define AuOpt_PLINK (1 << 6) /* pseudo-link */
27618+#define AuOpt_DIRPERM1 (1 << 7) /* ignore the lower dir's perm
27619+ bits */
27620+#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */
27621+#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
27622+#define AuOpt_SUM_W (1 << 11) /* unimplemented */
27623+#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */
27624+#define AuOpt_VERBOSE (1 << 13) /* print the cause of error */
27625+#define AuOpt_DIO (1 << 14) /* direct io */
27626+#define AuOpt_DIRREN (1 << 15) /* directory rename */
27627+
27628+#ifndef CONFIG_AUFS_HNOTIFY
27629+#undef AuOpt_UDBA_HNOTIFY
27630+#define AuOpt_UDBA_HNOTIFY 0
27631+#endif
27632+#ifndef CONFIG_AUFS_DIRREN
27633+#undef AuOpt_DIRREN
27634+#define AuOpt_DIRREN 0
27635+#endif
27636+#ifndef CONFIG_AUFS_SHWH
27637+#undef AuOpt_SHWH
27638+#define AuOpt_SHWH 0
27639+#endif
27640+
27641+#define AuOpt_Def (AuOpt_XINO \
27642+ | AuOpt_UDBA_REVAL \
27643+ | AuOpt_PLINK \
27644+ /* | AuOpt_DIRPERM1 */ \
27645+ | AuOpt_WARN_PERM)
27646+#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
27647+ | AuOpt_UDBA_REVAL \
27648+ | AuOpt_UDBA_HNOTIFY)
27649+
27650+#define au_opt_test(flags, name) (flags & AuOpt_##name)
27651+#define au_opt_set(flags, name) do { \
27652+ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
27653+ ((flags) |= AuOpt_##name); \
27654+} while (0)
27655+#define au_opt_set_udba(flags, name) do { \
27656+ (flags) &= ~AuOptMask_UDBA; \
27657+ ((flags) |= AuOpt_##name); \
27658+} while (0)
27659+#define au_opt_clr(flags, name) do { \
27660+ ((flags) &= ~AuOpt_##name); \
27661+} while (0)
27662+
27663+static inline unsigned int au_opts_plink(unsigned int mntflags)
27664+{
27665+#ifdef CONFIG_PROC_FS
27666+ return mntflags;
27667+#else
27668+ return mntflags & ~AuOpt_PLINK;
27669+#endif
27670+}
27671+
27672+/* ---------------------------------------------------------------------- */
27673+
27674+/* policies to select one among multiple writable branches */
27675+enum {
27676+ AuWbrCreate_TDP, /* top down parent */
27677+ AuWbrCreate_RR, /* round robin */
27678+ AuWbrCreate_MFS, /* most free space */
27679+ AuWbrCreate_MFSV, /* mfs with seconds */
27680+ AuWbrCreate_MFSRR, /* mfs then rr */
27681+ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */
27682+ AuWbrCreate_TDMFS, /* top down regardless parent and mfs */
27683+ AuWbrCreate_TDMFSV, /* top down regardless parent and mfs */
27684+ AuWbrCreate_PMFS, /* parent and mfs */
27685+ AuWbrCreate_PMFSV, /* parent and mfs with seconds */
27686+ AuWbrCreate_PMFSRR, /* parent, mfs and round-robin */
27687+ AuWbrCreate_PMFSRRV, /* plus seconds */
27688+
27689+ AuWbrCreate_Def = AuWbrCreate_TDP
27690+};
27691+
27692+enum {
27693+ AuWbrCopyup_TDP, /* top down parent */
27694+ AuWbrCopyup_BUP, /* bottom up parent */
27695+ AuWbrCopyup_BU, /* bottom up */
27696+
27697+ AuWbrCopyup_Def = AuWbrCopyup_TDP
27698+};
27699+
27700+/* ---------------------------------------------------------------------- */
27701+
27702+struct au_opt_add {
27703+ aufs_bindex_t bindex;
27704+ char *pathname;
27705+ int perm;
27706+ struct path path;
27707+};
27708+
27709+struct au_opt_del {
27710+ char *pathname;
27711+ struct path h_path;
27712+};
27713+
27714+struct au_opt_mod {
27715+ char *path;
27716+ int perm;
27717+ struct dentry *h_root;
27718+};
27719+
27720+struct au_opt_xino {
27721+ char *path;
27722+ struct file *file;
27723+};
27724+
27725+struct au_opt_xino_itrunc {
27726+ aufs_bindex_t bindex;
27727+};
27728+
27729+struct au_opt_wbr_create {
27730+ int wbr_create;
27731+ int mfs_second;
27732+ unsigned long long mfsrr_watermark;
27733+};
27734+
27735+struct au_opt {
27736+ int type;
27737+ union {
27738+ struct au_opt_xino xino;
27739+ struct au_opt_xino_itrunc xino_itrunc;
27740+ struct au_opt_add add;
27741+ struct au_opt_del del;
27742+ struct au_opt_mod mod;
27743+ int dirwh;
27744+ int rdcache;
27745+ unsigned int rdblk;
27746+ unsigned int rdhash;
27747+ int udba;
27748+ struct au_opt_wbr_create wbr_create;
27749+ int wbr_copyup;
27750+ unsigned int fhsm_second;
27751+ };
27752+};
27753+
27754+/* opts flags */
27755+#define AuOpts_REMOUNT 1
27756+#define AuOpts_REFRESH (1 << 1)
27757+#define AuOpts_TRUNC_XIB (1 << 2)
27758+#define AuOpts_REFRESH_DYAOP (1 << 3)
27759+#define AuOpts_REFRESH_IDOP (1 << 4)
27760+#define AuOpts_DR_FLUSHED (1 << 5)
27761+#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
27762+#define au_fset_opts(flags, name) \
27763+ do { (flags) |= AuOpts_##name; } while (0)
27764+#define au_fclr_opts(flags, name) \
27765+ do { (flags) &= ~AuOpts_##name; } while (0)
27766+
27767+#ifndef CONFIG_AUFS_DIRREN
27768+#undef AuOpts_DR_FLUSHED
27769+#define AuOpts_DR_FLUSHED 0
27770+#endif
27771+
27772+struct au_opts {
27773+ struct au_opt *opt;
27774+ int max_opt;
27775+
27776+ unsigned int given_udba;
27777+ unsigned int flags;
27778+ unsigned long sb_flags;
27779+};
27780+
27781+/* ---------------------------------------------------------------------- */
27782+
27783+/* opts.c */
27784+void au_optstr_br_perm(au_br_perm_str_t *str, int perm);
27785+const char *au_optstr_udba(int udba);
27786+const char *au_optstr_wbr_copyup(int wbr_copyup);
27787+const char *au_optstr_wbr_create(int wbr_create);
27788+
27789+void au_opts_free(struct au_opts *opts);
27790+struct super_block;
27791+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
27792+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
27793+ unsigned int pending);
27794+int au_opts_mount(struct super_block *sb, struct au_opts *opts);
27795+int au_opts_remount(struct super_block *sb, struct au_opts *opts);
27796+
27797+unsigned int au_opt_udba(struct super_block *sb);
27798+
27799+#endif /* __KERNEL__ */
27800+#endif /* __AUFS_OPTS_H__ */
27801diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
27802--- /usr/share/empty/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100
27803+++ linux/fs/aufs/plink.c 2020-01-27 10:57:18.175538316 +0100
27804@@ -0,0 +1,516 @@
27805+// SPDX-License-Identifier: GPL-2.0
27806+/*
27807+ * Copyright (C) 2005-2020 Junjiro R. Okajima
27808+ *
27809+ * This program, aufs is free software; you can redistribute it and/or modify
27810+ * it under the terms of the GNU General Public License as published by
27811+ * the Free Software Foundation; either version 2 of the License, or
27812+ * (at your option) any later version.
27813+ *
27814+ * This program is distributed in the hope that it will be useful,
27815+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27816+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27817+ * GNU General Public License for more details.
27818+ *
27819+ * You should have received a copy of the GNU General Public License
27820+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
27821+ */
27822+
27823+/*
27824+ * pseudo-link
27825+ */
27826+
27827+#include "aufs.h"
27828+
27829+/*
27830+ * the pseudo-link maintenance mode.
27831+ * during a user process maintains the pseudo-links,
27832+ * prohibit adding a new plink and branch manipulation.
27833+ *
27834+ * Flags
27835+ * NOPLM:
27836+ * For entry functions which will handle plink, and i_mutex is already held
27837+ * in VFS.
27838+ * They cannot wait and should return an error at once.
27839+ * Callers has to check the error.
27840+ * NOPLMW:
27841+ * For entry functions which will handle plink, but i_mutex is not held
27842+ * in VFS.
27843+ * They can wait the plink maintenance mode to finish.
27844+ *
27845+ * They behave like F_SETLK and F_SETLKW.
27846+ * If the caller never handle plink, then both flags are unnecessary.
27847+ */
27848+
27849+int au_plink_maint(struct super_block *sb, int flags)
27850+{
27851+ int err;
27852+ pid_t pid, ppid;
27853+ struct task_struct *parent, *prev;
27854+ struct au_sbinfo *sbi;
27855+
27856+ SiMustAnyLock(sb);
27857+
27858+ err = 0;
27859+ if (!au_opt_test(au_mntflags(sb), PLINK))
27860+ goto out;
27861+
27862+ sbi = au_sbi(sb);
27863+ pid = sbi->si_plink_maint_pid;
27864+ if (!pid || pid == current->pid)
27865+ goto out;
27866+
27867+ /* todo: it highly depends upon /sbin/mount.aufs */
27868+ prev = NULL;
27869+ parent = current;
27870+ ppid = 0;
27871+ rcu_read_lock();
27872+ while (1) {
27873+ parent = rcu_dereference(parent->real_parent);
27874+ if (parent == prev)
27875+ break;
27876+ ppid = task_pid_vnr(parent);
27877+ if (pid == ppid) {
27878+ rcu_read_unlock();
27879+ goto out;
27880+ }
27881+ prev = parent;
27882+ }
27883+ rcu_read_unlock();
27884+
27885+ if (au_ftest_lock(flags, NOPLMW)) {
27886+ /* if there is no i_mutex lock in VFS, we don't need to wait */
27887+ /* AuDebugOn(!lockdep_depth(current)); */
27888+ while (sbi->si_plink_maint_pid) {
27889+ si_read_unlock(sb);
27890+ /* gave up wake_up_bit() */
27891+ wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
27892+
27893+ if (au_ftest_lock(flags, FLUSH))
27894+ au_nwt_flush(&sbi->si_nowait);
27895+ si_noflush_read_lock(sb);
27896+ }
27897+ } else if (au_ftest_lock(flags, NOPLM)) {
27898+ AuDbg("ppid %d, pid %d\n", ppid, pid);
27899+ err = -EAGAIN;
27900+ }
27901+
27902+out:
27903+ return err;
27904+}
27905+
27906+void au_plink_maint_leave(struct au_sbinfo *sbinfo)
27907+{
27908+ spin_lock(&sbinfo->si_plink_maint_lock);
27909+ sbinfo->si_plink_maint_pid = 0;
27910+ spin_unlock(&sbinfo->si_plink_maint_lock);
27911+ wake_up_all(&sbinfo->si_plink_wq);
27912+}
27913+
27914+int au_plink_maint_enter(struct super_block *sb)
27915+{
27916+ int err;
27917+ struct au_sbinfo *sbinfo;
27918+
27919+ err = 0;
27920+ sbinfo = au_sbi(sb);
27921+ /* make sure i am the only one in this fs */
27922+ si_write_lock(sb, AuLock_FLUSH);
27923+ if (au_opt_test(au_mntflags(sb), PLINK)) {
27924+ spin_lock(&sbinfo->si_plink_maint_lock);
27925+ if (!sbinfo->si_plink_maint_pid)
27926+ sbinfo->si_plink_maint_pid = current->pid;
27927+ else
27928+ err = -EBUSY;
27929+ spin_unlock(&sbinfo->si_plink_maint_lock);
27930+ }
27931+ si_write_unlock(sb);
27932+
27933+ return err;
27934+}
27935+
27936+/* ---------------------------------------------------------------------- */
27937+
27938+#ifdef CONFIG_AUFS_DEBUG
27939+void au_plink_list(struct super_block *sb)
27940+{
27941+ int i;
27942+ struct au_sbinfo *sbinfo;
27943+ struct hlist_bl_head *hbl;
27944+ struct hlist_bl_node *pos;
27945+ struct au_icntnr *icntnr;
27946+
27947+ SiMustAnyLock(sb);
27948+
27949+ sbinfo = au_sbi(sb);
27950+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
27951+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
27952+
27953+ for (i = 0; i < AuPlink_NHASH; i++) {
27954+ hbl = sbinfo->si_plink + i;
27955+ hlist_bl_lock(hbl);
27956+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink)
27957+ AuDbg("%lu\n", icntnr->vfs_inode.i_ino);
27958+ hlist_bl_unlock(hbl);
27959+ }
27960+}
27961+#endif
27962+
27963+/* is the inode pseudo-linked? */
27964+int au_plink_test(struct inode *inode)
27965+{
27966+ int found, i;
27967+ struct au_sbinfo *sbinfo;
27968+ struct hlist_bl_head *hbl;
27969+ struct hlist_bl_node *pos;
27970+ struct au_icntnr *icntnr;
27971+
27972+ sbinfo = au_sbi(inode->i_sb);
27973+ AuRwMustAnyLock(&sbinfo->si_rwsem);
27974+ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
27975+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
27976+
27977+ found = 0;
27978+ i = au_plink_hash(inode->i_ino);
27979+ hbl = sbinfo->si_plink + i;
27980+ hlist_bl_lock(hbl);
27981+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink)
27982+ if (&icntnr->vfs_inode == inode) {
27983+ found = 1;
27984+ break;
27985+ }
27986+ hlist_bl_unlock(hbl);
27987+ return found;
27988+}
27989+
27990+/* ---------------------------------------------------------------------- */
27991+
27992+/*
27993+ * generate a name for plink.
27994+ * the file will be stored under AUFS_WH_PLINKDIR.
27995+ */
27996+/* 20 is max digits length of ulong 64 */
27997+#define PLINK_NAME_LEN ((20 + 1) * 2)
27998+
27999+static int plink_name(char *name, int len, struct inode *inode,
28000+ aufs_bindex_t bindex)
28001+{
28002+ int rlen;
28003+ struct inode *h_inode;
28004+
28005+ h_inode = au_h_iptr(inode, bindex);
28006+ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
28007+ return rlen;
28008+}
28009+
28010+struct au_do_plink_lkup_args {
28011+ struct dentry **errp;
28012+ struct qstr *tgtname;
28013+ struct dentry *h_parent;
28014+ struct au_branch *br;
28015+};
28016+
28017+static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
28018+ struct dentry *h_parent,
28019+ struct au_branch *br)
28020+{
28021+ struct dentry *h_dentry;
28022+ struct inode *h_inode;
28023+
28024+ h_inode = d_inode(h_parent);
28025+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD2);
28026+ h_dentry = vfsub_lkup_one(tgtname, h_parent);
28027+ inode_unlock_shared(h_inode);
28028+ return h_dentry;
28029+}
28030+
28031+static void au_call_do_plink_lkup(void *args)
28032+{
28033+ struct au_do_plink_lkup_args *a = args;
28034+ *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
28035+}
28036+
28037+/* lookup the plink-ed @inode under the branch at @bindex */
28038+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
28039+{
28040+ struct dentry *h_dentry, *h_parent;
28041+ struct au_branch *br;
28042+ int wkq_err;
28043+ char a[PLINK_NAME_LEN];
28044+ struct qstr tgtname = QSTR_INIT(a, 0);
28045+
28046+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
28047+
28048+ br = au_sbr(inode->i_sb, bindex);
28049+ h_parent = br->br_wbr->wbr_plink;
28050+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
28051+
28052+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
28053+ struct au_do_plink_lkup_args args = {
28054+ .errp = &h_dentry,
28055+ .tgtname = &tgtname,
28056+ .h_parent = h_parent,
28057+ .br = br
28058+ };
28059+
28060+ wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
28061+ if (unlikely(wkq_err))
28062+ h_dentry = ERR_PTR(wkq_err);
28063+ } else
28064+ h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
28065+
28066+ return h_dentry;
28067+}
28068+
28069+/* create a pseudo-link */
28070+static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
28071+ struct dentry *h_dentry, struct au_branch *br)
28072+{
28073+ int err;
28074+ struct path h_path = {
28075+ .mnt = au_br_mnt(br)
28076+ };
28077+ struct inode *h_dir, *delegated;
28078+
28079+ h_dir = d_inode(h_parent);
28080+ inode_lock_nested(h_dir, AuLsc_I_CHILD2);
28081+again:
28082+ h_path.dentry = vfsub_lkup_one(tgt, h_parent);
28083+ err = PTR_ERR(h_path.dentry);
28084+ if (IS_ERR(h_path.dentry))
28085+ goto out;
28086+
28087+ err = 0;
28088+ /* wh.plink dir is not monitored */
28089+ /* todo: is it really safe? */
28090+ if (d_is_positive(h_path.dentry)
28091+ && d_inode(h_path.dentry) != d_inode(h_dentry)) {
28092+ delegated = NULL;
28093+ err = vfsub_unlink(h_dir, &h_path, &delegated, /*force*/0);
28094+ if (unlikely(err == -EWOULDBLOCK)) {
28095+ pr_warn("cannot retry for NFSv4 delegation"
28096+ " for an internal unlink\n");
28097+ iput(delegated);
28098+ }
28099+ dput(h_path.dentry);
28100+ h_path.dentry = NULL;
28101+ if (!err)
28102+ goto again;
28103+ }
28104+ if (!err && d_is_negative(h_path.dentry)) {
28105+ delegated = NULL;
28106+ err = vfsub_link(h_dentry, h_dir, &h_path, &delegated);
28107+ if (unlikely(err == -EWOULDBLOCK)) {
28108+ pr_warn("cannot retry for NFSv4 delegation"
28109+ " for an internal link\n");
28110+ iput(delegated);
28111+ }
28112+ }
28113+ dput(h_path.dentry);
28114+
28115+out:
28116+ inode_unlock(h_dir);
28117+ return err;
28118+}
28119+
28120+struct do_whplink_args {
28121+ int *errp;
28122+ struct qstr *tgt;
28123+ struct dentry *h_parent;
28124+ struct dentry *h_dentry;
28125+ struct au_branch *br;
28126+};
28127+
28128+static void call_do_whplink(void *args)
28129+{
28130+ struct do_whplink_args *a = args;
28131+ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
28132+}
28133+
28134+static int whplink(struct dentry *h_dentry, struct inode *inode,
28135+ aufs_bindex_t bindex, struct au_branch *br)
28136+{
28137+ int err, wkq_err;
28138+ struct au_wbr *wbr;
28139+ struct dentry *h_parent;
28140+ char a[PLINK_NAME_LEN];
28141+ struct qstr tgtname = QSTR_INIT(a, 0);
28142+
28143+ wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
28144+ h_parent = wbr->wbr_plink;
28145+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
28146+
28147+ /* always superio. */
28148+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
28149+ struct do_whplink_args args = {
28150+ .errp = &err,
28151+ .tgt = &tgtname,
28152+ .h_parent = h_parent,
28153+ .h_dentry = h_dentry,
28154+ .br = br
28155+ };
28156+ wkq_err = au_wkq_wait(call_do_whplink, &args);
28157+ if (unlikely(wkq_err))
28158+ err = wkq_err;
28159+ } else
28160+ err = do_whplink(&tgtname, h_parent, h_dentry, br);
28161+
28162+ return err;
28163+}
28164+
28165+/*
28166+ * create a new pseudo-link for @h_dentry on @bindex.
28167+ * the linked inode is held in aufs @inode.
28168+ */
28169+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
28170+ struct dentry *h_dentry)
28171+{
28172+ struct super_block *sb;
28173+ struct au_sbinfo *sbinfo;
28174+ struct hlist_bl_head *hbl;
28175+ struct hlist_bl_node *pos;
28176+ struct au_icntnr *icntnr;
28177+ int found, err, cnt, i;
28178+
28179+ sb = inode->i_sb;
28180+ sbinfo = au_sbi(sb);
28181+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
28182+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
28183+
28184+ found = au_plink_test(inode);
28185+ if (found)
28186+ return;
28187+
28188+ i = au_plink_hash(inode->i_ino);
28189+ hbl = sbinfo->si_plink + i;
28190+ au_igrab(inode);
28191+
28192+ hlist_bl_lock(hbl);
28193+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink) {
28194+ if (&icntnr->vfs_inode == inode) {
28195+ found = 1;
28196+ break;
28197+ }
28198+ }
28199+ if (!found) {
28200+ icntnr = container_of(inode, struct au_icntnr, vfs_inode);
28201+ hlist_bl_add_head(&icntnr->plink, hbl);
28202+ }
28203+ hlist_bl_unlock(hbl);
28204+ if (!found) {
28205+ cnt = au_hbl_count(hbl);
28206+#define msg "unexpectedly unbalanced or too many pseudo-links"
28207+ if (cnt > AUFS_PLINK_WARN)
28208+ AuWarn1(msg ", %d\n", cnt);
28209+#undef msg
28210+ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
28211+ if (unlikely(err)) {
28212+ pr_warn("err %d, damaged pseudo link.\n", err);
28213+ au_hbl_del(&icntnr->plink, hbl);
28214+ iput(&icntnr->vfs_inode);
28215+ }
28216+ } else
28217+ iput(&icntnr->vfs_inode);
28218+}
28219+
28220+/* free all plinks */
28221+void au_plink_put(struct super_block *sb, int verbose)
28222+{
28223+ int i, warned;
28224+ struct au_sbinfo *sbinfo;
28225+ struct hlist_bl_head *hbl;
28226+ struct hlist_bl_node *pos, *tmp;
28227+ struct au_icntnr *icntnr;
28228+
28229+ SiMustWriteLock(sb);
28230+
28231+ sbinfo = au_sbi(sb);
28232+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
28233+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
28234+
28235+ /* no spin_lock since sbinfo is write-locked */
28236+ warned = 0;
28237+ for (i = 0; i < AuPlink_NHASH; i++) {
28238+ hbl = sbinfo->si_plink + i;
28239+ if (!warned && verbose && !hlist_bl_empty(hbl)) {
28240+ pr_warn("pseudo-link is not flushed");
28241+ warned = 1;
28242+ }
28243+ hlist_bl_for_each_entry_safe(icntnr, pos, tmp, hbl, plink)
28244+ iput(&icntnr->vfs_inode);
28245+ INIT_HLIST_BL_HEAD(hbl);
28246+ }
28247+}
28248+
28249+void au_plink_clean(struct super_block *sb, int verbose)
28250+{
28251+ struct dentry *root;
28252+
28253+ root = sb->s_root;
28254+ aufs_write_lock(root);
28255+ if (au_opt_test(au_mntflags(sb), PLINK))
28256+ au_plink_put(sb, verbose);
28257+ aufs_write_unlock(root);
28258+}
28259+
28260+static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id)
28261+{
28262+ int do_put;
28263+ aufs_bindex_t btop, bbot, bindex;
28264+
28265+ do_put = 0;
28266+ btop = au_ibtop(inode);
28267+ bbot = au_ibbot(inode);
28268+ if (btop >= 0) {
28269+ for (bindex = btop; bindex <= bbot; bindex++) {
28270+ if (!au_h_iptr(inode, bindex)
28271+ || au_ii_br_id(inode, bindex) != br_id)
28272+ continue;
28273+ au_set_h_iptr(inode, bindex, NULL, 0);
28274+ do_put = 1;
28275+ break;
28276+ }
28277+ if (do_put)
28278+ for (bindex = btop; bindex <= bbot; bindex++)
28279+ if (au_h_iptr(inode, bindex)) {
28280+ do_put = 0;
28281+ break;
28282+ }
28283+ } else
28284+ do_put = 1;
28285+
28286+ return do_put;
28287+}
28288+
28289+/* free the plinks on a branch specified by @br_id */
28290+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
28291+{
28292+ struct au_sbinfo *sbinfo;
28293+ struct hlist_bl_head *hbl;
28294+ struct hlist_bl_node *pos, *tmp;
28295+ struct au_icntnr *icntnr;
28296+ struct inode *inode;
28297+ int i, do_put;
28298+
28299+ SiMustWriteLock(sb);
28300+
28301+ sbinfo = au_sbi(sb);
28302+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
28303+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
28304+
28305+ /* no bit_lock since sbinfo is write-locked */
28306+ for (i = 0; i < AuPlink_NHASH; i++) {
28307+ hbl = sbinfo->si_plink + i;
28308+ hlist_bl_for_each_entry_safe(icntnr, pos, tmp, hbl, plink) {
28309+ inode = au_igrab(&icntnr->vfs_inode);
28310+ ii_write_lock_child(inode);
28311+ do_put = au_plink_do_half_refresh(inode, br_id);
28312+ if (do_put) {
28313+ hlist_bl_del(&icntnr->plink);
28314+ iput(inode);
28315+ }
28316+ ii_write_unlock(inode);
28317+ iput(inode);
28318+ }
28319+ }
28320+}
28321diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
28322--- /usr/share/empty/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100
28323+++ linux/fs/aufs/poll.c 2020-01-27 10:57:18.175538316 +0100
28324@@ -0,0 +1,51 @@
28325+// SPDX-License-Identifier: GPL-2.0
28326+/*
28327+ * Copyright (C) 2005-2020 Junjiro R. Okajima
28328+ *
28329+ * This program, aufs is free software; you can redistribute it and/or modify
28330+ * it under the terms of the GNU General Public License as published by
28331+ * the Free Software Foundation; either version 2 of the License, or
28332+ * (at your option) any later version.
28333+ *
28334+ * This program is distributed in the hope that it will be useful,
28335+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28336+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28337+ * GNU General Public License for more details.
28338+ *
28339+ * You should have received a copy of the GNU General Public License
28340+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
28341+ */
28342+
28343+/*
28344+ * poll operation
28345+ * There is only one filesystem which implements ->poll operation, currently.
28346+ */
28347+
28348+#include "aufs.h"
28349+
28350+__poll_t aufs_poll(struct file *file, struct poll_table_struct *pt)
28351+{
28352+ __poll_t mask;
28353+ struct file *h_file;
28354+ struct super_block *sb;
28355+
28356+ /* We should pretend an error happened. */
28357+ mask = EPOLLERR /* | EPOLLIN | EPOLLOUT */;
28358+ sb = file->f_path.dentry->d_sb;
28359+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
28360+
28361+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
28362+ if (IS_ERR(h_file)) {
28363+ AuDbg("h_file %ld\n", PTR_ERR(h_file));
28364+ goto out;
28365+ }
28366+
28367+ mask = vfs_poll(h_file, pt);
28368+ fput(h_file); /* instead of au_read_post() */
28369+
28370+out:
28371+ si_read_unlock(sb);
28372+ if (mask & EPOLLERR)
28373+ AuDbg("mask 0x%x\n", mask);
28374+ return mask;
28375+}
28376diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c
28377--- /usr/share/empty/fs/aufs/posix_acl.c 1970-01-01 01:00:00.000000000 +0100
28378+++ linux/fs/aufs/posix_acl.c 2020-01-27 10:57:18.175538316 +0100
28379@@ -0,0 +1,105 @@
28380+// SPDX-License-Identifier: GPL-2.0
28381+/*
28382+ * Copyright (C) 2014-2020 Junjiro R. Okajima
28383+ *
28384+ * This program, aufs is free software; you can redistribute it and/or modify
28385+ * it under the terms of the GNU General Public License as published by
28386+ * the Free Software Foundation; either version 2 of the License, or
28387+ * (at your option) any later version.
28388+ *
28389+ * This program is distributed in the hope that it will be useful,
28390+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28391+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28392+ * GNU General Public License for more details.
28393+ *
28394+ * You should have received a copy of the GNU General Public License
28395+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
28396+ */
28397+
28398+/*
28399+ * posix acl operations
28400+ */
28401+
28402+#include <linux/fs.h>
28403+#include "aufs.h"
28404+
28405+struct posix_acl *aufs_get_acl(struct inode *inode, int type)
28406+{
28407+ struct posix_acl *acl;
28408+ int err;
28409+ aufs_bindex_t bindex;
28410+ struct inode *h_inode;
28411+ struct super_block *sb;
28412+
28413+ acl = NULL;
28414+ sb = inode->i_sb;
28415+ si_read_lock(sb, AuLock_FLUSH);
28416+ ii_read_lock_child(inode);
28417+ if (!(sb->s_flags & SB_POSIXACL))
28418+ goto out;
28419+
28420+ bindex = au_ibtop(inode);
28421+ h_inode = au_h_iptr(inode, bindex);
28422+ if (unlikely(!h_inode
28423+ || ((h_inode->i_mode & S_IFMT)
28424+ != (inode->i_mode & S_IFMT)))) {
28425+ err = au_busy_or_stale();
28426+ acl = ERR_PTR(err);
28427+ goto out;
28428+ }
28429+
28430+ /* always topmost only */
28431+ acl = get_acl(h_inode, type);
28432+ if (IS_ERR(acl))
28433+ forget_cached_acl(inode, type);
28434+ else
28435+ set_cached_acl(inode, type, acl);
28436+
28437+out:
28438+ ii_read_unlock(inode);
28439+ si_read_unlock(sb);
28440+
28441+ AuTraceErrPtr(acl);
28442+ return acl;
28443+}
28444+
28445+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
28446+{
28447+ int err;
28448+ ssize_t ssz;
28449+ struct dentry *dentry;
28450+ struct au_sxattr arg = {
28451+ .type = AU_ACL_SET,
28452+ .u.acl_set = {
28453+ .acl = acl,
28454+ .type = type
28455+ },
28456+ };
28457+
28458+ IMustLock(inode);
28459+
28460+ if (inode->i_ino == AUFS_ROOT_INO)
28461+ dentry = dget(inode->i_sb->s_root);
28462+ else {
28463+ dentry = d_find_alias(inode);
28464+ if (!dentry)
28465+ dentry = d_find_any_alias(inode);
28466+ if (!dentry) {
28467+ pr_warn("cannot handle this inode, "
28468+ "please report to aufs-users ML\n");
28469+ err = -ENOENT;
28470+ goto out;
28471+ }
28472+ }
28473+
28474+ ssz = au_sxattr(dentry, inode, &arg);
28475+ /* forget even it if succeeds since the branch might set differently */
28476+ forget_cached_acl(inode, type);
28477+ dput(dentry);
28478+ err = ssz;
28479+ if (ssz >= 0)
28480+ err = 0;
28481+
28482+out:
28483+ return err;
28484+}
28485diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
28486--- /usr/share/empty/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100
28487+++ linux/fs/aufs/procfs.c 2020-04-03 08:16:47.547461775 +0200
28488@@ -0,0 +1,171 @@
28489+// SPDX-License-Identifier: GPL-2.0
28490+/*
28491+ * Copyright (C) 2010-2020 Junjiro R. Okajima
28492+ *
28493+ * This program, aufs is free software; you can redistribute it and/or modify
28494+ * it under the terms of the GNU General Public License as published by
28495+ * the Free Software Foundation; either version 2 of the License, or
28496+ * (at your option) any later version.
28497+ *
28498+ * This program is distributed in the hope that it will be useful,
28499+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28500+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28501+ * GNU General Public License for more details.
28502+ *
28503+ * You should have received a copy of the GNU General Public License
28504+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
28505+ */
28506+
28507+/*
28508+ * procfs interfaces
28509+ */
28510+
28511+#include <linux/proc_fs.h>
28512+#include "aufs.h"
28513+
28514+static int au_procfs_plm_release(struct inode *inode, struct file *file)
28515+{
28516+ struct au_sbinfo *sbinfo;
28517+
28518+ sbinfo = file->private_data;
28519+ if (sbinfo) {
28520+ au_plink_maint_leave(sbinfo);
28521+ kobject_put(&sbinfo->si_kobj);
28522+ }
28523+
28524+ return 0;
28525+}
28526+
28527+static void au_procfs_plm_write_clean(struct file *file)
28528+{
28529+ struct au_sbinfo *sbinfo;
28530+
28531+ sbinfo = file->private_data;
28532+ if (sbinfo)
28533+ au_plink_clean(sbinfo->si_sb, /*verbose*/0);
28534+}
28535+
28536+static int au_procfs_plm_write_si(struct file *file, unsigned long id)
28537+{
28538+ int err;
28539+ struct super_block *sb;
28540+ struct au_sbinfo *sbinfo;
28541+ struct hlist_bl_node *pos;
28542+
28543+ err = -EBUSY;
28544+ if (unlikely(file->private_data))
28545+ goto out;
28546+
28547+ sb = NULL;
28548+ /* don't use au_sbilist_lock() here */
28549+ hlist_bl_lock(&au_sbilist);
28550+ hlist_bl_for_each_entry(sbinfo, pos, &au_sbilist, si_list)
28551+ if (id == sysaufs_si_id(sbinfo)) {
28552+ if (kobject_get_unless_zero(&sbinfo->si_kobj))
28553+ sb = sbinfo->si_sb;
28554+ break;
28555+ }
28556+ hlist_bl_unlock(&au_sbilist);
28557+
28558+ err = -EINVAL;
28559+ if (unlikely(!sb))
28560+ goto out;
28561+
28562+ err = au_plink_maint_enter(sb);
28563+ if (!err)
28564+ /* keep kobject_get() */
28565+ file->private_data = sbinfo;
28566+ else
28567+ kobject_put(&sbinfo->si_kobj);
28568+out:
28569+ return err;
28570+}
28571+
28572+/*
28573+ * Accept a valid "si=xxxx" only.
28574+ * Once it is accepted successfully, accept "clean" too.
28575+ */
28576+static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf,
28577+ size_t count, loff_t *ppos)
28578+{
28579+ ssize_t err;
28580+ unsigned long id;
28581+ /* last newline is allowed */
28582+ char buf[3 + sizeof(unsigned long) * 2 + 1];
28583+
28584+ err = -EACCES;
28585+ if (unlikely(!capable(CAP_SYS_ADMIN)))
28586+ goto out;
28587+
28588+ err = -EINVAL;
28589+ if (unlikely(count > sizeof(buf)))
28590+ goto out;
28591+
28592+ err = copy_from_user(buf, ubuf, count);
28593+ if (unlikely(err)) {
28594+ err = -EFAULT;
28595+ goto out;
28596+ }
28597+ buf[count] = 0;
28598+
28599+ err = -EINVAL;
28600+ if (!strcmp("clean", buf)) {
28601+ au_procfs_plm_write_clean(file);
28602+ goto out_success;
28603+ } else if (unlikely(strncmp("si=", buf, 3)))
28604+ goto out;
28605+
28606+ err = kstrtoul(buf + 3, 16, &id);
28607+ if (unlikely(err))
28608+ goto out;
28609+
28610+ err = au_procfs_plm_write_si(file, id);
28611+ if (unlikely(err))
28612+ goto out;
28613+
28614+out_success:
28615+ err = count; /* success */
28616+out:
28617+ return err;
28618+}
28619+
28620+static const struct file_operations au_procfs_plm_fop = {
28621+ .write = au_procfs_plm_write,
28622+ .release = au_procfs_plm_release,
28623+ .owner = THIS_MODULE
28624+};
28625+
28626+/* ---------------------------------------------------------------------- */
28627+
28628+static struct proc_dir_entry *au_procfs_dir;
28629+
28630+void au_procfs_fin(void)
28631+{
28632+ remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir);
28633+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
28634+}
28635+
28636+int __init au_procfs_init(void)
28637+{
28638+ int err;
28639+ struct proc_dir_entry *entry;
28640+
28641+ err = -ENOMEM;
28642+ au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL);
28643+ if (unlikely(!au_procfs_dir))
28644+ goto out;
28645+
28646+ entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | 0200,
28647+ au_procfs_dir, &au_procfs_plm_fop);
28648+ if (unlikely(!entry))
28649+ goto out_dir;
28650+
28651+ err = 0;
28652+ goto out; /* success */
28653+
28654+
28655+out_dir:
28656+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
28657+out:
28658+ return err;
28659+}
28660diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
28661--- /usr/share/empty/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100
28662+++ linux/fs/aufs/rdu.c 2020-01-27 10:57:18.178871751 +0100
28663@@ -0,0 +1,384 @@
28664+// SPDX-License-Identifier: GPL-2.0
28665+/*
28666+ * Copyright (C) 2005-2020 Junjiro R. Okajima
28667+ *
28668+ * This program, aufs is free software; you can redistribute it and/or modify
28669+ * it under the terms of the GNU General Public License as published by
28670+ * the Free Software Foundation; either version 2 of the License, or
28671+ * (at your option) any later version.
28672+ *
28673+ * This program is distributed in the hope that it will be useful,
28674+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28675+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28676+ * GNU General Public License for more details.
28677+ *
28678+ * You should have received a copy of the GNU General Public License
28679+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
28680+ */
28681+
28682+/*
28683+ * readdir in userspace.
28684+ */
28685+
28686+#include <linux/compat.h>
28687+#include <linux/fs_stack.h>
28688+#include <linux/security.h>
28689+#include "aufs.h"
28690+
28691+/* bits for struct aufs_rdu.flags */
28692+#define AuRdu_CALLED 1
28693+#define AuRdu_CONT (1 << 1)
28694+#define AuRdu_FULL (1 << 2)
28695+#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name)
28696+#define au_fset_rdu(flags, name) \
28697+ do { (flags) |= AuRdu_##name; } while (0)
28698+#define au_fclr_rdu(flags, name) \
28699+ do { (flags) &= ~AuRdu_##name; } while (0)
28700+
28701+struct au_rdu_arg {
28702+ struct dir_context ctx;
28703+ struct aufs_rdu *rdu;
28704+ union au_rdu_ent_ul ent;
28705+ unsigned long end;
28706+
28707+ struct super_block *sb;
28708+ int err;
28709+};
28710+
28711+static int au_rdu_fill(struct dir_context *ctx, const char *name, int nlen,
28712+ loff_t offset, u64 h_ino, unsigned int d_type)
28713+{
28714+ int err, len;
28715+ struct au_rdu_arg *arg = container_of(ctx, struct au_rdu_arg, ctx);
28716+ struct aufs_rdu *rdu = arg->rdu;
28717+ struct au_rdu_ent ent;
28718+
28719+ err = 0;
28720+ arg->err = 0;
28721+ au_fset_rdu(rdu->cookie.flags, CALLED);
28722+ len = au_rdu_len(nlen);
28723+ if (arg->ent.ul + len < arg->end) {
28724+ ent.ino = h_ino;
28725+ ent.bindex = rdu->cookie.bindex;
28726+ ent.type = d_type;
28727+ ent.nlen = nlen;
28728+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
28729+ ent.type = DT_UNKNOWN;
28730+
28731+ /* unnecessary to support mmap_sem since this is a dir */
28732+ err = -EFAULT;
28733+ if (copy_to_user(arg->ent.e, &ent, sizeof(ent)))
28734+ goto out;
28735+ if (copy_to_user(arg->ent.e->name, name, nlen))
28736+ goto out;
28737+ /* the terminating NULL */
28738+ if (__put_user(0, arg->ent.e->name + nlen))
28739+ goto out;
28740+ err = 0;
28741+ /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */
28742+ arg->ent.ul += len;
28743+ rdu->rent++;
28744+ } else {
28745+ err = -EFAULT;
28746+ au_fset_rdu(rdu->cookie.flags, FULL);
28747+ rdu->full = 1;
28748+ rdu->tail = arg->ent;
28749+ }
28750+
28751+out:
28752+ /* AuTraceErr(err); */
28753+ return err;
28754+}
28755+
28756+static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg)
28757+{
28758+ int err;
28759+ loff_t offset;
28760+ struct au_rdu_cookie *cookie = &arg->rdu->cookie;
28761+
28762+ /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */
28763+ offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET);
28764+ err = offset;
28765+ if (unlikely(offset != cookie->h_pos))
28766+ goto out;
28767+
28768+ err = 0;
28769+ do {
28770+ arg->err = 0;
28771+ au_fclr_rdu(cookie->flags, CALLED);
28772+ /* smp_mb(); */
28773+ err = vfsub_iterate_dir(h_file, &arg->ctx);
28774+ if (err >= 0)
28775+ err = arg->err;
28776+ } while (!err
28777+ && au_ftest_rdu(cookie->flags, CALLED)
28778+ && !au_ftest_rdu(cookie->flags, FULL));
28779+ cookie->h_pos = h_file->f_pos;
28780+
28781+out:
28782+ AuTraceErr(err);
28783+ return err;
28784+}
28785+
28786+static int au_rdu(struct file *file, struct aufs_rdu *rdu)
28787+{
28788+ int err;
28789+ aufs_bindex_t bbot;
28790+ struct au_rdu_arg arg = {
28791+ .ctx = {
28792+ .actor = au_rdu_fill
28793+ }
28794+ };
28795+ struct dentry *dentry;
28796+ struct inode *inode;
28797+ struct file *h_file;
28798+ struct au_rdu_cookie *cookie = &rdu->cookie;
28799+
28800+ /* VERIFY_WRITE */
28801+ err = !access_ok(rdu->ent.e, rdu->sz);
28802+ if (unlikely(err)) {
28803+ err = -EFAULT;
28804+ AuTraceErr(err);
28805+ goto out;
28806+ }
28807+ rdu->rent = 0;
28808+ rdu->tail = rdu->ent;
28809+ rdu->full = 0;
28810+ arg.rdu = rdu;
28811+ arg.ent = rdu->ent;
28812+ arg.end = arg.ent.ul;
28813+ arg.end += rdu->sz;
28814+
28815+ err = -ENOTDIR;
28816+ if (unlikely(!file->f_op->iterate && !file->f_op->iterate_shared))
28817+ goto out;
28818+
28819+ err = security_file_permission(file, MAY_READ);
28820+ AuTraceErr(err);
28821+ if (unlikely(err))
28822+ goto out;
28823+
28824+ dentry = file->f_path.dentry;
28825+ inode = d_inode(dentry);
28826+ inode_lock_shared(inode);
28827+
28828+ arg.sb = inode->i_sb;
28829+ err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM);
28830+ if (unlikely(err))
28831+ goto out_mtx;
28832+ err = au_alive_dir(dentry);
28833+ if (unlikely(err))
28834+ goto out_si;
28835+ /* todo: reval? */
28836+ fi_read_lock(file);
28837+
28838+ err = -EAGAIN;
28839+ if (unlikely(au_ftest_rdu(cookie->flags, CONT)
28840+ && cookie->generation != au_figen(file)))
28841+ goto out_unlock;
28842+
28843+ err = 0;
28844+ if (!rdu->blk) {
28845+ rdu->blk = au_sbi(arg.sb)->si_rdblk;
28846+ if (!rdu->blk)
28847+ rdu->blk = au_dir_size(file, /*dentry*/NULL);
28848+ }
28849+ bbot = au_fbtop(file);
28850+ if (cookie->bindex < bbot)
28851+ cookie->bindex = bbot;
28852+ bbot = au_fbbot_dir(file);
28853+ /* AuDbg("b%d, b%d\n", cookie->bindex, bbot); */
28854+ for (; !err && cookie->bindex <= bbot;
28855+ cookie->bindex++, cookie->h_pos = 0) {
28856+ h_file = au_hf_dir(file, cookie->bindex);
28857+ if (!h_file)
28858+ continue;
28859+
28860+ au_fclr_rdu(cookie->flags, FULL);
28861+ err = au_rdu_do(h_file, &arg);
28862+ AuTraceErr(err);
28863+ if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err))
28864+ break;
28865+ }
28866+ AuDbg("rent %llu\n", rdu->rent);
28867+
28868+ if (!err && !au_ftest_rdu(cookie->flags, CONT)) {
28869+ rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH);
28870+ au_fset_rdu(cookie->flags, CONT);
28871+ cookie->generation = au_figen(file);
28872+ }
28873+
28874+ ii_read_lock_child(inode);
28875+ fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibtop(inode)));
28876+ ii_read_unlock(inode);
28877+
28878+out_unlock:
28879+ fi_read_unlock(file);
28880+out_si:
28881+ si_read_unlock(arg.sb);
28882+out_mtx:
28883+ inode_unlock_shared(inode);
28884+out:
28885+ AuTraceErr(err);
28886+ return err;
28887+}
28888+
28889+static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu)
28890+{
28891+ int err;
28892+ ino_t ino;
28893+ unsigned long long nent;
28894+ union au_rdu_ent_ul *u;
28895+ struct au_rdu_ent ent;
28896+ struct super_block *sb;
28897+
28898+ err = 0;
28899+ nent = rdu->nent;
28900+ u = &rdu->ent;
28901+ sb = file->f_path.dentry->d_sb;
28902+ si_read_lock(sb, AuLock_FLUSH);
28903+ while (nent-- > 0) {
28904+ /* unnecessary to support mmap_sem since this is a dir */
28905+ err = copy_from_user(&ent, u->e, sizeof(ent));
28906+ if (!err)
28907+ /* VERIFY_WRITE */
28908+ err = !access_ok(&u->e->ino, sizeof(ino));
28909+ if (unlikely(err)) {
28910+ err = -EFAULT;
28911+ AuTraceErr(err);
28912+ break;
28913+ }
28914+
28915+ /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */
28916+ if (!ent.wh)
28917+ err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino);
28918+ else
28919+ err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type,
28920+ &ino);
28921+ if (unlikely(err)) {
28922+ AuTraceErr(err);
28923+ break;
28924+ }
28925+
28926+ err = __put_user(ino, &u->e->ino);
28927+ if (unlikely(err)) {
28928+ err = -EFAULT;
28929+ AuTraceErr(err);
28930+ break;
28931+ }
28932+ u->ul += au_rdu_len(ent.nlen);
28933+ }
28934+ si_read_unlock(sb);
28935+
28936+ return err;
28937+}
28938+
28939+/* ---------------------------------------------------------------------- */
28940+
28941+static int au_rdu_verify(struct aufs_rdu *rdu)
28942+{
28943+ AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | "
28944+ "%llu, b%d, 0x%x, g%u}\n",
28945+ rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ],
28946+ rdu->blk,
28947+ rdu->rent, rdu->shwh, rdu->full,
28948+ rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags,
28949+ rdu->cookie.generation);
28950+
28951+ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu))
28952+ return 0;
28953+
28954+ AuDbg("%u:%u\n",
28955+ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu));
28956+ return -EINVAL;
28957+}
28958+
28959+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
28960+{
28961+ long err, e;
28962+ struct aufs_rdu rdu;
28963+ void __user *p = (void __user *)arg;
28964+
28965+ err = copy_from_user(&rdu, p, sizeof(rdu));
28966+ if (unlikely(err)) {
28967+ err = -EFAULT;
28968+ AuTraceErr(err);
28969+ goto out;
28970+ }
28971+ err = au_rdu_verify(&rdu);
28972+ if (unlikely(err))
28973+ goto out;
28974+
28975+ switch (cmd) {
28976+ case AUFS_CTL_RDU:
28977+ err = au_rdu(file, &rdu);
28978+ if (unlikely(err))
28979+ break;
28980+
28981+ e = copy_to_user(p, &rdu, sizeof(rdu));
28982+ if (unlikely(e)) {
28983+ err = -EFAULT;
28984+ AuTraceErr(err);
28985+ }
28986+ break;
28987+ case AUFS_CTL_RDU_INO:
28988+ err = au_rdu_ino(file, &rdu);
28989+ break;
28990+
28991+ default:
28992+ /* err = -ENOTTY; */
28993+ err = -EINVAL;
28994+ }
28995+
28996+out:
28997+ AuTraceErr(err);
28998+ return err;
28999+}
29000+
29001+#ifdef CONFIG_COMPAT
29002+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
29003+{
29004+ long err, e;
29005+ struct aufs_rdu rdu;
29006+ void __user *p = compat_ptr(arg);
29007+
29008+ /* todo: get_user()? */
29009+ err = copy_from_user(&rdu, p, sizeof(rdu));
29010+ if (unlikely(err)) {
29011+ err = -EFAULT;
29012+ AuTraceErr(err);
29013+ goto out;
29014+ }
29015+ rdu.ent.e = compat_ptr(rdu.ent.ul);
29016+ err = au_rdu_verify(&rdu);
29017+ if (unlikely(err))
29018+ goto out;
29019+
29020+ switch (cmd) {
29021+ case AUFS_CTL_RDU:
29022+ err = au_rdu(file, &rdu);
29023+ if (unlikely(err))
29024+ break;
29025+
29026+ rdu.ent.ul = ptr_to_compat(rdu.ent.e);
29027+ rdu.tail.ul = ptr_to_compat(rdu.tail.e);
29028+ e = copy_to_user(p, &rdu, sizeof(rdu));
29029+ if (unlikely(e)) {
29030+ err = -EFAULT;
29031+ AuTraceErr(err);
29032+ }
29033+ break;
29034+ case AUFS_CTL_RDU_INO:
29035+ err = au_rdu_ino(file, &rdu);
29036+ break;
29037+
29038+ default:
29039+ /* err = -ENOTTY; */
29040+ err = -EINVAL;
29041+ }
29042+
29043+out:
29044+ AuTraceErr(err);
29045+ return err;
29046+}
29047+#endif
29048diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h
29049--- /usr/share/empty/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100
29050+++ linux/fs/aufs/rwsem.h 2020-01-27 10:57:18.178871751 +0100
29051@@ -0,0 +1,73 @@
29052+/* SPDX-License-Identifier: GPL-2.0 */
29053+/*
29054+ * Copyright (C) 2005-2020 Junjiro R. Okajima
29055+ *
29056+ * This program, aufs is free software; you can redistribute it and/or modify
29057+ * it under the terms of the GNU General Public License as published by
29058+ * the Free Software Foundation; either version 2 of the License, or
29059+ * (at your option) any later version.
29060+ *
29061+ * This program is distributed in the hope that it will be useful,
29062+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29063+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29064+ * GNU General Public License for more details.
29065+ *
29066+ * You should have received a copy of the GNU General Public License
29067+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
29068+ */
29069+
29070+/*
29071+ * simple read-write semaphore wrappers
29072+ */
29073+
29074+#ifndef __AUFS_RWSEM_H__
29075+#define __AUFS_RWSEM_H__
29076+
29077+#ifdef __KERNEL__
29078+
29079+#include "debug.h"
29080+
29081+/* in the future, the name 'au_rwsem' will be totally gone */
29082+#define au_rwsem rw_semaphore
29083+
29084+/* to debug easier, do not make them inlined functions */
29085+#define AuRwMustNoWaiters(rw) AuDebugOn(rwsem_is_contended(rw))
29086+/* rwsem_is_locked() is unusable */
29087+#define AuRwMustReadLock(rw) AuDebugOn(!lockdep_recursing(current) \
29088+ && debug_locks \
29089+ && !lockdep_is_held_type(rw, 1))
29090+#define AuRwMustWriteLock(rw) AuDebugOn(!lockdep_recursing(current) \
29091+ && debug_locks \
29092+ && !lockdep_is_held_type(rw, 0))
29093+#define AuRwMustAnyLock(rw) AuDebugOn(!lockdep_recursing(current) \
29094+ && debug_locks \
29095+ && !lockdep_is_held(rw))
29096+#define AuRwDestroy(rw) AuDebugOn(!lockdep_recursing(current) \
29097+ && debug_locks \
29098+ && lockdep_is_held(rw))
29099+
29100+#define au_rw_init(rw) init_rwsem(rw)
29101+
29102+#define au_rw_init_wlock(rw) do { \
29103+ au_rw_init(rw); \
29104+ down_write(rw); \
29105+ } while (0)
29106+
29107+#define au_rw_init_wlock_nested(rw, lsc) do { \
29108+ au_rw_init(rw); \
29109+ down_write_nested(rw, lsc); \
29110+ } while (0)
29111+
29112+#define au_rw_read_lock(rw) down_read(rw)
29113+#define au_rw_read_lock_nested(rw, lsc) down_read_nested(rw, lsc)
29114+#define au_rw_read_unlock(rw) up_read(rw)
29115+#define au_rw_dgrade_lock(rw) downgrade_write(rw)
29116+#define au_rw_write_lock(rw) down_write(rw)
29117+#define au_rw_write_lock_nested(rw, lsc) down_write_nested(rw, lsc)
29118+#define au_rw_write_unlock(rw) up_write(rw)
29119+/* why is not _nested version defined? */
29120+#define au_rw_read_trylock(rw) down_read_trylock(rw)
29121+#define au_rw_write_trylock(rw) down_write_trylock(rw)
29122+
29123+#endif /* __KERNEL__ */
29124+#endif /* __AUFS_RWSEM_H__ */
29125diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
29126--- /usr/share/empty/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100
29127+++ linux/fs/aufs/sbinfo.c 2020-01-27 10:57:18.178871751 +0100
29128@@ -0,0 +1,314 @@
29129+// SPDX-License-Identifier: GPL-2.0
29130+/*
29131+ * Copyright (C) 2005-2020 Junjiro R. Okajima
29132+ *
29133+ * This program, aufs is free software; you can redistribute it and/or modify
29134+ * it under the terms of the GNU General Public License as published by
29135+ * the Free Software Foundation; either version 2 of the License, or
29136+ * (at your option) any later version.
29137+ *
29138+ * This program is distributed in the hope that it will be useful,
29139+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29140+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29141+ * GNU General Public License for more details.
29142+ *
29143+ * You should have received a copy of the GNU General Public License
29144+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
29145+ */
29146+
29147+/*
29148+ * superblock private data
29149+ */
29150+
29151+#include <linux/iversion.h>
29152+#include "aufs.h"
29153+
29154+/*
29155+ * they are necessary regardless sysfs is disabled.
29156+ */
29157+void au_si_free(struct kobject *kobj)
29158+{
29159+ int i;
29160+ struct au_sbinfo *sbinfo;
29161+ char *locked __maybe_unused; /* debug only */
29162+
29163+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
29164+ for (i = 0; i < AuPlink_NHASH; i++)
29165+ AuDebugOn(!hlist_bl_empty(sbinfo->si_plink + i));
29166+ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
29167+
29168+ AuLCntZero(au_lcnt_read(&sbinfo->si_ninodes, /*do_rev*/0));
29169+ au_lcnt_fin(&sbinfo->si_ninodes, /*do_sync*/0);
29170+ AuLCntZero(au_lcnt_read(&sbinfo->si_nfiles, /*do_rev*/0));
29171+ au_lcnt_fin(&sbinfo->si_nfiles, /*do_sync*/0);
29172+
29173+ dbgaufs_si_fin(sbinfo);
29174+ au_rw_write_lock(&sbinfo->si_rwsem);
29175+ au_br_free(sbinfo);
29176+ au_rw_write_unlock(&sbinfo->si_rwsem);
29177+
29178+ au_kfree_try_rcu(sbinfo->si_branch);
29179+ mutex_destroy(&sbinfo->si_xib_mtx);
29180+ AuRwDestroy(&sbinfo->si_rwsem);
29181+
29182+ au_lcnt_wait_for_fin(&sbinfo->si_ninodes);
29183+ /* si_nfiles is waited too */
29184+ au_kfree_rcu(sbinfo);
29185+}
29186+
29187+int au_si_alloc(struct super_block *sb)
29188+{
29189+ int err, i;
29190+ struct au_sbinfo *sbinfo;
29191+
29192+ err = -ENOMEM;
29193+ sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS);
29194+ if (unlikely(!sbinfo))
29195+ goto out;
29196+
29197+ /* will be reallocated separately */
29198+ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
29199+ if (unlikely(!sbinfo->si_branch))
29200+ goto out_sbinfo;
29201+
29202+ err = sysaufs_si_init(sbinfo);
29203+ if (!err) {
29204+ dbgaufs_si_null(sbinfo);
29205+ err = dbgaufs_si_init(sbinfo);
29206+ if (unlikely(err))
29207+ kobject_put(&sbinfo->si_kobj);
29208+ }
29209+ if (unlikely(err))
29210+ goto out_br;
29211+
29212+ au_nwt_init(&sbinfo->si_nowait);
29213+ au_rw_init_wlock(&sbinfo->si_rwsem);
29214+
29215+ au_lcnt_init(&sbinfo->si_ninodes, /*release*/NULL);
29216+ au_lcnt_init(&sbinfo->si_nfiles, /*release*/NULL);
29217+
29218+ sbinfo->si_bbot = -1;
29219+ sbinfo->si_last_br_id = AUFS_BRANCH_MAX / 2;
29220+
29221+ sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
29222+ sbinfo->si_wbr_create = AuWbrCreate_Def;
29223+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup;
29224+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create;
29225+
29226+ au_fhsm_init(sbinfo);
29227+
29228+ sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
29229+
29230+ sbinfo->si_xino_jiffy = jiffies;
29231+ sbinfo->si_xino_expire
29232+ = msecs_to_jiffies(AUFS_XINO_DEF_SEC * MSEC_PER_SEC);
29233+ mutex_init(&sbinfo->si_xib_mtx);
29234+ /* leave si_xib_last_pindex and si_xib_next_bit */
29235+
29236+ INIT_HLIST_BL_HEAD(&sbinfo->si_aopen);
29237+
29238+ sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
29239+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
29240+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
29241+ sbinfo->si_dirwh = AUFS_DIRWH_DEF;
29242+
29243+ for (i = 0; i < AuPlink_NHASH; i++)
29244+ INIT_HLIST_BL_HEAD(sbinfo->si_plink + i);
29245+ init_waitqueue_head(&sbinfo->si_plink_wq);
29246+ spin_lock_init(&sbinfo->si_plink_maint_lock);
29247+
29248+ INIT_HLIST_BL_HEAD(&sbinfo->si_files);
29249+
29250+ /* with getattr by default */
29251+ sbinfo->si_iop_array = aufs_iop;
29252+
29253+ /* leave other members for sysaufs and si_mnt. */
29254+ sbinfo->si_sb = sb;
29255+ sb->s_fs_info = sbinfo;
29256+ si_pid_set(sb);
29257+ return 0; /* success */
29258+
29259+out_br:
29260+ au_kfree_try_rcu(sbinfo->si_branch);
29261+out_sbinfo:
29262+ au_kfree_rcu(sbinfo);
29263+out:
29264+ return err;
29265+}
29266+
29267+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink)
29268+{
29269+ int err, sz;
29270+ struct au_branch **brp;
29271+
29272+ AuRwMustWriteLock(&sbinfo->si_rwsem);
29273+
29274+ err = -ENOMEM;
29275+ sz = sizeof(*brp) * (sbinfo->si_bbot + 1);
29276+ if (unlikely(!sz))
29277+ sz = sizeof(*brp);
29278+ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS,
29279+ may_shrink);
29280+ if (brp) {
29281+ sbinfo->si_branch = brp;
29282+ err = 0;
29283+ }
29284+
29285+ return err;
29286+}
29287+
29288+/* ---------------------------------------------------------------------- */
29289+
29290+unsigned int au_sigen_inc(struct super_block *sb)
29291+{
29292+ unsigned int gen;
29293+ struct inode *inode;
29294+
29295+ SiMustWriteLock(sb);
29296+
29297+ gen = ++au_sbi(sb)->si_generation;
29298+ au_update_digen(sb->s_root);
29299+ inode = d_inode(sb->s_root);
29300+ au_update_iigen(inode, /*half*/0);
29301+ inode_inc_iversion(inode);
29302+ return gen;
29303+}
29304+
29305+aufs_bindex_t au_new_br_id(struct super_block *sb)
29306+{
29307+ aufs_bindex_t br_id;
29308+ int i;
29309+ struct au_sbinfo *sbinfo;
29310+
29311+ SiMustWriteLock(sb);
29312+
29313+ sbinfo = au_sbi(sb);
29314+ for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
29315+ br_id = ++sbinfo->si_last_br_id;
29316+ AuDebugOn(br_id < 0);
29317+ if (br_id && au_br_index(sb, br_id) < 0)
29318+ return br_id;
29319+ }
29320+
29321+ return -1;
29322+}
29323+
29324+/* ---------------------------------------------------------------------- */
29325+
29326+/* it is ok that new 'nwt' tasks are appended while we are sleeping */
29327+int si_read_lock(struct super_block *sb, int flags)
29328+{
29329+ int err;
29330+
29331+ err = 0;
29332+ if (au_ftest_lock(flags, FLUSH))
29333+ au_nwt_flush(&au_sbi(sb)->si_nowait);
29334+
29335+ si_noflush_read_lock(sb);
29336+ err = au_plink_maint(sb, flags);
29337+ if (unlikely(err))
29338+ si_read_unlock(sb);
29339+
29340+ return err;
29341+}
29342+
29343+int si_write_lock(struct super_block *sb, int flags)
29344+{
29345+ int err;
29346+
29347+ if (au_ftest_lock(flags, FLUSH))
29348+ au_nwt_flush(&au_sbi(sb)->si_nowait);
29349+
29350+ si_noflush_write_lock(sb);
29351+ err = au_plink_maint(sb, flags);
29352+ if (unlikely(err))
29353+ si_write_unlock(sb);
29354+
29355+ return err;
29356+}
29357+
29358+/* dentry and super_block lock. call at entry point */
29359+int aufs_read_lock(struct dentry *dentry, int flags)
29360+{
29361+ int err;
29362+ struct super_block *sb;
29363+
29364+ sb = dentry->d_sb;
29365+ err = si_read_lock(sb, flags);
29366+ if (unlikely(err))
29367+ goto out;
29368+
29369+ if (au_ftest_lock(flags, DW))
29370+ di_write_lock_child(dentry);
29371+ else
29372+ di_read_lock_child(dentry, flags);
29373+
29374+ if (au_ftest_lock(flags, GEN)) {
29375+ err = au_digen_test(dentry, au_sigen(sb));
29376+ if (!au_opt_test(au_mntflags(sb), UDBA_NONE))
29377+ AuDebugOn(!err && au_dbrange_test(dentry));
29378+ else if (!err)
29379+ err = au_dbrange_test(dentry);
29380+ if (unlikely(err))
29381+ aufs_read_unlock(dentry, flags);
29382+ }
29383+
29384+out:
29385+ return err;
29386+}
29387+
29388+void aufs_read_unlock(struct dentry *dentry, int flags)
29389+{
29390+ if (au_ftest_lock(flags, DW))
29391+ di_write_unlock(dentry);
29392+ else
29393+ di_read_unlock(dentry, flags);
29394+ si_read_unlock(dentry->d_sb);
29395+}
29396+
29397+void aufs_write_lock(struct dentry *dentry)
29398+{
29399+ si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW);
29400+ di_write_lock_child(dentry);
29401+}
29402+
29403+void aufs_write_unlock(struct dentry *dentry)
29404+{
29405+ di_write_unlock(dentry);
29406+ si_write_unlock(dentry->d_sb);
29407+}
29408+
29409+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
29410+{
29411+ int err;
29412+ unsigned int sigen;
29413+ struct super_block *sb;
29414+
29415+ sb = d1->d_sb;
29416+ err = si_read_lock(sb, flags);
29417+ if (unlikely(err))
29418+ goto out;
29419+
29420+ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIRS));
29421+
29422+ if (au_ftest_lock(flags, GEN)) {
29423+ sigen = au_sigen(sb);
29424+ err = au_digen_test(d1, sigen);
29425+ AuDebugOn(!err && au_dbrange_test(d1));
29426+ if (!err) {
29427+ err = au_digen_test(d2, sigen);
29428+ AuDebugOn(!err && au_dbrange_test(d2));
29429+ }
29430+ if (unlikely(err))
29431+ aufs_read_and_write_unlock2(d1, d2);
29432+ }
29433+
29434+out:
29435+ return err;
29436+}
29437+
29438+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
29439+{
29440+ di_write_unlock2(d1, d2);
29441+ si_read_unlock(d1->d_sb);
29442+}
29443diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
29444--- /usr/share/empty/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
29445+++ linux/fs/aufs/super.c 2020-01-27 10:57:18.178871751 +0100
29446@@ -0,0 +1,1047 @@
29447+// SPDX-License-Identifier: GPL-2.0
29448+/*
29449+ * Copyright (C) 2005-2020 Junjiro R. Okajima
29450+ *
29451+ * This program, aufs is free software; you can redistribute it and/or modify
29452+ * it under the terms of the GNU General Public License as published by
29453+ * the Free Software Foundation; either version 2 of the License, or
29454+ * (at your option) any later version.
29455+ *
29456+ * This program is distributed in the hope that it will be useful,
29457+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29458+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29459+ * GNU General Public License for more details.
29460+ *
29461+ * You should have received a copy of the GNU General Public License
29462+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
29463+ */
29464+
29465+/*
29466+ * mount and super_block operations
29467+ */
29468+
29469+#include <linux/iversion.h>
29470+#include <linux/mm.h>
29471+#include <linux/seq_file.h>
29472+#include <linux/statfs.h>
29473+#include <linux/vmalloc.h>
29474+#include "aufs.h"
29475+
29476+/*
29477+ * super_operations
29478+ */
29479+static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
29480+{
29481+ struct au_icntnr *c;
29482+
29483+ c = au_cache_alloc_icntnr();
29484+ if (c) {
29485+ au_icntnr_init(c);
29486+ inode_set_iversion(&c->vfs_inode, 1); /* sigen(sb); */
29487+ c->iinfo.ii_hinode = NULL;
29488+ return &c->vfs_inode;
29489+ }
29490+ return NULL;
29491+}
29492+
29493+static void aufs_destroy_inode(struct inode *inode)
29494+{
29495+ if (!au_is_bad_inode(inode))
29496+ au_iinfo_fin(inode);
29497+}
29498+
29499+static void aufs_free_inode(struct inode *inode)
29500+{
29501+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
29502+}
29503+
29504+struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
29505+{
29506+ struct inode *inode;
29507+ int err;
29508+
29509+ inode = iget_locked(sb, ino);
29510+ if (unlikely(!inode)) {
29511+ inode = ERR_PTR(-ENOMEM);
29512+ goto out;
29513+ }
29514+ if (!(inode->i_state & I_NEW))
29515+ goto out;
29516+
29517+ err = au_xigen_new(inode);
29518+ if (!err)
29519+ err = au_iinfo_init(inode);
29520+ if (!err)
29521+ inode_inc_iversion(inode);
29522+ else {
29523+ iget_failed(inode);
29524+ inode = ERR_PTR(err);
29525+ }
29526+
29527+out:
29528+ /* never return NULL */
29529+ AuDebugOn(!inode);
29530+ AuTraceErrPtr(inode);
29531+ return inode;
29532+}
29533+
29534+/* lock free root dinfo */
29535+static int au_show_brs(struct seq_file *seq, struct super_block *sb)
29536+{
29537+ int err;
29538+ aufs_bindex_t bindex, bbot;
29539+ struct path path;
29540+ struct au_hdentry *hdp;
29541+ struct au_branch *br;
29542+ au_br_perm_str_t perm;
29543+
29544+ err = 0;
29545+ bbot = au_sbbot(sb);
29546+ bindex = 0;
29547+ hdp = au_hdentry(au_di(sb->s_root), bindex);
29548+ for (; !err && bindex <= bbot; bindex++, hdp++) {
29549+ br = au_sbr(sb, bindex);
29550+ path.mnt = au_br_mnt(br);
29551+ path.dentry = hdp->hd_dentry;
29552+ err = au_seq_path(seq, &path);
29553+ if (!err) {
29554+ au_optstr_br_perm(&perm, br->br_perm);
29555+ seq_printf(seq, "=%s", perm.a);
29556+ if (bindex != bbot)
29557+ seq_putc(seq, ':');
29558+ }
29559+ }
29560+ if (unlikely(err || seq_has_overflowed(seq)))
29561+ err = -E2BIG;
29562+
29563+ return err;
29564+}
29565+
29566+static void au_gen_fmt(char *fmt, int len __maybe_unused, const char *pat,
29567+ const char *append)
29568+{
29569+ char *p;
29570+
29571+ p = fmt;
29572+ while (*pat != ':')
29573+ *p++ = *pat++;
29574+ *p++ = *pat++;
29575+ strcpy(p, append);
29576+ AuDebugOn(strlen(fmt) >= len);
29577+}
29578+
29579+static void au_show_wbr_create(struct seq_file *m, int v,
29580+ struct au_sbinfo *sbinfo)
29581+{
29582+ const char *pat;
29583+ char fmt[32];
29584+ struct au_wbr_mfs *mfs;
29585+
29586+ AuRwMustAnyLock(&sbinfo->si_rwsem);
29587+
29588+ seq_puts(m, ",create=");
29589+ pat = au_optstr_wbr_create(v);
29590+ mfs = &sbinfo->si_wbr_mfs;
29591+ switch (v) {
29592+ case AuWbrCreate_TDP:
29593+ case AuWbrCreate_RR:
29594+ case AuWbrCreate_MFS:
29595+ case AuWbrCreate_PMFS:
29596+ seq_puts(m, pat);
29597+ break;
29598+ case AuWbrCreate_MFSRR:
29599+ case AuWbrCreate_TDMFS:
29600+ case AuWbrCreate_PMFSRR:
29601+ au_gen_fmt(fmt, sizeof(fmt), pat, "%llu");
29602+ seq_printf(m, fmt, mfs->mfsrr_watermark);
29603+ break;
29604+ case AuWbrCreate_MFSV:
29605+ case AuWbrCreate_PMFSV:
29606+ au_gen_fmt(fmt, sizeof(fmt), pat, "%lu");
29607+ seq_printf(m, fmt,
29608+ jiffies_to_msecs(mfs->mfs_expire)
29609+ / MSEC_PER_SEC);
29610+ break;
29611+ case AuWbrCreate_MFSRRV:
29612+ case AuWbrCreate_TDMFSV:
29613+ case AuWbrCreate_PMFSRRV:
29614+ au_gen_fmt(fmt, sizeof(fmt), pat, "%llu:%lu");
29615+ seq_printf(m, fmt, mfs->mfsrr_watermark,
29616+ jiffies_to_msecs(mfs->mfs_expire) / MSEC_PER_SEC);
29617+ break;
29618+ default:
29619+ BUG();
29620+ }
29621+}
29622+
29623+static int au_show_xino(struct seq_file *seq, struct super_block *sb)
29624+{
29625+#ifdef CONFIG_SYSFS
29626+ return 0;
29627+#else
29628+ int err;
29629+ const int len = sizeof(AUFS_XINO_FNAME) - 1;
29630+ aufs_bindex_t bindex, brid;
29631+ struct qstr *name;
29632+ struct file *f;
29633+ struct dentry *d, *h_root;
29634+ struct au_branch *br;
29635+
29636+ AuRwMustAnyLock(&sbinfo->si_rwsem);
29637+
29638+ err = 0;
29639+ f = au_sbi(sb)->si_xib;
29640+ if (!f)
29641+ goto out;
29642+
29643+ /* stop printing the default xino path on the first writable branch */
29644+ h_root = NULL;
29645+ bindex = au_xi_root(sb, f->f_path.dentry);
29646+ if (bindex >= 0) {
29647+ br = au_sbr_sb(sb, bindex);
29648+ h_root = au_br_dentry(br);
29649+ }
29650+
29651+ d = f->f_path.dentry;
29652+ name = &d->d_name;
29653+ /* safe ->d_parent because the file is unlinked */
29654+ if (d->d_parent == h_root
29655+ && name->len == len
29656+ && !memcmp(name->name, AUFS_XINO_FNAME, len))
29657+ goto out;
29658+
29659+ seq_puts(seq, ",xino=");
29660+ err = au_xino_path(seq, f);
29661+
29662+out:
29663+ return err;
29664+#endif
29665+}
29666+
29667+/* seq_file will re-call me in case of too long string */
29668+static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
29669+{
29670+ int err;
29671+ unsigned int mnt_flags, v;
29672+ struct super_block *sb;
29673+ struct au_sbinfo *sbinfo;
29674+
29675+#define AuBool(name, str) do { \
29676+ v = au_opt_test(mnt_flags, name); \
29677+ if (v != au_opt_test(AuOpt_Def, name)) \
29678+ seq_printf(m, ",%s" #str, v ? "" : "no"); \
29679+} while (0)
29680+
29681+#define AuStr(name, str) do { \
29682+ v = mnt_flags & AuOptMask_##name; \
29683+ if (v != (AuOpt_Def & AuOptMask_##name)) \
29684+ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
29685+} while (0)
29686+
29687+#define AuUInt(name, str, val) do { \
29688+ if (val != AUFS_##name##_DEF) \
29689+ seq_printf(m, "," #str "=%u", val); \
29690+} while (0)
29691+
29692+ sb = dentry->d_sb;
29693+ if (sb->s_flags & SB_POSIXACL)
29694+ seq_puts(m, ",acl");
29695+#if 0 /* reserved for future use */
29696+ if (sb->s_flags & SB_I_VERSION)
29697+ seq_puts(m, ",i_version");
29698+#endif
29699+
29700+ /* lock free root dinfo */
29701+ si_noflush_read_lock(sb);
29702+ sbinfo = au_sbi(sb);
29703+ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
29704+
29705+ mnt_flags = au_mntflags(sb);
29706+ if (au_opt_test(mnt_flags, XINO)) {
29707+ err = au_show_xino(m, sb);
29708+ if (unlikely(err))
29709+ goto out;
29710+ } else
29711+ seq_puts(m, ",noxino");
29712+
29713+ AuBool(TRUNC_XINO, trunc_xino);
29714+ AuStr(UDBA, udba);
29715+ AuBool(SHWH, shwh);
29716+ AuBool(PLINK, plink);
29717+ AuBool(DIO, dio);
29718+ AuBool(DIRPERM1, dirperm1);
29719+
29720+ v = sbinfo->si_wbr_create;
29721+ if (v != AuWbrCreate_Def)
29722+ au_show_wbr_create(m, v, sbinfo);
29723+
29724+ v = sbinfo->si_wbr_copyup;
29725+ if (v != AuWbrCopyup_Def)
29726+ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
29727+
29728+ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
29729+ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
29730+ seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
29731+
29732+ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
29733+
29734+ v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC;
29735+ AuUInt(RDCACHE, rdcache, v);
29736+
29737+ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
29738+ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
29739+
29740+ au_fhsm_show(m, sbinfo);
29741+
29742+ AuBool(DIRREN, dirren);
29743+ AuBool(SUM, sum);
29744+ /* AuBool(SUM_W, wsum); */
29745+ AuBool(WARN_PERM, warn_perm);
29746+ AuBool(VERBOSE, verbose);
29747+
29748+out:
29749+ /* be sure to print "br:" last */
29750+ if (!sysaufs_brs) {
29751+ seq_puts(m, ",br:");
29752+ au_show_brs(m, sb);
29753+ }
29754+ si_read_unlock(sb);
29755+ return 0;
29756+
29757+#undef AuBool
29758+#undef AuStr
29759+#undef AuUInt
29760+}
29761+
29762+/* ---------------------------------------------------------------------- */
29763+
29764+/* sum mode which returns the summation for statfs(2) */
29765+
29766+static u64 au_add_till_max(u64 a, u64 b)
29767+{
29768+ u64 old;
29769+
29770+ old = a;
29771+ a += b;
29772+ if (old <= a)
29773+ return a;
29774+ return ULLONG_MAX;
29775+}
29776+
29777+static u64 au_mul_till_max(u64 a, long mul)
29778+{
29779+ u64 old;
29780+
29781+ old = a;
29782+ a *= mul;
29783+ if (old <= a)
29784+ return a;
29785+ return ULLONG_MAX;
29786+}
29787+
29788+static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
29789+{
29790+ int err;
29791+ long bsize, factor;
29792+ u64 blocks, bfree, bavail, files, ffree;
29793+ aufs_bindex_t bbot, bindex, i;
29794+ unsigned char shared;
29795+ struct path h_path;
29796+ struct super_block *h_sb;
29797+
29798+ err = 0;
29799+ bsize = LONG_MAX;
29800+ files = 0;
29801+ ffree = 0;
29802+ blocks = 0;
29803+ bfree = 0;
29804+ bavail = 0;
29805+ bbot = au_sbbot(sb);
29806+ for (bindex = 0; bindex <= bbot; bindex++) {
29807+ h_path.mnt = au_sbr_mnt(sb, bindex);
29808+ h_sb = h_path.mnt->mnt_sb;
29809+ shared = 0;
29810+ for (i = 0; !shared && i < bindex; i++)
29811+ shared = (au_sbr_sb(sb, i) == h_sb);
29812+ if (shared)
29813+ continue;
29814+
29815+ /* sb->s_root for NFS is unreliable */
29816+ h_path.dentry = h_path.mnt->mnt_root;
29817+ err = vfs_statfs(&h_path, buf);
29818+ if (unlikely(err))
29819+ goto out;
29820+
29821+ if (bsize > buf->f_bsize) {
29822+ /*
29823+ * we will reduce bsize, so we have to expand blocks
29824+ * etc. to match them again
29825+ */
29826+ factor = (bsize / buf->f_bsize);
29827+ blocks = au_mul_till_max(blocks, factor);
29828+ bfree = au_mul_till_max(bfree, factor);
29829+ bavail = au_mul_till_max(bavail, factor);
29830+ bsize = buf->f_bsize;
29831+ }
29832+
29833+ factor = (buf->f_bsize / bsize);
29834+ blocks = au_add_till_max(blocks,
29835+ au_mul_till_max(buf->f_blocks, factor));
29836+ bfree = au_add_till_max(bfree,
29837+ au_mul_till_max(buf->f_bfree, factor));
29838+ bavail = au_add_till_max(bavail,
29839+ au_mul_till_max(buf->f_bavail, factor));
29840+ files = au_add_till_max(files, buf->f_files);
29841+ ffree = au_add_till_max(ffree, buf->f_ffree);
29842+ }
29843+
29844+ buf->f_bsize = bsize;
29845+ buf->f_blocks = blocks;
29846+ buf->f_bfree = bfree;
29847+ buf->f_bavail = bavail;
29848+ buf->f_files = files;
29849+ buf->f_ffree = ffree;
29850+ buf->f_frsize = 0;
29851+
29852+out:
29853+ return err;
29854+}
29855+
29856+static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
29857+{
29858+ int err;
29859+ struct path h_path;
29860+ struct super_block *sb;
29861+
29862+ /* lock free root dinfo */
29863+ sb = dentry->d_sb;
29864+ si_noflush_read_lock(sb);
29865+ if (!au_opt_test(au_mntflags(sb), SUM)) {
29866+ /* sb->s_root for NFS is unreliable */
29867+ h_path.mnt = au_sbr_mnt(sb, 0);
29868+ h_path.dentry = h_path.mnt->mnt_root;
29869+ err = vfs_statfs(&h_path, buf);
29870+ } else
29871+ err = au_statfs_sum(sb, buf);
29872+ si_read_unlock(sb);
29873+
29874+ if (!err) {
29875+ buf->f_type = AUFS_SUPER_MAGIC;
29876+ buf->f_namelen = AUFS_MAX_NAMELEN;
29877+ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
29878+ }
29879+ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
29880+
29881+ return err;
29882+}
29883+
29884+/* ---------------------------------------------------------------------- */
29885+
29886+static int aufs_sync_fs(struct super_block *sb, int wait)
29887+{
29888+ int err, e;
29889+ aufs_bindex_t bbot, bindex;
29890+ struct au_branch *br;
29891+ struct super_block *h_sb;
29892+
29893+ err = 0;
29894+ si_noflush_read_lock(sb);
29895+ bbot = au_sbbot(sb);
29896+ for (bindex = 0; bindex <= bbot; bindex++) {
29897+ br = au_sbr(sb, bindex);
29898+ if (!au_br_writable(br->br_perm))
29899+ continue;
29900+
29901+ h_sb = au_sbr_sb(sb, bindex);
29902+ e = vfsub_sync_filesystem(h_sb, wait);
29903+ if (unlikely(e && !err))
29904+ err = e;
29905+ /* go on even if an error happens */
29906+ }
29907+ si_read_unlock(sb);
29908+
29909+ return err;
29910+}
29911+
29912+/* ---------------------------------------------------------------------- */
29913+
29914+/* final actions when unmounting a file system */
29915+static void aufs_put_super(struct super_block *sb)
29916+{
29917+ struct au_sbinfo *sbinfo;
29918+
29919+ sbinfo = au_sbi(sb);
29920+ if (sbinfo)
29921+ kobject_put(&sbinfo->si_kobj);
29922+}
29923+
29924+/* ---------------------------------------------------------------------- */
29925+
29926+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb,
29927+ struct super_block *sb, void *arg)
29928+{
29929+ void *array;
29930+ unsigned long long n, sz;
29931+
29932+ array = NULL;
29933+ n = 0;
29934+ if (!*hint)
29935+ goto out;
29936+
29937+ if (*hint > ULLONG_MAX / sizeof(array)) {
29938+ array = ERR_PTR(-EMFILE);
29939+ pr_err("hint %llu\n", *hint);
29940+ goto out;
29941+ }
29942+
29943+ sz = sizeof(array) * *hint;
29944+ array = kzalloc(sz, GFP_NOFS);
29945+ if (unlikely(!array))
29946+ array = vzalloc(sz);
29947+ if (unlikely(!array)) {
29948+ array = ERR_PTR(-ENOMEM);
29949+ goto out;
29950+ }
29951+
29952+ n = cb(sb, array, *hint, arg);
29953+ AuDebugOn(n > *hint);
29954+
29955+out:
29956+ *hint = n;
29957+ return array;
29958+}
29959+
29960+static unsigned long long au_iarray_cb(struct super_block *sb, void *a,
29961+ unsigned long long max __maybe_unused,
29962+ void *arg)
29963+{
29964+ unsigned long long n;
29965+ struct inode **p, *inode;
29966+ struct list_head *head;
29967+
29968+ n = 0;
29969+ p = a;
29970+ head = arg;
29971+ spin_lock(&sb->s_inode_list_lock);
29972+ list_for_each_entry(inode, head, i_sb_list) {
29973+ if (!au_is_bad_inode(inode)
29974+ && au_ii(inode)->ii_btop >= 0) {
29975+ spin_lock(&inode->i_lock);
29976+ if (atomic_read(&inode->i_count)) {
29977+ au_igrab(inode);
29978+ *p++ = inode;
29979+ n++;
29980+ AuDebugOn(n > max);
29981+ }
29982+ spin_unlock(&inode->i_lock);
29983+ }
29984+ }
29985+ spin_unlock(&sb->s_inode_list_lock);
29986+
29987+ return n;
29988+}
29989+
29990+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max)
29991+{
29992+ struct au_sbinfo *sbi;
29993+
29994+ sbi = au_sbi(sb);
29995+ *max = au_lcnt_read(&sbi->si_ninodes, /*do_rev*/1);
29996+ return au_array_alloc(max, au_iarray_cb, sb, &sb->s_inodes);
29997+}
29998+
29999+void au_iarray_free(struct inode **a, unsigned long long max)
30000+{
30001+ unsigned long long ull;
30002+
30003+ for (ull = 0; ull < max; ull++)
30004+ iput(a[ull]);
30005+ kvfree(a);
30006+}
30007+
30008+/* ---------------------------------------------------------------------- */
30009+
30010+/*
30011+ * refresh dentry and inode at remount time.
30012+ */
30013+/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */
30014+static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags,
30015+ struct dentry *parent)
30016+{
30017+ int err;
30018+
30019+ di_write_lock_child(dentry);
30020+ di_read_lock_parent(parent, AuLock_IR);
30021+ err = au_refresh_dentry(dentry, parent);
30022+ if (!err && dir_flags)
30023+ au_hn_reset(d_inode(dentry), dir_flags);
30024+ di_read_unlock(parent, AuLock_IR);
30025+ di_write_unlock(dentry);
30026+
30027+ return err;
30028+}
30029+
30030+static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
30031+ struct au_sbinfo *sbinfo,
30032+ const unsigned int dir_flags, unsigned int do_idop)
30033+{
30034+ int err;
30035+ struct dentry *parent;
30036+
30037+ err = 0;
30038+ parent = dget_parent(dentry);
30039+ if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
30040+ if (d_really_is_positive(dentry)) {
30041+ if (!d_is_dir(dentry))
30042+ err = au_do_refresh(dentry, /*dir_flags*/0,
30043+ parent);
30044+ else {
30045+ err = au_do_refresh(dentry, dir_flags, parent);
30046+ if (unlikely(err))
30047+ au_fset_si(sbinfo, FAILED_REFRESH_DIR);
30048+ }
30049+ } else
30050+ err = au_do_refresh(dentry, /*dir_flags*/0, parent);
30051+ AuDbgDentry(dentry);
30052+ }
30053+ dput(parent);
30054+
30055+ if (!err) {
30056+ if (do_idop)
30057+ au_refresh_dop(dentry, /*force_reval*/0);
30058+ } else
30059+ au_refresh_dop(dentry, /*force_reval*/1);
30060+
30061+ AuTraceErr(err);
30062+ return err;
30063+}
30064+
30065+static int au_refresh_d(struct super_block *sb, unsigned int do_idop)
30066+{
30067+ int err, i, j, ndentry, e;
30068+ unsigned int sigen;
30069+ struct au_dcsub_pages dpages;
30070+ struct au_dpage *dpage;
30071+ struct dentry **dentries, *d;
30072+ struct au_sbinfo *sbinfo;
30073+ struct dentry *root = sb->s_root;
30074+ const unsigned int dir_flags = au_hi_flags(d_inode(root), /*isdir*/1);
30075+
30076+ if (do_idop)
30077+ au_refresh_dop(root, /*force_reval*/0);
30078+
30079+ err = au_dpages_init(&dpages, GFP_NOFS);
30080+ if (unlikely(err))
30081+ goto out;
30082+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
30083+ if (unlikely(err))
30084+ goto out_dpages;
30085+
30086+ sigen = au_sigen(sb);
30087+ sbinfo = au_sbi(sb);
30088+ for (i = 0; i < dpages.ndpage; i++) {
30089+ dpage = dpages.dpages + i;
30090+ dentries = dpage->dentries;
30091+ ndentry = dpage->ndentry;
30092+ for (j = 0; j < ndentry; j++) {
30093+ d = dentries[j];
30094+ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags,
30095+ do_idop);
30096+ if (unlikely(e && !err))
30097+ err = e;
30098+ /* go on even err */
30099+ }
30100+ }
30101+
30102+out_dpages:
30103+ au_dpages_free(&dpages);
30104+out:
30105+ return err;
30106+}
30107+
30108+static int au_refresh_i(struct super_block *sb, unsigned int do_idop)
30109+{
30110+ int err, e;
30111+ unsigned int sigen;
30112+ unsigned long long max, ull;
30113+ struct inode *inode, **array;
30114+
30115+ array = au_iarray_alloc(sb, &max);
30116+ err = PTR_ERR(array);
30117+ if (IS_ERR(array))
30118+ goto out;
30119+
30120+ err = 0;
30121+ sigen = au_sigen(sb);
30122+ for (ull = 0; ull < max; ull++) {
30123+ inode = array[ull];
30124+ if (unlikely(!inode))
30125+ break;
30126+
30127+ e = 0;
30128+ ii_write_lock_child(inode);
30129+ if (au_iigen(inode, NULL) != sigen) {
30130+ e = au_refresh_hinode_self(inode);
30131+ if (unlikely(e)) {
30132+ au_refresh_iop(inode, /*force_getattr*/1);
30133+ pr_err("error %d, i%lu\n", e, inode->i_ino);
30134+ if (!err)
30135+ err = e;
30136+ /* go on even if err */
30137+ }
30138+ }
30139+ if (!e && do_idop)
30140+ au_refresh_iop(inode, /*force_getattr*/0);
30141+ ii_write_unlock(inode);
30142+ }
30143+
30144+ au_iarray_free(array, max);
30145+
30146+out:
30147+ return err;
30148+}
30149+
30150+static void au_remount_refresh(struct super_block *sb, unsigned int do_idop)
30151+{
30152+ int err, e;
30153+ unsigned int udba;
30154+ aufs_bindex_t bindex, bbot;
30155+ struct dentry *root;
30156+ struct inode *inode;
30157+ struct au_branch *br;
30158+ struct au_sbinfo *sbi;
30159+
30160+ au_sigen_inc(sb);
30161+ sbi = au_sbi(sb);
30162+ au_fclr_si(sbi, FAILED_REFRESH_DIR);
30163+
30164+ root = sb->s_root;
30165+ DiMustNoWaiters(root);
30166+ inode = d_inode(root);
30167+ IiMustNoWaiters(inode);
30168+
30169+ udba = au_opt_udba(sb);
30170+ bbot = au_sbbot(sb);
30171+ for (bindex = 0; bindex <= bbot; bindex++) {
30172+ br = au_sbr(sb, bindex);
30173+ err = au_hnotify_reset_br(udba, br, br->br_perm);
30174+ if (unlikely(err))
30175+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
30176+ bindex, err);
30177+ /* go on even if err */
30178+ }
30179+ au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
30180+
30181+ if (do_idop) {
30182+ if (au_ftest_si(sbi, NO_DREVAL)) {
30183+ AuDebugOn(sb->s_d_op == &aufs_dop_noreval);
30184+ sb->s_d_op = &aufs_dop_noreval;
30185+ AuDebugOn(sbi->si_iop_array == aufs_iop_nogetattr);
30186+ sbi->si_iop_array = aufs_iop_nogetattr;
30187+ } else {
30188+ AuDebugOn(sb->s_d_op == &aufs_dop);
30189+ sb->s_d_op = &aufs_dop;
30190+ AuDebugOn(sbi->si_iop_array == aufs_iop);
30191+ sbi->si_iop_array = aufs_iop;
30192+ }
30193+ pr_info("reset to %ps and %ps\n",
30194+ sb->s_d_op, sbi->si_iop_array);
30195+ }
30196+
30197+ di_write_unlock(root);
30198+ err = au_refresh_d(sb, do_idop);
30199+ e = au_refresh_i(sb, do_idop);
30200+ if (unlikely(e && !err))
30201+ err = e;
30202+ /* aufs_write_lock() calls ..._child() */
30203+ di_write_lock_child(root);
30204+
30205+ au_cpup_attr_all(inode, /*force*/1);
30206+
30207+ if (unlikely(err))
30208+ AuIOErr("refresh failed, ignored, %d\n", err);
30209+}
30210+
30211+/* stop extra interpretation of errno in mount(8), and strange error messages */
30212+static int cvt_err(int err)
30213+{
30214+ AuTraceErr(err);
30215+
30216+ switch (err) {
30217+ case -ENOENT:
30218+ case -ENOTDIR:
30219+ case -EEXIST:
30220+ case -EIO:
30221+ err = -EINVAL;
30222+ }
30223+ return err;
30224+}
30225+
30226+static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
30227+{
30228+ int err, do_dx;
30229+ unsigned int mntflags;
30230+ struct au_opts opts = {
30231+ .opt = NULL
30232+ };
30233+ struct dentry *root;
30234+ struct inode *inode;
30235+ struct au_sbinfo *sbinfo;
30236+
30237+ err = 0;
30238+ root = sb->s_root;
30239+ if (!data || !*data) {
30240+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
30241+ if (!err) {
30242+ di_write_lock_child(root);
30243+ err = au_opts_verify(sb, *flags, /*pending*/0);
30244+ aufs_write_unlock(root);
30245+ }
30246+ goto out;
30247+ }
30248+
30249+ err = -ENOMEM;
30250+ opts.opt = (void *)__get_free_page(GFP_NOFS);
30251+ if (unlikely(!opts.opt))
30252+ goto out;
30253+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
30254+ opts.flags = AuOpts_REMOUNT;
30255+ opts.sb_flags = *flags;
30256+
30257+ /* parse it before aufs lock */
30258+ err = au_opts_parse(sb, data, &opts);
30259+ if (unlikely(err))
30260+ goto out_opts;
30261+
30262+ sbinfo = au_sbi(sb);
30263+ inode = d_inode(root);
30264+ inode_lock(inode);
30265+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
30266+ if (unlikely(err))
30267+ goto out_mtx;
30268+ di_write_lock_child(root);
30269+
30270+ /* au_opts_remount() may return an error */
30271+ err = au_opts_remount(sb, &opts);
30272+ au_opts_free(&opts);
30273+
30274+ if (au_ftest_opts(opts.flags, REFRESH))
30275+ au_remount_refresh(sb, au_ftest_opts(opts.flags, REFRESH_IDOP));
30276+
30277+ if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
30278+ mntflags = au_mntflags(sb);
30279+ do_dx = !!au_opt_test(mntflags, DIO);
30280+ au_dy_arefresh(do_dx);
30281+ }
30282+
30283+ au_fhsm_wrote_all(sb, /*force*/1); /* ?? */
30284+ aufs_write_unlock(root);
30285+
30286+out_mtx:
30287+ inode_unlock(inode);
30288+out_opts:
30289+ free_page((unsigned long)opts.opt);
30290+out:
30291+ err = cvt_err(err);
30292+ AuTraceErr(err);
30293+ return err;
30294+}
30295+
30296+static const struct super_operations aufs_sop = {
30297+ .alloc_inode = aufs_alloc_inode,
30298+ .destroy_inode = aufs_destroy_inode,
30299+ .free_inode = aufs_free_inode,
30300+ /* always deleting, no clearing */
30301+ .drop_inode = generic_delete_inode,
30302+ .show_options = aufs_show_options,
30303+ .statfs = aufs_statfs,
30304+ .put_super = aufs_put_super,
30305+ .sync_fs = aufs_sync_fs,
30306+ .remount_fs = aufs_remount_fs
30307+};
30308+
30309+/* ---------------------------------------------------------------------- */
30310+
30311+static int alloc_root(struct super_block *sb)
30312+{
30313+ int err;
30314+ struct inode *inode;
30315+ struct dentry *root;
30316+
30317+ err = -ENOMEM;
30318+ inode = au_iget_locked(sb, AUFS_ROOT_INO);
30319+ err = PTR_ERR(inode);
30320+ if (IS_ERR(inode))
30321+ goto out;
30322+
30323+ inode->i_op = aufs_iop + AuIop_DIR; /* with getattr by default */
30324+ inode->i_fop = &aufs_dir_fop;
30325+ inode->i_mode = S_IFDIR;
30326+ set_nlink(inode, 2);
30327+ unlock_new_inode(inode);
30328+
30329+ root = d_make_root(inode);
30330+ if (unlikely(!root))
30331+ goto out;
30332+ err = PTR_ERR(root);
30333+ if (IS_ERR(root))
30334+ goto out;
30335+
30336+ err = au_di_init(root);
30337+ if (!err) {
30338+ sb->s_root = root;
30339+ return 0; /* success */
30340+ }
30341+ dput(root);
30342+
30343+out:
30344+ return err;
30345+}
30346+
30347+static int aufs_fill_super(struct super_block *sb, void *raw_data,
30348+ int silent __maybe_unused)
30349+{
30350+ int err;
30351+ struct au_opts opts = {
30352+ .opt = NULL
30353+ };
30354+ struct au_sbinfo *sbinfo;
30355+ struct dentry *root;
30356+ struct inode *inode;
30357+ char *arg = raw_data;
30358+
30359+ if (unlikely(!arg || !*arg)) {
30360+ err = -EINVAL;
30361+ pr_err("no arg\n");
30362+ goto out;
30363+ }
30364+
30365+ err = -ENOMEM;
30366+ opts.opt = (void *)__get_free_page(GFP_NOFS);
30367+ if (unlikely(!opts.opt))
30368+ goto out;
30369+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
30370+ opts.sb_flags = sb->s_flags;
30371+
30372+ err = au_si_alloc(sb);
30373+ if (unlikely(err))
30374+ goto out_opts;
30375+ sbinfo = au_sbi(sb);
30376+
30377+ /* all timestamps always follow the ones on the branch */
30378+ sb->s_flags |= SB_NOATIME | SB_NODIRATIME;
30379+ sb->s_flags |= SB_I_VERSION; /* do we really need this? */
30380+ sb->s_op = &aufs_sop;
30381+ sb->s_d_op = &aufs_dop;
30382+ sb->s_magic = AUFS_SUPER_MAGIC;
30383+ sb->s_maxbytes = 0;
30384+ sb->s_stack_depth = 1;
30385+ au_export_init(sb);
30386+ au_xattr_init(sb);
30387+
30388+ err = alloc_root(sb);
30389+ if (unlikely(err)) {
30390+ si_write_unlock(sb);
30391+ goto out_info;
30392+ }
30393+ root = sb->s_root;
30394+ inode = d_inode(root);
30395+
30396+ /*
30397+ * actually we can parse options regardless aufs lock here.
30398+ * but at remount time, parsing must be done before aufs lock.
30399+ * so we follow the same rule.
30400+ */
30401+ ii_write_lock_parent(inode);
30402+ aufs_write_unlock(root);
30403+ err = au_opts_parse(sb, arg, &opts);
30404+ if (unlikely(err))
30405+ goto out_root;
30406+
30407+ /* lock vfs_inode first, then aufs. */
30408+ inode_lock(inode);
30409+ aufs_write_lock(root);
30410+ err = au_opts_mount(sb, &opts);
30411+ au_opts_free(&opts);
30412+ if (!err && au_ftest_si(sbinfo, NO_DREVAL)) {
30413+ sb->s_d_op = &aufs_dop_noreval;
30414+ pr_info("%ps\n", sb->s_d_op);
30415+ au_refresh_dop(root, /*force_reval*/0);
30416+ sbinfo->si_iop_array = aufs_iop_nogetattr;
30417+ au_refresh_iop(inode, /*force_getattr*/0);
30418+ }
30419+ aufs_write_unlock(root);
30420+ inode_unlock(inode);
30421+ if (!err)
30422+ goto out_opts; /* success */
30423+
30424+out_root:
30425+ dput(root);
30426+ sb->s_root = NULL;
30427+out_info:
30428+ kobject_put(&sbinfo->si_kobj);
30429+ sb->s_fs_info = NULL;
30430+out_opts:
30431+ free_page((unsigned long)opts.opt);
30432+out:
30433+ AuTraceErr(err);
30434+ err = cvt_err(err);
30435+ AuTraceErr(err);
30436+ return err;
30437+}
30438+
30439+/* ---------------------------------------------------------------------- */
30440+
30441+static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags,
30442+ const char *dev_name __maybe_unused,
30443+ void *raw_data)
30444+{
30445+ struct dentry *root;
30446+
30447+ /* all timestamps always follow the ones on the branch */
30448+ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
30449+ root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super);
30450+ if (IS_ERR(root))
30451+ goto out;
30452+
30453+ au_sbilist_add(root->d_sb);
30454+
30455+out:
30456+ return root;
30457+}
30458+
30459+static void aufs_kill_sb(struct super_block *sb)
30460+{
30461+ struct au_sbinfo *sbinfo;
30462+
30463+ sbinfo = au_sbi(sb);
30464+ if (sbinfo) {
30465+ au_sbilist_del(sb);
30466+ aufs_write_lock(sb->s_root);
30467+ au_fhsm_fin(sb);
30468+ if (sbinfo->si_wbr_create_ops->fin)
30469+ sbinfo->si_wbr_create_ops->fin(sb);
30470+ if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
30471+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
30472+ au_remount_refresh(sb, /*do_idop*/0);
30473+ }
30474+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
30475+ au_plink_put(sb, /*verbose*/1);
30476+ au_xino_clr(sb);
30477+ au_dr_opt_flush(sb);
30478+ sbinfo->si_sb = NULL;
30479+ aufs_write_unlock(sb->s_root);
30480+ au_nwt_flush(&sbinfo->si_nowait);
30481+ }
30482+ kill_anon_super(sb);
30483+}
30484+
30485+struct file_system_type aufs_fs_type = {
30486+ .name = AUFS_FSTYPE,
30487+ /* a race between rename and others */
30488+ .fs_flags = FS_RENAME_DOES_D_MOVE,
30489+ .mount = aufs_mount,
30490+ .kill_sb = aufs_kill_sb,
30491+ /* no need to __module_get() and module_put(). */
30492+ .owner = THIS_MODULE,
30493+};
30494diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
30495--- /usr/share/empty/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100
30496+++ linux/fs/aufs/super.h 2020-01-27 10:57:18.178871751 +0100
30497@@ -0,0 +1,589 @@
30498+/* SPDX-License-Identifier: GPL-2.0 */
30499+/*
30500+ * Copyright (C) 2005-2020 Junjiro R. Okajima
30501+ *
30502+ * This program, aufs is free software; you can redistribute it and/or modify
30503+ * it under the terms of the GNU General Public License as published by
30504+ * the Free Software Foundation; either version 2 of the License, or
30505+ * (at your option) any later version.
30506+ *
30507+ * This program is distributed in the hope that it will be useful,
30508+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30509+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30510+ * GNU General Public License for more details.
30511+ *
30512+ * You should have received a copy of the GNU General Public License
30513+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
30514+ */
30515+
30516+/*
30517+ * super_block operations
30518+ */
30519+
30520+#ifndef __AUFS_SUPER_H__
30521+#define __AUFS_SUPER_H__
30522+
30523+#ifdef __KERNEL__
30524+
30525+#include <linux/fs.h>
30526+#include <linux/kobject.h>
30527+#include "hbl.h"
30528+#include "lcnt.h"
30529+#include "rwsem.h"
30530+#include "wkq.h"
30531+
30532+/* policies to select one among multiple writable branches */
30533+struct au_wbr_copyup_operations {
30534+ int (*copyup)(struct dentry *dentry);
30535+};
30536+
30537+#define AuWbr_DIR 1 /* target is a dir */
30538+#define AuWbr_PARENT (1 << 1) /* always require a parent */
30539+
30540+#define au_ftest_wbr(flags, name) ((flags) & AuWbr_##name)
30541+#define au_fset_wbr(flags, name) { (flags) |= AuWbr_##name; }
30542+#define au_fclr_wbr(flags, name) { (flags) &= ~AuWbr_##name; }
30543+
30544+struct au_wbr_create_operations {
30545+ int (*create)(struct dentry *dentry, unsigned int flags);
30546+ int (*init)(struct super_block *sb);
30547+ int (*fin)(struct super_block *sb);
30548+};
30549+
30550+struct au_wbr_mfs {
30551+ struct mutex mfs_lock; /* protect this structure */
30552+ unsigned long mfs_jiffy;
30553+ unsigned long mfs_expire;
30554+ aufs_bindex_t mfs_bindex;
30555+
30556+ unsigned long long mfsrr_bytes;
30557+ unsigned long long mfsrr_watermark;
30558+};
30559+
30560+#define AuPlink_NHASH 100
30561+static inline int au_plink_hash(ino_t ino)
30562+{
30563+ return ino % AuPlink_NHASH;
30564+}
30565+
30566+/* File-based Hierarchical Storage Management */
30567+struct au_fhsm {
30568+#ifdef CONFIG_AUFS_FHSM
30569+ /* allow only one process who can receive the notification */
30570+ spinlock_t fhsm_spin;
30571+ pid_t fhsm_pid;
30572+ wait_queue_head_t fhsm_wqh;
30573+ atomic_t fhsm_readable;
30574+
30575+ /* these are protected by si_rwsem */
30576+ unsigned long fhsm_expire;
30577+ aufs_bindex_t fhsm_bottom;
30578+#endif
30579+};
30580+
30581+struct au_branch;
30582+struct au_sbinfo {
30583+ /* nowait tasks in the system-wide workqueue */
30584+ struct au_nowait_tasks si_nowait;
30585+
30586+ /*
30587+ * tried sb->s_umount, but failed due to the dependency between i_mutex.
30588+ * rwsem for au_sbinfo is necessary.
30589+ */
30590+ struct au_rwsem si_rwsem;
30591+
30592+ /*
30593+ * dirty approach to protect sb->sb_inodes and ->s_files (gone) from
30594+ * remount.
30595+ */
30596+ au_lcnt_t si_ninodes, si_nfiles;
30597+
30598+ /* branch management */
30599+ unsigned int si_generation;
30600+
30601+ /* see AuSi_ flags */
30602+ unsigned char au_si_status;
30603+
30604+ aufs_bindex_t si_bbot;
30605+
30606+ /* dirty trick to keep br_id plus */
30607+ unsigned int si_last_br_id :
30608+ sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1;
30609+ struct au_branch **si_branch;
30610+
30611+ /* policy to select a writable branch */
30612+ unsigned char si_wbr_copyup;
30613+ unsigned char si_wbr_create;
30614+ struct au_wbr_copyup_operations *si_wbr_copyup_ops;
30615+ struct au_wbr_create_operations *si_wbr_create_ops;
30616+
30617+ /* round robin */
30618+ atomic_t si_wbr_rr_next;
30619+
30620+ /* most free space */
30621+ struct au_wbr_mfs si_wbr_mfs;
30622+
30623+ /* File-based Hierarchical Storage Management */
30624+ struct au_fhsm si_fhsm;
30625+
30626+ /* mount flags */
30627+ /* include/asm-ia64/siginfo.h defines a macro named si_flags */
30628+ unsigned int si_mntflags;
30629+
30630+ /* external inode number (bitmap and translation table) */
30631+ vfs_readf_t si_xread;
30632+ vfs_writef_t si_xwrite;
30633+ loff_t si_ximaxent; /* max entries in a xino */
30634+
30635+ struct file *si_xib;
30636+ struct mutex si_xib_mtx; /* protect xib members */
30637+ unsigned long *si_xib_buf;
30638+ unsigned long si_xib_last_pindex;
30639+ int si_xib_next_bit;
30640+
30641+ unsigned long si_xino_jiffy;
30642+ unsigned long si_xino_expire;
30643+ /* reserved for future use */
30644+ /* unsigned long long si_xib_limit; */ /* Max xib file size */
30645+
30646+#ifdef CONFIG_AUFS_EXPORT
30647+ /* i_generation */
30648+ /* todo: make xigen file an array to support many inode numbers */
30649+ struct file *si_xigen;
30650+ atomic_t si_xigen_next;
30651+#endif
30652+
30653+ /* dirty trick to support atomic_open */
30654+ struct hlist_bl_head si_aopen;
30655+
30656+ /* vdir parameters */
30657+ unsigned long si_rdcache; /* max cache time in jiffies */
30658+ unsigned int si_rdblk; /* deblk size */
30659+ unsigned int si_rdhash; /* hash size */
30660+
30661+ /*
30662+ * If the number of whiteouts are larger than si_dirwh, leave all of
30663+ * them after au_whtmp_ren to reduce the cost of rmdir(2).
30664+ * future fsck.aufs or kernel thread will remove them later.
30665+ * Otherwise, remove all whiteouts and the dir in rmdir(2).
30666+ */
30667+ unsigned int si_dirwh;
30668+
30669+ /* pseudo_link list */
30670+ struct hlist_bl_head si_plink[AuPlink_NHASH];
30671+ wait_queue_head_t si_plink_wq;
30672+ spinlock_t si_plink_maint_lock;
30673+ pid_t si_plink_maint_pid;
30674+
30675+ /* file list */
30676+ struct hlist_bl_head si_files;
30677+
30678+ /* with/without getattr, brother of sb->s_d_op */
30679+ const struct inode_operations *si_iop_array;
30680+
30681+ /*
30682+ * sysfs and lifetime management.
30683+ * this is not a small structure and it may be a waste of memory in case
30684+ * of sysfs is disabled, particularly when many aufs-es are mounted.
30685+ * but using sysfs is majority.
30686+ */
30687+ struct kobject si_kobj;
30688+#ifdef CONFIG_DEBUG_FS
30689+ struct dentry *si_dbgaufs;
30690+ struct dentry *si_dbgaufs_plink;
30691+ struct dentry *si_dbgaufs_xib;
30692+#ifdef CONFIG_AUFS_EXPORT
30693+ struct dentry *si_dbgaufs_xigen;
30694+#endif
30695+#endif
30696+
30697+#ifdef CONFIG_AUFS_SBILIST
30698+ struct hlist_bl_node si_list;
30699+#endif
30700+
30701+ /* dirty, necessary for unmounting, sysfs and sysrq */
30702+ struct super_block *si_sb;
30703+};
30704+
30705+/* sbinfo status flags */
30706+/*
30707+ * set true when refresh_dirs() failed at remount time.
30708+ * then try refreshing dirs at access time again.
30709+ * if it is false, refreshing dirs at access time is unnecessary
30710+ */
30711+#define AuSi_FAILED_REFRESH_DIR 1
30712+#define AuSi_FHSM (1 << 1) /* fhsm is active now */
30713+#define AuSi_NO_DREVAL (1 << 2) /* disable all d_revalidate */
30714+
30715+#ifndef CONFIG_AUFS_FHSM
30716+#undef AuSi_FHSM
30717+#define AuSi_FHSM 0
30718+#endif
30719+
30720+static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
30721+ unsigned int flag)
30722+{
30723+ AuRwMustAnyLock(&sbi->si_rwsem);
30724+ return sbi->au_si_status & flag;
30725+}
30726+#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name)
30727+#define au_fset_si(sbinfo, name) do { \
30728+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
30729+ (sbinfo)->au_si_status |= AuSi_##name; \
30730+} while (0)
30731+#define au_fclr_si(sbinfo, name) do { \
30732+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
30733+ (sbinfo)->au_si_status &= ~AuSi_##name; \
30734+} while (0)
30735+
30736+/* ---------------------------------------------------------------------- */
30737+
30738+/* policy to select one among writable branches */
30739+#define AuWbrCopyup(sbinfo, ...) \
30740+ ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__))
30741+#define AuWbrCreate(sbinfo, ...) \
30742+ ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__))
30743+
30744+/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
30745+#define AuLock_DW 1 /* write-lock dentry */
30746+#define AuLock_IR (1 << 1) /* read-lock inode */
30747+#define AuLock_IW (1 << 2) /* write-lock inode */
30748+#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
30749+#define AuLock_DIRS (1 << 4) /* target is a pair of dirs */
30750+ /* except RENAME_EXCHANGE */
30751+#define AuLock_NOPLM (1 << 5) /* return err in plm mode */
30752+#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */
30753+#define AuLock_GEN (1 << 7) /* test digen/iigen */
30754+#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
30755+#define au_fset_lock(flags, name) \
30756+ do { (flags) |= AuLock_##name; } while (0)
30757+#define au_fclr_lock(flags, name) \
30758+ do { (flags) &= ~AuLock_##name; } while (0)
30759+
30760+/* ---------------------------------------------------------------------- */
30761+
30762+/* super.c */
30763+extern struct file_system_type aufs_fs_type;
30764+struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
30765+typedef unsigned long long (*au_arraycb_t)(struct super_block *sb, void *array,
30766+ unsigned long long max, void *arg);
30767+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb,
30768+ struct super_block *sb, void *arg);
30769+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
30770+void au_iarray_free(struct inode **a, unsigned long long max);
30771+
30772+/* sbinfo.c */
30773+void au_si_free(struct kobject *kobj);
30774+int au_si_alloc(struct super_block *sb);
30775+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink);
30776+
30777+unsigned int au_sigen_inc(struct super_block *sb);
30778+aufs_bindex_t au_new_br_id(struct super_block *sb);
30779+
30780+int si_read_lock(struct super_block *sb, int flags);
30781+int si_write_lock(struct super_block *sb, int flags);
30782+int aufs_read_lock(struct dentry *dentry, int flags);
30783+void aufs_read_unlock(struct dentry *dentry, int flags);
30784+void aufs_write_lock(struct dentry *dentry);
30785+void aufs_write_unlock(struct dentry *dentry);
30786+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
30787+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
30788+
30789+/* wbr_policy.c */
30790+extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
30791+extern struct au_wbr_create_operations au_wbr_create_ops[];
30792+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
30793+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex);
30794+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t btop);
30795+
30796+/* mvdown.c */
30797+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *arg);
30798+
30799+#ifdef CONFIG_AUFS_FHSM
30800+/* fhsm.c */
30801+
30802+static inline pid_t au_fhsm_pid(struct au_fhsm *fhsm)
30803+{
30804+ pid_t pid;
30805+
30806+ spin_lock(&fhsm->fhsm_spin);
30807+ pid = fhsm->fhsm_pid;
30808+ spin_unlock(&fhsm->fhsm_spin);
30809+
30810+ return pid;
30811+}
30812+
30813+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force);
30814+void au_fhsm_wrote_all(struct super_block *sb, int force);
30815+int au_fhsm_fd(struct super_block *sb, int oflags);
30816+int au_fhsm_br_alloc(struct au_branch *br);
30817+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex);
30818+void au_fhsm_fin(struct super_block *sb);
30819+void au_fhsm_init(struct au_sbinfo *sbinfo);
30820+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec);
30821+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo);
30822+#else
30823+AuStubVoid(au_fhsm_wrote, struct super_block *sb, aufs_bindex_t bindex,
30824+ int force)
30825+AuStubVoid(au_fhsm_wrote_all, struct super_block *sb, int force)
30826+AuStub(int, au_fhsm_fd, return -EOPNOTSUPP, struct super_block *sb, int oflags)
30827+AuStub(pid_t, au_fhsm_pid, return 0, struct au_fhsm *fhsm)
30828+AuStubInt0(au_fhsm_br_alloc, struct au_branch *br)
30829+AuStubVoid(au_fhsm_set_bottom, struct super_block *sb, aufs_bindex_t bindex)
30830+AuStubVoid(au_fhsm_fin, struct super_block *sb)
30831+AuStubVoid(au_fhsm_init, struct au_sbinfo *sbinfo)
30832+AuStubVoid(au_fhsm_set, struct au_sbinfo *sbinfo, unsigned int sec)
30833+AuStubVoid(au_fhsm_show, struct seq_file *seq, struct au_sbinfo *sbinfo)
30834+#endif
30835+
30836+/* ---------------------------------------------------------------------- */
30837+
30838+static inline struct au_sbinfo *au_sbi(struct super_block *sb)
30839+{
30840+ return sb->s_fs_info;
30841+}
30842+
30843+/* ---------------------------------------------------------------------- */
30844+
30845+#ifdef CONFIG_AUFS_EXPORT
30846+int au_test_nfsd(void);
30847+void au_export_init(struct super_block *sb);
30848+void au_xigen_inc(struct inode *inode);
30849+int au_xigen_new(struct inode *inode);
30850+int au_xigen_set(struct super_block *sb, struct path *path);
30851+void au_xigen_clr(struct super_block *sb);
30852+
30853+static inline int au_busy_or_stale(void)
30854+{
30855+ if (!au_test_nfsd())
30856+ return -EBUSY;
30857+ return -ESTALE;
30858+}
30859+#else
30860+AuStubInt0(au_test_nfsd, void)
30861+AuStubVoid(au_export_init, struct super_block *sb)
30862+AuStubVoid(au_xigen_inc, struct inode *inode)
30863+AuStubInt0(au_xigen_new, struct inode *inode)
30864+AuStubInt0(au_xigen_set, struct super_block *sb, struct path *path)
30865+AuStubVoid(au_xigen_clr, struct super_block *sb)
30866+AuStub(int, au_busy_or_stale, return -EBUSY, void)
30867+#endif /* CONFIG_AUFS_EXPORT */
30868+
30869+/* ---------------------------------------------------------------------- */
30870+
30871+#ifdef CONFIG_AUFS_SBILIST
30872+/* module.c */
30873+extern struct hlist_bl_head au_sbilist;
30874+
30875+static inline void au_sbilist_init(void)
30876+{
30877+ INIT_HLIST_BL_HEAD(&au_sbilist);
30878+}
30879+
30880+static inline void au_sbilist_add(struct super_block *sb)
30881+{
30882+ au_hbl_add(&au_sbi(sb)->si_list, &au_sbilist);
30883+}
30884+
30885+static inline void au_sbilist_del(struct super_block *sb)
30886+{
30887+ au_hbl_del(&au_sbi(sb)->si_list, &au_sbilist);
30888+}
30889+
30890+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
30891+static inline void au_sbilist_lock(void)
30892+{
30893+ hlist_bl_lock(&au_sbilist);
30894+}
30895+
30896+static inline void au_sbilist_unlock(void)
30897+{
30898+ hlist_bl_unlock(&au_sbilist);
30899+}
30900+#define AuGFP_SBILIST GFP_ATOMIC
30901+#else
30902+AuStubVoid(au_sbilist_lock, void)
30903+AuStubVoid(au_sbilist_unlock, void)
30904+#define AuGFP_SBILIST GFP_NOFS
30905+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
30906+#else
30907+AuStubVoid(au_sbilist_init, void)
30908+AuStubVoid(au_sbilist_add, struct super_block *sb)
30909+AuStubVoid(au_sbilist_del, struct super_block *sb)
30910+AuStubVoid(au_sbilist_lock, void)
30911+AuStubVoid(au_sbilist_unlock, void)
30912+#define AuGFP_SBILIST GFP_NOFS
30913+#endif
30914+
30915+/* ---------------------------------------------------------------------- */
30916+
30917+static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
30918+{
30919+ /*
30920+ * This function is a dynamic '__init' function actually,
30921+ * so the tiny check for si_rwsem is unnecessary.
30922+ */
30923+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
30924+#ifdef CONFIG_DEBUG_FS
30925+ sbinfo->si_dbgaufs = NULL;
30926+ sbinfo->si_dbgaufs_plink = NULL;
30927+ sbinfo->si_dbgaufs_xib = NULL;
30928+#ifdef CONFIG_AUFS_EXPORT
30929+ sbinfo->si_dbgaufs_xigen = NULL;
30930+#endif
30931+#endif
30932+}
30933+
30934+/* ---------------------------------------------------------------------- */
30935+
30936+/* current->atomic_flags */
30937+/* this value should never corrupt the ones defined in linux/sched.h */
30938+#define PFA_AUFS 0x10
30939+
30940+TASK_PFA_TEST(AUFS, test_aufs) /* task_test_aufs */
30941+TASK_PFA_SET(AUFS, aufs) /* task_set_aufs */
30942+TASK_PFA_CLEAR(AUFS, aufs) /* task_clear_aufs */
30943+
30944+static inline int si_pid_test(struct super_block *sb)
30945+{
30946+ return !!task_test_aufs(current);
30947+}
30948+
30949+static inline void si_pid_clr(struct super_block *sb)
30950+{
30951+ AuDebugOn(!task_test_aufs(current));
30952+ task_clear_aufs(current);
30953+}
30954+
30955+static inline void si_pid_set(struct super_block *sb)
30956+{
30957+ AuDebugOn(task_test_aufs(current));
30958+ task_set_aufs(current);
30959+}
30960+
30961+/* ---------------------------------------------------------------------- */
30962+
30963+/* lock superblock. mainly for entry point functions */
30964+#define __si_read_lock(sb) au_rw_read_lock(&au_sbi(sb)->si_rwsem)
30965+#define __si_write_lock(sb) au_rw_write_lock(&au_sbi(sb)->si_rwsem)
30966+#define __si_read_trylock(sb) au_rw_read_trylock(&au_sbi(sb)->si_rwsem)
30967+#define __si_write_trylock(sb) au_rw_write_trylock(&au_sbi(sb)->si_rwsem)
30968+/*
30969+#define __si_read_trylock_nested(sb) \
30970+ au_rw_read_trylock_nested(&au_sbi(sb)->si_rwsem)
30971+#define __si_write_trylock_nested(sb) \
30972+ au_rw_write_trylock_nested(&au_sbi(sb)->si_rwsem)
30973+*/
30974+
30975+#define __si_read_unlock(sb) au_rw_read_unlock(&au_sbi(sb)->si_rwsem)
30976+#define __si_write_unlock(sb) au_rw_write_unlock(&au_sbi(sb)->si_rwsem)
30977+#define __si_downgrade_lock(sb) au_rw_dgrade_lock(&au_sbi(sb)->si_rwsem)
30978+
30979+#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
30980+#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
30981+#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
30982+
30983+static inline void si_noflush_read_lock(struct super_block *sb)
30984+{
30985+ __si_read_lock(sb);
30986+ si_pid_set(sb);
30987+}
30988+
30989+static inline int si_noflush_read_trylock(struct super_block *sb)
30990+{
30991+ int locked;
30992+
30993+ locked = __si_read_trylock(sb);
30994+ if (locked)
30995+ si_pid_set(sb);
30996+ return locked;
30997+}
30998+
30999+static inline void si_noflush_write_lock(struct super_block *sb)
31000+{
31001+ __si_write_lock(sb);
31002+ si_pid_set(sb);
31003+}
31004+
31005+static inline int si_noflush_write_trylock(struct super_block *sb)
31006+{
31007+ int locked;
31008+
31009+ locked = __si_write_trylock(sb);
31010+ if (locked)
31011+ si_pid_set(sb);
31012+ return locked;
31013+}
31014+
31015+#if 0 /* reserved */
31016+static inline int si_read_trylock(struct super_block *sb, int flags)
31017+{
31018+ if (au_ftest_lock(flags, FLUSH))
31019+ au_nwt_flush(&au_sbi(sb)->si_nowait);
31020+ return si_noflush_read_trylock(sb);
31021+}
31022+#endif
31023+
31024+static inline void si_read_unlock(struct super_block *sb)
31025+{
31026+ si_pid_clr(sb);
31027+ __si_read_unlock(sb);
31028+}
31029+
31030+#if 0 /* reserved */
31031+static inline int si_write_trylock(struct super_block *sb, int flags)
31032+{
31033+ if (au_ftest_lock(flags, FLUSH))
31034+ au_nwt_flush(&au_sbi(sb)->si_nowait);
31035+ return si_noflush_write_trylock(sb);
31036+}
31037+#endif
31038+
31039+static inline void si_write_unlock(struct super_block *sb)
31040+{
31041+ si_pid_clr(sb);
31042+ __si_write_unlock(sb);
31043+}
31044+
31045+#if 0 /* reserved */
31046+static inline void si_downgrade_lock(struct super_block *sb)
31047+{
31048+ __si_downgrade_lock(sb);
31049+}
31050+#endif
31051+
31052+/* ---------------------------------------------------------------------- */
31053+
31054+static inline aufs_bindex_t au_sbbot(struct super_block *sb)
31055+{
31056+ SiMustAnyLock(sb);
31057+ return au_sbi(sb)->si_bbot;
31058+}
31059+
31060+static inline unsigned int au_mntflags(struct super_block *sb)
31061+{
31062+ SiMustAnyLock(sb);
31063+ return au_sbi(sb)->si_mntflags;
31064+}
31065+
31066+static inline unsigned int au_sigen(struct super_block *sb)
31067+{
31068+ SiMustAnyLock(sb);
31069+ return au_sbi(sb)->si_generation;
31070+}
31071+
31072+static inline struct au_branch *au_sbr(struct super_block *sb,
31073+ aufs_bindex_t bindex)
31074+{
31075+ SiMustAnyLock(sb);
31076+ return au_sbi(sb)->si_branch[0 + bindex];
31077+}
31078+
31079+static inline loff_t au_xi_maxent(struct super_block *sb)
31080+{
31081+ SiMustAnyLock(sb);
31082+ return au_sbi(sb)->si_ximaxent;
31083+}
31084+
31085+#endif /* __KERNEL__ */
31086+#endif /* __AUFS_SUPER_H__ */
31087diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c
31088--- /usr/share/empty/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
31089+++ linux/fs/aufs/sysaufs.c 2020-01-27 10:57:18.178871751 +0100
31090@@ -0,0 +1,93 @@
31091+// SPDX-License-Identifier: GPL-2.0
31092+/*
31093+ * Copyright (C) 2005-2020 Junjiro R. Okajima
31094+ *
31095+ * This program, aufs is free software; you can redistribute it and/or modify
31096+ * it under the terms of the GNU General Public License as published by
31097+ * the Free Software Foundation; either version 2 of the License, or
31098+ * (at your option) any later version.
31099+ *
31100+ * This program is distributed in the hope that it will be useful,
31101+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31102+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31103+ * GNU General Public License for more details.
31104+ *
31105+ * You should have received a copy of the GNU General Public License
31106+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
31107+ */
31108+
31109+/*
31110+ * sysfs interface and lifetime management
31111+ * they are necessary regardless sysfs is disabled.
31112+ */
31113+
31114+#include <linux/random.h>
31115+#include "aufs.h"
31116+
31117+unsigned long sysaufs_si_mask;
31118+struct kset *sysaufs_kset;
31119+
31120+#define AuSiAttr(_name) { \
31121+ .attr = { .name = __stringify(_name), .mode = 0444 }, \
31122+ .show = sysaufs_si_##_name, \
31123+}
31124+
31125+static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
31126+struct attribute *sysaufs_si_attrs[] = {
31127+ &sysaufs_si_attr_xi_path.attr,
31128+ NULL,
31129+};
31130+
31131+static const struct sysfs_ops au_sbi_ops = {
31132+ .show = sysaufs_si_show
31133+};
31134+
31135+static struct kobj_type au_sbi_ktype = {
31136+ .release = au_si_free,
31137+ .sysfs_ops = &au_sbi_ops,
31138+ .default_attrs = sysaufs_si_attrs
31139+};
31140+
31141+/* ---------------------------------------------------------------------- */
31142+
31143+int sysaufs_si_init(struct au_sbinfo *sbinfo)
31144+{
31145+ int err;
31146+
31147+ sbinfo->si_kobj.kset = sysaufs_kset;
31148+ /* cf. sysaufs_name() */
31149+ err = kobject_init_and_add
31150+ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL,
31151+ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
31152+
31153+ return err;
31154+}
31155+
31156+void sysaufs_fin(void)
31157+{
31158+ sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group);
31159+ kset_unregister(sysaufs_kset);
31160+}
31161+
31162+int __init sysaufs_init(void)
31163+{
31164+ int err;
31165+
31166+ do {
31167+ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
31168+ } while (!sysaufs_si_mask);
31169+
31170+ err = -EINVAL;
31171+ sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
31172+ if (unlikely(!sysaufs_kset))
31173+ goto out;
31174+ err = PTR_ERR(sysaufs_kset);
31175+ if (IS_ERR(sysaufs_kset))
31176+ goto out;
31177+ err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group);
31178+ if (unlikely(err))
31179+ kset_unregister(sysaufs_kset);
31180+
31181+out:
31182+ return err;
31183+}
31184diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h
31185--- /usr/share/empty/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
31186+++ linux/fs/aufs/sysaufs.h 2020-01-27 10:57:18.178871751 +0100
31187@@ -0,0 +1,102 @@
31188+/* SPDX-License-Identifier: GPL-2.0 */
31189+/*
31190+ * Copyright (C) 2005-2020 Junjiro R. Okajima
31191+ *
31192+ * This program, aufs is free software; you can redistribute it and/or modify
31193+ * it under the terms of the GNU General Public License as published by
31194+ * the Free Software Foundation; either version 2 of the License, or
31195+ * (at your option) any later version.
31196+ *
31197+ * This program is distributed in the hope that it will be useful,
31198+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31199+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31200+ * GNU General Public License for more details.
31201+ *
31202+ * You should have received a copy of the GNU General Public License
31203+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
31204+ */
31205+
31206+/*
31207+ * sysfs interface and mount lifetime management
31208+ */
31209+
31210+#ifndef __SYSAUFS_H__
31211+#define __SYSAUFS_H__
31212+
31213+#ifdef __KERNEL__
31214+
31215+#include <linux/sysfs.h>
31216+#include "module.h"
31217+
31218+struct super_block;
31219+struct au_sbinfo;
31220+
31221+struct sysaufs_si_attr {
31222+ struct attribute attr;
31223+ int (*show)(struct seq_file *seq, struct super_block *sb);
31224+};
31225+
31226+/* ---------------------------------------------------------------------- */
31227+
31228+/* sysaufs.c */
31229+extern unsigned long sysaufs_si_mask;
31230+extern struct kset *sysaufs_kset;
31231+extern struct attribute *sysaufs_si_attrs[];
31232+int sysaufs_si_init(struct au_sbinfo *sbinfo);
31233+int __init sysaufs_init(void);
31234+void sysaufs_fin(void);
31235+
31236+/* ---------------------------------------------------------------------- */
31237+
31238+/* some people doesn't like to show a pointer in kernel */
31239+static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
31240+{
31241+ return sysaufs_si_mask ^ (unsigned long)sbinfo;
31242+}
31243+
31244+#define SysaufsSiNamePrefix "si_"
31245+#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16)
31246+static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
31247+{
31248+ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
31249+ sysaufs_si_id(sbinfo));
31250+}
31251+
31252+struct au_branch;
31253+#ifdef CONFIG_SYSFS
31254+/* sysfs.c */
31255+extern struct attribute_group *sysaufs_attr_group;
31256+
31257+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
31258+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
31259+ char *buf);
31260+long au_brinfo_ioctl(struct file *file, unsigned long arg);
31261+#ifdef CONFIG_COMPAT
31262+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg);
31263+#endif
31264+
31265+void sysaufs_br_init(struct au_branch *br);
31266+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
31267+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
31268+
31269+#define sysaufs_brs_init() do {} while (0)
31270+
31271+#else
31272+#define sysaufs_attr_group NULL
31273+
31274+AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb)
31275+AuStub(ssize_t, sysaufs_si_show, return 0, struct kobject *kobj,
31276+ struct attribute *attr, char *buf)
31277+AuStubVoid(sysaufs_br_init, struct au_branch *br)
31278+AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
31279+AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
31280+
31281+static inline void sysaufs_brs_init(void)
31282+{
31283+ sysaufs_brs = 0;
31284+}
31285+
31286+#endif /* CONFIG_SYSFS */
31287+
31288+#endif /* __KERNEL__ */
31289+#endif /* __SYSAUFS_H__ */
31290diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
31291--- /usr/share/empty/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100
31292+++ linux/fs/aufs/sysfs.c 2020-01-27 10:57:18.178871751 +0100
31293@@ -0,0 +1,374 @@
31294+// SPDX-License-Identifier: GPL-2.0
31295+/*
31296+ * Copyright (C) 2005-2020 Junjiro R. Okajima
31297+ *
31298+ * This program, aufs is free software; you can redistribute it and/or modify
31299+ * it under the terms of the GNU General Public License as published by
31300+ * the Free Software Foundation; either version 2 of the License, or
31301+ * (at your option) any later version.
31302+ *
31303+ * This program is distributed in the hope that it will be useful,
31304+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31305+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31306+ * GNU General Public License for more details.
31307+ *
31308+ * You should have received a copy of the GNU General Public License
31309+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
31310+ */
31311+
31312+/*
31313+ * sysfs interface
31314+ */
31315+
31316+#include <linux/compat.h>
31317+#include <linux/seq_file.h>
31318+#include "aufs.h"
31319+
31320+#ifdef CONFIG_AUFS_FS_MODULE
31321+/* this entry violates the "one line per file" policy of sysfs */
31322+static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr,
31323+ char *buf)
31324+{
31325+ ssize_t err;
31326+ static char *conf =
31327+/* this file is generated at compiling */
31328+#include "conf.str"
31329+ ;
31330+
31331+ err = snprintf(buf, PAGE_SIZE, conf);
31332+ if (unlikely(err >= PAGE_SIZE))
31333+ err = -EFBIG;
31334+ return err;
31335+}
31336+
31337+static struct kobj_attribute au_config_attr = __ATTR_RO(config);
31338+#endif
31339+
31340+static struct attribute *au_attr[] = {
31341+#ifdef CONFIG_AUFS_FS_MODULE
31342+ &au_config_attr.attr,
31343+#endif
31344+ NULL, /* need to NULL terminate the list of attributes */
31345+};
31346+
31347+static struct attribute_group sysaufs_attr_group_body = {
31348+ .attrs = au_attr
31349+};
31350+
31351+struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
31352+
31353+/* ---------------------------------------------------------------------- */
31354+
31355+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
31356+{
31357+ int err;
31358+
31359+ SiMustAnyLock(sb);
31360+
31361+ err = 0;
31362+ if (au_opt_test(au_mntflags(sb), XINO)) {
31363+ err = au_xino_path(seq, au_sbi(sb)->si_xib);
31364+ seq_putc(seq, '\n');
31365+ }
31366+ return err;
31367+}
31368+
31369+/*
31370+ * the lifetime of branch is independent from the entry under sysfs.
31371+ * sysfs handles the lifetime of the entry, and never call ->show() after it is
31372+ * unlinked.
31373+ */
31374+static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
31375+ aufs_bindex_t bindex, int idx)
31376+{
31377+ int err;
31378+ struct path path;
31379+ struct dentry *root;
31380+ struct au_branch *br;
31381+ au_br_perm_str_t perm;
31382+
31383+ AuDbg("b%d\n", bindex);
31384+
31385+ err = 0;
31386+ root = sb->s_root;
31387+ di_read_lock_parent(root, !AuLock_IR);
31388+ br = au_sbr(sb, bindex);
31389+
31390+ switch (idx) {
31391+ case AuBrSysfs_BR:
31392+ path.mnt = au_br_mnt(br);
31393+ path.dentry = au_h_dptr(root, bindex);
31394+ err = au_seq_path(seq, &path);
31395+ if (!err) {
31396+ au_optstr_br_perm(&perm, br->br_perm);
31397+ seq_printf(seq, "=%s\n", perm.a);
31398+ }
31399+ break;
31400+ case AuBrSysfs_BRID:
31401+ seq_printf(seq, "%d\n", br->br_id);
31402+ break;
31403+ }
31404+ di_read_unlock(root, !AuLock_IR);
31405+ if (unlikely(err || seq_has_overflowed(seq)))
31406+ err = -E2BIG;
31407+
31408+ return err;
31409+}
31410+
31411+/* ---------------------------------------------------------------------- */
31412+
31413+static struct seq_file *au_seq(char *p, ssize_t len)
31414+{
31415+ struct seq_file *seq;
31416+
31417+ seq = kzalloc(sizeof(*seq), GFP_NOFS);
31418+ if (seq) {
31419+ /* mutex_init(&seq.lock); */
31420+ seq->buf = p;
31421+ seq->size = len;
31422+ return seq; /* success */
31423+ }
31424+
31425+ seq = ERR_PTR(-ENOMEM);
31426+ return seq;
31427+}
31428+
31429+#define SysaufsBr_PREFIX "br"
31430+#define SysaufsBrid_PREFIX "brid"
31431+
31432+/* todo: file size may exceed PAGE_SIZE */
31433+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
31434+ char *buf)
31435+{
31436+ ssize_t err;
31437+ int idx;
31438+ long l;
31439+ aufs_bindex_t bbot;
31440+ struct au_sbinfo *sbinfo;
31441+ struct super_block *sb;
31442+ struct seq_file *seq;
31443+ char *name;
31444+ struct attribute **cattr;
31445+
31446+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
31447+ sb = sbinfo->si_sb;
31448+
31449+ /*
31450+ * prevent a race condition between sysfs and aufs.
31451+ * for instance, sysfs_file_read() calls sysfs_get_active_two() which
31452+ * prohibits maintaining the sysfs entries.
31453+ * hew we acquire read lock after sysfs_get_active_two().
31454+ * on the other hand, the remount process may maintain the sysfs/aufs
31455+ * entries after acquiring write lock.
31456+ * it can cause a deadlock.
31457+ * simply we gave up processing read here.
31458+ */
31459+ err = -EBUSY;
31460+ if (unlikely(!si_noflush_read_trylock(sb)))
31461+ goto out;
31462+
31463+ seq = au_seq(buf, PAGE_SIZE);
31464+ err = PTR_ERR(seq);
31465+ if (IS_ERR(seq))
31466+ goto out_unlock;
31467+
31468+ name = (void *)attr->name;
31469+ cattr = sysaufs_si_attrs;
31470+ while (*cattr) {
31471+ if (!strcmp(name, (*cattr)->name)) {
31472+ err = container_of(*cattr, struct sysaufs_si_attr, attr)
31473+ ->show(seq, sb);
31474+ goto out_seq;
31475+ }
31476+ cattr++;
31477+ }
31478+
31479+ if (!strncmp(name, SysaufsBrid_PREFIX,
31480+ sizeof(SysaufsBrid_PREFIX) - 1)) {
31481+ idx = AuBrSysfs_BRID;
31482+ name += sizeof(SysaufsBrid_PREFIX) - 1;
31483+ } else if (!strncmp(name, SysaufsBr_PREFIX,
31484+ sizeof(SysaufsBr_PREFIX) - 1)) {
31485+ idx = AuBrSysfs_BR;
31486+ name += sizeof(SysaufsBr_PREFIX) - 1;
31487+ } else
31488+ BUG();
31489+
31490+ err = kstrtol(name, 10, &l);
31491+ if (!err) {
31492+ bbot = au_sbbot(sb);
31493+ if (l <= bbot)
31494+ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l, idx);
31495+ else
31496+ err = -ENOENT;
31497+ }
31498+
31499+out_seq:
31500+ if (!err) {
31501+ err = seq->count;
31502+ /* sysfs limit */
31503+ if (unlikely(err == PAGE_SIZE))
31504+ err = -EFBIG;
31505+ }
31506+ au_kfree_rcu(seq);
31507+out_unlock:
31508+ si_read_unlock(sb);
31509+out:
31510+ return err;
31511+}
31512+
31513+/* ---------------------------------------------------------------------- */
31514+
31515+static int au_brinfo(struct super_block *sb, union aufs_brinfo __user *arg)
31516+{
31517+ int err;
31518+ int16_t brid;
31519+ aufs_bindex_t bindex, bbot;
31520+ size_t sz;
31521+ char *buf;
31522+ struct seq_file *seq;
31523+ struct au_branch *br;
31524+
31525+ si_read_lock(sb, AuLock_FLUSH);
31526+ bbot = au_sbbot(sb);
31527+ err = bbot + 1;
31528+ if (!arg)
31529+ goto out;
31530+
31531+ err = -ENOMEM;
31532+ buf = (void *)__get_free_page(GFP_NOFS);
31533+ if (unlikely(!buf))
31534+ goto out;
31535+
31536+ seq = au_seq(buf, PAGE_SIZE);
31537+ err = PTR_ERR(seq);
31538+ if (IS_ERR(seq))
31539+ goto out_buf;
31540+
31541+ sz = sizeof(*arg) - offsetof(union aufs_brinfo, path);
31542+ for (bindex = 0; bindex <= bbot; bindex++, arg++) {
31543+ /* VERIFY_WRITE */
31544+ err = !access_ok(arg, sizeof(*arg));
31545+ if (unlikely(err))
31546+ break;
31547+
31548+ br = au_sbr(sb, bindex);
31549+ brid = br->br_id;
31550+ BUILD_BUG_ON(sizeof(brid) != sizeof(arg->id));
31551+ err = __put_user(brid, &arg->id);
31552+ if (unlikely(err))
31553+ break;
31554+
31555+ BUILD_BUG_ON(sizeof(br->br_perm) != sizeof(arg->perm));
31556+ err = __put_user(br->br_perm, &arg->perm);
31557+ if (unlikely(err))
31558+ break;
31559+
31560+ err = au_seq_path(seq, &br->br_path);
31561+ if (unlikely(err))
31562+ break;
31563+ seq_putc(seq, '\0');
31564+ if (!seq_has_overflowed(seq)) {
31565+ err = copy_to_user(arg->path, seq->buf, seq->count);
31566+ seq->count = 0;
31567+ if (unlikely(err))
31568+ break;
31569+ } else {
31570+ err = -E2BIG;
31571+ goto out_seq;
31572+ }
31573+ }
31574+ if (unlikely(err))
31575+ err = -EFAULT;
31576+
31577+out_seq:
31578+ au_kfree_rcu(seq);
31579+out_buf:
31580+ free_page((unsigned long)buf);
31581+out:
31582+ si_read_unlock(sb);
31583+ return err;
31584+}
31585+
31586+long au_brinfo_ioctl(struct file *file, unsigned long arg)
31587+{
31588+ return au_brinfo(file->f_path.dentry->d_sb, (void __user *)arg);
31589+}
31590+
31591+#ifdef CONFIG_COMPAT
31592+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg)
31593+{
31594+ return au_brinfo(file->f_path.dentry->d_sb, compat_ptr(arg));
31595+}
31596+#endif
31597+
31598+/* ---------------------------------------------------------------------- */
31599+
31600+void sysaufs_br_init(struct au_branch *br)
31601+{
31602+ int i;
31603+ struct au_brsysfs *br_sysfs;
31604+ struct attribute *attr;
31605+
31606+ br_sysfs = br->br_sysfs;
31607+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
31608+ attr = &br_sysfs->attr;
31609+ sysfs_attr_init(attr);
31610+ attr->name = br_sysfs->name;
31611+ attr->mode = 0444;
31612+ br_sysfs++;
31613+ }
31614+}
31615+
31616+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
31617+{
31618+ struct au_branch *br;
31619+ struct kobject *kobj;
31620+ struct au_brsysfs *br_sysfs;
31621+ int i;
31622+ aufs_bindex_t bbot;
31623+
31624+ if (!sysaufs_brs)
31625+ return;
31626+
31627+ kobj = &au_sbi(sb)->si_kobj;
31628+ bbot = au_sbbot(sb);
31629+ for (; bindex <= bbot; bindex++) {
31630+ br = au_sbr(sb, bindex);
31631+ br_sysfs = br->br_sysfs;
31632+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
31633+ sysfs_remove_file(kobj, &br_sysfs->attr);
31634+ br_sysfs++;
31635+ }
31636+ }
31637+}
31638+
31639+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
31640+{
31641+ int err, i;
31642+ aufs_bindex_t bbot;
31643+ struct kobject *kobj;
31644+ struct au_branch *br;
31645+ struct au_brsysfs *br_sysfs;
31646+
31647+ if (!sysaufs_brs)
31648+ return;
31649+
31650+ kobj = &au_sbi(sb)->si_kobj;
31651+ bbot = au_sbbot(sb);
31652+ for (; bindex <= bbot; bindex++) {
31653+ br = au_sbr(sb, bindex);
31654+ br_sysfs = br->br_sysfs;
31655+ snprintf(br_sysfs[AuBrSysfs_BR].name, sizeof(br_sysfs->name),
31656+ SysaufsBr_PREFIX "%d", bindex);
31657+ snprintf(br_sysfs[AuBrSysfs_BRID].name, sizeof(br_sysfs->name),
31658+ SysaufsBrid_PREFIX "%d", bindex);
31659+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
31660+ err = sysfs_create_file(kobj, &br_sysfs->attr);
31661+ if (unlikely(err))
31662+ pr_warn("failed %s under sysfs(%d)\n",
31663+ br_sysfs->name, err);
31664+ br_sysfs++;
31665+ }
31666+ }
31667+}
31668diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
31669--- /usr/share/empty/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100
31670+++ linux/fs/aufs/sysrq.c 2020-01-27 10:57:18.178871751 +0100
31671@@ -0,0 +1,149 @@
31672+// SPDX-License-Identifier: GPL-2.0
31673+/*
31674+ * Copyright (C) 2005-2020 Junjiro R. Okajima
31675+ *
31676+ * This program, aufs is free software; you can redistribute it and/or modify
31677+ * it under the terms of the GNU General Public License as published by
31678+ * the Free Software Foundation; either version 2 of the License, or
31679+ * (at your option) any later version.
31680+ *
31681+ * This program is distributed in the hope that it will be useful,
31682+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31683+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31684+ * GNU General Public License for more details.
31685+ *
31686+ * You should have received a copy of the GNU General Public License
31687+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
31688+ */
31689+
31690+/*
31691+ * magic sysrq handler
31692+ */
31693+
31694+/* #include <linux/sysrq.h> */
31695+#include <linux/writeback.h>
31696+#include "aufs.h"
31697+
31698+/* ---------------------------------------------------------------------- */
31699+
31700+static void sysrq_sb(struct super_block *sb)
31701+{
31702+ char *plevel;
31703+ struct au_sbinfo *sbinfo;
31704+ struct file *file;
31705+ struct hlist_bl_head *files;
31706+ struct hlist_bl_node *pos;
31707+ struct au_finfo *finfo;
31708+ struct inode *i;
31709+
31710+ plevel = au_plevel;
31711+ au_plevel = KERN_WARNING;
31712+
31713+ /* since we define pr_fmt, call printk directly */
31714+#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str)
31715+
31716+ sbinfo = au_sbi(sb);
31717+ printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo));
31718+ pr("superblock\n");
31719+ au_dpri_sb(sb);
31720+
31721+#if 0 /* reserved */
31722+ do {
31723+ int err, i, j, ndentry;
31724+ struct au_dcsub_pages dpages;
31725+ struct au_dpage *dpage;
31726+
31727+ err = au_dpages_init(&dpages, GFP_ATOMIC);
31728+ if (unlikely(err))
31729+ break;
31730+ err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL);
31731+ if (!err)
31732+ for (i = 0; i < dpages.ndpage; i++) {
31733+ dpage = dpages.dpages + i;
31734+ ndentry = dpage->ndentry;
31735+ for (j = 0; j < ndentry; j++)
31736+ au_dpri_dentry(dpage->dentries[j]);
31737+ }
31738+ au_dpages_free(&dpages);
31739+ } while (0);
31740+#endif
31741+
31742+ pr("isolated inode\n");
31743+ spin_lock(&sb->s_inode_list_lock);
31744+ list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
31745+ spin_lock(&i->i_lock);
31746+ if (hlist_empty(&i->i_dentry))
31747+ au_dpri_inode(i);
31748+ spin_unlock(&i->i_lock);
31749+ }
31750+ spin_unlock(&sb->s_inode_list_lock);
31751+
31752+ pr("files\n");
31753+ files = &au_sbi(sb)->si_files;
31754+ hlist_bl_lock(files);
31755+ hlist_bl_for_each_entry(finfo, pos, files, fi_hlist) {
31756+ umode_t mode;
31757+
31758+ file = finfo->fi_file;
31759+ mode = file_inode(file)->i_mode;
31760+ if (!special_file(mode))
31761+ au_dpri_file(file);
31762+ }
31763+ hlist_bl_unlock(files);
31764+ pr("done\n");
31765+
31766+#undef pr
31767+ au_plevel = plevel;
31768+}
31769+
31770+/* ---------------------------------------------------------------------- */
31771+
31772+/* module parameter */
31773+static char *aufs_sysrq_key = "a";
31774+module_param_named(sysrq, aufs_sysrq_key, charp, 0444);
31775+MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
31776+
31777+static void au_sysrq(int key __maybe_unused)
31778+{
31779+ struct au_sbinfo *sbinfo;
31780+ struct hlist_bl_node *pos;
31781+
31782+ lockdep_off();
31783+ au_sbilist_lock();
31784+ hlist_bl_for_each_entry(sbinfo, pos, &au_sbilist, si_list)
31785+ sysrq_sb(sbinfo->si_sb);
31786+ au_sbilist_unlock();
31787+ lockdep_on();
31788+}
31789+
31790+static struct sysrq_key_op au_sysrq_op = {
31791+ .handler = au_sysrq,
31792+ .help_msg = "Aufs",
31793+ .action_msg = "Aufs",
31794+ .enable_mask = SYSRQ_ENABLE_DUMP
31795+};
31796+
31797+/* ---------------------------------------------------------------------- */
31798+
31799+int __init au_sysrq_init(void)
31800+{
31801+ int err;
31802+ char key;
31803+
31804+ err = -1;
31805+ key = *aufs_sysrq_key;
31806+ if ('a' <= key && key <= 'z')
31807+ err = register_sysrq_key(key, &au_sysrq_op);
31808+ if (unlikely(err))
31809+ pr_err("err %d, sysrq=%c\n", err, key);
31810+ return err;
31811+}
31812+
31813+void au_sysrq_fin(void)
31814+{
31815+ int err;
31816+
31817+ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
31818+ if (unlikely(err))
31819+ pr_err("err %d (ignored)\n", err);
31820+}
31821diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
31822--- /usr/share/empty/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100
31823+++ linux/fs/aufs/vdir.c 2020-01-27 10:57:18.178871751 +0100
31824@@ -0,0 +1,896 @@
31825+// SPDX-License-Identifier: GPL-2.0
31826+/*
31827+ * Copyright (C) 2005-2020 Junjiro R. Okajima
31828+ *
31829+ * This program, aufs is free software; you can redistribute it and/or modify
31830+ * it under the terms of the GNU General Public License as published by
31831+ * the Free Software Foundation; either version 2 of the License, or
31832+ * (at your option) any later version.
31833+ *
31834+ * This program is distributed in the hope that it will be useful,
31835+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31836+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31837+ * GNU General Public License for more details.
31838+ *
31839+ * You should have received a copy of the GNU General Public License
31840+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
31841+ */
31842+
31843+/*
31844+ * virtual or vertical directory
31845+ */
31846+
31847+#include <linux/iversion.h>
31848+#include "aufs.h"
31849+
31850+static unsigned int calc_size(int nlen)
31851+{
31852+ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
31853+}
31854+
31855+static int set_deblk_end(union au_vdir_deblk_p *p,
31856+ union au_vdir_deblk_p *deblk_end)
31857+{
31858+ if (calc_size(0) <= deblk_end->deblk - p->deblk) {
31859+ p->de->de_str.len = 0;
31860+ /* smp_mb(); */
31861+ return 0;
31862+ }
31863+ return -1; /* error */
31864+}
31865+
31866+/* returns true or false */
31867+static int is_deblk_end(union au_vdir_deblk_p *p,
31868+ union au_vdir_deblk_p *deblk_end)
31869+{
31870+ if (calc_size(0) <= deblk_end->deblk - p->deblk)
31871+ return !p->de->de_str.len;
31872+ return 1;
31873+}
31874+
31875+static unsigned char *last_deblk(struct au_vdir *vdir)
31876+{
31877+ return vdir->vd_deblk[vdir->vd_nblk - 1];
31878+}
31879+
31880+/* ---------------------------------------------------------------------- */
31881+
31882+/* estimate the appropriate size for name hash table */
31883+unsigned int au_rdhash_est(loff_t sz)
31884+{
31885+ unsigned int n;
31886+
31887+ n = UINT_MAX;
31888+ sz >>= 10;
31889+ if (sz < n)
31890+ n = sz;
31891+ if (sz < AUFS_RDHASH_DEF)
31892+ n = AUFS_RDHASH_DEF;
31893+ /* pr_info("n %u\n", n); */
31894+ return n;
31895+}
31896+
31897+/*
31898+ * the allocated memory has to be freed by
31899+ * au_nhash_wh_free() or au_nhash_de_free().
31900+ */
31901+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
31902+{
31903+ struct hlist_head *head;
31904+ unsigned int u;
31905+ size_t sz;
31906+
31907+ sz = sizeof(*nhash->nh_head) * num_hash;
31908+ head = kmalloc(sz, gfp);
31909+ if (head) {
31910+ nhash->nh_num = num_hash;
31911+ nhash->nh_head = head;
31912+ for (u = 0; u < num_hash; u++)
31913+ INIT_HLIST_HEAD(head++);
31914+ return 0; /* success */
31915+ }
31916+
31917+ return -ENOMEM;
31918+}
31919+
31920+static void nhash_count(struct hlist_head *head)
31921+{
31922+#if 0 /* debugging */
31923+ unsigned long n;
31924+ struct hlist_node *pos;
31925+
31926+ n = 0;
31927+ hlist_for_each(pos, head)
31928+ n++;
31929+ pr_info("%lu\n", n);
31930+#endif
31931+}
31932+
31933+static void au_nhash_wh_do_free(struct hlist_head *head)
31934+{
31935+ struct au_vdir_wh *pos;
31936+ struct hlist_node *node;
31937+
31938+ hlist_for_each_entry_safe(pos, node, head, wh_hash)
31939+ au_kfree_rcu(pos);
31940+}
31941+
31942+static void au_nhash_de_do_free(struct hlist_head *head)
31943+{
31944+ struct au_vdir_dehstr *pos;
31945+ struct hlist_node *node;
31946+
31947+ hlist_for_each_entry_safe(pos, node, head, hash)
31948+ au_cache_free_vdir_dehstr(pos);
31949+}
31950+
31951+static void au_nhash_do_free(struct au_nhash *nhash,
31952+ void (*free)(struct hlist_head *head))
31953+{
31954+ unsigned int n;
31955+ struct hlist_head *head;
31956+
31957+ n = nhash->nh_num;
31958+ if (!n)
31959+ return;
31960+
31961+ head = nhash->nh_head;
31962+ while (n-- > 0) {
31963+ nhash_count(head);
31964+ free(head++);
31965+ }
31966+ au_kfree_try_rcu(nhash->nh_head);
31967+}
31968+
31969+void au_nhash_wh_free(struct au_nhash *whlist)
31970+{
31971+ au_nhash_do_free(whlist, au_nhash_wh_do_free);
31972+}
31973+
31974+static void au_nhash_de_free(struct au_nhash *delist)
31975+{
31976+ au_nhash_do_free(delist, au_nhash_de_do_free);
31977+}
31978+
31979+/* ---------------------------------------------------------------------- */
31980+
31981+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
31982+ int limit)
31983+{
31984+ int num;
31985+ unsigned int u, n;
31986+ struct hlist_head *head;
31987+ struct au_vdir_wh *pos;
31988+
31989+ num = 0;
31990+ n = whlist->nh_num;
31991+ head = whlist->nh_head;
31992+ for (u = 0; u < n; u++, head++)
31993+ hlist_for_each_entry(pos, head, wh_hash)
31994+ if (pos->wh_bindex == btgt && ++num > limit)
31995+ return 1;
31996+ return 0;
31997+}
31998+
31999+static struct hlist_head *au_name_hash(struct au_nhash *nhash,
32000+ unsigned char *name,
32001+ unsigned int len)
32002+{
32003+ unsigned int v;
32004+ /* const unsigned int magic_bit = 12; */
32005+
32006+ AuDebugOn(!nhash->nh_num || !nhash->nh_head);
32007+
32008+ v = 0;
32009+ if (len > 8)
32010+ len = 8;
32011+ while (len--)
32012+ v += *name++;
32013+ /* v = hash_long(v, magic_bit); */
32014+ v %= nhash->nh_num;
32015+ return nhash->nh_head + v;
32016+}
32017+
32018+static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
32019+ int nlen)
32020+{
32021+ return str->len == nlen && !memcmp(str->name, name, nlen);
32022+}
32023+
32024+/* returns found or not */
32025+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
32026+{
32027+ struct hlist_head *head;
32028+ struct au_vdir_wh *pos;
32029+ struct au_vdir_destr *str;
32030+
32031+ head = au_name_hash(whlist, name, nlen);
32032+ hlist_for_each_entry(pos, head, wh_hash) {
32033+ str = &pos->wh_str;
32034+ AuDbg("%.*s\n", str->len, str->name);
32035+ if (au_nhash_test_name(str, name, nlen))
32036+ return 1;
32037+ }
32038+ return 0;
32039+}
32040+
32041+/* returns found(true) or not */
32042+static int test_known(struct au_nhash *delist, char *name, int nlen)
32043+{
32044+ struct hlist_head *head;
32045+ struct au_vdir_dehstr *pos;
32046+ struct au_vdir_destr *str;
32047+
32048+ head = au_name_hash(delist, name, nlen);
32049+ hlist_for_each_entry(pos, head, hash) {
32050+ str = pos->str;
32051+ AuDbg("%.*s\n", str->len, str->name);
32052+ if (au_nhash_test_name(str, name, nlen))
32053+ return 1;
32054+ }
32055+ return 0;
32056+}
32057+
32058+static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
32059+ unsigned char d_type)
32060+{
32061+#ifdef CONFIG_AUFS_SHWH
32062+ wh->wh_ino = ino;
32063+ wh->wh_type = d_type;
32064+#endif
32065+}
32066+
32067+/* ---------------------------------------------------------------------- */
32068+
32069+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
32070+ unsigned int d_type, aufs_bindex_t bindex,
32071+ unsigned char shwh)
32072+{
32073+ int err;
32074+ struct au_vdir_destr *str;
32075+ struct au_vdir_wh *wh;
32076+
32077+ AuDbg("%.*s\n", nlen, name);
32078+ AuDebugOn(!whlist->nh_num || !whlist->nh_head);
32079+
32080+ err = -ENOMEM;
32081+ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
32082+ if (unlikely(!wh))
32083+ goto out;
32084+
32085+ err = 0;
32086+ wh->wh_bindex = bindex;
32087+ if (shwh)
32088+ au_shwh_init_wh(wh, ino, d_type);
32089+ str = &wh->wh_str;
32090+ str->len = nlen;
32091+ memcpy(str->name, name, nlen);
32092+ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
32093+ /* smp_mb(); */
32094+
32095+out:
32096+ return err;
32097+}
32098+
32099+static int append_deblk(struct au_vdir *vdir)
32100+{
32101+ int err;
32102+ unsigned long ul;
32103+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
32104+ union au_vdir_deblk_p p, deblk_end;
32105+ unsigned char **o;
32106+
32107+ err = -ENOMEM;
32108+ o = au_krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
32109+ GFP_NOFS, /*may_shrink*/0);
32110+ if (unlikely(!o))
32111+ goto out;
32112+
32113+ vdir->vd_deblk = o;
32114+ p.deblk = kmalloc(deblk_sz, GFP_NOFS);
32115+ if (p.deblk) {
32116+ ul = vdir->vd_nblk++;
32117+ vdir->vd_deblk[ul] = p.deblk;
32118+ vdir->vd_last.ul = ul;
32119+ vdir->vd_last.p.deblk = p.deblk;
32120+ deblk_end.deblk = p.deblk + deblk_sz;
32121+ err = set_deblk_end(&p, &deblk_end);
32122+ }
32123+
32124+out:
32125+ return err;
32126+}
32127+
32128+static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
32129+ unsigned int d_type, struct au_nhash *delist)
32130+{
32131+ int err;
32132+ unsigned int sz;
32133+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
32134+ union au_vdir_deblk_p p, *room, deblk_end;
32135+ struct au_vdir_dehstr *dehstr;
32136+
32137+ p.deblk = last_deblk(vdir);
32138+ deblk_end.deblk = p.deblk + deblk_sz;
32139+ room = &vdir->vd_last.p;
32140+ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
32141+ || !is_deblk_end(room, &deblk_end));
32142+
32143+ sz = calc_size(nlen);
32144+ if (unlikely(sz > deblk_end.deblk - room->deblk)) {
32145+ err = append_deblk(vdir);
32146+ if (unlikely(err))
32147+ goto out;
32148+
32149+ p.deblk = last_deblk(vdir);
32150+ deblk_end.deblk = p.deblk + deblk_sz;
32151+ /* smp_mb(); */
32152+ AuDebugOn(room->deblk != p.deblk);
32153+ }
32154+
32155+ err = -ENOMEM;
32156+ dehstr = au_cache_alloc_vdir_dehstr();
32157+ if (unlikely(!dehstr))
32158+ goto out;
32159+
32160+ dehstr->str = &room->de->de_str;
32161+ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
32162+ room->de->de_ino = ino;
32163+ room->de->de_type = d_type;
32164+ room->de->de_str.len = nlen;
32165+ memcpy(room->de->de_str.name, name, nlen);
32166+
32167+ err = 0;
32168+ room->deblk += sz;
32169+ if (unlikely(set_deblk_end(room, &deblk_end)))
32170+ err = append_deblk(vdir);
32171+ /* smp_mb(); */
32172+
32173+out:
32174+ return err;
32175+}
32176+
32177+/* ---------------------------------------------------------------------- */
32178+
32179+void au_vdir_free(struct au_vdir *vdir)
32180+{
32181+ unsigned char **deblk;
32182+
32183+ deblk = vdir->vd_deblk;
32184+ while (vdir->vd_nblk--)
32185+ au_kfree_try_rcu(*deblk++);
32186+ au_kfree_try_rcu(vdir->vd_deblk);
32187+ au_cache_free_vdir(vdir);
32188+}
32189+
32190+static struct au_vdir *alloc_vdir(struct file *file)
32191+{
32192+ struct au_vdir *vdir;
32193+ struct super_block *sb;
32194+ int err;
32195+
32196+ sb = file->f_path.dentry->d_sb;
32197+ SiMustAnyLock(sb);
32198+
32199+ err = -ENOMEM;
32200+ vdir = au_cache_alloc_vdir();
32201+ if (unlikely(!vdir))
32202+ goto out;
32203+
32204+ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
32205+ if (unlikely(!vdir->vd_deblk))
32206+ goto out_free;
32207+
32208+ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
32209+ if (!vdir->vd_deblk_sz) {
32210+ /* estimate the appropriate size for deblk */
32211+ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
32212+ /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
32213+ }
32214+ vdir->vd_nblk = 0;
32215+ vdir->vd_version = 0;
32216+ vdir->vd_jiffy = 0;
32217+ err = append_deblk(vdir);
32218+ if (!err)
32219+ return vdir; /* success */
32220+
32221+ au_kfree_try_rcu(vdir->vd_deblk);
32222+
32223+out_free:
32224+ au_cache_free_vdir(vdir);
32225+out:
32226+ vdir = ERR_PTR(err);
32227+ return vdir;
32228+}
32229+
32230+static int reinit_vdir(struct au_vdir *vdir)
32231+{
32232+ int err;
32233+ union au_vdir_deblk_p p, deblk_end;
32234+
32235+ while (vdir->vd_nblk > 1) {
32236+ au_kfree_try_rcu(vdir->vd_deblk[vdir->vd_nblk - 1]);
32237+ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
32238+ vdir->vd_nblk--;
32239+ }
32240+ p.deblk = vdir->vd_deblk[0];
32241+ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
32242+ err = set_deblk_end(&p, &deblk_end);
32243+ /* keep vd_dblk_sz */
32244+ vdir->vd_last.ul = 0;
32245+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
32246+ vdir->vd_version = 0;
32247+ vdir->vd_jiffy = 0;
32248+ /* smp_mb(); */
32249+ return err;
32250+}
32251+
32252+/* ---------------------------------------------------------------------- */
32253+
32254+#define AuFillVdir_CALLED 1
32255+#define AuFillVdir_WHABLE (1 << 1)
32256+#define AuFillVdir_SHWH (1 << 2)
32257+#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
32258+#define au_fset_fillvdir(flags, name) \
32259+ do { (flags) |= AuFillVdir_##name; } while (0)
32260+#define au_fclr_fillvdir(flags, name) \
32261+ do { (flags) &= ~AuFillVdir_##name; } while (0)
32262+
32263+#ifndef CONFIG_AUFS_SHWH
32264+#undef AuFillVdir_SHWH
32265+#define AuFillVdir_SHWH 0
32266+#endif
32267+
32268+struct fillvdir_arg {
32269+ struct dir_context ctx;
32270+ struct file *file;
32271+ struct au_vdir *vdir;
32272+ struct au_nhash delist;
32273+ struct au_nhash whlist;
32274+ aufs_bindex_t bindex;
32275+ unsigned int flags;
32276+ int err;
32277+};
32278+
32279+static int fillvdir(struct dir_context *ctx, const char *__name, int nlen,
32280+ loff_t offset __maybe_unused, u64 h_ino,
32281+ unsigned int d_type)
32282+{
32283+ struct fillvdir_arg *arg = container_of(ctx, struct fillvdir_arg, ctx);
32284+ char *name = (void *)__name;
32285+ struct super_block *sb;
32286+ ino_t ino;
32287+ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
32288+
32289+ arg->err = 0;
32290+ sb = arg->file->f_path.dentry->d_sb;
32291+ au_fset_fillvdir(arg->flags, CALLED);
32292+ /* smp_mb(); */
32293+ if (nlen <= AUFS_WH_PFX_LEN
32294+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
32295+ if (test_known(&arg->delist, name, nlen)
32296+ || au_nhash_test_known_wh(&arg->whlist, name, nlen))
32297+ goto out; /* already exists or whiteouted */
32298+
32299+ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
32300+ if (!arg->err) {
32301+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
32302+ d_type = DT_UNKNOWN;
32303+ arg->err = append_de(arg->vdir, name, nlen, ino,
32304+ d_type, &arg->delist);
32305+ }
32306+ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
32307+ name += AUFS_WH_PFX_LEN;
32308+ nlen -= AUFS_WH_PFX_LEN;
32309+ if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
32310+ goto out; /* already whiteouted */
32311+
32312+ ino = 0; /* just to suppress a warning */
32313+ if (shwh)
32314+ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
32315+ &ino);
32316+ if (!arg->err) {
32317+ if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
32318+ d_type = DT_UNKNOWN;
32319+ arg->err = au_nhash_append_wh
32320+ (&arg->whlist, name, nlen, ino, d_type,
32321+ arg->bindex, shwh);
32322+ }
32323+ }
32324+
32325+out:
32326+ if (!arg->err)
32327+ arg->vdir->vd_jiffy = jiffies;
32328+ /* smp_mb(); */
32329+ AuTraceErr(arg->err);
32330+ return arg->err;
32331+}
32332+
32333+static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
32334+ struct au_nhash *whlist, struct au_nhash *delist)
32335+{
32336+#ifdef CONFIG_AUFS_SHWH
32337+ int err;
32338+ unsigned int nh, u;
32339+ struct hlist_head *head;
32340+ struct au_vdir_wh *pos;
32341+ struct hlist_node *n;
32342+ char *p, *o;
32343+ struct au_vdir_destr *destr;
32344+
32345+ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
32346+
32347+ err = -ENOMEM;
32348+ o = p = (void *)__get_free_page(GFP_NOFS);
32349+ if (unlikely(!p))
32350+ goto out;
32351+
32352+ err = 0;
32353+ nh = whlist->nh_num;
32354+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
32355+ p += AUFS_WH_PFX_LEN;
32356+ for (u = 0; u < nh; u++) {
32357+ head = whlist->nh_head + u;
32358+ hlist_for_each_entry_safe(pos, n, head, wh_hash) {
32359+ destr = &pos->wh_str;
32360+ memcpy(p, destr->name, destr->len);
32361+ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
32362+ pos->wh_ino, pos->wh_type, delist);
32363+ if (unlikely(err))
32364+ break;
32365+ }
32366+ }
32367+
32368+ free_page((unsigned long)o);
32369+
32370+out:
32371+ AuTraceErr(err);
32372+ return err;
32373+#else
32374+ return 0;
32375+#endif
32376+}
32377+
32378+static int au_do_read_vdir(struct fillvdir_arg *arg)
32379+{
32380+ int err;
32381+ unsigned int rdhash;
32382+ loff_t offset;
32383+ aufs_bindex_t bbot, bindex, btop;
32384+ unsigned char shwh;
32385+ struct file *hf, *file;
32386+ struct super_block *sb;
32387+
32388+ file = arg->file;
32389+ sb = file->f_path.dentry->d_sb;
32390+ SiMustAnyLock(sb);
32391+
32392+ rdhash = au_sbi(sb)->si_rdhash;
32393+ if (!rdhash)
32394+ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
32395+ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
32396+ if (unlikely(err))
32397+ goto out;
32398+ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
32399+ if (unlikely(err))
32400+ goto out_delist;
32401+
32402+ err = 0;
32403+ arg->flags = 0;
32404+ shwh = 0;
32405+ if (au_opt_test(au_mntflags(sb), SHWH)) {
32406+ shwh = 1;
32407+ au_fset_fillvdir(arg->flags, SHWH);
32408+ }
32409+ btop = au_fbtop(file);
32410+ bbot = au_fbbot_dir(file);
32411+ for (bindex = btop; !err && bindex <= bbot; bindex++) {
32412+ hf = au_hf_dir(file, bindex);
32413+ if (!hf)
32414+ continue;
32415+
32416+ offset = vfsub_llseek(hf, 0, SEEK_SET);
32417+ err = offset;
32418+ if (unlikely(offset))
32419+ break;
32420+
32421+ arg->bindex = bindex;
32422+ au_fclr_fillvdir(arg->flags, WHABLE);
32423+ if (shwh
32424+ || (bindex != bbot
32425+ && au_br_whable(au_sbr_perm(sb, bindex))))
32426+ au_fset_fillvdir(arg->flags, WHABLE);
32427+ do {
32428+ arg->err = 0;
32429+ au_fclr_fillvdir(arg->flags, CALLED);
32430+ /* smp_mb(); */
32431+ err = vfsub_iterate_dir(hf, &arg->ctx);
32432+ if (err >= 0)
32433+ err = arg->err;
32434+ } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
32435+
32436+ /*
32437+ * dir_relax() may be good for concurrency, but aufs should not
32438+ * use it since it will cause a lockdep problem.
32439+ */
32440+ }
32441+
32442+ if (!err && shwh)
32443+ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
32444+
32445+ au_nhash_wh_free(&arg->whlist);
32446+
32447+out_delist:
32448+ au_nhash_de_free(&arg->delist);
32449+out:
32450+ return err;
32451+}
32452+
32453+static int read_vdir(struct file *file, int may_read)
32454+{
32455+ int err;
32456+ unsigned long expire;
32457+ unsigned char do_read;
32458+ struct fillvdir_arg arg = {
32459+ .ctx = {
32460+ .actor = fillvdir
32461+ }
32462+ };
32463+ struct inode *inode;
32464+ struct au_vdir *vdir, *allocated;
32465+
32466+ err = 0;
32467+ inode = file_inode(file);
32468+ IMustLock(inode);
32469+ IiMustWriteLock(inode);
32470+ SiMustAnyLock(inode->i_sb);
32471+
32472+ allocated = NULL;
32473+ do_read = 0;
32474+ expire = au_sbi(inode->i_sb)->si_rdcache;
32475+ vdir = au_ivdir(inode);
32476+ if (!vdir) {
32477+ do_read = 1;
32478+ vdir = alloc_vdir(file);
32479+ err = PTR_ERR(vdir);
32480+ if (IS_ERR(vdir))
32481+ goto out;
32482+ err = 0;
32483+ allocated = vdir;
32484+ } else if (may_read
32485+ && (!inode_eq_iversion(inode, vdir->vd_version)
32486+ || time_after(jiffies, vdir->vd_jiffy + expire))) {
32487+ do_read = 1;
32488+ err = reinit_vdir(vdir);
32489+ if (unlikely(err))
32490+ goto out;
32491+ }
32492+
32493+ if (!do_read)
32494+ return 0; /* success */
32495+
32496+ arg.file = file;
32497+ arg.vdir = vdir;
32498+ err = au_do_read_vdir(&arg);
32499+ if (!err) {
32500+ /* file->f_pos = 0; */ /* todo: ctx->pos? */
32501+ vdir->vd_version = inode_query_iversion(inode);
32502+ vdir->vd_last.ul = 0;
32503+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
32504+ if (allocated)
32505+ au_set_ivdir(inode, allocated);
32506+ } else if (allocated)
32507+ au_vdir_free(allocated);
32508+
32509+out:
32510+ return err;
32511+}
32512+
32513+static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
32514+{
32515+ int err, rerr;
32516+ unsigned long ul, n;
32517+ const unsigned int deblk_sz = src->vd_deblk_sz;
32518+
32519+ AuDebugOn(tgt->vd_nblk != 1);
32520+
32521+ err = -ENOMEM;
32522+ if (tgt->vd_nblk < src->vd_nblk) {
32523+ unsigned char **p;
32524+
32525+ p = au_krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
32526+ GFP_NOFS, /*may_shrink*/0);
32527+ if (unlikely(!p))
32528+ goto out;
32529+ tgt->vd_deblk = p;
32530+ }
32531+
32532+ if (tgt->vd_deblk_sz != deblk_sz) {
32533+ unsigned char *p;
32534+
32535+ tgt->vd_deblk_sz = deblk_sz;
32536+ p = au_krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS,
32537+ /*may_shrink*/1);
32538+ if (unlikely(!p))
32539+ goto out;
32540+ tgt->vd_deblk[0] = p;
32541+ }
32542+ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
32543+ tgt->vd_version = src->vd_version;
32544+ tgt->vd_jiffy = src->vd_jiffy;
32545+
32546+ n = src->vd_nblk;
32547+ for (ul = 1; ul < n; ul++) {
32548+ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
32549+ GFP_NOFS);
32550+ if (unlikely(!tgt->vd_deblk[ul]))
32551+ goto out;
32552+ tgt->vd_nblk++;
32553+ }
32554+ tgt->vd_nblk = n;
32555+ tgt->vd_last.ul = tgt->vd_last.ul;
32556+ tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul];
32557+ tgt->vd_last.p.deblk += src->vd_last.p.deblk
32558+ - src->vd_deblk[src->vd_last.ul];
32559+ /* smp_mb(); */
32560+ return 0; /* success */
32561+
32562+out:
32563+ rerr = reinit_vdir(tgt);
32564+ BUG_ON(rerr);
32565+ return err;
32566+}
32567+
32568+int au_vdir_init(struct file *file)
32569+{
32570+ int err;
32571+ struct inode *inode;
32572+ struct au_vdir *vdir_cache, *allocated;
32573+
32574+ /* test file->f_pos here instead of ctx->pos */
32575+ err = read_vdir(file, !file->f_pos);
32576+ if (unlikely(err))
32577+ goto out;
32578+
32579+ allocated = NULL;
32580+ vdir_cache = au_fvdir_cache(file);
32581+ if (!vdir_cache) {
32582+ vdir_cache = alloc_vdir(file);
32583+ err = PTR_ERR(vdir_cache);
32584+ if (IS_ERR(vdir_cache))
32585+ goto out;
32586+ allocated = vdir_cache;
32587+ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
32588+ /* test file->f_pos here instead of ctx->pos */
32589+ err = reinit_vdir(vdir_cache);
32590+ if (unlikely(err))
32591+ goto out;
32592+ } else
32593+ return 0; /* success */
32594+
32595+ inode = file_inode(file);
32596+ err = copy_vdir(vdir_cache, au_ivdir(inode));
32597+ if (!err) {
32598+ file->f_version = inode_query_iversion(inode);
32599+ if (allocated)
32600+ au_set_fvdir_cache(file, allocated);
32601+ } else if (allocated)
32602+ au_vdir_free(allocated);
32603+
32604+out:
32605+ return err;
32606+}
32607+
32608+static loff_t calc_offset(struct au_vdir *vdir)
32609+{
32610+ loff_t offset;
32611+ union au_vdir_deblk_p p;
32612+
32613+ p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
32614+ offset = vdir->vd_last.p.deblk - p.deblk;
32615+ offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
32616+ return offset;
32617+}
32618+
32619+/* returns true or false */
32620+static int seek_vdir(struct file *file, struct dir_context *ctx)
32621+{
32622+ int valid;
32623+ unsigned int deblk_sz;
32624+ unsigned long ul, n;
32625+ loff_t offset;
32626+ union au_vdir_deblk_p p, deblk_end;
32627+ struct au_vdir *vdir_cache;
32628+
32629+ valid = 1;
32630+ vdir_cache = au_fvdir_cache(file);
32631+ offset = calc_offset(vdir_cache);
32632+ AuDbg("offset %lld\n", offset);
32633+ if (ctx->pos == offset)
32634+ goto out;
32635+
32636+ vdir_cache->vd_last.ul = 0;
32637+ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
32638+ if (!ctx->pos)
32639+ goto out;
32640+
32641+ valid = 0;
32642+ deblk_sz = vdir_cache->vd_deblk_sz;
32643+ ul = div64_u64(ctx->pos, deblk_sz);
32644+ AuDbg("ul %lu\n", ul);
32645+ if (ul >= vdir_cache->vd_nblk)
32646+ goto out;
32647+
32648+ n = vdir_cache->vd_nblk;
32649+ for (; ul < n; ul++) {
32650+ p.deblk = vdir_cache->vd_deblk[ul];
32651+ deblk_end.deblk = p.deblk + deblk_sz;
32652+ offset = ul;
32653+ offset *= deblk_sz;
32654+ while (!is_deblk_end(&p, &deblk_end) && offset < ctx->pos) {
32655+ unsigned int l;
32656+
32657+ l = calc_size(p.de->de_str.len);
32658+ offset += l;
32659+ p.deblk += l;
32660+ }
32661+ if (!is_deblk_end(&p, &deblk_end)) {
32662+ valid = 1;
32663+ vdir_cache->vd_last.ul = ul;
32664+ vdir_cache->vd_last.p = p;
32665+ break;
32666+ }
32667+ }
32668+
32669+out:
32670+ /* smp_mb(); */
32671+ if (!valid)
32672+ AuDbg("valid %d\n", !valid);
32673+ return valid;
32674+}
32675+
32676+int au_vdir_fill_de(struct file *file, struct dir_context *ctx)
32677+{
32678+ unsigned int l, deblk_sz;
32679+ union au_vdir_deblk_p deblk_end;
32680+ struct au_vdir *vdir_cache;
32681+ struct au_vdir_de *de;
32682+
32683+ if (!seek_vdir(file, ctx))
32684+ return 0;
32685+
32686+ vdir_cache = au_fvdir_cache(file);
32687+ deblk_sz = vdir_cache->vd_deblk_sz;
32688+ while (1) {
32689+ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
32690+ deblk_end.deblk += deblk_sz;
32691+ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
32692+ de = vdir_cache->vd_last.p.de;
32693+ AuDbg("%.*s, off%lld, i%lu, dt%d\n",
32694+ de->de_str.len, de->de_str.name, ctx->pos,
32695+ (unsigned long)de->de_ino, de->de_type);
32696+ if (unlikely(!dir_emit(ctx, de->de_str.name,
32697+ de->de_str.len, de->de_ino,
32698+ de->de_type))) {
32699+ /* todo: ignore the error caused by udba? */
32700+ /* return err; */
32701+ return 0;
32702+ }
32703+
32704+ l = calc_size(de->de_str.len);
32705+ vdir_cache->vd_last.p.deblk += l;
32706+ ctx->pos += l;
32707+ }
32708+ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
32709+ vdir_cache->vd_last.ul++;
32710+ vdir_cache->vd_last.p.deblk
32711+ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
32712+ ctx->pos = deblk_sz * vdir_cache->vd_last.ul;
32713+ continue;
32714+ }
32715+ break;
32716+ }
32717+
32718+ /* smp_mb(); */
32719+ return 0;
32720+}
32721diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
32722--- /usr/share/empty/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100
32723+++ linux/fs/aufs/vfsub.c 2020-01-27 10:57:18.178871751 +0100
32724@@ -0,0 +1,902 @@
32725+// SPDX-License-Identifier: GPL-2.0
32726+/*
32727+ * Copyright (C) 2005-2020 Junjiro R. Okajima
32728+ *
32729+ * This program, aufs is free software; you can redistribute it and/or modify
32730+ * it under the terms of the GNU General Public License as published by
32731+ * the Free Software Foundation; either version 2 of the License, or
32732+ * (at your option) any later version.
32733+ *
32734+ * This program is distributed in the hope that it will be useful,
32735+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32736+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32737+ * GNU General Public License for more details.
32738+ *
32739+ * You should have received a copy of the GNU General Public License
32740+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
32741+ */
32742+
32743+/*
32744+ * sub-routines for VFS
32745+ */
32746+
32747+#include <linux/mnt_namespace.h>
32748+#include <linux/namei.h>
32749+#include <linux/nsproxy.h>
32750+#include <linux/security.h>
32751+#include <linux/splice.h>
32752+#include "aufs.h"
32753+
32754+#ifdef CONFIG_AUFS_BR_FUSE
32755+int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb)
32756+{
32757+ if (!au_test_fuse(h_sb) || !au_userns)
32758+ return 0;
32759+
32760+ return is_current_mnt_ns(mnt) ? 0 : -EACCES;
32761+}
32762+#endif
32763+
32764+int vfsub_sync_filesystem(struct super_block *h_sb, int wait)
32765+{
32766+ int err;
32767+
32768+ lockdep_off();
32769+ down_read(&h_sb->s_umount);
32770+ err = __sync_filesystem(h_sb, wait);
32771+ up_read(&h_sb->s_umount);
32772+ lockdep_on();
32773+
32774+ return err;
32775+}
32776+
32777+/* ---------------------------------------------------------------------- */
32778+
32779+int vfsub_update_h_iattr(struct path *h_path, int *did)
32780+{
32781+ int err;
32782+ struct kstat st;
32783+ struct super_block *h_sb;
32784+
32785+ /* for remote fs, leave work for its getattr or d_revalidate */
32786+ /* for bad i_attr fs, handle them in aufs_getattr() */
32787+ /* still some fs may acquire i_mutex. we need to skip them */
32788+ err = 0;
32789+ if (!did)
32790+ did = &err;
32791+ h_sb = h_path->dentry->d_sb;
32792+ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
32793+ if (*did)
32794+ err = vfsub_getattr(h_path, &st);
32795+
32796+ return err;
32797+}
32798+
32799+/* ---------------------------------------------------------------------- */
32800+
32801+struct file *vfsub_dentry_open(struct path *path, int flags)
32802+{
32803+ struct file *file;
32804+
32805+ file = dentry_open(path, flags /* | __FMODE_NONOTIFY */,
32806+ current_cred());
32807+ if (!IS_ERR_OR_NULL(file)
32808+ && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
32809+ i_readcount_inc(d_inode(path->dentry));
32810+
32811+ return file;
32812+}
32813+
32814+struct file *vfsub_filp_open(const char *path, int oflags, int mode)
32815+{
32816+ struct file *file;
32817+
32818+ lockdep_off();
32819+ file = filp_open(path,
32820+ oflags /* | __FMODE_NONOTIFY */,
32821+ mode);
32822+ lockdep_on();
32823+ if (IS_ERR(file))
32824+ goto out;
32825+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
32826+
32827+out:
32828+ return file;
32829+}
32830+
32831+/*
32832+ * Ideally this function should call VFS:do_last() in order to keep all its
32833+ * checkings. But it is very hard for aufs to regenerate several VFS internal
32834+ * structure such as nameidata. This is a second (or third) best approach.
32835+ * cf. linux/fs/namei.c:do_last(), lookup_open() and atomic_open().
32836+ */
32837+int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
32838+ struct vfsub_aopen_args *args)
32839+{
32840+ int err;
32841+ struct au_branch *br = args->br;
32842+ struct file *file = args->file;
32843+ /* copied from linux/fs/namei.c:atomic_open() */
32844+ struct dentry *const DENTRY_NOT_SET = (void *)-1UL;
32845+
32846+ IMustLock(dir);
32847+ AuDebugOn(!dir->i_op->atomic_open);
32848+
32849+ err = au_br_test_oflag(args->open_flag, br);
32850+ if (unlikely(err))
32851+ goto out;
32852+
32853+ au_lcnt_inc(&br->br_nfiles);
32854+ file->f_path.dentry = DENTRY_NOT_SET;
32855+ file->f_path.mnt = au_br_mnt(br);
32856+ AuDbg("%ps\n", dir->i_op->atomic_open);
32857+ err = dir->i_op->atomic_open(dir, dentry, file, args->open_flag,
32858+ args->create_mode);
32859+ if (unlikely(err < 0)) {
32860+ au_lcnt_dec(&br->br_nfiles);
32861+ goto out;
32862+ }
32863+
32864+ /* temporary workaround for nfsv4 branch */
32865+ if (au_test_nfs(dir->i_sb))
32866+ nfs_mark_for_revalidate(dir);
32867+
32868+ if (file->f_mode & FMODE_CREATED)
32869+ fsnotify_create(dir, dentry);
32870+ if (!(file->f_mode & FMODE_OPENED)) {
32871+ au_lcnt_dec(&br->br_nfiles);
32872+ goto out;
32873+ }
32874+
32875+ /* todo: call VFS:may_open() here */
32876+ /* todo: ima_file_check() too? */
32877+ if (!err && (args->open_flag & __FMODE_EXEC))
32878+ err = deny_write_access(file);
32879+ if (!err)
32880+ fsnotify_open(file);
32881+ else
32882+ au_lcnt_dec(&br->br_nfiles);
32883+ /* note that the file is created and still opened */
32884+
32885+out:
32886+ return err;
32887+}
32888+
32889+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
32890+{
32891+ int err;
32892+
32893+ err = kern_path(name, flags, path);
32894+ if (!err && d_is_positive(path->dentry))
32895+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
32896+ return err;
32897+}
32898+
32899+struct dentry *vfsub_lookup_one_len_unlocked(const char *name,
32900+ struct dentry *parent, int len)
32901+{
32902+ struct path path = {
32903+ .mnt = NULL
32904+ };
32905+
32906+ path.dentry = lookup_one_len_unlocked(name, parent, len);
32907+ if (IS_ERR(path.dentry))
32908+ goto out;
32909+ if (d_is_positive(path.dentry))
32910+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
32911+
32912+out:
32913+ AuTraceErrPtr(path.dentry);
32914+ return path.dentry;
32915+}
32916+
32917+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
32918+ int len)
32919+{
32920+ struct path path = {
32921+ .mnt = NULL
32922+ };
32923+
32924+ /* VFS checks it too, but by WARN_ON_ONCE() */
32925+ IMustLock(d_inode(parent));
32926+
32927+ path.dentry = lookup_one_len(name, parent, len);
32928+ if (IS_ERR(path.dentry))
32929+ goto out;
32930+ if (d_is_positive(path.dentry))
32931+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
32932+
32933+out:
32934+ AuTraceErrPtr(path.dentry);
32935+ return path.dentry;
32936+}
32937+
32938+void vfsub_call_lkup_one(void *args)
32939+{
32940+ struct vfsub_lkup_one_args *a = args;
32941+ *a->errp = vfsub_lkup_one(a->name, a->parent);
32942+}
32943+
32944+/* ---------------------------------------------------------------------- */
32945+
32946+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
32947+ struct dentry *d2, struct au_hinode *hdir2)
32948+{
32949+ struct dentry *d;
32950+
32951+ lockdep_off();
32952+ d = lock_rename(d1, d2);
32953+ lockdep_on();
32954+ au_hn_suspend(hdir1);
32955+ if (hdir1 != hdir2)
32956+ au_hn_suspend(hdir2);
32957+
32958+ return d;
32959+}
32960+
32961+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
32962+ struct dentry *d2, struct au_hinode *hdir2)
32963+{
32964+ au_hn_resume(hdir1);
32965+ if (hdir1 != hdir2)
32966+ au_hn_resume(hdir2);
32967+ lockdep_off();
32968+ unlock_rename(d1, d2);
32969+ lockdep_on();
32970+}
32971+
32972+/* ---------------------------------------------------------------------- */
32973+
32974+int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl)
32975+{
32976+ int err;
32977+ struct dentry *d;
32978+
32979+ IMustLock(dir);
32980+
32981+ d = path->dentry;
32982+ path->dentry = d->d_parent;
32983+ err = security_path_mknod(path, d, mode, 0);
32984+ path->dentry = d;
32985+ if (unlikely(err))
32986+ goto out;
32987+
32988+ lockdep_off();
32989+ err = vfs_create(dir, path->dentry, mode, want_excl);
32990+ lockdep_on();
32991+ if (!err) {
32992+ struct path tmp = *path;
32993+ int did;
32994+
32995+ vfsub_update_h_iattr(&tmp, &did);
32996+ if (did) {
32997+ tmp.dentry = path->dentry->d_parent;
32998+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
32999+ }
33000+ /*ignore*/
33001+ }
33002+
33003+out:
33004+ return err;
33005+}
33006+
33007+int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
33008+{
33009+ int err;
33010+ struct dentry *d;
33011+
33012+ IMustLock(dir);
33013+
33014+ d = path->dentry;
33015+ path->dentry = d->d_parent;
33016+ err = security_path_symlink(path, d, symname);
33017+ path->dentry = d;
33018+ if (unlikely(err))
33019+ goto out;
33020+
33021+ lockdep_off();
33022+ err = vfs_symlink(dir, path->dentry, symname);
33023+ lockdep_on();
33024+ if (!err) {
33025+ struct path tmp = *path;
33026+ int did;
33027+
33028+ vfsub_update_h_iattr(&tmp, &did);
33029+ if (did) {
33030+ tmp.dentry = path->dentry->d_parent;
33031+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33032+ }
33033+ /*ignore*/
33034+ }
33035+
33036+out:
33037+ return err;
33038+}
33039+
33040+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
33041+{
33042+ int err;
33043+ struct dentry *d;
33044+
33045+ IMustLock(dir);
33046+
33047+ d = path->dentry;
33048+ path->dentry = d->d_parent;
33049+ err = security_path_mknod(path, d, mode, new_encode_dev(dev));
33050+ path->dentry = d;
33051+ if (unlikely(err))
33052+ goto out;
33053+
33054+ lockdep_off();
33055+ err = vfs_mknod(dir, path->dentry, mode, dev);
33056+ lockdep_on();
33057+ if (!err) {
33058+ struct path tmp = *path;
33059+ int did;
33060+
33061+ vfsub_update_h_iattr(&tmp, &did);
33062+ if (did) {
33063+ tmp.dentry = path->dentry->d_parent;
33064+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33065+ }
33066+ /*ignore*/
33067+ }
33068+
33069+out:
33070+ return err;
33071+}
33072+
33073+static int au_test_nlink(struct inode *inode)
33074+{
33075+ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
33076+
33077+ if (!au_test_fs_no_limit_nlink(inode->i_sb)
33078+ || inode->i_nlink < link_max)
33079+ return 0;
33080+ return -EMLINK;
33081+}
33082+
33083+int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path,
33084+ struct inode **delegated_inode)
33085+{
33086+ int err;
33087+ struct dentry *d;
33088+
33089+ IMustLock(dir);
33090+
33091+ err = au_test_nlink(d_inode(src_dentry));
33092+ if (unlikely(err))
33093+ return err;
33094+
33095+ /* we don't call may_linkat() */
33096+ d = path->dentry;
33097+ path->dentry = d->d_parent;
33098+ err = security_path_link(src_dentry, path, d);
33099+ path->dentry = d;
33100+ if (unlikely(err))
33101+ goto out;
33102+
33103+ lockdep_off();
33104+ err = vfs_link(src_dentry, dir, path->dentry, delegated_inode);
33105+ lockdep_on();
33106+ if (!err) {
33107+ struct path tmp = *path;
33108+ int did;
33109+
33110+ /* fuse has different memory inode for the same inumber */
33111+ vfsub_update_h_iattr(&tmp, &did);
33112+ if (did) {
33113+ tmp.dentry = path->dentry->d_parent;
33114+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33115+ tmp.dentry = src_dentry;
33116+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33117+ }
33118+ /*ignore*/
33119+ }
33120+
33121+out:
33122+ return err;
33123+}
33124+
33125+int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
33126+ struct inode *dir, struct path *path,
33127+ struct inode **delegated_inode, unsigned int flags)
33128+{
33129+ int err;
33130+ struct path tmp = {
33131+ .mnt = path->mnt
33132+ };
33133+ struct dentry *d;
33134+
33135+ IMustLock(dir);
33136+ IMustLock(src_dir);
33137+
33138+ d = path->dentry;
33139+ path->dentry = d->d_parent;
33140+ tmp.dentry = src_dentry->d_parent;
33141+ err = security_path_rename(&tmp, src_dentry, path, d, /*flags*/0);
33142+ path->dentry = d;
33143+ if (unlikely(err))
33144+ goto out;
33145+
33146+ lockdep_off();
33147+ err = vfs_rename(src_dir, src_dentry, dir, path->dentry,
33148+ delegated_inode, flags);
33149+ lockdep_on();
33150+ if (!err) {
33151+ int did;
33152+
33153+ tmp.dentry = d->d_parent;
33154+ vfsub_update_h_iattr(&tmp, &did);
33155+ if (did) {
33156+ tmp.dentry = src_dentry;
33157+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33158+ tmp.dentry = src_dentry->d_parent;
33159+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33160+ }
33161+ /*ignore*/
33162+ }
33163+
33164+out:
33165+ return err;
33166+}
33167+
33168+int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
33169+{
33170+ int err;
33171+ struct dentry *d;
33172+
33173+ IMustLock(dir);
33174+
33175+ d = path->dentry;
33176+ path->dentry = d->d_parent;
33177+ err = security_path_mkdir(path, d, mode);
33178+ path->dentry = d;
33179+ if (unlikely(err))
33180+ goto out;
33181+
33182+ lockdep_off();
33183+ err = vfs_mkdir(dir, path->dentry, mode);
33184+ lockdep_on();
33185+ if (!err) {
33186+ struct path tmp = *path;
33187+ int did;
33188+
33189+ vfsub_update_h_iattr(&tmp, &did);
33190+ if (did) {
33191+ tmp.dentry = path->dentry->d_parent;
33192+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33193+ }
33194+ /*ignore*/
33195+ }
33196+
33197+out:
33198+ return err;
33199+}
33200+
33201+int vfsub_rmdir(struct inode *dir, struct path *path)
33202+{
33203+ int err;
33204+ struct dentry *d;
33205+
33206+ IMustLock(dir);
33207+
33208+ d = path->dentry;
33209+ path->dentry = d->d_parent;
33210+ err = security_path_rmdir(path, d);
33211+ path->dentry = d;
33212+ if (unlikely(err))
33213+ goto out;
33214+
33215+ lockdep_off();
33216+ err = vfs_rmdir(dir, path->dentry);
33217+ lockdep_on();
33218+ if (!err) {
33219+ struct path tmp = {
33220+ .dentry = path->dentry->d_parent,
33221+ .mnt = path->mnt
33222+ };
33223+
33224+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
33225+ }
33226+
33227+out:
33228+ return err;
33229+}
33230+
33231+/* ---------------------------------------------------------------------- */
33232+
33233+/* todo: support mmap_sem? */
33234+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
33235+ loff_t *ppos)
33236+{
33237+ ssize_t err;
33238+
33239+ lockdep_off();
33240+ err = vfs_read(file, ubuf, count, ppos);
33241+ lockdep_on();
33242+ if (err >= 0)
33243+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
33244+ return err;
33245+}
33246+
33247+/* todo: kernel_read()? */
33248+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
33249+ loff_t *ppos)
33250+{
33251+ ssize_t err;
33252+ mm_segment_t oldfs;
33253+ union {
33254+ void *k;
33255+ char __user *u;
33256+ } buf;
33257+
33258+ buf.k = kbuf;
33259+ oldfs = get_fs();
33260+ set_fs(KERNEL_DS);
33261+ err = vfsub_read_u(file, buf.u, count, ppos);
33262+ set_fs(oldfs);
33263+ return err;
33264+}
33265+
33266+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
33267+ loff_t *ppos)
33268+{
33269+ ssize_t err;
33270+
33271+ lockdep_off();
33272+ err = vfs_write(file, ubuf, count, ppos);
33273+ lockdep_on();
33274+ if (err >= 0)
33275+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
33276+ return err;
33277+}
33278+
33279+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
33280+{
33281+ ssize_t err;
33282+ mm_segment_t oldfs;
33283+ union {
33284+ void *k;
33285+ const char __user *u;
33286+ } buf;
33287+
33288+ buf.k = kbuf;
33289+ oldfs = get_fs();
33290+ set_fs(KERNEL_DS);
33291+ err = vfsub_write_u(file, buf.u, count, ppos);
33292+ set_fs(oldfs);
33293+ return err;
33294+}
33295+
33296+int vfsub_flush(struct file *file, fl_owner_t id)
33297+{
33298+ int err;
33299+
33300+ err = 0;
33301+ if (file->f_op->flush) {
33302+ if (!au_test_nfs(file->f_path.dentry->d_sb))
33303+ err = file->f_op->flush(file, id);
33304+ else {
33305+ lockdep_off();
33306+ err = file->f_op->flush(file, id);
33307+ lockdep_on();
33308+ }
33309+ if (!err)
33310+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
33311+ /*ignore*/
33312+ }
33313+ return err;
33314+}
33315+
33316+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx)
33317+{
33318+ int err;
33319+
33320+ AuDbg("%pD, ctx{%ps, %llu}\n", file, ctx->actor, ctx->pos);
33321+
33322+ lockdep_off();
33323+ err = iterate_dir(file, ctx);
33324+ lockdep_on();
33325+ if (err >= 0)
33326+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
33327+
33328+ return err;
33329+}
33330+
33331+long vfsub_splice_to(struct file *in, loff_t *ppos,
33332+ struct pipe_inode_info *pipe, size_t len,
33333+ unsigned int flags)
33334+{
33335+ long err;
33336+
33337+ lockdep_off();
33338+ err = do_splice_to(in, ppos, pipe, len, flags);
33339+ lockdep_on();
33340+ file_accessed(in);
33341+ if (err >= 0)
33342+ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
33343+ return err;
33344+}
33345+
33346+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
33347+ loff_t *ppos, size_t len, unsigned int flags)
33348+{
33349+ long err;
33350+
33351+ lockdep_off();
33352+ err = do_splice_from(pipe, out, ppos, len, flags);
33353+ lockdep_on();
33354+ if (err >= 0)
33355+ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
33356+ return err;
33357+}
33358+
33359+int vfsub_fsync(struct file *file, struct path *path, int datasync)
33360+{
33361+ int err;
33362+
33363+ /* file can be NULL */
33364+ lockdep_off();
33365+ err = vfs_fsync(file, datasync);
33366+ lockdep_on();
33367+ if (!err) {
33368+ if (!path) {
33369+ AuDebugOn(!file);
33370+ path = &file->f_path;
33371+ }
33372+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
33373+ }
33374+ return err;
33375+}
33376+
33377+/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
33378+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
33379+ struct file *h_file)
33380+{
33381+ int err;
33382+ struct inode *h_inode;
33383+ struct super_block *h_sb;
33384+
33385+ if (!h_file) {
33386+ err = vfsub_truncate(h_path, length);
33387+ goto out;
33388+ }
33389+
33390+ h_inode = d_inode(h_path->dentry);
33391+ h_sb = h_inode->i_sb;
33392+ lockdep_off();
33393+ sb_start_write(h_sb);
33394+ lockdep_on();
33395+ err = locks_verify_truncate(h_inode, h_file, length);
33396+ if (!err)
33397+ err = security_path_truncate(h_path);
33398+ if (!err) {
33399+ lockdep_off();
33400+ err = do_truncate(h_path->dentry, length, attr, h_file);
33401+ lockdep_on();
33402+ }
33403+ lockdep_off();
33404+ sb_end_write(h_sb);
33405+ lockdep_on();
33406+
33407+out:
33408+ return err;
33409+}
33410+
33411+/* ---------------------------------------------------------------------- */
33412+
33413+struct au_vfsub_mkdir_args {
33414+ int *errp;
33415+ struct inode *dir;
33416+ struct path *path;
33417+ int mode;
33418+};
33419+
33420+static void au_call_vfsub_mkdir(void *args)
33421+{
33422+ struct au_vfsub_mkdir_args *a = args;
33423+ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
33424+}
33425+
33426+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
33427+{
33428+ int err, do_sio, wkq_err;
33429+
33430+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
33431+ if (!do_sio) {
33432+ lockdep_off();
33433+ err = vfsub_mkdir(dir, path, mode);
33434+ lockdep_on();
33435+ } else {
33436+ struct au_vfsub_mkdir_args args = {
33437+ .errp = &err,
33438+ .dir = dir,
33439+ .path = path,
33440+ .mode = mode
33441+ };
33442+ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
33443+ if (unlikely(wkq_err))
33444+ err = wkq_err;
33445+ }
33446+
33447+ return err;
33448+}
33449+
33450+struct au_vfsub_rmdir_args {
33451+ int *errp;
33452+ struct inode *dir;
33453+ struct path *path;
33454+};
33455+
33456+static void au_call_vfsub_rmdir(void *args)
33457+{
33458+ struct au_vfsub_rmdir_args *a = args;
33459+ *a->errp = vfsub_rmdir(a->dir, a->path);
33460+}
33461+
33462+int vfsub_sio_rmdir(struct inode *dir, struct path *path)
33463+{
33464+ int err, do_sio, wkq_err;
33465+
33466+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
33467+ if (!do_sio) {
33468+ lockdep_off();
33469+ err = vfsub_rmdir(dir, path);
33470+ lockdep_on();
33471+ } else {
33472+ struct au_vfsub_rmdir_args args = {
33473+ .errp = &err,
33474+ .dir = dir,
33475+ .path = path
33476+ };
33477+ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
33478+ if (unlikely(wkq_err))
33479+ err = wkq_err;
33480+ }
33481+
33482+ return err;
33483+}
33484+
33485+/* ---------------------------------------------------------------------- */
33486+
33487+struct notify_change_args {
33488+ int *errp;
33489+ struct path *path;
33490+ struct iattr *ia;
33491+ struct inode **delegated_inode;
33492+};
33493+
33494+static void call_notify_change(void *args)
33495+{
33496+ struct notify_change_args *a = args;
33497+ struct inode *h_inode;
33498+
33499+ h_inode = d_inode(a->path->dentry);
33500+ IMustLock(h_inode);
33501+
33502+ *a->errp = -EPERM;
33503+ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
33504+ lockdep_off();
33505+ *a->errp = notify_change(a->path->dentry, a->ia,
33506+ a->delegated_inode);
33507+ lockdep_on();
33508+ if (!*a->errp)
33509+ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
33510+ }
33511+ AuTraceErr(*a->errp);
33512+}
33513+
33514+int vfsub_notify_change(struct path *path, struct iattr *ia,
33515+ struct inode **delegated_inode)
33516+{
33517+ int err;
33518+ struct notify_change_args args = {
33519+ .errp = &err,
33520+ .path = path,
33521+ .ia = ia,
33522+ .delegated_inode = delegated_inode
33523+ };
33524+
33525+ call_notify_change(&args);
33526+
33527+ return err;
33528+}
33529+
33530+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
33531+ struct inode **delegated_inode)
33532+{
33533+ int err, wkq_err;
33534+ struct notify_change_args args = {
33535+ .errp = &err,
33536+ .path = path,
33537+ .ia = ia,
33538+ .delegated_inode = delegated_inode
33539+ };
33540+
33541+ wkq_err = au_wkq_wait(call_notify_change, &args);
33542+ if (unlikely(wkq_err))
33543+ err = wkq_err;
33544+
33545+ return err;
33546+}
33547+
33548+/* ---------------------------------------------------------------------- */
33549+
33550+struct unlink_args {
33551+ int *errp;
33552+ struct inode *dir;
33553+ struct path *path;
33554+ struct inode **delegated_inode;
33555+};
33556+
33557+static void call_unlink(void *args)
33558+{
33559+ struct unlink_args *a = args;
33560+ struct dentry *d = a->path->dentry;
33561+ struct inode *h_inode;
33562+ const int stop_sillyrename = (au_test_nfs(d->d_sb)
33563+ && au_dcount(d) == 1);
33564+
33565+ IMustLock(a->dir);
33566+
33567+ a->path->dentry = d->d_parent;
33568+ *a->errp = security_path_unlink(a->path, d);
33569+ a->path->dentry = d;
33570+ if (unlikely(*a->errp))
33571+ return;
33572+
33573+ if (!stop_sillyrename)
33574+ dget(d);
33575+ h_inode = NULL;
33576+ if (d_is_positive(d)) {
33577+ h_inode = d_inode(d);
33578+ ihold(h_inode);
33579+ }
33580+
33581+ lockdep_off();
33582+ *a->errp = vfs_unlink(a->dir, d, a->delegated_inode);
33583+ lockdep_on();
33584+ if (!*a->errp) {
33585+ struct path tmp = {
33586+ .dentry = d->d_parent,
33587+ .mnt = a->path->mnt
33588+ };
33589+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
33590+ }
33591+
33592+ if (!stop_sillyrename)
33593+ dput(d);
33594+ if (h_inode)
33595+ iput(h_inode);
33596+
33597+ AuTraceErr(*a->errp);
33598+}
33599+
33600+/*
33601+ * @dir: must be locked.
33602+ * @dentry: target dentry.
33603+ */
33604+int vfsub_unlink(struct inode *dir, struct path *path,
33605+ struct inode **delegated_inode, int force)
33606+{
33607+ int err;
33608+ struct unlink_args args = {
33609+ .errp = &err,
33610+ .dir = dir,
33611+ .path = path,
33612+ .delegated_inode = delegated_inode
33613+ };
33614+
33615+ if (!force)
33616+ call_unlink(&args);
33617+ else {
33618+ int wkq_err;
33619+
33620+ wkq_err = au_wkq_wait(call_unlink, &args);
33621+ if (unlikely(wkq_err))
33622+ err = wkq_err;
33623+ }
33624+
33625+ return err;
33626+}
33627diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
33628--- /usr/share/empty/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
33629+++ linux/fs/aufs/vfsub.h 2020-01-27 10:57:18.178871751 +0100
33630@@ -0,0 +1,354 @@
33631+/* SPDX-License-Identifier: GPL-2.0 */
33632+/*
33633+ * Copyright (C) 2005-2020 Junjiro R. Okajima
33634+ *
33635+ * This program, aufs is free software; you can redistribute it and/or modify
33636+ * it under the terms of the GNU General Public License as published by
33637+ * the Free Software Foundation; either version 2 of the License, or
33638+ * (at your option) any later version.
33639+ *
33640+ * This program is distributed in the hope that it will be useful,
33641+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
33642+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33643+ * GNU General Public License for more details.
33644+ *
33645+ * You should have received a copy of the GNU General Public License
33646+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
33647+ */
33648+
33649+/*
33650+ * sub-routines for VFS
33651+ */
33652+
33653+#ifndef __AUFS_VFSUB_H__
33654+#define __AUFS_VFSUB_H__
33655+
33656+#ifdef __KERNEL__
33657+
33658+#include <linux/fs.h>
33659+#include <linux/mount.h>
33660+#include <linux/posix_acl.h>
33661+#include <linux/xattr.h>
33662+#include "debug.h"
33663+
33664+/* copied from linux/fs/internal.h */
33665+/* todo: BAD approach!! */
33666+extern void __mnt_drop_write(struct vfsmount *);
33667+extern struct file *alloc_empty_file(int, const struct cred *);
33668+
33669+/* ---------------------------------------------------------------------- */
33670+
33671+/* lock subclass for lower inode */
33672+/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
33673+/* reduce? gave up. */
33674+enum {
33675+ AuLsc_I_Begin = I_MUTEX_PARENT2, /* 5 */
33676+ AuLsc_I_PARENT, /* lower inode, parent first */
33677+ AuLsc_I_PARENT2, /* copyup dirs */
33678+ AuLsc_I_PARENT3, /* copyup wh */
33679+ AuLsc_I_CHILD,
33680+ AuLsc_I_CHILD2,
33681+ AuLsc_I_End
33682+};
33683+
33684+/* to debug easier, do not make them inlined functions */
33685+#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
33686+#define IMustLock(i) AuDebugOn(!inode_is_locked(i))
33687+
33688+/* ---------------------------------------------------------------------- */
33689+
33690+static inline void vfsub_drop_nlink(struct inode *inode)
33691+{
33692+ AuDebugOn(!inode->i_nlink);
33693+ drop_nlink(inode);
33694+}
33695+
33696+static inline void vfsub_dead_dir(struct inode *inode)
33697+{
33698+ AuDebugOn(!S_ISDIR(inode->i_mode));
33699+ inode->i_flags |= S_DEAD;
33700+ clear_nlink(inode);
33701+}
33702+
33703+static inline int vfsub_native_ro(struct inode *inode)
33704+{
33705+ return sb_rdonly(inode->i_sb)
33706+ || IS_RDONLY(inode)
33707+ /* || IS_APPEND(inode) */
33708+ || IS_IMMUTABLE(inode);
33709+}
33710+
33711+#ifdef CONFIG_AUFS_BR_FUSE
33712+int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb);
33713+#else
33714+AuStubInt0(vfsub_test_mntns, struct vfsmount *mnt, struct super_block *h_sb);
33715+#endif
33716+
33717+int vfsub_sync_filesystem(struct super_block *h_sb, int wait);
33718+
33719+/* ---------------------------------------------------------------------- */
33720+
33721+int vfsub_update_h_iattr(struct path *h_path, int *did);
33722+struct file *vfsub_dentry_open(struct path *path, int flags);
33723+struct file *vfsub_filp_open(const char *path, int oflags, int mode);
33724+struct au_branch;
33725+struct vfsub_aopen_args {
33726+ struct file *file;
33727+ unsigned int open_flag;
33728+ umode_t create_mode;
33729+ struct au_branch *br;
33730+};
33731+int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
33732+ struct vfsub_aopen_args *args);
33733+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
33734+
33735+struct dentry *vfsub_lookup_one_len_unlocked(const char *name,
33736+ struct dentry *parent, int len);
33737+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
33738+ int len);
33739+
33740+struct vfsub_lkup_one_args {
33741+ struct dentry **errp;
33742+ struct qstr *name;
33743+ struct dentry *parent;
33744+};
33745+
33746+static inline struct dentry *vfsub_lkup_one(struct qstr *name,
33747+ struct dentry *parent)
33748+{
33749+ return vfsub_lookup_one_len(name->name, parent, name->len);
33750+}
33751+
33752+void vfsub_call_lkup_one(void *args);
33753+
33754+/* ---------------------------------------------------------------------- */
33755+
33756+static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
33757+{
33758+ int err;
33759+
33760+ lockdep_off();
33761+ err = mnt_want_write(mnt);
33762+ lockdep_on();
33763+ return err;
33764+}
33765+
33766+static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
33767+{
33768+ lockdep_off();
33769+ mnt_drop_write(mnt);
33770+ lockdep_on();
33771+}
33772+
33773+#if 0 /* reserved */
33774+static inline void vfsub_mnt_drop_write_file(struct file *file)
33775+{
33776+ lockdep_off();
33777+ mnt_drop_write_file(file);
33778+ lockdep_on();
33779+}
33780+#endif
33781+
33782+/* ---------------------------------------------------------------------- */
33783+
33784+struct au_hinode;
33785+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
33786+ struct dentry *d2, struct au_hinode *hdir2);
33787+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
33788+ struct dentry *d2, struct au_hinode *hdir2);
33789+
33790+int vfsub_create(struct inode *dir, struct path *path, int mode,
33791+ bool want_excl);
33792+int vfsub_symlink(struct inode *dir, struct path *path,
33793+ const char *symname);
33794+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
33795+int vfsub_link(struct dentry *src_dentry, struct inode *dir,
33796+ struct path *path, struct inode **delegated_inode);
33797+int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
33798+ struct inode *hdir, struct path *path,
33799+ struct inode **delegated_inode, unsigned int flags);
33800+int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
33801+int vfsub_rmdir(struct inode *dir, struct path *path);
33802+
33803+/* ---------------------------------------------------------------------- */
33804+
33805+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
33806+ loff_t *ppos);
33807+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
33808+ loff_t *ppos);
33809+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
33810+ loff_t *ppos);
33811+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
33812+ loff_t *ppos);
33813+int vfsub_flush(struct file *file, fl_owner_t id);
33814+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx);
33815+
33816+static inline loff_t vfsub_f_size_read(struct file *file)
33817+{
33818+ return i_size_read(file_inode(file));
33819+}
33820+
33821+static inline unsigned int vfsub_file_flags(struct file *file)
33822+{
33823+ unsigned int flags;
33824+
33825+ spin_lock(&file->f_lock);
33826+ flags = file->f_flags;
33827+ spin_unlock(&file->f_lock);
33828+
33829+ return flags;
33830+}
33831+
33832+static inline int vfsub_file_execed(struct file *file)
33833+{
33834+ /* todo: direct access f_flags */
33835+ return !!(vfsub_file_flags(file) & __FMODE_EXEC);
33836+}
33837+
33838+#if 0 /* reserved */
33839+static inline void vfsub_file_accessed(struct file *h_file)
33840+{
33841+ file_accessed(h_file);
33842+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
33843+}
33844+#endif
33845+
33846+#if 0 /* reserved */
33847+static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
33848+ struct dentry *h_dentry)
33849+{
33850+ struct path h_path = {
33851+ .dentry = h_dentry,
33852+ .mnt = h_mnt
33853+ };
33854+ touch_atime(&h_path);
33855+ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
33856+}
33857+#endif
33858+
33859+static inline int vfsub_update_time(struct inode *h_inode,
33860+ struct timespec64 *ts, int flags)
33861+{
33862+ return update_time(h_inode, ts, flags);
33863+ /* no vfsub_update_h_iattr() since we don't have struct path */
33864+}
33865+
33866+#ifdef CONFIG_FS_POSIX_ACL
33867+static inline int vfsub_acl_chmod(struct inode *h_inode, umode_t h_mode)
33868+{
33869+ int err;
33870+
33871+ err = posix_acl_chmod(h_inode, h_mode);
33872+ if (err == -EOPNOTSUPP)
33873+ err = 0;
33874+ return err;
33875+}
33876+#else
33877+AuStubInt0(vfsub_acl_chmod, struct inode *h_inode, umode_t h_mode);
33878+#endif
33879+
33880+long vfsub_splice_to(struct file *in, loff_t *ppos,
33881+ struct pipe_inode_info *pipe, size_t len,
33882+ unsigned int flags);
33883+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
33884+ loff_t *ppos, size_t len, unsigned int flags);
33885+
33886+static inline long vfsub_truncate(struct path *path, loff_t length)
33887+{
33888+ long err;
33889+
33890+ lockdep_off();
33891+ err = vfs_truncate(path, length);
33892+ lockdep_on();
33893+ return err;
33894+}
33895+
33896+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
33897+ struct file *h_file);
33898+int vfsub_fsync(struct file *file, struct path *path, int datasync);
33899+
33900+/*
33901+ * re-use branch fs's ioctl(FICLONE) while aufs itself doesn't support such
33902+ * ioctl.
33903+ */
33904+static inline loff_t vfsub_clone_file_range(struct file *src, struct file *dst,
33905+ loff_t len)
33906+{
33907+ loff_t err;
33908+
33909+ lockdep_off();
33910+ err = vfs_clone_file_range(src, 0, dst, 0, len, /*remap_flags*/0);
33911+ lockdep_on();
33912+
33913+ return err;
33914+}
33915+
33916+/* copy_file_range(2) is a systemcall */
33917+static inline ssize_t vfsub_copy_file_range(struct file *src, loff_t src_pos,
33918+ struct file *dst, loff_t dst_pos,
33919+ size_t len, unsigned int flags)
33920+{
33921+ ssize_t ssz;
33922+
33923+ lockdep_off();
33924+ ssz = vfs_copy_file_range(src, src_pos, dst, dst_pos, len, flags);
33925+ lockdep_on();
33926+
33927+ return ssz;
33928+}
33929+
33930+/* ---------------------------------------------------------------------- */
33931+
33932+static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
33933+{
33934+ loff_t err;
33935+
33936+ lockdep_off();
33937+ err = vfs_llseek(file, offset, origin);
33938+ lockdep_on();
33939+ return err;
33940+}
33941+
33942+/* ---------------------------------------------------------------------- */
33943+
33944+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
33945+int vfsub_sio_rmdir(struct inode *dir, struct path *path);
33946+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
33947+ struct inode **delegated_inode);
33948+int vfsub_notify_change(struct path *path, struct iattr *ia,
33949+ struct inode **delegated_inode);
33950+int vfsub_unlink(struct inode *dir, struct path *path,
33951+ struct inode **delegated_inode, int force);
33952+
33953+static inline int vfsub_getattr(const struct path *path, struct kstat *st)
33954+{
33955+ return vfs_getattr(path, st, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT);
33956+}
33957+
33958+/* ---------------------------------------------------------------------- */
33959+
33960+static inline int vfsub_setxattr(struct dentry *dentry, const char *name,
33961+ const void *value, size_t size, int flags)
33962+{
33963+ int err;
33964+
33965+ lockdep_off();
33966+ err = vfs_setxattr(dentry, name, value, size, flags);
33967+ lockdep_on();
33968+
33969+ return err;
33970+}
33971+
33972+static inline int vfsub_removexattr(struct dentry *dentry, const char *name)
33973+{
33974+ int err;
33975+
33976+ lockdep_off();
33977+ err = vfs_removexattr(dentry, name);
33978+ lockdep_on();
33979+
33980+ return err;
33981+}
33982+
33983+#endif /* __KERNEL__ */
33984+#endif /* __AUFS_VFSUB_H__ */
33985diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
33986--- /usr/share/empty/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100
33987+++ linux/fs/aufs/wbr_policy.c 2020-01-27 10:57:18.178871751 +0100
33988@@ -0,0 +1,830 @@
33989+// SPDX-License-Identifier: GPL-2.0
33990+/*
33991+ * Copyright (C) 2005-2020 Junjiro R. Okajima
33992+ *
33993+ * This program, aufs is free software; you can redistribute it and/or modify
33994+ * it under the terms of the GNU General Public License as published by
33995+ * the Free Software Foundation; either version 2 of the License, or
33996+ * (at your option) any later version.
33997+ *
33998+ * This program is distributed in the hope that it will be useful,
33999+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
34000+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34001+ * GNU General Public License for more details.
34002+ *
34003+ * You should have received a copy of the GNU General Public License
34004+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
34005+ */
34006+
34007+/*
34008+ * policies for selecting one among multiple writable branches
34009+ */
34010+
34011+#include <linux/statfs.h>
34012+#include "aufs.h"
34013+
34014+/* subset of cpup_attr() */
34015+static noinline_for_stack
34016+int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
34017+{
34018+ int err, sbits;
34019+ struct iattr ia;
34020+ struct inode *h_isrc;
34021+
34022+ h_isrc = d_inode(h_src);
34023+ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
34024+ ia.ia_mode = h_isrc->i_mode;
34025+ ia.ia_uid = h_isrc->i_uid;
34026+ ia.ia_gid = h_isrc->i_gid;
34027+ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
34028+ au_cpup_attr_flags(d_inode(h_path->dentry), h_isrc->i_flags);
34029+ /* no delegation since it is just created */
34030+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
34031+
34032+ /* is this nfs only? */
34033+ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
34034+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
34035+ ia.ia_mode = h_isrc->i_mode;
34036+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
34037+ }
34038+
34039+ return err;
34040+}
34041+
34042+#define AuCpdown_PARENT_OPQ 1
34043+#define AuCpdown_WHED (1 << 1)
34044+#define AuCpdown_MADE_DIR (1 << 2)
34045+#define AuCpdown_DIROPQ (1 << 3)
34046+#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name)
34047+#define au_fset_cpdown(flags, name) \
34048+ do { (flags) |= AuCpdown_##name; } while (0)
34049+#define au_fclr_cpdown(flags, name) \
34050+ do { (flags) &= ~AuCpdown_##name; } while (0)
34051+
34052+static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
34053+ unsigned int *flags)
34054+{
34055+ int err;
34056+ struct dentry *opq_dentry;
34057+
34058+ opq_dentry = au_diropq_create(dentry, bdst);
34059+ err = PTR_ERR(opq_dentry);
34060+ if (IS_ERR(opq_dentry))
34061+ goto out;
34062+ dput(opq_dentry);
34063+ au_fset_cpdown(*flags, DIROPQ);
34064+
34065+out:
34066+ return err;
34067+}
34068+
34069+static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
34070+ struct inode *dir, aufs_bindex_t bdst)
34071+{
34072+ int err;
34073+ struct path h_path;
34074+ struct au_branch *br;
34075+
34076+ br = au_sbr(dentry->d_sb, bdst);
34077+ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
34078+ err = PTR_ERR(h_path.dentry);
34079+ if (IS_ERR(h_path.dentry))
34080+ goto out;
34081+
34082+ err = 0;
34083+ if (d_is_positive(h_path.dentry)) {
34084+ h_path.mnt = au_br_mnt(br);
34085+ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
34086+ dentry);
34087+ }
34088+ dput(h_path.dentry);
34089+
34090+out:
34091+ return err;
34092+}
34093+
34094+static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
34095+ struct au_pin *pin,
34096+ struct dentry *h_parent, void *arg)
34097+{
34098+ int err, rerr;
34099+ aufs_bindex_t bopq, btop;
34100+ struct path h_path;
34101+ struct dentry *parent;
34102+ struct inode *h_dir, *h_inode, *inode, *dir;
34103+ unsigned int *flags = arg;
34104+
34105+ btop = au_dbtop(dentry);
34106+ /* dentry is di-locked */
34107+ parent = dget_parent(dentry);
34108+ dir = d_inode(parent);
34109+ h_dir = d_inode(h_parent);
34110+ AuDebugOn(h_dir != au_h_iptr(dir, bdst));
34111+ IMustLock(h_dir);
34112+
34113+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
34114+ if (unlikely(err < 0))
34115+ goto out;
34116+ h_path.dentry = au_h_dptr(dentry, bdst);
34117+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
34118+ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path, 0755);
34119+ if (unlikely(err))
34120+ goto out_put;
34121+ au_fset_cpdown(*flags, MADE_DIR);
34122+
34123+ bopq = au_dbdiropq(dentry);
34124+ au_fclr_cpdown(*flags, WHED);
34125+ au_fclr_cpdown(*flags, DIROPQ);
34126+ if (au_dbwh(dentry) == bdst)
34127+ au_fset_cpdown(*flags, WHED);
34128+ if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst)
34129+ au_fset_cpdown(*flags, PARENT_OPQ);
34130+ h_inode = d_inode(h_path.dentry);
34131+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
34132+ if (au_ftest_cpdown(*flags, WHED)) {
34133+ err = au_cpdown_dir_opq(dentry, bdst, flags);
34134+ if (unlikely(err)) {
34135+ inode_unlock(h_inode);
34136+ goto out_dir;
34137+ }
34138+ }
34139+
34140+ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, btop));
34141+ inode_unlock(h_inode);
34142+ if (unlikely(err))
34143+ goto out_opq;
34144+
34145+ if (au_ftest_cpdown(*flags, WHED)) {
34146+ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
34147+ if (unlikely(err))
34148+ goto out_opq;
34149+ }
34150+
34151+ inode = d_inode(dentry);
34152+ if (au_ibbot(inode) < bdst)
34153+ au_set_ibbot(inode, bdst);
34154+ au_set_h_iptr(inode, bdst, au_igrab(h_inode),
34155+ au_hi_flags(inode, /*isdir*/1));
34156+ au_fhsm_wrote(dentry->d_sb, bdst, /*force*/0);
34157+ goto out; /* success */
34158+
34159+ /* revert */
34160+out_opq:
34161+ if (au_ftest_cpdown(*flags, DIROPQ)) {
34162+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
34163+ rerr = au_diropq_remove(dentry, bdst);
34164+ inode_unlock(h_inode);
34165+ if (unlikely(rerr)) {
34166+ AuIOErr("failed removing diropq for %pd b%d (%d)\n",
34167+ dentry, bdst, rerr);
34168+ err = -EIO;
34169+ goto out;
34170+ }
34171+ }
34172+out_dir:
34173+ if (au_ftest_cpdown(*flags, MADE_DIR)) {
34174+ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
34175+ if (unlikely(rerr)) {
34176+ AuIOErr("failed removing %pd b%d (%d)\n",
34177+ dentry, bdst, rerr);
34178+ err = -EIO;
34179+ }
34180+ }
34181+out_put:
34182+ au_set_h_dptr(dentry, bdst, NULL);
34183+ if (au_dbbot(dentry) == bdst)
34184+ au_update_dbbot(dentry);
34185+out:
34186+ dput(parent);
34187+ return err;
34188+}
34189+
34190+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
34191+{
34192+ int err;
34193+ unsigned int flags;
34194+
34195+ flags = 0;
34196+ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &flags);
34197+
34198+ return err;
34199+}
34200+
34201+/* ---------------------------------------------------------------------- */
34202+
34203+/* policies for create */
34204+
34205+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex)
34206+{
34207+ int err, i, j, ndentry;
34208+ aufs_bindex_t bopq;
34209+ struct au_dcsub_pages dpages;
34210+ struct au_dpage *dpage;
34211+ struct dentry **dentries, *parent, *d;
34212+
34213+ err = au_dpages_init(&dpages, GFP_NOFS);
34214+ if (unlikely(err))
34215+ goto out;
34216+ parent = dget_parent(dentry);
34217+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0);
34218+ if (unlikely(err))
34219+ goto out_free;
34220+
34221+ err = bindex;
34222+ for (i = 0; i < dpages.ndpage; i++) {
34223+ dpage = dpages.dpages + i;
34224+ dentries = dpage->dentries;
34225+ ndentry = dpage->ndentry;
34226+ for (j = 0; j < ndentry; j++) {
34227+ d = dentries[j];
34228+ di_read_lock_parent2(d, !AuLock_IR);
34229+ bopq = au_dbdiropq(d);
34230+ di_read_unlock(d, !AuLock_IR);
34231+ if (bopq >= 0 && bopq < err)
34232+ err = bopq;
34233+ }
34234+ }
34235+
34236+out_free:
34237+ dput(parent);
34238+ au_dpages_free(&dpages);
34239+out:
34240+ return err;
34241+}
34242+
34243+static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
34244+{
34245+ for (; bindex >= 0; bindex--)
34246+ if (!au_br_rdonly(au_sbr(sb, bindex)))
34247+ return bindex;
34248+ return -EROFS;
34249+}
34250+
34251+/* top down parent */
34252+static int au_wbr_create_tdp(struct dentry *dentry,
34253+ unsigned int flags __maybe_unused)
34254+{
34255+ int err;
34256+ aufs_bindex_t btop, bindex;
34257+ struct super_block *sb;
34258+ struct dentry *parent, *h_parent;
34259+
34260+ sb = dentry->d_sb;
34261+ btop = au_dbtop(dentry);
34262+ err = btop;
34263+ if (!au_br_rdonly(au_sbr(sb, btop)))
34264+ goto out;
34265+
34266+ err = -EROFS;
34267+ parent = dget_parent(dentry);
34268+ for (bindex = au_dbtop(parent); bindex < btop; bindex++) {
34269+ h_parent = au_h_dptr(parent, bindex);
34270+ if (!h_parent || d_is_negative(h_parent))
34271+ continue;
34272+
34273+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
34274+ err = bindex;
34275+ break;
34276+ }
34277+ }
34278+ dput(parent);
34279+
34280+ /* bottom up here */
34281+ if (unlikely(err < 0)) {
34282+ err = au_wbr_bu(sb, btop - 1);
34283+ if (err >= 0)
34284+ err = au_wbr_nonopq(dentry, err);
34285+ }
34286+
34287+out:
34288+ AuDbg("b%d\n", err);
34289+ return err;
34290+}
34291+
34292+/* ---------------------------------------------------------------------- */
34293+
34294+/* an exception for the policy other than tdp */
34295+static int au_wbr_create_exp(struct dentry *dentry)
34296+{
34297+ int err;
34298+ aufs_bindex_t bwh, bdiropq;
34299+ struct dentry *parent;
34300+
34301+ err = -1;
34302+ bwh = au_dbwh(dentry);
34303+ parent = dget_parent(dentry);
34304+ bdiropq = au_dbdiropq(parent);
34305+ if (bwh >= 0) {
34306+ if (bdiropq >= 0)
34307+ err = min(bdiropq, bwh);
34308+ else
34309+ err = bwh;
34310+ AuDbg("%d\n", err);
34311+ } else if (bdiropq >= 0) {
34312+ err = bdiropq;
34313+ AuDbg("%d\n", err);
34314+ }
34315+ dput(parent);
34316+
34317+ if (err >= 0)
34318+ err = au_wbr_nonopq(dentry, err);
34319+
34320+ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
34321+ err = -1;
34322+
34323+ AuDbg("%d\n", err);
34324+ return err;
34325+}
34326+
34327+/* ---------------------------------------------------------------------- */
34328+
34329+/* round robin */
34330+static int au_wbr_create_init_rr(struct super_block *sb)
34331+{
34332+ int err;
34333+
34334+ err = au_wbr_bu(sb, au_sbbot(sb));
34335+ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
34336+ /* smp_mb(); */
34337+
34338+ AuDbg("b%d\n", err);
34339+ return err;
34340+}
34341+
34342+static int au_wbr_create_rr(struct dentry *dentry, unsigned int flags)
34343+{
34344+ int err, nbr;
34345+ unsigned int u;
34346+ aufs_bindex_t bindex, bbot;
34347+ struct super_block *sb;
34348+ atomic_t *next;
34349+
34350+ err = au_wbr_create_exp(dentry);
34351+ if (err >= 0)
34352+ goto out;
34353+
34354+ sb = dentry->d_sb;
34355+ next = &au_sbi(sb)->si_wbr_rr_next;
34356+ bbot = au_sbbot(sb);
34357+ nbr = bbot + 1;
34358+ for (bindex = 0; bindex <= bbot; bindex++) {
34359+ if (!au_ftest_wbr(flags, DIR)) {
34360+ err = atomic_dec_return(next) + 1;
34361+ /* modulo for 0 is meaningless */
34362+ if (unlikely(!err))
34363+ err = atomic_dec_return(next) + 1;
34364+ } else
34365+ err = atomic_read(next);
34366+ AuDbg("%d\n", err);
34367+ u = err;
34368+ err = u % nbr;
34369+ AuDbg("%d\n", err);
34370+ if (!au_br_rdonly(au_sbr(sb, err)))
34371+ break;
34372+ err = -EROFS;
34373+ }
34374+
34375+ if (err >= 0)
34376+ err = au_wbr_nonopq(dentry, err);
34377+
34378+out:
34379+ AuDbg("%d\n", err);
34380+ return err;
34381+}
34382+
34383+/* ---------------------------------------------------------------------- */
34384+
34385+/* most free space */
34386+static void au_mfs(struct dentry *dentry, struct dentry *parent)
34387+{
34388+ struct super_block *sb;
34389+ struct au_branch *br;
34390+ struct au_wbr_mfs *mfs;
34391+ struct dentry *h_parent;
34392+ aufs_bindex_t bindex, bbot;
34393+ int err;
34394+ unsigned long long b, bavail;
34395+ struct path h_path;
34396+ /* reduce the stack usage */
34397+ struct kstatfs *st;
34398+
34399+ st = kmalloc(sizeof(*st), GFP_NOFS);
34400+ if (unlikely(!st)) {
34401+ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
34402+ return;
34403+ }
34404+
34405+ bavail = 0;
34406+ sb = dentry->d_sb;
34407+ mfs = &au_sbi(sb)->si_wbr_mfs;
34408+ MtxMustLock(&mfs->mfs_lock);
34409+ mfs->mfs_bindex = -EROFS;
34410+ mfs->mfsrr_bytes = 0;
34411+ if (!parent) {
34412+ bindex = 0;
34413+ bbot = au_sbbot(sb);
34414+ } else {
34415+ bindex = au_dbtop(parent);
34416+ bbot = au_dbtaildir(parent);
34417+ }
34418+
34419+ for (; bindex <= bbot; bindex++) {
34420+ if (parent) {
34421+ h_parent = au_h_dptr(parent, bindex);
34422+ if (!h_parent || d_is_negative(h_parent))
34423+ continue;
34424+ }
34425+ br = au_sbr(sb, bindex);
34426+ if (au_br_rdonly(br))
34427+ continue;
34428+
34429+ /* sb->s_root for NFS is unreliable */
34430+ h_path.mnt = au_br_mnt(br);
34431+ h_path.dentry = h_path.mnt->mnt_root;
34432+ err = vfs_statfs(&h_path, st);
34433+ if (unlikely(err)) {
34434+ AuWarn1("failed statfs, b%d, %d\n", bindex, err);
34435+ continue;
34436+ }
34437+
34438+ /* when the available size is equal, select the lower one */
34439+ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
34440+ || sizeof(b) < sizeof(st->f_bsize));
34441+ b = st->f_bavail * st->f_bsize;
34442+ br->br_wbr->wbr_bytes = b;
34443+ if (b >= bavail) {
34444+ bavail = b;
34445+ mfs->mfs_bindex = bindex;
34446+ mfs->mfs_jiffy = jiffies;
34447+ }
34448+ }
34449+
34450+ mfs->mfsrr_bytes = bavail;
34451+ AuDbg("b%d\n", mfs->mfs_bindex);
34452+ au_kfree_rcu(st);
34453+}
34454+
34455+static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags)
34456+{
34457+ int err;
34458+ struct dentry *parent;
34459+ struct super_block *sb;
34460+ struct au_wbr_mfs *mfs;
34461+
34462+ err = au_wbr_create_exp(dentry);
34463+ if (err >= 0)
34464+ goto out;
34465+
34466+ sb = dentry->d_sb;
34467+ parent = NULL;
34468+ if (au_ftest_wbr(flags, PARENT))
34469+ parent = dget_parent(dentry);
34470+ mfs = &au_sbi(sb)->si_wbr_mfs;
34471+ mutex_lock(&mfs->mfs_lock);
34472+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
34473+ || mfs->mfs_bindex < 0
34474+ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
34475+ au_mfs(dentry, parent);
34476+ mutex_unlock(&mfs->mfs_lock);
34477+ err = mfs->mfs_bindex;
34478+ dput(parent);
34479+
34480+ if (err >= 0)
34481+ err = au_wbr_nonopq(dentry, err);
34482+
34483+out:
34484+ AuDbg("b%d\n", err);
34485+ return err;
34486+}
34487+
34488+static int au_wbr_create_init_mfs(struct super_block *sb)
34489+{
34490+ struct au_wbr_mfs *mfs;
34491+
34492+ mfs = &au_sbi(sb)->si_wbr_mfs;
34493+ mutex_init(&mfs->mfs_lock);
34494+ mfs->mfs_jiffy = 0;
34495+ mfs->mfs_bindex = -EROFS;
34496+
34497+ return 0;
34498+}
34499+
34500+static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
34501+{
34502+ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
34503+ return 0;
34504+}
34505+
34506+/* ---------------------------------------------------------------------- */
34507+
34508+/* top down regardless parent, and then mfs */
34509+static int au_wbr_create_tdmfs(struct dentry *dentry,
34510+ unsigned int flags __maybe_unused)
34511+{
34512+ int err;
34513+ aufs_bindex_t bwh, btail, bindex, bfound, bmfs;
34514+ unsigned long long watermark;
34515+ struct super_block *sb;
34516+ struct au_wbr_mfs *mfs;
34517+ struct au_branch *br;
34518+ struct dentry *parent;
34519+
34520+ sb = dentry->d_sb;
34521+ mfs = &au_sbi(sb)->si_wbr_mfs;
34522+ mutex_lock(&mfs->mfs_lock);
34523+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
34524+ || mfs->mfs_bindex < 0)
34525+ au_mfs(dentry, /*parent*/NULL);
34526+ watermark = mfs->mfsrr_watermark;
34527+ bmfs = mfs->mfs_bindex;
34528+ mutex_unlock(&mfs->mfs_lock);
34529+
34530+ /* another style of au_wbr_create_exp() */
34531+ bwh = au_dbwh(dentry);
34532+ parent = dget_parent(dentry);
34533+ btail = au_dbtaildir(parent);
34534+ if (bwh >= 0 && bwh < btail)
34535+ btail = bwh;
34536+
34537+ err = au_wbr_nonopq(dentry, btail);
34538+ if (unlikely(err < 0))
34539+ goto out;
34540+ btail = err;
34541+ bfound = -1;
34542+ for (bindex = 0; bindex <= btail; bindex++) {
34543+ br = au_sbr(sb, bindex);
34544+ if (au_br_rdonly(br))
34545+ continue;
34546+ if (br->br_wbr->wbr_bytes > watermark) {
34547+ bfound = bindex;
34548+ break;
34549+ }
34550+ }
34551+ err = bfound;
34552+ if (err < 0)
34553+ err = bmfs;
34554+
34555+out:
34556+ dput(parent);
34557+ AuDbg("b%d\n", err);
34558+ return err;
34559+}
34560+
34561+/* ---------------------------------------------------------------------- */
34562+
34563+/* most free space and then round robin */
34564+static int au_wbr_create_mfsrr(struct dentry *dentry, unsigned int flags)
34565+{
34566+ int err;
34567+ struct au_wbr_mfs *mfs;
34568+
34569+ err = au_wbr_create_mfs(dentry, flags);
34570+ if (err >= 0) {
34571+ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
34572+ mutex_lock(&mfs->mfs_lock);
34573+ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
34574+ err = au_wbr_create_rr(dentry, flags);
34575+ mutex_unlock(&mfs->mfs_lock);
34576+ }
34577+
34578+ AuDbg("b%d\n", err);
34579+ return err;
34580+}
34581+
34582+static int au_wbr_create_init_mfsrr(struct super_block *sb)
34583+{
34584+ int err;
34585+
34586+ au_wbr_create_init_mfs(sb); /* ignore */
34587+ err = au_wbr_create_init_rr(sb);
34588+
34589+ return err;
34590+}
34591+
34592+/* ---------------------------------------------------------------------- */
34593+
34594+/* top down parent and most free space */
34595+static int au_wbr_create_pmfs(struct dentry *dentry, unsigned int flags)
34596+{
34597+ int err, e2;
34598+ unsigned long long b;
34599+ aufs_bindex_t bindex, btop, bbot;
34600+ struct super_block *sb;
34601+ struct dentry *parent, *h_parent;
34602+ struct au_branch *br;
34603+
34604+ err = au_wbr_create_tdp(dentry, flags);
34605+ if (unlikely(err < 0))
34606+ goto out;
34607+ parent = dget_parent(dentry);
34608+ btop = au_dbtop(parent);
34609+ bbot = au_dbtaildir(parent);
34610+ if (btop == bbot)
34611+ goto out_parent; /* success */
34612+
34613+ e2 = au_wbr_create_mfs(dentry, flags);
34614+ if (e2 < 0)
34615+ goto out_parent; /* success */
34616+
34617+ /* when the available size is equal, select upper one */
34618+ sb = dentry->d_sb;
34619+ br = au_sbr(sb, err);
34620+ b = br->br_wbr->wbr_bytes;
34621+ AuDbg("b%d, %llu\n", err, b);
34622+
34623+ for (bindex = btop; bindex <= bbot; bindex++) {
34624+ h_parent = au_h_dptr(parent, bindex);
34625+ if (!h_parent || d_is_negative(h_parent))
34626+ continue;
34627+
34628+ br = au_sbr(sb, bindex);
34629+ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
34630+ b = br->br_wbr->wbr_bytes;
34631+ err = bindex;
34632+ AuDbg("b%d, %llu\n", err, b);
34633+ }
34634+ }
34635+
34636+ if (err >= 0)
34637+ err = au_wbr_nonopq(dentry, err);
34638+
34639+out_parent:
34640+ dput(parent);
34641+out:
34642+ AuDbg("b%d\n", err);
34643+ return err;
34644+}
34645+
34646+/* ---------------------------------------------------------------------- */
34647+
34648+/*
34649+ * - top down parent
34650+ * - most free space with parent
34651+ * - most free space round-robin regardless parent
34652+ */
34653+static int au_wbr_create_pmfsrr(struct dentry *dentry, unsigned int flags)
34654+{
34655+ int err;
34656+ unsigned long long watermark;
34657+ struct super_block *sb;
34658+ struct au_branch *br;
34659+ struct au_wbr_mfs *mfs;
34660+
34661+ err = au_wbr_create_pmfs(dentry, flags | AuWbr_PARENT);
34662+ if (unlikely(err < 0))
34663+ goto out;
34664+
34665+ sb = dentry->d_sb;
34666+ br = au_sbr(sb, err);
34667+ mfs = &au_sbi(sb)->si_wbr_mfs;
34668+ mutex_lock(&mfs->mfs_lock);
34669+ watermark = mfs->mfsrr_watermark;
34670+ mutex_unlock(&mfs->mfs_lock);
34671+ if (br->br_wbr->wbr_bytes < watermark)
34672+ /* regardless the parent dir */
34673+ err = au_wbr_create_mfsrr(dentry, flags);
34674+
34675+out:
34676+ AuDbg("b%d\n", err);
34677+ return err;
34678+}
34679+
34680+/* ---------------------------------------------------------------------- */
34681+
34682+/* policies for copyup */
34683+
34684+/* top down parent */
34685+static int au_wbr_copyup_tdp(struct dentry *dentry)
34686+{
34687+ return au_wbr_create_tdp(dentry, /*flags, anything is ok*/0);
34688+}
34689+
34690+/* bottom up parent */
34691+static int au_wbr_copyup_bup(struct dentry *dentry)
34692+{
34693+ int err;
34694+ aufs_bindex_t bindex, btop;
34695+ struct dentry *parent, *h_parent;
34696+ struct super_block *sb;
34697+
34698+ err = -EROFS;
34699+ sb = dentry->d_sb;
34700+ parent = dget_parent(dentry);
34701+ btop = au_dbtop(parent);
34702+ for (bindex = au_dbtop(dentry); bindex >= btop; bindex--) {
34703+ h_parent = au_h_dptr(parent, bindex);
34704+ if (!h_parent || d_is_negative(h_parent))
34705+ continue;
34706+
34707+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
34708+ err = bindex;
34709+ break;
34710+ }
34711+ }
34712+ dput(parent);
34713+
34714+ /* bottom up here */
34715+ if (unlikely(err < 0))
34716+ err = au_wbr_bu(sb, btop - 1);
34717+
34718+ AuDbg("b%d\n", err);
34719+ return err;
34720+}
34721+
34722+/* bottom up */
34723+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t btop)
34724+{
34725+ int err;
34726+
34727+ err = au_wbr_bu(dentry->d_sb, btop);
34728+ AuDbg("b%d\n", err);
34729+ if (err > btop)
34730+ err = au_wbr_nonopq(dentry, err);
34731+
34732+ AuDbg("b%d\n", err);
34733+ return err;
34734+}
34735+
34736+static int au_wbr_copyup_bu(struct dentry *dentry)
34737+{
34738+ int err;
34739+ aufs_bindex_t btop;
34740+
34741+ btop = au_dbtop(dentry);
34742+ err = au_wbr_do_copyup_bu(dentry, btop);
34743+ return err;
34744+}
34745+
34746+/* ---------------------------------------------------------------------- */
34747+
34748+struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
34749+ [AuWbrCopyup_TDP] = {
34750+ .copyup = au_wbr_copyup_tdp
34751+ },
34752+ [AuWbrCopyup_BUP] = {
34753+ .copyup = au_wbr_copyup_bup
34754+ },
34755+ [AuWbrCopyup_BU] = {
34756+ .copyup = au_wbr_copyup_bu
34757+ }
34758+};
34759+
34760+struct au_wbr_create_operations au_wbr_create_ops[] = {
34761+ [AuWbrCreate_TDP] = {
34762+ .create = au_wbr_create_tdp
34763+ },
34764+ [AuWbrCreate_RR] = {
34765+ .create = au_wbr_create_rr,
34766+ .init = au_wbr_create_init_rr
34767+ },
34768+ [AuWbrCreate_MFS] = {
34769+ .create = au_wbr_create_mfs,
34770+ .init = au_wbr_create_init_mfs,
34771+ .fin = au_wbr_create_fin_mfs
34772+ },
34773+ [AuWbrCreate_MFSV] = {
34774+ .create = au_wbr_create_mfs,
34775+ .init = au_wbr_create_init_mfs,
34776+ .fin = au_wbr_create_fin_mfs
34777+ },
34778+ [AuWbrCreate_MFSRR] = {
34779+ .create = au_wbr_create_mfsrr,
34780+ .init = au_wbr_create_init_mfsrr,
34781+ .fin = au_wbr_create_fin_mfs
34782+ },
34783+ [AuWbrCreate_MFSRRV] = {
34784+ .create = au_wbr_create_mfsrr,
34785+ .init = au_wbr_create_init_mfsrr,
34786+ .fin = au_wbr_create_fin_mfs
34787+ },
34788+ [AuWbrCreate_TDMFS] = {
34789+ .create = au_wbr_create_tdmfs,
34790+ .init = au_wbr_create_init_mfs,
34791+ .fin = au_wbr_create_fin_mfs
34792+ },
34793+ [AuWbrCreate_TDMFSV] = {
34794+ .create = au_wbr_create_tdmfs,
34795+ .init = au_wbr_create_init_mfs,
34796+ .fin = au_wbr_create_fin_mfs
34797+ },
34798+ [AuWbrCreate_PMFS] = {
34799+ .create = au_wbr_create_pmfs,
34800+ .init = au_wbr_create_init_mfs,
34801+ .fin = au_wbr_create_fin_mfs
34802+ },
34803+ [AuWbrCreate_PMFSV] = {
34804+ .create = au_wbr_create_pmfs,
34805+ .init = au_wbr_create_init_mfs,
34806+ .fin = au_wbr_create_fin_mfs
34807+ },
34808+ [AuWbrCreate_PMFSRR] = {
34809+ .create = au_wbr_create_pmfsrr,
34810+ .init = au_wbr_create_init_mfsrr,
34811+ .fin = au_wbr_create_fin_mfs
34812+ },
34813+ [AuWbrCreate_PMFSRRV] = {
34814+ .create = au_wbr_create_pmfsrr,
34815+ .init = au_wbr_create_init_mfsrr,
34816+ .fin = au_wbr_create_fin_mfs
34817+ }
34818+};
34819diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
34820--- /usr/share/empty/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100
34821+++ linux/fs/aufs/whout.c 2020-01-27 10:57:18.178871751 +0100
34822@@ -0,0 +1,1062 @@
34823+// SPDX-License-Identifier: GPL-2.0
34824+/*
34825+ * Copyright (C) 2005-2020 Junjiro R. Okajima
34826+ *
34827+ * This program, aufs is free software; you can redistribute it and/or modify
34828+ * it under the terms of the GNU General Public License as published by
34829+ * the Free Software Foundation; either version 2 of the License, or
34830+ * (at your option) any later version.
34831+ *
34832+ * This program is distributed in the hope that it will be useful,
34833+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
34834+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34835+ * GNU General Public License for more details.
34836+ *
34837+ * You should have received a copy of the GNU General Public License
34838+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
34839+ */
34840+
34841+/*
34842+ * whiteout for logical deletion and opaque directory
34843+ */
34844+
34845+#include "aufs.h"
34846+
34847+#define WH_MASK 0444
34848+
34849+/*
34850+ * If a directory contains this file, then it is opaque. We start with the
34851+ * .wh. flag so that it is blocked by lookup.
34852+ */
34853+static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ,
34854+ sizeof(AUFS_WH_DIROPQ) - 1);
34855+
34856+/*
34857+ * generate whiteout name, which is NOT terminated by NULL.
34858+ * @name: original d_name.name
34859+ * @len: original d_name.len
34860+ * @wh: whiteout qstr
34861+ * returns zero when succeeds, otherwise error.
34862+ * succeeded value as wh->name should be freed by kfree().
34863+ */
34864+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
34865+{
34866+ char *p;
34867+
34868+ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
34869+ return -ENAMETOOLONG;
34870+
34871+ wh->len = name->len + AUFS_WH_PFX_LEN;
34872+ p = kmalloc(wh->len, GFP_NOFS);
34873+ wh->name = p;
34874+ if (p) {
34875+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
34876+ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
34877+ /* smp_mb(); */
34878+ return 0;
34879+ }
34880+ return -ENOMEM;
34881+}
34882+
34883+/* ---------------------------------------------------------------------- */
34884+
34885+/*
34886+ * test if the @wh_name exists under @h_parent.
34887+ * @try_sio specifies the necessary of super-io.
34888+ */
34889+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio)
34890+{
34891+ int err;
34892+ struct dentry *wh_dentry;
34893+
34894+ if (!try_sio)
34895+ wh_dentry = vfsub_lkup_one(wh_name, h_parent);
34896+ else
34897+ wh_dentry = au_sio_lkup_one(wh_name, h_parent);
34898+ err = PTR_ERR(wh_dentry);
34899+ if (IS_ERR(wh_dentry)) {
34900+ if (err == -ENAMETOOLONG)
34901+ err = 0;
34902+ goto out;
34903+ }
34904+
34905+ err = 0;
34906+ if (d_is_negative(wh_dentry))
34907+ goto out_wh; /* success */
34908+
34909+ err = 1;
34910+ if (d_is_reg(wh_dentry))
34911+ goto out_wh; /* success */
34912+
34913+ err = -EIO;
34914+ AuIOErr("%pd Invalid whiteout entry type 0%o.\n",
34915+ wh_dentry, d_inode(wh_dentry)->i_mode);
34916+
34917+out_wh:
34918+ dput(wh_dentry);
34919+out:
34920+ return err;
34921+}
34922+
34923+/*
34924+ * test if the @h_dentry sets opaque or not.
34925+ */
34926+int au_diropq_test(struct dentry *h_dentry)
34927+{
34928+ int err;
34929+ struct inode *h_dir;
34930+
34931+ h_dir = d_inode(h_dentry);
34932+ err = au_wh_test(h_dentry, &diropq_name,
34933+ au_test_h_perm_sio(h_dir, MAY_EXEC));
34934+ return err;
34935+}
34936+
34937+/*
34938+ * returns a negative dentry whose name is unique and temporary.
34939+ */
34940+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
34941+ struct qstr *prefix)
34942+{
34943+ struct dentry *dentry;
34944+ int i;
34945+ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
34946+ *name, *p;
34947+ /* strict atomic_t is unnecessary here */
34948+ static unsigned short cnt;
34949+ struct qstr qs;
34950+
34951+ BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
34952+
34953+ name = defname;
34954+ qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
34955+ if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
34956+ dentry = ERR_PTR(-ENAMETOOLONG);
34957+ if (unlikely(qs.len > NAME_MAX))
34958+ goto out;
34959+ dentry = ERR_PTR(-ENOMEM);
34960+ name = kmalloc(qs.len + 1, GFP_NOFS);
34961+ if (unlikely(!name))
34962+ goto out;
34963+ }
34964+
34965+ /* doubly whiteout-ed */
34966+ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
34967+ p = name + AUFS_WH_PFX_LEN * 2;
34968+ memcpy(p, prefix->name, prefix->len);
34969+ p += prefix->len;
34970+ *p++ = '.';
34971+ AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
34972+
34973+ qs.name = name;
34974+ for (i = 0; i < 3; i++) {
34975+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
34976+ dentry = au_sio_lkup_one(&qs, h_parent);
34977+ if (IS_ERR(dentry) || d_is_negative(dentry))
34978+ goto out_name;
34979+ dput(dentry);
34980+ }
34981+ /* pr_warn("could not get random name\n"); */
34982+ dentry = ERR_PTR(-EEXIST);
34983+ AuDbg("%.*s\n", AuLNPair(&qs));
34984+ BUG();
34985+
34986+out_name:
34987+ if (name != defname)
34988+ au_kfree_try_rcu(name);
34989+out:
34990+ AuTraceErrPtr(dentry);
34991+ return dentry;
34992+}
34993+
34994+/*
34995+ * rename the @h_dentry on @br to the whiteouted temporary name.
34996+ */
34997+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
34998+{
34999+ int err;
35000+ struct path h_path = {
35001+ .mnt = au_br_mnt(br)
35002+ };
35003+ struct inode *h_dir, *delegated;
35004+ struct dentry *h_parent;
35005+
35006+ h_parent = h_dentry->d_parent; /* dir inode is locked */
35007+ h_dir = d_inode(h_parent);
35008+ IMustLock(h_dir);
35009+
35010+ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
35011+ err = PTR_ERR(h_path.dentry);
35012+ if (IS_ERR(h_path.dentry))
35013+ goto out;
35014+
35015+ /* under the same dir, no need to lock_rename() */
35016+ delegated = NULL;
35017+ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path, &delegated,
35018+ /*flags*/0);
35019+ AuTraceErr(err);
35020+ if (unlikely(err == -EWOULDBLOCK)) {
35021+ pr_warn("cannot retry for NFSv4 delegation"
35022+ " for an internal rename\n");
35023+ iput(delegated);
35024+ }
35025+ dput(h_path.dentry);
35026+
35027+out:
35028+ AuTraceErr(err);
35029+ return err;
35030+}
35031+
35032+/* ---------------------------------------------------------------------- */
35033+/*
35034+ * functions for removing a whiteout
35035+ */
35036+
35037+static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
35038+{
35039+ int err, force;
35040+ struct inode *delegated;
35041+
35042+ /*
35043+ * forces superio when the dir has a sticky bit.
35044+ * this may be a violation of unix fs semantics.
35045+ */
35046+ force = (h_dir->i_mode & S_ISVTX)
35047+ && !uid_eq(current_fsuid(), d_inode(h_path->dentry)->i_uid);
35048+ delegated = NULL;
35049+ err = vfsub_unlink(h_dir, h_path, &delegated, force);
35050+ if (unlikely(err == -EWOULDBLOCK)) {
35051+ pr_warn("cannot retry for NFSv4 delegation"
35052+ " for an internal unlink\n");
35053+ iput(delegated);
35054+ }
35055+ return err;
35056+}
35057+
35058+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
35059+ struct dentry *dentry)
35060+{
35061+ int err;
35062+
35063+ err = do_unlink_wh(h_dir, h_path);
35064+ if (!err && dentry)
35065+ au_set_dbwh(dentry, -1);
35066+
35067+ return err;
35068+}
35069+
35070+static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
35071+ struct au_branch *br)
35072+{
35073+ int err;
35074+ struct path h_path = {
35075+ .mnt = au_br_mnt(br)
35076+ };
35077+
35078+ err = 0;
35079+ h_path.dentry = vfsub_lkup_one(wh, h_parent);
35080+ if (IS_ERR(h_path.dentry))
35081+ err = PTR_ERR(h_path.dentry);
35082+ else {
35083+ if (d_is_reg(h_path.dentry))
35084+ err = do_unlink_wh(d_inode(h_parent), &h_path);
35085+ dput(h_path.dentry);
35086+ }
35087+
35088+ return err;
35089+}
35090+
35091+/* ---------------------------------------------------------------------- */
35092+/*
35093+ * initialize/clean whiteout for a branch
35094+ */
35095+
35096+static void au_wh_clean(struct inode *h_dir, struct path *whpath,
35097+ const int isdir)
35098+{
35099+ int err;
35100+ struct inode *delegated;
35101+
35102+ if (d_is_negative(whpath->dentry))
35103+ return;
35104+
35105+ if (isdir)
35106+ err = vfsub_rmdir(h_dir, whpath);
35107+ else {
35108+ delegated = NULL;
35109+ err = vfsub_unlink(h_dir, whpath, &delegated, /*force*/0);
35110+ if (unlikely(err == -EWOULDBLOCK)) {
35111+ pr_warn("cannot retry for NFSv4 delegation"
35112+ " for an internal unlink\n");
35113+ iput(delegated);
35114+ }
35115+ }
35116+ if (unlikely(err))
35117+ pr_warn("failed removing %pd (%d), ignored.\n",
35118+ whpath->dentry, err);
35119+}
35120+
35121+static int test_linkable(struct dentry *h_root)
35122+{
35123+ struct inode *h_dir = d_inode(h_root);
35124+
35125+ if (h_dir->i_op->link)
35126+ return 0;
35127+
35128+ pr_err("%pd (%s) doesn't support link(2), use noplink and rw+nolwh\n",
35129+ h_root, au_sbtype(h_root->d_sb));
35130+ return -ENOSYS; /* the branch doesn't have its ->link() */
35131+}
35132+
35133+/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
35134+static int au_whdir(struct inode *h_dir, struct path *path)
35135+{
35136+ int err;
35137+
35138+ err = -EEXIST;
35139+ if (d_is_negative(path->dentry)) {
35140+ int mode = 0700;
35141+
35142+ if (au_test_nfs(path->dentry->d_sb))
35143+ mode |= 0111;
35144+ err = vfsub_mkdir(h_dir, path, mode);
35145+ } else if (d_is_dir(path->dentry))
35146+ err = 0;
35147+ else
35148+ pr_err("unknown %pd exists\n", path->dentry);
35149+
35150+ return err;
35151+}
35152+
35153+struct au_wh_base {
35154+ const struct qstr *name;
35155+ struct dentry *dentry;
35156+};
35157+
35158+static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
35159+ struct path *h_path)
35160+{
35161+ h_path->dentry = base[AuBrWh_BASE].dentry;
35162+ au_wh_clean(h_dir, h_path, /*isdir*/0);
35163+ h_path->dentry = base[AuBrWh_PLINK].dentry;
35164+ au_wh_clean(h_dir, h_path, /*isdir*/1);
35165+ h_path->dentry = base[AuBrWh_ORPH].dentry;
35166+ au_wh_clean(h_dir, h_path, /*isdir*/1);
35167+}
35168+
35169+/*
35170+ * returns tri-state,
35171+ * minus: error, caller should print the message
35172+ * zero: success
35173+ * plus: error, caller should NOT print the message
35174+ */
35175+static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
35176+ int do_plink, struct au_wh_base base[],
35177+ struct path *h_path)
35178+{
35179+ int err;
35180+ struct inode *h_dir;
35181+
35182+ h_dir = d_inode(h_root);
35183+ h_path->dentry = base[AuBrWh_BASE].dentry;
35184+ au_wh_clean(h_dir, h_path, /*isdir*/0);
35185+ h_path->dentry = base[AuBrWh_PLINK].dentry;
35186+ if (do_plink) {
35187+ err = test_linkable(h_root);
35188+ if (unlikely(err)) {
35189+ err = 1;
35190+ goto out;
35191+ }
35192+
35193+ err = au_whdir(h_dir, h_path);
35194+ if (unlikely(err))
35195+ goto out;
35196+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
35197+ } else
35198+ au_wh_clean(h_dir, h_path, /*isdir*/1);
35199+ h_path->dentry = base[AuBrWh_ORPH].dentry;
35200+ err = au_whdir(h_dir, h_path);
35201+ if (unlikely(err))
35202+ goto out;
35203+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
35204+
35205+out:
35206+ return err;
35207+}
35208+
35209+/*
35210+ * for the moment, aufs supports the branch filesystem which does not support
35211+ * link(2). testing on FAT which does not support i_op->setattr() fully either,
35212+ * copyup failed. finally, such filesystem will not be used as the writable
35213+ * branch.
35214+ *
35215+ * returns tri-state, see above.
35216+ */
35217+static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
35218+ int do_plink, struct au_wh_base base[],
35219+ struct path *h_path)
35220+{
35221+ int err;
35222+ struct inode *h_dir;
35223+
35224+ WbrWhMustWriteLock(wbr);
35225+
35226+ err = test_linkable(h_root);
35227+ if (unlikely(err)) {
35228+ err = 1;
35229+ goto out;
35230+ }
35231+
35232+ /*
35233+ * todo: should this create be done in /sbin/mount.aufs helper?
35234+ */
35235+ err = -EEXIST;
35236+ h_dir = d_inode(h_root);
35237+ if (d_is_negative(base[AuBrWh_BASE].dentry)) {
35238+ h_path->dentry = base[AuBrWh_BASE].dentry;
35239+ err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true);
35240+ } else if (d_is_reg(base[AuBrWh_BASE].dentry))
35241+ err = 0;
35242+ else
35243+ pr_err("unknown %pd2 exists\n", base[AuBrWh_BASE].dentry);
35244+ if (unlikely(err))
35245+ goto out;
35246+
35247+ h_path->dentry = base[AuBrWh_PLINK].dentry;
35248+ if (do_plink) {
35249+ err = au_whdir(h_dir, h_path);
35250+ if (unlikely(err))
35251+ goto out;
35252+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
35253+ } else
35254+ au_wh_clean(h_dir, h_path, /*isdir*/1);
35255+ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
35256+
35257+ h_path->dentry = base[AuBrWh_ORPH].dentry;
35258+ err = au_whdir(h_dir, h_path);
35259+ if (unlikely(err))
35260+ goto out;
35261+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
35262+
35263+out:
35264+ return err;
35265+}
35266+
35267+/*
35268+ * initialize the whiteout base file/dir for @br.
35269+ */
35270+int au_wh_init(struct au_branch *br, struct super_block *sb)
35271+{
35272+ int err, i;
35273+ const unsigned char do_plink
35274+ = !!au_opt_test(au_mntflags(sb), PLINK);
35275+ struct inode *h_dir;
35276+ struct path path = br->br_path;
35277+ struct dentry *h_root = path.dentry;
35278+ struct au_wbr *wbr = br->br_wbr;
35279+ static const struct qstr base_name[] = {
35280+ [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME,
35281+ sizeof(AUFS_BASE_NAME) - 1),
35282+ [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME,
35283+ sizeof(AUFS_PLINKDIR_NAME) - 1),
35284+ [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME,
35285+ sizeof(AUFS_ORPHDIR_NAME) - 1)
35286+ };
35287+ struct au_wh_base base[] = {
35288+ [AuBrWh_BASE] = {
35289+ .name = base_name + AuBrWh_BASE,
35290+ .dentry = NULL
35291+ },
35292+ [AuBrWh_PLINK] = {
35293+ .name = base_name + AuBrWh_PLINK,
35294+ .dentry = NULL
35295+ },
35296+ [AuBrWh_ORPH] = {
35297+ .name = base_name + AuBrWh_ORPH,
35298+ .dentry = NULL
35299+ }
35300+ };
35301+
35302+ if (wbr)
35303+ WbrWhMustWriteLock(wbr);
35304+
35305+ for (i = 0; i < AuBrWh_Last; i++) {
35306+ /* doubly whiteouted */
35307+ struct dentry *d;
35308+
35309+ d = au_wh_lkup(h_root, (void *)base[i].name, br);
35310+ err = PTR_ERR(d);
35311+ if (IS_ERR(d))
35312+ goto out;
35313+
35314+ base[i].dentry = d;
35315+ AuDebugOn(wbr
35316+ && wbr->wbr_wh[i]
35317+ && wbr->wbr_wh[i] != base[i].dentry);
35318+ }
35319+
35320+ if (wbr)
35321+ for (i = 0; i < AuBrWh_Last; i++) {
35322+ dput(wbr->wbr_wh[i]);
35323+ wbr->wbr_wh[i] = NULL;
35324+ }
35325+
35326+ err = 0;
35327+ if (!au_br_writable(br->br_perm)) {
35328+ h_dir = d_inode(h_root);
35329+ au_wh_init_ro(h_dir, base, &path);
35330+ } else if (!au_br_wh_linkable(br->br_perm)) {
35331+ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
35332+ if (err > 0)
35333+ goto out;
35334+ else if (err)
35335+ goto out_err;
35336+ } else {
35337+ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
35338+ if (err > 0)
35339+ goto out;
35340+ else if (err)
35341+ goto out_err;
35342+ }
35343+ goto out; /* success */
35344+
35345+out_err:
35346+ pr_err("an error(%d) on the writable branch %pd(%s)\n",
35347+ err, h_root, au_sbtype(h_root->d_sb));
35348+out:
35349+ for (i = 0; i < AuBrWh_Last; i++)
35350+ dput(base[i].dentry);
35351+ return err;
35352+}
35353+
35354+/* ---------------------------------------------------------------------- */
35355+/*
35356+ * whiteouts are all hard-linked usually.
35357+ * when its link count reaches a ceiling, we create a new whiteout base
35358+ * asynchronously.
35359+ */
35360+
35361+struct reinit_br_wh {
35362+ struct super_block *sb;
35363+ struct au_branch *br;
35364+};
35365+
35366+static void reinit_br_wh(void *arg)
35367+{
35368+ int err;
35369+ aufs_bindex_t bindex;
35370+ struct path h_path;
35371+ struct reinit_br_wh *a = arg;
35372+ struct au_wbr *wbr;
35373+ struct inode *dir, *delegated;
35374+ struct dentry *h_root;
35375+ struct au_hinode *hdir;
35376+
35377+ err = 0;
35378+ wbr = a->br->br_wbr;
35379+ /* big aufs lock */
35380+ si_noflush_write_lock(a->sb);
35381+ if (!au_br_writable(a->br->br_perm))
35382+ goto out;
35383+ bindex = au_br_index(a->sb, a->br->br_id);
35384+ if (unlikely(bindex < 0))
35385+ goto out;
35386+
35387+ di_read_lock_parent(a->sb->s_root, AuLock_IR);
35388+ dir = d_inode(a->sb->s_root);
35389+ hdir = au_hi(dir, bindex);
35390+ h_root = au_h_dptr(a->sb->s_root, bindex);
35391+ AuDebugOn(h_root != au_br_dentry(a->br));
35392+
35393+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
35394+ wbr_wh_write_lock(wbr);
35395+ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
35396+ h_root, a->br);
35397+ if (!err) {
35398+ h_path.dentry = wbr->wbr_whbase;
35399+ h_path.mnt = au_br_mnt(a->br);
35400+ delegated = NULL;
35401+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated,
35402+ /*force*/0);
35403+ if (unlikely(err == -EWOULDBLOCK)) {
35404+ pr_warn("cannot retry for NFSv4 delegation"
35405+ " for an internal unlink\n");
35406+ iput(delegated);
35407+ }
35408+ } else {
35409+ pr_warn("%pd is moved, ignored\n", wbr->wbr_whbase);
35410+ err = 0;
35411+ }
35412+ dput(wbr->wbr_whbase);
35413+ wbr->wbr_whbase = NULL;
35414+ if (!err)
35415+ err = au_wh_init(a->br, a->sb);
35416+ wbr_wh_write_unlock(wbr);
35417+ au_hn_inode_unlock(hdir);
35418+ di_read_unlock(a->sb->s_root, AuLock_IR);
35419+ if (!err)
35420+ au_fhsm_wrote(a->sb, bindex, /*force*/0);
35421+
35422+out:
35423+ if (wbr)
35424+ atomic_dec(&wbr->wbr_wh_running);
35425+ au_lcnt_dec(&a->br->br_count);
35426+ si_write_unlock(a->sb);
35427+ au_nwt_done(&au_sbi(a->sb)->si_nowait);
35428+ au_kfree_rcu(a);
35429+ if (unlikely(err))
35430+ AuIOErr("err %d\n", err);
35431+}
35432+
35433+static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
35434+{
35435+ int do_dec, wkq_err;
35436+ struct reinit_br_wh *arg;
35437+
35438+ do_dec = 1;
35439+ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
35440+ goto out;
35441+
35442+ /* ignore ENOMEM */
35443+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
35444+ if (arg) {
35445+ /*
35446+ * dec(wh_running), kfree(arg) and dec(br_count)
35447+ * in reinit function
35448+ */
35449+ arg->sb = sb;
35450+ arg->br = br;
35451+ au_lcnt_inc(&br->br_count);
35452+ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0);
35453+ if (unlikely(wkq_err)) {
35454+ atomic_dec(&br->br_wbr->wbr_wh_running);
35455+ au_lcnt_dec(&br->br_count);
35456+ au_kfree_rcu(arg);
35457+ }
35458+ do_dec = 0;
35459+ }
35460+
35461+out:
35462+ if (do_dec)
35463+ atomic_dec(&br->br_wbr->wbr_wh_running);
35464+}
35465+
35466+/* ---------------------------------------------------------------------- */
35467+
35468+/*
35469+ * create the whiteout @wh.
35470+ */
35471+static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
35472+ struct dentry *wh)
35473+{
35474+ int err;
35475+ struct path h_path = {
35476+ .dentry = wh
35477+ };
35478+ struct au_branch *br;
35479+ struct au_wbr *wbr;
35480+ struct dentry *h_parent;
35481+ struct inode *h_dir, *delegated;
35482+
35483+ h_parent = wh->d_parent; /* dir inode is locked */
35484+ h_dir = d_inode(h_parent);
35485+ IMustLock(h_dir);
35486+
35487+ br = au_sbr(sb, bindex);
35488+ h_path.mnt = au_br_mnt(br);
35489+ wbr = br->br_wbr;
35490+ wbr_wh_read_lock(wbr);
35491+ if (wbr->wbr_whbase) {
35492+ delegated = NULL;
35493+ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path, &delegated);
35494+ if (unlikely(err == -EWOULDBLOCK)) {
35495+ pr_warn("cannot retry for NFSv4 delegation"
35496+ " for an internal link\n");
35497+ iput(delegated);
35498+ }
35499+ if (!err || err != -EMLINK)
35500+ goto out;
35501+
35502+ /* link count full. re-initialize br_whbase. */
35503+ kick_reinit_br_wh(sb, br);
35504+ }
35505+
35506+ /* return this error in this context */
35507+ err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true);
35508+ if (!err)
35509+ au_fhsm_wrote(sb, bindex, /*force*/0);
35510+
35511+out:
35512+ wbr_wh_read_unlock(wbr);
35513+ return err;
35514+}
35515+
35516+/* ---------------------------------------------------------------------- */
35517+
35518+/*
35519+ * create or remove the diropq.
35520+ */
35521+static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
35522+ unsigned int flags)
35523+{
35524+ struct dentry *opq_dentry, *h_dentry;
35525+ struct super_block *sb;
35526+ struct au_branch *br;
35527+ int err;
35528+
35529+ sb = dentry->d_sb;
35530+ br = au_sbr(sb, bindex);
35531+ h_dentry = au_h_dptr(dentry, bindex);
35532+ opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry);
35533+ if (IS_ERR(opq_dentry))
35534+ goto out;
35535+
35536+ if (au_ftest_diropq(flags, CREATE)) {
35537+ err = link_or_create_wh(sb, bindex, opq_dentry);
35538+ if (!err) {
35539+ au_set_dbdiropq(dentry, bindex);
35540+ goto out; /* success */
35541+ }
35542+ } else {
35543+ struct path tmp = {
35544+ .dentry = opq_dentry,
35545+ .mnt = au_br_mnt(br)
35546+ };
35547+ err = do_unlink_wh(au_h_iptr(d_inode(dentry), bindex), &tmp);
35548+ if (!err)
35549+ au_set_dbdiropq(dentry, -1);
35550+ }
35551+ dput(opq_dentry);
35552+ opq_dentry = ERR_PTR(err);
35553+
35554+out:
35555+ return opq_dentry;
35556+}
35557+
35558+struct do_diropq_args {
35559+ struct dentry **errp;
35560+ struct dentry *dentry;
35561+ aufs_bindex_t bindex;
35562+ unsigned int flags;
35563+};
35564+
35565+static void call_do_diropq(void *args)
35566+{
35567+ struct do_diropq_args *a = args;
35568+ *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
35569+}
35570+
35571+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
35572+ unsigned int flags)
35573+{
35574+ struct dentry *diropq, *h_dentry;
35575+
35576+ h_dentry = au_h_dptr(dentry, bindex);
35577+ if (!au_test_h_perm_sio(d_inode(h_dentry), MAY_EXEC | MAY_WRITE))
35578+ diropq = do_diropq(dentry, bindex, flags);
35579+ else {
35580+ int wkq_err;
35581+ struct do_diropq_args args = {
35582+ .errp = &diropq,
35583+ .dentry = dentry,
35584+ .bindex = bindex,
35585+ .flags = flags
35586+ };
35587+
35588+ wkq_err = au_wkq_wait(call_do_diropq, &args);
35589+ if (unlikely(wkq_err))
35590+ diropq = ERR_PTR(wkq_err);
35591+ }
35592+
35593+ return diropq;
35594+}
35595+
35596+/* ---------------------------------------------------------------------- */
35597+
35598+/*
35599+ * lookup whiteout dentry.
35600+ * @h_parent: lower parent dentry which must exist and be locked
35601+ * @base_name: name of dentry which will be whiteouted
35602+ * returns dentry for whiteout.
35603+ */
35604+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
35605+ struct au_branch *br)
35606+{
35607+ int err;
35608+ struct qstr wh_name;
35609+ struct dentry *wh_dentry;
35610+
35611+ err = au_wh_name_alloc(&wh_name, base_name);
35612+ wh_dentry = ERR_PTR(err);
35613+ if (!err) {
35614+ wh_dentry = vfsub_lkup_one(&wh_name, h_parent);
35615+ au_kfree_try_rcu(wh_name.name);
35616+ }
35617+ return wh_dentry;
35618+}
35619+
35620+/*
35621+ * link/create a whiteout for @dentry on @bindex.
35622+ */
35623+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
35624+ struct dentry *h_parent)
35625+{
35626+ struct dentry *wh_dentry;
35627+ struct super_block *sb;
35628+ int err;
35629+
35630+ sb = dentry->d_sb;
35631+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
35632+ if (!IS_ERR(wh_dentry) && d_is_negative(wh_dentry)) {
35633+ err = link_or_create_wh(sb, bindex, wh_dentry);
35634+ if (!err) {
35635+ au_set_dbwh(dentry, bindex);
35636+ au_fhsm_wrote(sb, bindex, /*force*/0);
35637+ } else {
35638+ dput(wh_dentry);
35639+ wh_dentry = ERR_PTR(err);
35640+ }
35641+ }
35642+
35643+ return wh_dentry;
35644+}
35645+
35646+/* ---------------------------------------------------------------------- */
35647+
35648+/* Delete all whiteouts in this directory on branch bindex. */
35649+static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
35650+ aufs_bindex_t bindex, struct au_branch *br)
35651+{
35652+ int err;
35653+ unsigned long ul, n;
35654+ struct qstr wh_name;
35655+ char *p;
35656+ struct hlist_head *head;
35657+ struct au_vdir_wh *pos;
35658+ struct au_vdir_destr *str;
35659+
35660+ err = -ENOMEM;
35661+ p = (void *)__get_free_page(GFP_NOFS);
35662+ wh_name.name = p;
35663+ if (unlikely(!wh_name.name))
35664+ goto out;
35665+
35666+ err = 0;
35667+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
35668+ p += AUFS_WH_PFX_LEN;
35669+ n = whlist->nh_num;
35670+ head = whlist->nh_head;
35671+ for (ul = 0; !err && ul < n; ul++, head++) {
35672+ hlist_for_each_entry(pos, head, wh_hash) {
35673+ if (pos->wh_bindex != bindex)
35674+ continue;
35675+
35676+ str = &pos->wh_str;
35677+ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
35678+ memcpy(p, str->name, str->len);
35679+ wh_name.len = AUFS_WH_PFX_LEN + str->len;
35680+ err = unlink_wh_name(h_dentry, &wh_name, br);
35681+ if (!err)
35682+ continue;
35683+ break;
35684+ }
35685+ AuIOErr("whiteout name too long %.*s\n",
35686+ str->len, str->name);
35687+ err = -EIO;
35688+ break;
35689+ }
35690+ }
35691+ free_page((unsigned long)wh_name.name);
35692+
35693+out:
35694+ return err;
35695+}
35696+
35697+struct del_wh_children_args {
35698+ int *errp;
35699+ struct dentry *h_dentry;
35700+ struct au_nhash *whlist;
35701+ aufs_bindex_t bindex;
35702+ struct au_branch *br;
35703+};
35704+
35705+static void call_del_wh_children(void *args)
35706+{
35707+ struct del_wh_children_args *a = args;
35708+ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
35709+}
35710+
35711+/* ---------------------------------------------------------------------- */
35712+
35713+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
35714+{
35715+ struct au_whtmp_rmdir *whtmp;
35716+ int err;
35717+ unsigned int rdhash;
35718+
35719+ SiMustAnyLock(sb);
35720+
35721+ whtmp = kzalloc(sizeof(*whtmp), gfp);
35722+ if (unlikely(!whtmp)) {
35723+ whtmp = ERR_PTR(-ENOMEM);
35724+ goto out;
35725+ }
35726+
35727+ /* no estimation for dir size */
35728+ rdhash = au_sbi(sb)->si_rdhash;
35729+ if (!rdhash)
35730+ rdhash = AUFS_RDHASH_DEF;
35731+ err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
35732+ if (unlikely(err)) {
35733+ au_kfree_rcu(whtmp);
35734+ whtmp = ERR_PTR(err);
35735+ }
35736+
35737+out:
35738+ return whtmp;
35739+}
35740+
35741+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
35742+{
35743+ if (whtmp->br)
35744+ au_lcnt_dec(&whtmp->br->br_count);
35745+ dput(whtmp->wh_dentry);
35746+ iput(whtmp->dir);
35747+ au_nhash_wh_free(&whtmp->whlist);
35748+ au_kfree_rcu(whtmp);
35749+}
35750+
35751+/*
35752+ * rmdir the whiteouted temporary named dir @h_dentry.
35753+ * @whlist: whiteouted children.
35754+ */
35755+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
35756+ struct dentry *wh_dentry, struct au_nhash *whlist)
35757+{
35758+ int err;
35759+ unsigned int h_nlink;
35760+ struct path h_tmp;
35761+ struct inode *wh_inode, *h_dir;
35762+ struct au_branch *br;
35763+
35764+ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */
35765+ IMustLock(h_dir);
35766+
35767+ br = au_sbr(dir->i_sb, bindex);
35768+ wh_inode = d_inode(wh_dentry);
35769+ inode_lock_nested(wh_inode, AuLsc_I_CHILD);
35770+
35771+ /*
35772+ * someone else might change some whiteouts while we were sleeping.
35773+ * it means this whlist may have an obsoleted entry.
35774+ */
35775+ if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
35776+ err = del_wh_children(wh_dentry, whlist, bindex, br);
35777+ else {
35778+ int wkq_err;
35779+ struct del_wh_children_args args = {
35780+ .errp = &err,
35781+ .h_dentry = wh_dentry,
35782+ .whlist = whlist,
35783+ .bindex = bindex,
35784+ .br = br
35785+ };
35786+
35787+ wkq_err = au_wkq_wait(call_del_wh_children, &args);
35788+ if (unlikely(wkq_err))
35789+ err = wkq_err;
35790+ }
35791+ inode_unlock(wh_inode);
35792+
35793+ if (!err) {
35794+ h_tmp.dentry = wh_dentry;
35795+ h_tmp.mnt = au_br_mnt(br);
35796+ h_nlink = h_dir->i_nlink;
35797+ err = vfsub_rmdir(h_dir, &h_tmp);
35798+ /* some fs doesn't change the parent nlink in some cases */
35799+ h_nlink -= h_dir->i_nlink;
35800+ }
35801+
35802+ if (!err) {
35803+ if (au_ibtop(dir) == bindex) {
35804+ /* todo: dir->i_mutex is necessary */
35805+ au_cpup_attr_timesizes(dir);
35806+ if (h_nlink)
35807+ vfsub_drop_nlink(dir);
35808+ }
35809+ return 0; /* success */
35810+ }
35811+
35812+ pr_warn("failed removing %pd(%d), ignored\n", wh_dentry, err);
35813+ return err;
35814+}
35815+
35816+static void call_rmdir_whtmp(void *args)
35817+{
35818+ int err;
35819+ aufs_bindex_t bindex;
35820+ struct au_whtmp_rmdir *a = args;
35821+ struct super_block *sb;
35822+ struct dentry *h_parent;
35823+ struct inode *h_dir;
35824+ struct au_hinode *hdir;
35825+
35826+ /* rmdir by nfsd may cause deadlock with this i_mutex */
35827+ /* inode_lock(a->dir); */
35828+ err = -EROFS;
35829+ sb = a->dir->i_sb;
35830+ si_read_lock(sb, !AuLock_FLUSH);
35831+ if (!au_br_writable(a->br->br_perm))
35832+ goto out;
35833+ bindex = au_br_index(sb, a->br->br_id);
35834+ if (unlikely(bindex < 0))
35835+ goto out;
35836+
35837+ err = -EIO;
35838+ ii_write_lock_parent(a->dir);
35839+ h_parent = dget_parent(a->wh_dentry);
35840+ h_dir = d_inode(h_parent);
35841+ hdir = au_hi(a->dir, bindex);
35842+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
35843+ if (unlikely(err))
35844+ goto out_mnt;
35845+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
35846+ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
35847+ a->br);
35848+ if (!err)
35849+ err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist);
35850+ au_hn_inode_unlock(hdir);
35851+ vfsub_mnt_drop_write(au_br_mnt(a->br));
35852+
35853+out_mnt:
35854+ dput(h_parent);
35855+ ii_write_unlock(a->dir);
35856+out:
35857+ /* inode_unlock(a->dir); */
35858+ au_whtmp_rmdir_free(a);
35859+ si_read_unlock(sb);
35860+ au_nwt_done(&au_sbi(sb)->si_nowait);
35861+ if (unlikely(err))
35862+ AuIOErr("err %d\n", err);
35863+}
35864+
35865+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
35866+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
35867+{
35868+ int wkq_err;
35869+ struct super_block *sb;
35870+
35871+ IMustLock(dir);
35872+
35873+ /* all post-process will be done in do_rmdir_whtmp(). */
35874+ sb = dir->i_sb;
35875+ args->dir = au_igrab(dir);
35876+ args->br = au_sbr(sb, bindex);
35877+ au_lcnt_inc(&args->br->br_count);
35878+ args->wh_dentry = dget(wh_dentry);
35879+ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0);
35880+ if (unlikely(wkq_err)) {
35881+ pr_warn("rmdir error %pd (%d), ignored\n", wh_dentry, wkq_err);
35882+ au_whtmp_rmdir_free(args);
35883+ }
35884+}
35885diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h
35886--- /usr/share/empty/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100
35887+++ linux/fs/aufs/whout.h 2020-01-27 10:57:18.178871751 +0100
35888@@ -0,0 +1,86 @@
35889+/* SPDX-License-Identifier: GPL-2.0 */
35890+/*
35891+ * Copyright (C) 2005-2020 Junjiro R. Okajima
35892+ *
35893+ * This program, aufs is free software; you can redistribute it and/or modify
35894+ * it under the terms of the GNU General Public License as published by
35895+ * the Free Software Foundation; either version 2 of the License, or
35896+ * (at your option) any later version.
35897+ *
35898+ * This program is distributed in the hope that it will be useful,
35899+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
35900+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35901+ * GNU General Public License for more details.
35902+ *
35903+ * You should have received a copy of the GNU General Public License
35904+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
35905+ */
35906+
35907+/*
35908+ * whiteout for logical deletion and opaque directory
35909+ */
35910+
35911+#ifndef __AUFS_WHOUT_H__
35912+#define __AUFS_WHOUT_H__
35913+
35914+#ifdef __KERNEL__
35915+
35916+#include "dir.h"
35917+
35918+/* whout.c */
35919+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
35920+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio);
35921+int au_diropq_test(struct dentry *h_dentry);
35922+struct au_branch;
35923+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
35924+ struct qstr *prefix);
35925+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
35926+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
35927+ struct dentry *dentry);
35928+int au_wh_init(struct au_branch *br, struct super_block *sb);
35929+
35930+/* diropq flags */
35931+#define AuDiropq_CREATE 1
35932+#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name)
35933+#define au_fset_diropq(flags, name) \
35934+ do { (flags) |= AuDiropq_##name; } while (0)
35935+#define au_fclr_diropq(flags, name) \
35936+ do { (flags) &= ~AuDiropq_##name; } while (0)
35937+
35938+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
35939+ unsigned int flags);
35940+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
35941+ struct au_branch *br);
35942+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
35943+ struct dentry *h_parent);
35944+
35945+/* real rmdir for the whiteout-ed dir */
35946+struct au_whtmp_rmdir {
35947+ struct inode *dir;
35948+ struct au_branch *br;
35949+ struct dentry *wh_dentry;
35950+ struct au_nhash whlist;
35951+};
35952+
35953+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
35954+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
35955+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
35956+ struct dentry *wh_dentry, struct au_nhash *whlist);
35957+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
35958+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
35959+
35960+/* ---------------------------------------------------------------------- */
35961+
35962+static inline struct dentry *au_diropq_create(struct dentry *dentry,
35963+ aufs_bindex_t bindex)
35964+{
35965+ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
35966+}
35967+
35968+static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
35969+{
35970+ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
35971+}
35972+
35973+#endif /* __KERNEL__ */
35974+#endif /* __AUFS_WHOUT_H__ */
35975diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
35976--- /usr/share/empty/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100
35977+++ linux/fs/aufs/wkq.c 2020-04-03 08:16:47.547461775 +0200
35978@@ -0,0 +1,372 @@
35979+// SPDX-License-Identifier: GPL-2.0
35980+/*
35981+ * Copyright (C) 2005-2020 Junjiro R. Okajima
35982+ *
35983+ * This program, aufs is free software; you can redistribute it and/or modify
35984+ * it under the terms of the GNU General Public License as published by
35985+ * the Free Software Foundation; either version 2 of the License, or
35986+ * (at your option) any later version.
35987+ *
35988+ * This program is distributed in the hope that it will be useful,
35989+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
35990+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35991+ * GNU General Public License for more details.
35992+ *
35993+ * You should have received a copy of the GNU General Public License
35994+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
35995+ */
35996+
35997+/*
35998+ * workqueue for asynchronous/super-io operations
35999+ * todo: try new credential scheme
36000+ */
36001+
36002+#include <linux/module.h>
36003+#include "aufs.h"
36004+
36005+/* internal workqueue named AUFS_WKQ_NAME */
36006+
36007+static struct workqueue_struct *au_wkq;
36008+
36009+struct au_wkinfo {
36010+ struct work_struct wk;
36011+ struct kobject *kobj;
36012+
36013+ unsigned int flags; /* see wkq.h */
36014+
36015+ au_wkq_func_t func;
36016+ void *args;
36017+
36018+#ifdef CONFIG_LOCKDEP
36019+ int dont_check;
36020+ struct held_lock **hlock;
36021+#endif
36022+
36023+ struct completion *comp;
36024+};
36025+
36026+/* ---------------------------------------------------------------------- */
36027+/*
36028+ * Aufs passes some operations to the workqueue such as the internal copyup.
36029+ * This scheme looks rather unnatural for LOCKDEP debugging feature, since the
36030+ * job run by workqueue depends upon the locks acquired in the other task.
36031+ * Delegating a small operation to the workqueue, aufs passes its lockdep
36032+ * information too. And the job in the workqueue restores the info in order to
36033+ * pretend as if it acquired those locks. This is just to make LOCKDEP work
36034+ * correctly and expectedly.
36035+ */
36036+
36037+#ifndef CONFIG_LOCKDEP
36038+AuStubInt0(au_wkq_lockdep_alloc, struct au_wkinfo *wkinfo);
36039+AuStubVoid(au_wkq_lockdep_free, struct au_wkinfo *wkinfo);
36040+AuStubVoid(au_wkq_lockdep_pre, struct au_wkinfo *wkinfo);
36041+AuStubVoid(au_wkq_lockdep_post, struct au_wkinfo *wkinfo);
36042+AuStubVoid(au_wkq_lockdep_init, struct au_wkinfo *wkinfo);
36043+#else
36044+static void au_wkq_lockdep_init(struct au_wkinfo *wkinfo)
36045+{
36046+ wkinfo->hlock = NULL;
36047+ wkinfo->dont_check = 0;
36048+}
36049+
36050+/*
36051+ * 1: matched
36052+ * 0: unmatched
36053+ */
36054+static int au_wkq_lockdep_test(struct lock_class_key *key, const char *name)
36055+{
36056+ static DEFINE_SPINLOCK(spin);
36057+ static struct {
36058+ char *name;
36059+ struct lock_class_key *key;
36060+ } a[] = {
36061+ { .name = "&sbinfo->si_rwsem" },
36062+ { .name = "&finfo->fi_rwsem" },
36063+ { .name = "&dinfo->di_rwsem" },
36064+ { .name = "&iinfo->ii_rwsem" }
36065+ };
36066+ static int set;
36067+ int i;
36068+
36069+ /* lockless read from 'set.' see below */
36070+ if (set == ARRAY_SIZE(a)) {
36071+ for (i = 0; i < ARRAY_SIZE(a); i++)
36072+ if (a[i].key == key)
36073+ goto match;
36074+ goto unmatch;
36075+ }
36076+
36077+ spin_lock(&spin);
36078+ if (set)
36079+ for (i = 0; i < ARRAY_SIZE(a); i++)
36080+ if (a[i].key == key) {
36081+ spin_unlock(&spin);
36082+ goto match;
36083+ }
36084+ for (i = 0; i < ARRAY_SIZE(a); i++) {
36085+ if (a[i].key) {
36086+ if (unlikely(a[i].key == key)) { /* rare but possible */
36087+ spin_unlock(&spin);
36088+ goto match;
36089+ } else
36090+ continue;
36091+ }
36092+ if (strstr(a[i].name, name)) {
36093+ /*
36094+ * the order of these three lines is important for the
36095+ * lockless read above.
36096+ */
36097+ a[i].key = key;
36098+ spin_unlock(&spin);
36099+ set++;
36100+ /* AuDbg("%d, %s\n", set, name); */
36101+ goto match;
36102+ }
36103+ }
36104+ spin_unlock(&spin);
36105+ goto unmatch;
36106+
36107+match:
36108+ return 1;
36109+unmatch:
36110+ return 0;
36111+}
36112+
36113+static int au_wkq_lockdep_alloc(struct au_wkinfo *wkinfo)
36114+{
36115+ int err, n;
36116+ struct task_struct *curr;
36117+ struct held_lock **hl, *held_locks, *p;
36118+
36119+ err = 0;
36120+ curr = current;
36121+ wkinfo->dont_check = lockdep_recursing(curr);
36122+ if (wkinfo->dont_check)
36123+ goto out;
36124+ n = curr->lockdep_depth;
36125+ if (!n)
36126+ goto out;
36127+
36128+ err = -ENOMEM;
36129+ wkinfo->hlock = kmalloc_array(n + 1, sizeof(*wkinfo->hlock), GFP_NOFS);
36130+ if (unlikely(!wkinfo->hlock))
36131+ goto out;
36132+
36133+ err = 0;
36134+#if 0 /* left for debugging */
36135+ if (0 && au_debug_test())
36136+ lockdep_print_held_locks(curr);
36137+#endif
36138+ held_locks = curr->held_locks;
36139+ hl = wkinfo->hlock;
36140+ while (n--) {
36141+ p = held_locks++;
36142+ if (au_wkq_lockdep_test(p->instance->key, p->instance->name))
36143+ *hl++ = p;
36144+ }
36145+ *hl = NULL;
36146+
36147+out:
36148+ return err;
36149+}
36150+
36151+static void au_wkq_lockdep_free(struct au_wkinfo *wkinfo)
36152+{
36153+ au_kfree_try_rcu(wkinfo->hlock);
36154+}
36155+
36156+static void au_wkq_lockdep_pre(struct au_wkinfo *wkinfo)
36157+{
36158+ struct held_lock *p, **hl = wkinfo->hlock;
36159+ int subclass;
36160+
36161+ if (wkinfo->dont_check)
36162+ lockdep_off();
36163+ if (!hl)
36164+ return;
36165+ while ((p = *hl++)) { /* assignment */
36166+ subclass = lockdep_hlock_class(p)->subclass;
36167+ /* AuDbg("%s, %d\n", p->instance->name, subclass); */
36168+ if (p->read)
36169+ rwsem_acquire_read(p->instance, subclass, 0,
36170+ /*p->acquire_ip*/_RET_IP_);
36171+ else
36172+ rwsem_acquire(p->instance, subclass, 0,
36173+ /*p->acquire_ip*/_RET_IP_);
36174+ }
36175+}
36176+
36177+static void au_wkq_lockdep_post(struct au_wkinfo *wkinfo)
36178+{
36179+ struct held_lock *p, **hl = wkinfo->hlock;
36180+
36181+ if (wkinfo->dont_check)
36182+ lockdep_on();
36183+ if (!hl)
36184+ return;
36185+ while ((p = *hl++)) /* assignment */
36186+ rwsem_release(p->instance, 0, /*p->acquire_ip*/_RET_IP_);
36187+}
36188+#endif
36189+
36190+static void wkq_func(struct work_struct *wk)
36191+{
36192+ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
36193+
36194+ AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID));
36195+ AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY);
36196+
36197+ au_wkq_lockdep_pre(wkinfo);
36198+ wkinfo->func(wkinfo->args);
36199+ au_wkq_lockdep_post(wkinfo);
36200+ if (au_ftest_wkq(wkinfo->flags, WAIT))
36201+ complete(wkinfo->comp);
36202+ else {
36203+ kobject_put(wkinfo->kobj);
36204+ module_put(THIS_MODULE); /* todo: ?? */
36205+ au_kfree_rcu(wkinfo);
36206+ }
36207+}
36208+
36209+/*
36210+ * Since struct completion is large, try allocating it dynamically.
36211+ */
36212+#define AuWkqCompDeclare(name) struct completion *comp = NULL
36213+
36214+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
36215+{
36216+ *comp = kmalloc(sizeof(**comp), GFP_NOFS);
36217+ if (*comp) {
36218+ init_completion(*comp);
36219+ wkinfo->comp = *comp;
36220+ return 0;
36221+ }
36222+ return -ENOMEM;
36223+}
36224+
36225+static void au_wkq_comp_free(struct completion *comp)
36226+{
36227+ au_kfree_rcu(comp);
36228+}
36229+
36230+static void au_wkq_run(struct au_wkinfo *wkinfo)
36231+{
36232+ if (au_ftest_wkq(wkinfo->flags, NEST)) {
36233+ if (au_wkq_test()) {
36234+ AuWarn1("wkq from wkq, unless silly-rename on NFS,"
36235+ " due to a dead dir by UDBA,"
36236+ " or async xino write?\n");
36237+ AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT));
36238+ }
36239+ } else
36240+ au_dbg_verify_kthread();
36241+
36242+ if (au_ftest_wkq(wkinfo->flags, WAIT)) {
36243+ INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func);
36244+ queue_work(au_wkq, &wkinfo->wk);
36245+ } else {
36246+ INIT_WORK(&wkinfo->wk, wkq_func);
36247+ schedule_work(&wkinfo->wk);
36248+ }
36249+}
36250+
36251+/*
36252+ * Be careful. It is easy to make deadlock happen.
36253+ * processA: lock, wkq and wait
36254+ * processB: wkq and wait, lock in wkq
36255+ * --> deadlock
36256+ */
36257+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args)
36258+{
36259+ int err;
36260+ AuWkqCompDeclare(comp);
36261+ struct au_wkinfo wkinfo = {
36262+ .flags = flags,
36263+ .func = func,
36264+ .args = args
36265+ };
36266+
36267+ err = au_wkq_comp_alloc(&wkinfo, &comp);
36268+ if (unlikely(err))
36269+ goto out;
36270+ err = au_wkq_lockdep_alloc(&wkinfo);
36271+ if (unlikely(err))
36272+ goto out_comp;
36273+ if (!err) {
36274+ au_wkq_run(&wkinfo);
36275+ /* no timeout, no interrupt */
36276+ wait_for_completion(wkinfo.comp);
36277+ }
36278+ au_wkq_lockdep_free(&wkinfo);
36279+
36280+out_comp:
36281+ au_wkq_comp_free(comp);
36282+out:
36283+ destroy_work_on_stack(&wkinfo.wk);
36284+ return err;
36285+}
36286+
36287+/*
36288+ * Note: dget/dput() in func for aufs dentries are not supported. It will be a
36289+ * problem in a concurrent umounting.
36290+ */
36291+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
36292+ unsigned int flags)
36293+{
36294+ int err;
36295+ struct au_wkinfo *wkinfo;
36296+
36297+ atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
36298+
36299+ /*
36300+ * wkq_func() must free this wkinfo.
36301+ * it highly depends upon the implementation of workqueue.
36302+ */
36303+ err = 0;
36304+ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
36305+ if (wkinfo) {
36306+ wkinfo->kobj = &au_sbi(sb)->si_kobj;
36307+ wkinfo->flags = flags & ~AuWkq_WAIT;
36308+ wkinfo->func = func;
36309+ wkinfo->args = args;
36310+ wkinfo->comp = NULL;
36311+ au_wkq_lockdep_init(wkinfo);
36312+ kobject_get(wkinfo->kobj);
36313+ __module_get(THIS_MODULE); /* todo: ?? */
36314+
36315+ au_wkq_run(wkinfo);
36316+ } else {
36317+ err = -ENOMEM;
36318+ au_nwt_done(&au_sbi(sb)->si_nowait);
36319+ }
36320+
36321+ return err;
36322+}
36323+
36324+/* ---------------------------------------------------------------------- */
36325+
36326+void au_nwt_init(struct au_nowait_tasks *nwt)
36327+{
36328+ atomic_set(&nwt->nw_len, 0);
36329+ /* smp_mb(); */ /* atomic_set */
36330+ init_waitqueue_head(&nwt->nw_wq);
36331+}
36332+
36333+void au_wkq_fin(void)
36334+{
36335+ destroy_workqueue(au_wkq);
36336+}
36337+
36338+int __init au_wkq_init(void)
36339+{
36340+ int err;
36341+
36342+ err = 0;
36343+ au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE);
36344+ if (IS_ERR(au_wkq))
36345+ err = PTR_ERR(au_wkq);
36346+ else if (!au_wkq)
36347+ err = -ENOMEM;
36348+
36349+ return err;
36350+}
36351diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
36352--- /usr/share/empty/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100
36353+++ linux/fs/aufs/wkq.h 2020-01-27 10:57:18.182205184 +0100
36354@@ -0,0 +1,89 @@
36355+/* SPDX-License-Identifier: GPL-2.0 */
36356+/*
36357+ * Copyright (C) 2005-2020 Junjiro R. Okajima
36358+ *
36359+ * This program, aufs is free software; you can redistribute it and/or modify
36360+ * it under the terms of the GNU General Public License as published by
36361+ * the Free Software Foundation; either version 2 of the License, or
36362+ * (at your option) any later version.
36363+ *
36364+ * This program is distributed in the hope that it will be useful,
36365+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
36366+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36367+ * GNU General Public License for more details.
36368+ *
36369+ * You should have received a copy of the GNU General Public License
36370+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
36371+ */
36372+
36373+/*
36374+ * workqueue for asynchronous/super-io operations
36375+ * todo: try new credentials management scheme
36376+ */
36377+
36378+#ifndef __AUFS_WKQ_H__
36379+#define __AUFS_WKQ_H__
36380+
36381+#ifdef __KERNEL__
36382+
36383+#include <linux/wait.h>
36384+
36385+struct super_block;
36386+
36387+/* ---------------------------------------------------------------------- */
36388+
36389+/*
36390+ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
36391+ */
36392+struct au_nowait_tasks {
36393+ atomic_t nw_len;
36394+ wait_queue_head_t nw_wq;
36395+};
36396+
36397+/* ---------------------------------------------------------------------- */
36398+
36399+typedef void (*au_wkq_func_t)(void *args);
36400+
36401+/* wkq flags */
36402+#define AuWkq_WAIT 1
36403+#define AuWkq_NEST (1 << 1)
36404+#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name)
36405+#define au_fset_wkq(flags, name) \
36406+ do { (flags) |= AuWkq_##name; } while (0)
36407+#define au_fclr_wkq(flags, name) \
36408+ do { (flags) &= ~AuWkq_##name; } while (0)
36409+
36410+/* wkq.c */
36411+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args);
36412+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
36413+ unsigned int flags);
36414+void au_nwt_init(struct au_nowait_tasks *nwt);
36415+int __init au_wkq_init(void);
36416+void au_wkq_fin(void);
36417+
36418+/* ---------------------------------------------------------------------- */
36419+
36420+static inline int au_wkq_test(void)
36421+{
36422+ return current->flags & PF_WQ_WORKER;
36423+}
36424+
36425+static inline int au_wkq_wait(au_wkq_func_t func, void *args)
36426+{
36427+ return au_wkq_do_wait(AuWkq_WAIT, func, args);
36428+}
36429+
36430+static inline void au_nwt_done(struct au_nowait_tasks *nwt)
36431+{
36432+ if (atomic_dec_and_test(&nwt->nw_len))
36433+ wake_up_all(&nwt->nw_wq);
36434+}
36435+
36436+static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
36437+{
36438+ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
36439+ return 0;
36440+}
36441+
36442+#endif /* __KERNEL__ */
36443+#endif /* __AUFS_WKQ_H__ */
36444diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
36445--- /usr/share/empty/fs/aufs/xattr.c 1970-01-01 01:00:00.000000000 +0100
36446+++ linux/fs/aufs/xattr.c 2020-01-27 10:57:18.182205184 +0100
36447@@ -0,0 +1,356 @@
36448+// SPDX-License-Identifier: GPL-2.0
36449+/*
36450+ * Copyright (C) 2014-2020 Junjiro R. Okajima
36451+ *
36452+ * This program, aufs is free software; you can redistribute it and/or modify
36453+ * it under the terms of the GNU General Public License as published by
36454+ * the Free Software Foundation; either version 2 of the License, or
36455+ * (at your option) any later version.
36456+ *
36457+ * This program is distributed in the hope that it will be useful,
36458+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
36459+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36460+ * GNU General Public License for more details.
36461+ *
36462+ * You should have received a copy of the GNU General Public License
36463+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
36464+ */
36465+
36466+/*
36467+ * handling xattr functions
36468+ */
36469+
36470+#include <linux/fs.h>
36471+#include <linux/posix_acl_xattr.h>
36472+#include <linux/xattr.h>
36473+#include "aufs.h"
36474+
36475+static int au_xattr_ignore(int err, char *name, unsigned int ignore_flags)
36476+{
36477+ if (!ignore_flags)
36478+ goto out;
36479+ switch (err) {
36480+ case -ENOMEM:
36481+ case -EDQUOT:
36482+ goto out;
36483+ }
36484+
36485+ if ((ignore_flags & AuBrAttr_ICEX) == AuBrAttr_ICEX) {
36486+ err = 0;
36487+ goto out;
36488+ }
36489+
36490+#define cmp(brattr, prefix) do { \
36491+ if (!strncmp(name, XATTR_##prefix##_PREFIX, \
36492+ XATTR_##prefix##_PREFIX_LEN)) { \
36493+ if (ignore_flags & AuBrAttr_ICEX_##brattr) \
36494+ err = 0; \
36495+ goto out; \
36496+ } \
36497+ } while (0)
36498+
36499+ cmp(SEC, SECURITY);
36500+ cmp(SYS, SYSTEM);
36501+ cmp(TR, TRUSTED);
36502+ cmp(USR, USER);
36503+#undef cmp
36504+
36505+ if (ignore_flags & AuBrAttr_ICEX_OTH)
36506+ err = 0;
36507+
36508+out:
36509+ return err;
36510+}
36511+
36512+static const int au_xattr_out_of_list = AuBrAttr_ICEX_OTH << 1;
36513+
36514+static int au_do_cpup_xattr(struct dentry *h_dst, struct dentry *h_src,
36515+ char *name, char **buf, unsigned int ignore_flags,
36516+ unsigned int verbose)
36517+{
36518+ int err;
36519+ ssize_t ssz;
36520+ struct inode *h_idst;
36521+
36522+ ssz = vfs_getxattr_alloc(h_src, name, buf, 0, GFP_NOFS);
36523+ err = ssz;
36524+ if (unlikely(err <= 0)) {
36525+ if (err == -ENODATA
36526+ || (err == -EOPNOTSUPP
36527+ && ((ignore_flags & au_xattr_out_of_list)
36528+ || (au_test_nfs_noacl(d_inode(h_src))
36529+ && (!strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS)
36530+ || !strcmp(name,
36531+ XATTR_NAME_POSIX_ACL_DEFAULT))))
36532+ ))
36533+ err = 0;
36534+ if (err && (verbose || au_debug_test()))
36535+ pr_err("%s, err %d\n", name, err);
36536+ goto out;
36537+ }
36538+
36539+ /* unlock it temporary */
36540+ h_idst = d_inode(h_dst);
36541+ inode_unlock(h_idst);
36542+ err = vfsub_setxattr(h_dst, name, *buf, ssz, /*flags*/0);
36543+ inode_lock_nested(h_idst, AuLsc_I_CHILD2);
36544+ if (unlikely(err)) {
36545+ if (verbose || au_debug_test())
36546+ pr_err("%s, err %d\n", name, err);
36547+ err = au_xattr_ignore(err, name, ignore_flags);
36548+ }
36549+
36550+out:
36551+ return err;
36552+}
36553+
36554+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags,
36555+ unsigned int verbose)
36556+{
36557+ int err, unlocked, acl_access, acl_default;
36558+ ssize_t ssz;
36559+ struct inode *h_isrc, *h_idst;
36560+ char *value, *p, *o, *e;
36561+
36562+ /* try stopping to update the source inode while we are referencing */
36563+ /* there should not be the parent-child relationship between them */
36564+ h_isrc = d_inode(h_src);
36565+ h_idst = d_inode(h_dst);
36566+ inode_unlock(h_idst);
36567+ inode_lock_shared_nested(h_isrc, AuLsc_I_CHILD);
36568+ inode_lock_nested(h_idst, AuLsc_I_CHILD2);
36569+ unlocked = 0;
36570+
36571+ /* some filesystems don't list POSIX ACL, for example tmpfs */
36572+ ssz = vfs_listxattr(h_src, NULL, 0);
36573+ err = ssz;
36574+ if (unlikely(err < 0)) {
36575+ AuTraceErr(err);
36576+ if (err == -ENODATA
36577+ || err == -EOPNOTSUPP)
36578+ err = 0; /* ignore */
36579+ goto out;
36580+ }
36581+
36582+ err = 0;
36583+ p = NULL;
36584+ o = NULL;
36585+ if (ssz) {
36586+ err = -ENOMEM;
36587+ p = kmalloc(ssz, GFP_NOFS);
36588+ o = p;
36589+ if (unlikely(!p))
36590+ goto out;
36591+ err = vfs_listxattr(h_src, p, ssz);
36592+ }
36593+ inode_unlock_shared(h_isrc);
36594+ unlocked = 1;
36595+ AuDbg("err %d, ssz %zd\n", err, ssz);
36596+ if (unlikely(err < 0))
36597+ goto out_free;
36598+
36599+ err = 0;
36600+ e = p + ssz;
36601+ value = NULL;
36602+ acl_access = 0;
36603+ acl_default = 0;
36604+ while (!err && p < e) {
36605+ acl_access |= !strncmp(p, XATTR_NAME_POSIX_ACL_ACCESS,
36606+ sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1);
36607+ acl_default |= !strncmp(p, XATTR_NAME_POSIX_ACL_DEFAULT,
36608+ sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)
36609+ - 1);
36610+ err = au_do_cpup_xattr(h_dst, h_src, p, &value, ignore_flags,
36611+ verbose);
36612+ p += strlen(p) + 1;
36613+ }
36614+ AuTraceErr(err);
36615+ ignore_flags |= au_xattr_out_of_list;
36616+ if (!err && !acl_access) {
36617+ err = au_do_cpup_xattr(h_dst, h_src,
36618+ XATTR_NAME_POSIX_ACL_ACCESS, &value,
36619+ ignore_flags, verbose);
36620+ AuTraceErr(err);
36621+ }
36622+ if (!err && !acl_default) {
36623+ err = au_do_cpup_xattr(h_dst, h_src,
36624+ XATTR_NAME_POSIX_ACL_DEFAULT, &value,
36625+ ignore_flags, verbose);
36626+ AuTraceErr(err);
36627+ }
36628+
36629+ au_kfree_try_rcu(value);
36630+
36631+out_free:
36632+ au_kfree_try_rcu(o);
36633+out:
36634+ if (!unlocked)
36635+ inode_unlock_shared(h_isrc);
36636+ AuTraceErr(err);
36637+ return err;
36638+}
36639+
36640+/* ---------------------------------------------------------------------- */
36641+
36642+static int au_smack_reentering(struct super_block *sb)
36643+{
36644+#if IS_ENABLED(CONFIG_SECURITY_SMACK)
36645+ /*
36646+ * as a part of lookup, smack_d_instantiate() is called, and it calls
36647+ * i_op->getxattr(). ouch.
36648+ */
36649+ return si_pid_test(sb);
36650+#else
36651+ return 0;
36652+#endif
36653+}
36654+
36655+enum {
36656+ AU_XATTR_LIST,
36657+ AU_XATTR_GET
36658+};
36659+
36660+struct au_lgxattr {
36661+ int type;
36662+ union {
36663+ struct {
36664+ char *list;
36665+ size_t size;
36666+ } list;
36667+ struct {
36668+ const char *name;
36669+ void *value;
36670+ size_t size;
36671+ } get;
36672+ } u;
36673+};
36674+
36675+static ssize_t au_lgxattr(struct dentry *dentry, struct au_lgxattr *arg)
36676+{
36677+ ssize_t err;
36678+ int reenter;
36679+ struct path h_path;
36680+ struct super_block *sb;
36681+
36682+ sb = dentry->d_sb;
36683+ reenter = au_smack_reentering(sb);
36684+ if (!reenter) {
36685+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
36686+ if (unlikely(err))
36687+ goto out;
36688+ }
36689+ err = au_h_path_getattr(dentry, /*force*/1, &h_path, reenter);
36690+ if (unlikely(err))
36691+ goto out_si;
36692+ if (unlikely(!h_path.dentry))
36693+ /* illegally overlapped or something */
36694+ goto out_di; /* pretending success */
36695+
36696+ /* always topmost entry only */
36697+ switch (arg->type) {
36698+ case AU_XATTR_LIST:
36699+ err = vfs_listxattr(h_path.dentry,
36700+ arg->u.list.list, arg->u.list.size);
36701+ break;
36702+ case AU_XATTR_GET:
36703+ AuDebugOn(d_is_negative(h_path.dentry));
36704+ err = vfs_getxattr(h_path.dentry,
36705+ arg->u.get.name, arg->u.get.value,
36706+ arg->u.get.size);
36707+ break;
36708+ }
36709+
36710+out_di:
36711+ if (!reenter)
36712+ di_read_unlock(dentry, AuLock_IR);
36713+out_si:
36714+ if (!reenter)
36715+ si_read_unlock(sb);
36716+out:
36717+ AuTraceErr(err);
36718+ return err;
36719+}
36720+
36721+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size)
36722+{
36723+ struct au_lgxattr arg = {
36724+ .type = AU_XATTR_LIST,
36725+ .u.list = {
36726+ .list = list,
36727+ .size = size
36728+ },
36729+ };
36730+
36731+ return au_lgxattr(dentry, &arg);
36732+}
36733+
36734+static ssize_t au_getxattr(struct dentry *dentry,
36735+ struct inode *inode __maybe_unused,
36736+ const char *name, void *value, size_t size)
36737+{
36738+ struct au_lgxattr arg = {
36739+ .type = AU_XATTR_GET,
36740+ .u.get = {
36741+ .name = name,
36742+ .value = value,
36743+ .size = size
36744+ },
36745+ };
36746+
36747+ return au_lgxattr(dentry, &arg);
36748+}
36749+
36750+static int au_setxattr(struct dentry *dentry, struct inode *inode,
36751+ const char *name, const void *value, size_t size,
36752+ int flags)
36753+{
36754+ struct au_sxattr arg = {
36755+ .type = AU_XATTR_SET,
36756+ .u.set = {
36757+ .name = name,
36758+ .value = value,
36759+ .size = size,
36760+ .flags = flags
36761+ },
36762+ };
36763+
36764+ return au_sxattr(dentry, inode, &arg);
36765+}
36766+
36767+/* ---------------------------------------------------------------------- */
36768+
36769+static int au_xattr_get(const struct xattr_handler *handler,
36770+ struct dentry *dentry, struct inode *inode,
36771+ const char *name, void *buffer, size_t size)
36772+{
36773+ return au_getxattr(dentry, inode, name, buffer, size);
36774+}
36775+
36776+static int au_xattr_set(const struct xattr_handler *handler,
36777+ struct dentry *dentry, struct inode *inode,
36778+ const char *name, const void *value, size_t size,
36779+ int flags)
36780+{
36781+ return au_setxattr(dentry, inode, name, value, size, flags);
36782+}
36783+
36784+static const struct xattr_handler au_xattr_handler = {
36785+ .name = "",
36786+ .prefix = "",
36787+ .get = au_xattr_get,
36788+ .set = au_xattr_set
36789+};
36790+
36791+static const struct xattr_handler *au_xattr_handlers[] = {
36792+#ifdef CONFIG_FS_POSIX_ACL
36793+ &posix_acl_access_xattr_handler,
36794+ &posix_acl_default_xattr_handler,
36795+#endif
36796+ &au_xattr_handler, /* must be last */
36797+ NULL
36798+};
36799+
36800+void au_xattr_init(struct super_block *sb)
36801+{
36802+ sb->s_xattr = au_xattr_handlers;
36803+}
36804diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
36805--- /usr/share/empty/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100
36806+++ linux/fs/aufs/xino.c 2020-04-03 08:16:49.834195677 +0200
36807@@ -0,0 +1,1966 @@
36808+// SPDX-License-Identifier: GPL-2.0
36809+/*
36810+ * Copyright (C) 2005-2020 Junjiro R. Okajima
36811+ *
36812+ * This program, aufs is free software; you can redistribute it and/or modify
36813+ * it under the terms of the GNU General Public License as published by
36814+ * the Free Software Foundation; either version 2 of the License, or
36815+ * (at your option) any later version.
36816+ *
36817+ * This program is distributed in the hope that it will be useful,
36818+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
36819+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36820+ * GNU General Public License for more details.
36821+ *
36822+ * You should have received a copy of the GNU General Public License
36823+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
36824+ */
36825+
36826+/*
36827+ * external inode number translation table and bitmap
36828+ *
36829+ * things to consider
36830+ * - the lifetime
36831+ * + au_xino object
36832+ * + XINO files (xino, xib, xigen)
36833+ * + dynamic debugfs entries (xiN)
36834+ * + static debugfs entries (xib, xigen)
36835+ * + static sysfs entry (xi_path)
36836+ * - several entry points to handle them.
36837+ * + mount(2) without xino option (default)
36838+ * + mount(2) with xino option
36839+ * + mount(2) with noxino option
36840+ * + umount(2)
36841+ * + remount with add/del branches
36842+ * + remount with xino/noxino options
36843+ */
36844+
36845+#include <linux/seq_file.h>
36846+#include <linux/statfs.h>
36847+#include "aufs.h"
36848+
36849+static aufs_bindex_t sbr_find_shared(struct super_block *sb, aufs_bindex_t btop,
36850+ aufs_bindex_t bbot,
36851+ struct super_block *h_sb)
36852+{
36853+ /* todo: try binary-search if the branches are many */
36854+ for (; btop <= bbot; btop++)
36855+ if (h_sb == au_sbr_sb(sb, btop))
36856+ return btop;
36857+ return -1;
36858+}
36859+
36860+/*
36861+ * find another branch who is on the same filesystem of the specified
36862+ * branch{@btgt}. search until @bbot.
36863+ */
36864+static aufs_bindex_t is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
36865+ aufs_bindex_t bbot)
36866+{
36867+ aufs_bindex_t bindex;
36868+ struct super_block *tgt_sb;
36869+
36870+ tgt_sb = au_sbr_sb(sb, btgt);
36871+ bindex = sbr_find_shared(sb, /*btop*/0, btgt - 1, tgt_sb);
36872+ if (bindex < 0)
36873+ bindex = sbr_find_shared(sb, btgt + 1, bbot, tgt_sb);
36874+
36875+ return bindex;
36876+}
36877+
36878+/* ---------------------------------------------------------------------- */
36879+
36880+/*
36881+ * stop unnecessary notify events at creating xino files
36882+ */
36883+
36884+aufs_bindex_t au_xi_root(struct super_block *sb, struct dentry *dentry)
36885+{
36886+ aufs_bindex_t bfound, bindex, bbot;
36887+ struct dentry *parent;
36888+ struct au_branch *br;
36889+
36890+ bfound = -1;
36891+ parent = dentry->d_parent; /* safe d_parent access */
36892+ bbot = au_sbbot(sb);
36893+ for (bindex = 0; bindex <= bbot; bindex++) {
36894+ br = au_sbr(sb, bindex);
36895+ if (au_br_dentry(br) == parent) {
36896+ bfound = bindex;
36897+ break;
36898+ }
36899+ }
36900+
36901+ AuDbg("bfound b%d\n", bfound);
36902+ return bfound;
36903+}
36904+
36905+struct au_xino_lock_dir {
36906+ struct au_hinode *hdir;
36907+ struct dentry *parent;
36908+ struct inode *dir;
36909+};
36910+
36911+static struct dentry *au_dget_parent_lock(struct dentry *dentry,
36912+ unsigned int lsc)
36913+{
36914+ struct dentry *parent;
36915+ struct inode *dir;
36916+
36917+ parent = dget_parent(dentry);
36918+ dir = d_inode(parent);
36919+ inode_lock_nested(dir, lsc);
36920+#if 0 /* it should not happen */
36921+ spin_lock(&dentry->d_lock);
36922+ if (unlikely(dentry->d_parent != parent)) {
36923+ spin_unlock(&dentry->d_lock);
36924+ inode_unlock(dir);
36925+ dput(parent);
36926+ parent = NULL;
36927+ goto out;
36928+ }
36929+ spin_unlock(&dentry->d_lock);
36930+
36931+out:
36932+#endif
36933+ return parent;
36934+}
36935+
36936+static void au_xino_lock_dir(struct super_block *sb, struct path *xipath,
36937+ struct au_xino_lock_dir *ldir)
36938+{
36939+ aufs_bindex_t bindex;
36940+
36941+ ldir->hdir = NULL;
36942+ bindex = au_xi_root(sb, xipath->dentry);
36943+ if (bindex >= 0) {
36944+ /* rw branch root */
36945+ ldir->hdir = au_hi(d_inode(sb->s_root), bindex);
36946+ au_hn_inode_lock_nested(ldir->hdir, AuLsc_I_PARENT);
36947+ } else {
36948+ /* other */
36949+ ldir->parent = au_dget_parent_lock(xipath->dentry,
36950+ AuLsc_I_PARENT);
36951+ ldir->dir = d_inode(ldir->parent);
36952+ }
36953+}
36954+
36955+static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
36956+{
36957+ if (ldir->hdir)
36958+ au_hn_inode_unlock(ldir->hdir);
36959+ else {
36960+ inode_unlock(ldir->dir);
36961+ dput(ldir->parent);
36962+ }
36963+}
36964+
36965+/* ---------------------------------------------------------------------- */
36966+
36967+/*
36968+ * create and set a new xino file
36969+ */
36970+struct file *au_xino_create(struct super_block *sb, char *fpath, int silent,
36971+ int wbrtop)
36972+{
36973+ struct file *file;
36974+ struct dentry *h_parent, *d;
36975+ struct inode *h_dir, *inode;
36976+ int err;
36977+ static DEFINE_MUTEX(mtx);
36978+
36979+ /*
36980+ * at mount-time, and the xino file is the default path,
36981+ * hnotify is disabled so we have no notify events to ignore.
36982+ * when a user specified the xino, we cannot get au_hdir to be ignored.
36983+ */
36984+ if (!wbrtop)
36985+ mutex_lock(&mtx);
36986+ file = vfsub_filp_open(fpath, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
36987+ /* | __FMODE_NONOTIFY */,
36988+ 0666);
36989+ if (IS_ERR(file)) {
36990+ if (!wbrtop)
36991+ mutex_unlock(&mtx);
36992+ if (!silent)
36993+ pr_err("open %s(%ld)\n", fpath, PTR_ERR(file));
36994+ return file;
36995+ }
36996+
36997+ /* keep file count */
36998+ err = 0;
36999+ d = file->f_path.dentry;
37000+ h_parent = au_dget_parent_lock(d, AuLsc_I_PARENT);
37001+ if (!wbrtop)
37002+ mutex_unlock(&mtx);
37003+ /* mnt_want_write() is unnecessary here */
37004+ h_dir = d_inode(h_parent);
37005+ inode = file_inode(file);
37006+ /* no delegation since it is just created */
37007+ if (inode->i_nlink)
37008+ err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL,
37009+ /*force*/0);
37010+ inode_unlock(h_dir);
37011+ dput(h_parent);
37012+ if (unlikely(err)) {
37013+ if (!silent)
37014+ pr_err("unlink %s(%d)\n", fpath, err);
37015+ goto out;
37016+ }
37017+
37018+ err = -EINVAL;
37019+ if (unlikely(sb == d->d_sb)) {
37020+ if (!silent)
37021+ pr_err("%s must be outside\n", fpath);
37022+ goto out;
37023+ }
37024+ if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
37025+ if (!silent)
37026+ pr_err("xino doesn't support %s(%s)\n",
37027+ fpath, au_sbtype(d->d_sb));
37028+ goto out;
37029+ }
37030+ return file; /* success */
37031+
37032+out:
37033+ fput(file);
37034+ file = ERR_PTR(err);
37035+ return file;
37036+}
37037+
37038+/*
37039+ * create a new xinofile at the same place/path as @base.
37040+ */
37041+struct file *au_xino_create2(struct super_block *sb, struct path *base,
37042+ struct file *copy_src)
37043+{
37044+ struct file *file;
37045+ struct dentry *dentry, *parent;
37046+ struct inode *dir, *delegated;
37047+ struct qstr *name;
37048+ struct path path;
37049+ int err, do_unlock;
37050+ struct au_xino_lock_dir ldir;
37051+
37052+ do_unlock = 1;
37053+ au_xino_lock_dir(sb, base, &ldir);
37054+ dentry = base->dentry;
37055+ parent = dentry->d_parent; /* dir inode is locked */
37056+ dir = d_inode(parent);
37057+ IMustLock(dir);
37058+
37059+ name = &dentry->d_name;
37060+ path.dentry = vfsub_lookup_one_len(name->name, parent, name->len);
37061+ if (IS_ERR(path.dentry)) {
37062+ file = (void *)path.dentry;
37063+ pr_err("%pd lookup err %ld\n", dentry, PTR_ERR(path.dentry));
37064+ goto out;
37065+ }
37066+
37067+ /* no need to mnt_want_write() since we call dentry_open() later */
37068+ err = vfs_create(dir, path.dentry, 0666, NULL);
37069+ if (unlikely(err)) {
37070+ file = ERR_PTR(err);
37071+ pr_err("%pd create err %d\n", dentry, err);
37072+ goto out_dput;
37073+ }
37074+
37075+ path.mnt = base->mnt;
37076+ file = vfsub_dentry_open(&path,
37077+ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
37078+ /* | __FMODE_NONOTIFY */);
37079+ if (IS_ERR(file)) {
37080+ pr_err("%pd open err %ld\n", dentry, PTR_ERR(file));
37081+ goto out_dput;
37082+ }
37083+
37084+ delegated = NULL;
37085+ err = vfsub_unlink(dir, &file->f_path, &delegated, /*force*/0);
37086+ au_xino_unlock_dir(&ldir);
37087+ do_unlock = 0;
37088+ if (unlikely(err == -EWOULDBLOCK)) {
37089+ pr_warn("cannot retry for NFSv4 delegation"
37090+ " for an internal unlink\n");
37091+ iput(delegated);
37092+ }
37093+ if (unlikely(err)) {
37094+ pr_err("%pd unlink err %d\n", dentry, err);
37095+ goto out_fput;
37096+ }
37097+
37098+ if (copy_src) {
37099+ /* no one can touch copy_src xino */
37100+ err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src));
37101+ if (unlikely(err)) {
37102+ pr_err("%pd copy err %d\n", dentry, err);
37103+ goto out_fput;
37104+ }
37105+ }
37106+ goto out_dput; /* success */
37107+
37108+out_fput:
37109+ fput(file);
37110+ file = ERR_PTR(err);
37111+out_dput:
37112+ dput(path.dentry);
37113+out:
37114+ if (do_unlock)
37115+ au_xino_unlock_dir(&ldir);
37116+ return file;
37117+}
37118+
37119+struct file *au_xino_file1(struct au_xino *xi)
37120+{
37121+ struct file *file;
37122+ unsigned int u, nfile;
37123+
37124+ file = NULL;
37125+ nfile = xi->xi_nfile;
37126+ for (u = 0; u < nfile; u++) {
37127+ file = xi->xi_file[u];
37128+ if (file)
37129+ break;
37130+ }
37131+
37132+ return file;
37133+}
37134+
37135+static int au_xino_file_set(struct au_xino *xi, int idx, struct file *file)
37136+{
37137+ int err;
37138+ struct file *f;
37139+ void *p;
37140+
37141+ if (file)
37142+ get_file(file);
37143+
37144+ err = 0;
37145+ f = NULL;
37146+ if (idx < xi->xi_nfile) {
37147+ f = xi->xi_file[idx];
37148+ if (f)
37149+ fput(f);
37150+ } else {
37151+ p = au_kzrealloc(xi->xi_file,
37152+ sizeof(*xi->xi_file) * xi->xi_nfile,
37153+ sizeof(*xi->xi_file) * (idx + 1),
37154+ GFP_NOFS, /*may_shrink*/0);
37155+ if (p) {
37156+ MtxMustLock(&xi->xi_mtx);
37157+ xi->xi_file = p;
37158+ xi->xi_nfile = idx + 1;
37159+ } else {
37160+ err = -ENOMEM;
37161+ if (file)
37162+ fput(file);
37163+ goto out;
37164+ }
37165+ }
37166+ xi->xi_file[idx] = file;
37167+
37168+out:
37169+ return err;
37170+}
37171+
37172+/*
37173+ * if @xinew->xi is not set, then create new xigen file.
37174+ */
37175+struct file *au_xi_new(struct super_block *sb, struct au_xi_new *xinew)
37176+{
37177+ struct file *file;
37178+ int err;
37179+
37180+ SiMustAnyLock(sb);
37181+
37182+ file = au_xino_create2(sb, xinew->base, xinew->copy_src);
37183+ if (IS_ERR(file)) {
37184+ err = PTR_ERR(file);
37185+ pr_err("%s[%d], err %d\n",
37186+ xinew->xi ? "xino" : "xigen",
37187+ xinew->idx, err);
37188+ goto out;
37189+ }
37190+
37191+ if (xinew->xi)
37192+ err = au_xino_file_set(xinew->xi, xinew->idx, file);
37193+ else {
37194+ BUG();
37195+ /* todo: make xigen file an array */
37196+ /* err = au_xigen_file_set(sb, xinew->idx, file); */
37197+ }
37198+ fput(file);
37199+ if (unlikely(err))
37200+ file = ERR_PTR(err);
37201+
37202+out:
37203+ return file;
37204+}
37205+
37206+/* ---------------------------------------------------------------------- */
37207+
37208+/*
37209+ * truncate xino files
37210+ */
37211+static int au_xino_do_trunc(struct super_block *sb, aufs_bindex_t bindex,
37212+ int idx, struct kstatfs *st)
37213+{
37214+ int err;
37215+ blkcnt_t blocks;
37216+ struct file *file, *new_xino;
37217+ struct au_xi_new xinew = {
37218+ .idx = idx
37219+ };
37220+
37221+ err = 0;
37222+ xinew.xi = au_sbr(sb, bindex)->br_xino;
37223+ file = au_xino_file(xinew.xi, idx);
37224+ if (!file)
37225+ goto out;
37226+
37227+ xinew.base = &file->f_path;
37228+ err = vfs_statfs(xinew.base, st);
37229+ if (unlikely(err)) {
37230+ AuErr1("statfs err %d, ignored\n", err);
37231+ err = 0;
37232+ goto out;
37233+ }
37234+
37235+ blocks = file_inode(file)->i_blocks;
37236+ pr_info("begin truncating xino(b%d-%d), ib%llu, %llu/%llu free blks\n",
37237+ bindex, idx, (u64)blocks, st->f_bfree, st->f_blocks);
37238+
37239+ xinew.copy_src = file;
37240+ new_xino = au_xi_new(sb, &xinew);
37241+ if (IS_ERR(new_xino)) {
37242+ err = PTR_ERR(new_xino);
37243+ pr_err("xino(b%d-%d), err %d, ignored\n", bindex, idx, err);
37244+ goto out;
37245+ }
37246+
37247+ err = vfs_statfs(&new_xino->f_path, st);
37248+ if (!err)
37249+ pr_info("end truncating xino(b%d-%d), ib%llu, %llu/%llu free blks\n",
37250+ bindex, idx, (u64)file_inode(new_xino)->i_blocks,
37251+ st->f_bfree, st->f_blocks);
37252+ else {
37253+ AuErr1("statfs err %d, ignored\n", err);
37254+ err = 0;
37255+ }
37256+
37257+out:
37258+ return err;
37259+}
37260+
37261+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex, int idx_begin)
37262+{
37263+ int err, i;
37264+ unsigned long jiffy;
37265+ aufs_bindex_t bbot;
37266+ struct kstatfs *st;
37267+ struct au_branch *br;
37268+ struct au_xino *xi;
37269+
37270+ err = -ENOMEM;
37271+ st = kmalloc(sizeof(*st), GFP_NOFS);
37272+ if (unlikely(!st))
37273+ goto out;
37274+
37275+ err = -EINVAL;
37276+ bbot = au_sbbot(sb);
37277+ if (unlikely(bindex < 0 || bbot < bindex))
37278+ goto out_st;
37279+
37280+ err = 0;
37281+ jiffy = jiffies;
37282+ br = au_sbr(sb, bindex);
37283+ xi = br->br_xino;
37284+ for (i = idx_begin; !err && i < xi->xi_nfile; i++)
37285+ err = au_xino_do_trunc(sb, bindex, i, st);
37286+ if (!err)
37287+ au_sbi(sb)->si_xino_jiffy = jiffy;
37288+
37289+out_st:
37290+ au_kfree_rcu(st);
37291+out:
37292+ return err;
37293+}
37294+
37295+struct xino_do_trunc_args {
37296+ struct super_block *sb;
37297+ struct au_branch *br;
37298+ int idx;
37299+};
37300+
37301+static void xino_do_trunc(void *_args)
37302+{
37303+ struct xino_do_trunc_args *args = _args;
37304+ struct super_block *sb;
37305+ struct au_branch *br;
37306+ struct inode *dir;
37307+ int err, idx;
37308+ aufs_bindex_t bindex;
37309+
37310+ err = 0;
37311+ sb = args->sb;
37312+ dir = d_inode(sb->s_root);
37313+ br = args->br;
37314+ idx = args->idx;
37315+
37316+ si_noflush_write_lock(sb);
37317+ ii_read_lock_parent(dir);
37318+ bindex = au_br_index(sb, br->br_id);
37319+ err = au_xino_trunc(sb, bindex, idx);
37320+ ii_read_unlock(dir);
37321+ if (unlikely(err))
37322+ pr_warn("err b%d, (%d)\n", bindex, err);
37323+ atomic_dec(&br->br_xino->xi_truncating);
37324+ au_lcnt_dec(&br->br_count);
37325+ si_write_unlock(sb);
37326+ au_nwt_done(&au_sbi(sb)->si_nowait);
37327+ au_kfree_rcu(args);
37328+}
37329+
37330+/*
37331+ * returns the index in the xi_file array whose corresponding file is necessary
37332+ * to truncate, or -1 which means no need to truncate.
37333+ */
37334+static int xino_trunc_test(struct super_block *sb, struct au_branch *br)
37335+{
37336+ int err;
37337+ unsigned int u;
37338+ struct kstatfs st;
37339+ struct au_sbinfo *sbinfo;
37340+ struct au_xino *xi;
37341+ struct file *file;
37342+
37343+ /* todo: si_xino_expire and the ratio should be customizable */
37344+ sbinfo = au_sbi(sb);
37345+ if (time_before(jiffies,
37346+ sbinfo->si_xino_jiffy + sbinfo->si_xino_expire))
37347+ return -1;
37348+
37349+ /* truncation border */
37350+ xi = br->br_xino;
37351+ for (u = 0; u < xi->xi_nfile; u++) {
37352+ file = au_xino_file(xi, u);
37353+ if (!file)
37354+ continue;
37355+
37356+ err = vfs_statfs(&file->f_path, &st);
37357+ if (unlikely(err)) {
37358+ AuErr1("statfs err %d, ignored\n", err);
37359+ return -1;
37360+ }
37361+ if (div64_u64(st.f_bfree * 100, st.f_blocks)
37362+ >= AUFS_XINO_DEF_TRUNC)
37363+ return u;
37364+ }
37365+
37366+ return -1;
37367+}
37368+
37369+static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
37370+{
37371+ int idx;
37372+ struct xino_do_trunc_args *args;
37373+ int wkq_err;
37374+
37375+ idx = xino_trunc_test(sb, br);
37376+ if (idx < 0)
37377+ return;
37378+
37379+ if (atomic_inc_return(&br->br_xino->xi_truncating) > 1)
37380+ goto out;
37381+
37382+ /* lock and kfree() will be called in trunc_xino() */
37383+ args = kmalloc(sizeof(*args), GFP_NOFS);
37384+ if (unlikely(!args)) {
37385+ AuErr1("no memory\n");
37386+ goto out;
37387+ }
37388+
37389+ au_lcnt_inc(&br->br_count);
37390+ args->sb = sb;
37391+ args->br = br;
37392+ args->idx = idx;
37393+ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0);
37394+ if (!wkq_err)
37395+ return; /* success */
37396+
37397+ pr_err("wkq %d\n", wkq_err);
37398+ au_lcnt_dec(&br->br_count);
37399+ au_kfree_rcu(args);
37400+
37401+out:
37402+ atomic_dec(&br->br_xino->xi_truncating);
37403+}
37404+
37405+/* ---------------------------------------------------------------------- */
37406+
37407+struct au_xi_calc {
37408+ int idx;
37409+ loff_t pos;
37410+};
37411+
37412+static void au_xi_calc(struct super_block *sb, ino_t h_ino,
37413+ struct au_xi_calc *calc)
37414+{
37415+ loff_t maxent;
37416+
37417+ maxent = au_xi_maxent(sb);
37418+ calc->idx = div64_u64_rem(h_ino, maxent, &calc->pos);
37419+ calc->pos *= sizeof(ino_t);
37420+}
37421+
37422+static int au_xino_do_new_async(struct super_block *sb, struct au_branch *br,
37423+ struct au_xi_calc *calc)
37424+{
37425+ int err;
37426+ struct file *file;
37427+ struct au_xino *xi = br->br_xino;
37428+ struct au_xi_new xinew = {
37429+ .xi = xi
37430+ };
37431+
37432+ SiMustAnyLock(sb);
37433+
37434+ err = 0;
37435+ if (!xi)
37436+ goto out;
37437+
37438+ mutex_lock(&xi->xi_mtx);
37439+ file = au_xino_file(xi, calc->idx);
37440+ if (file)
37441+ goto out_mtx;
37442+
37443+ file = au_xino_file(xi, /*idx*/-1);
37444+ AuDebugOn(!file);
37445+ xinew.idx = calc->idx;
37446+ xinew.base = &file->f_path;
37447+ /* xinew.copy_src = NULL; */
37448+ file = au_xi_new(sb, &xinew);
37449+ if (IS_ERR(file))
37450+ err = PTR_ERR(file);
37451+
37452+out_mtx:
37453+ mutex_unlock(&xi->xi_mtx);
37454+out:
37455+ return err;
37456+}
37457+
37458+struct au_xino_do_new_async_args {
37459+ struct super_block *sb;
37460+ struct au_branch *br;
37461+ struct au_xi_calc calc;
37462+ ino_t ino;
37463+};
37464+
37465+struct au_xi_writing {
37466+ struct hlist_bl_node node;
37467+ ino_t h_ino, ino;
37468+};
37469+
37470+static int au_xino_do_write(vfs_writef_t write, struct file *file,
37471+ struct au_xi_calc *calc, ino_t ino);
37472+
37473+static void au_xino_call_do_new_async(void *args)
37474+{
37475+ struct au_xino_do_new_async_args *a = args;
37476+ struct au_branch *br;
37477+ struct super_block *sb;
37478+ struct au_sbinfo *sbi;
37479+ struct inode *root;
37480+ struct file *file;
37481+ struct au_xi_writing *del, *p;
37482+ struct hlist_bl_head *hbl;
37483+ struct hlist_bl_node *pos;
37484+ int err;
37485+
37486+ br = a->br;
37487+ sb = a->sb;
37488+ sbi = au_sbi(sb);
37489+ si_noflush_read_lock(sb);
37490+ root = d_inode(sb->s_root);
37491+ ii_read_lock_child(root);
37492+ err = au_xino_do_new_async(sb, br, &a->calc);
37493+ if (unlikely(err)) {
37494+ AuIOErr("err %d\n", err);
37495+ goto out;
37496+ }
37497+
37498+ file = au_xino_file(br->br_xino, a->calc.idx);
37499+ AuDebugOn(!file);
37500+ err = au_xino_do_write(sbi->si_xwrite, file, &a->calc, a->ino);
37501+ if (unlikely(err)) {
37502+ AuIOErr("err %d\n", err);
37503+ goto out;
37504+ }
37505+
37506+ del = NULL;
37507+ hbl = &br->br_xino->xi_writing;
37508+ hlist_bl_lock(hbl);
37509+ au_hbl_for_each(pos, hbl) {
37510+ p = container_of(pos, struct au_xi_writing, node);
37511+ if (p->ino == a->ino) {
37512+ del = p;
37513+ hlist_bl_del(&p->node);
37514+ break;
37515+ }
37516+ }
37517+ hlist_bl_unlock(hbl);
37518+ au_kfree_rcu(del);
37519+
37520+out:
37521+ au_lcnt_dec(&br->br_count);
37522+ ii_read_unlock(root);
37523+ si_read_unlock(sb);
37524+ au_nwt_done(&sbi->si_nowait);
37525+ au_kfree_rcu(a);
37526+}
37527+
37528+/*
37529+ * create a new xino file asynchronously
37530+ */
37531+static int au_xino_new_async(struct super_block *sb, struct au_branch *br,
37532+ struct au_xi_calc *calc, ino_t ino)
37533+{
37534+ int err;
37535+ struct au_xino_do_new_async_args *arg;
37536+
37537+ err = -ENOMEM;
37538+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
37539+ if (unlikely(!arg))
37540+ goto out;
37541+
37542+ arg->sb = sb;
37543+ arg->br = br;
37544+ arg->calc = *calc;
37545+ arg->ino = ino;
37546+ au_lcnt_inc(&br->br_count);
37547+ err = au_wkq_nowait(au_xino_call_do_new_async, arg, sb, AuWkq_NEST);
37548+ if (unlikely(err)) {
37549+ pr_err("wkq %d\n", err);
37550+ au_lcnt_dec(&br->br_count);
37551+ au_kfree_rcu(arg);
37552+ }
37553+
37554+out:
37555+ return err;
37556+}
37557+
37558+/*
37559+ * read @ino from xinofile for the specified branch{@sb, @bindex}
37560+ * at the position of @h_ino.
37561+ */
37562+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
37563+ ino_t *ino)
37564+{
37565+ int err;
37566+ ssize_t sz;
37567+ struct au_xi_calc calc;
37568+ struct au_sbinfo *sbinfo;
37569+ struct file *file;
37570+ struct au_xino *xi;
37571+ struct hlist_bl_head *hbl;
37572+ struct hlist_bl_node *pos;
37573+ struct au_xi_writing *p;
37574+
37575+ *ino = 0;
37576+ if (!au_opt_test(au_mntflags(sb), XINO))
37577+ return 0; /* no xino */
37578+
37579+ err = 0;
37580+ au_xi_calc(sb, h_ino, &calc);
37581+ xi = au_sbr(sb, bindex)->br_xino;
37582+ file = au_xino_file(xi, calc.idx);
37583+ if (!file) {
37584+ hbl = &xi->xi_writing;
37585+ hlist_bl_lock(hbl);
37586+ au_hbl_for_each(pos, hbl) {
37587+ p = container_of(pos, struct au_xi_writing, node);
37588+ if (p->h_ino == h_ino) {
37589+ AuDbg("hi%llu, i%llu, found\n",
37590+ (u64)p->h_ino, (u64)p->ino);
37591+ *ino = p->ino;
37592+ break;
37593+ }
37594+ }
37595+ hlist_bl_unlock(hbl);
37596+ return 0;
37597+ } else if (vfsub_f_size_read(file) < calc.pos + sizeof(*ino))
37598+ return 0; /* no xino */
37599+
37600+ sbinfo = au_sbi(sb);
37601+ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &calc.pos);
37602+ if (sz == sizeof(*ino))
37603+ return 0; /* success */
37604+
37605+ err = sz;
37606+ if (unlikely(sz >= 0)) {
37607+ err = -EIO;
37608+ AuIOErr("xino read error (%zd)\n", sz);
37609+ }
37610+ return err;
37611+}
37612+
37613+static int au_xino_do_write(vfs_writef_t write, struct file *file,
37614+ struct au_xi_calc *calc, ino_t ino)
37615+{
37616+ ssize_t sz;
37617+
37618+ sz = xino_fwrite(write, file, &ino, sizeof(ino), &calc->pos);
37619+ if (sz == sizeof(ino))
37620+ return 0; /* success */
37621+
37622+ AuIOErr("write failed (%zd)\n", sz);
37623+ return -EIO;
37624+}
37625+
37626+/*
37627+ * write @ino to the xinofile for the specified branch{@sb, @bindex}
37628+ * at the position of @h_ino.
37629+ * even if @ino is zero, it is written to the xinofile and means no entry.
37630+ * if the size of the xino file on a specific filesystem exceeds the watermark,
37631+ * try truncating it.
37632+ */
37633+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
37634+ ino_t ino)
37635+{
37636+ int err;
37637+ unsigned int mnt_flags;
37638+ struct au_xi_calc calc;
37639+ struct file *file;
37640+ struct au_branch *br;
37641+ struct au_xino *xi;
37642+ struct au_xi_writing *p;
37643+
37644+ SiMustAnyLock(sb);
37645+
37646+ mnt_flags = au_mntflags(sb);
37647+ if (!au_opt_test(mnt_flags, XINO))
37648+ return 0;
37649+
37650+ au_xi_calc(sb, h_ino, &calc);
37651+ br = au_sbr(sb, bindex);
37652+ xi = br->br_xino;
37653+ file = au_xino_file(xi, calc.idx);
37654+ if (!file) {
37655+ /* store the inum pair into the list */
37656+ p = kmalloc(sizeof(*p), GFP_NOFS | __GFP_NOFAIL);
37657+ p->h_ino = h_ino;
37658+ p->ino = ino;
37659+ au_hbl_add(&p->node, &xi->xi_writing);
37660+
37661+ /* create and write a new xino file asynchronously */
37662+ err = au_xino_new_async(sb, br, &calc, ino);
37663+ if (!err)
37664+ return 0; /* success */
37665+ goto out;
37666+ }
37667+
37668+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, file, &calc, ino);
37669+ if (!err) {
37670+ br = au_sbr(sb, bindex);
37671+ if (au_opt_test(mnt_flags, TRUNC_XINO)
37672+ && au_test_fs_trunc_xino(au_br_sb(br)))
37673+ xino_try_trunc(sb, br);
37674+ return 0; /* success */
37675+ }
37676+
37677+out:
37678+ AuIOErr("write failed (%d)\n", err);
37679+ return -EIO;
37680+}
37681+
37682+static ssize_t xino_fread_wkq(vfs_readf_t func, struct file *file, void *buf,
37683+ size_t size, loff_t *pos);
37684+
37685+/* todo: unnecessary to support mmap_sem since kernel-space? */
37686+ssize_t xino_fread(vfs_readf_t func, struct file *file, void *kbuf, size_t size,
37687+ loff_t *pos)
37688+{
37689+ ssize_t err;
37690+ mm_segment_t oldfs;
37691+ union {
37692+ void *k;
37693+ char __user *u;
37694+ } buf;
37695+ int i;
37696+ const int prevent_endless = 10;
37697+
37698+ i = 0;
37699+ buf.k = kbuf;
37700+ oldfs = get_fs();
37701+ set_fs(KERNEL_DS);
37702+ do {
37703+ err = func(file, buf.u, size, pos);
37704+ if (err == -EINTR
37705+ && !au_wkq_test()
37706+ && fatal_signal_pending(current)) {
37707+ set_fs(oldfs);
37708+ err = xino_fread_wkq(func, file, kbuf, size, pos);
37709+ BUG_ON(err == -EINTR);
37710+ oldfs = get_fs();
37711+ set_fs(KERNEL_DS);
37712+ }
37713+ } while (i++ < prevent_endless
37714+ && (err == -EAGAIN || err == -EINTR));
37715+ set_fs(oldfs);
37716+
37717+#if 0 /* reserved for future use */
37718+ if (err > 0)
37719+ fsnotify_access(file->f_path.dentry);
37720+#endif
37721+
37722+ return err;
37723+}
37724+
37725+struct xino_fread_args {
37726+ ssize_t *errp;
37727+ vfs_readf_t func;
37728+ struct file *file;
37729+ void *buf;
37730+ size_t size;
37731+ loff_t *pos;
37732+};
37733+
37734+static void call_xino_fread(void *args)
37735+{
37736+ struct xino_fread_args *a = args;
37737+ *a->errp = xino_fread(a->func, a->file, a->buf, a->size, a->pos);
37738+}
37739+
37740+static ssize_t xino_fread_wkq(vfs_readf_t func, struct file *file, void *buf,
37741+ size_t size, loff_t *pos)
37742+{
37743+ ssize_t err;
37744+ int wkq_err;
37745+ struct xino_fread_args args = {
37746+ .errp = &err,
37747+ .func = func,
37748+ .file = file,
37749+ .buf = buf,
37750+ .size = size,
37751+ .pos = pos
37752+ };
37753+
37754+ wkq_err = au_wkq_wait(call_xino_fread, &args);
37755+ if (unlikely(wkq_err))
37756+ err = wkq_err;
37757+
37758+ return err;
37759+}
37760+
37761+static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf,
37762+ size_t size, loff_t *pos);
37763+
37764+static ssize_t do_xino_fwrite(vfs_writef_t func, struct file *file, void *kbuf,
37765+ size_t size, loff_t *pos)
37766+{
37767+ ssize_t err;
37768+ mm_segment_t oldfs;
37769+ union {
37770+ void *k;
37771+ const char __user *u;
37772+ } buf;
37773+ int i;
37774+ const int prevent_endless = 10;
37775+
37776+ i = 0;
37777+ buf.k = kbuf;
37778+ oldfs = get_fs();
37779+ set_fs(KERNEL_DS);
37780+ do {
37781+ err = func(file, buf.u, size, pos);
37782+ if (err == -EINTR
37783+ && !au_wkq_test()
37784+ && fatal_signal_pending(current)) {
37785+ set_fs(oldfs);
37786+ err = xino_fwrite_wkq(func, file, kbuf, size, pos);
37787+ BUG_ON(err == -EINTR);
37788+ oldfs = get_fs();
37789+ set_fs(KERNEL_DS);
37790+ }
37791+ } while (i++ < prevent_endless
37792+ && (err == -EAGAIN || err == -EINTR));
37793+ set_fs(oldfs);
37794+
37795+#if 0 /* reserved for future use */
37796+ if (err > 0)
37797+ fsnotify_modify(file->f_path.dentry);
37798+#endif
37799+
37800+ return err;
37801+}
37802+
37803+struct do_xino_fwrite_args {
37804+ ssize_t *errp;
37805+ vfs_writef_t func;
37806+ struct file *file;
37807+ void *buf;
37808+ size_t size;
37809+ loff_t *pos;
37810+};
37811+
37812+static void call_do_xino_fwrite(void *args)
37813+{
37814+ struct do_xino_fwrite_args *a = args;
37815+ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
37816+}
37817+
37818+static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf,
37819+ size_t size, loff_t *pos)
37820+{
37821+ ssize_t err;
37822+ int wkq_err;
37823+ struct do_xino_fwrite_args args = {
37824+ .errp = &err,
37825+ .func = func,
37826+ .file = file,
37827+ .buf = buf,
37828+ .size = size,
37829+ .pos = pos
37830+ };
37831+
37832+ /*
37833+ * it breaks RLIMIT_FSIZE and normal user's limit,
37834+ * users should care about quota and real 'filesystem full.'
37835+ */
37836+ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
37837+ if (unlikely(wkq_err))
37838+ err = wkq_err;
37839+
37840+ return err;
37841+}
37842+
37843+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf,
37844+ size_t size, loff_t *pos)
37845+{
37846+ ssize_t err;
37847+
37848+ if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
37849+ lockdep_off();
37850+ err = do_xino_fwrite(func, file, buf, size, pos);
37851+ lockdep_on();
37852+ } else {
37853+ lockdep_off();
37854+ err = xino_fwrite_wkq(func, file, buf, size, pos);
37855+ lockdep_on();
37856+ }
37857+
37858+ return err;
37859+}
37860+
37861+/* ---------------------------------------------------------------------- */
37862+
37863+/*
37864+ * inode number bitmap
37865+ */
37866+static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
37867+static ino_t xib_calc_ino(unsigned long pindex, int bit)
37868+{
37869+ ino_t ino;
37870+
37871+ AuDebugOn(bit < 0 || page_bits <= bit);
37872+ ino = AUFS_FIRST_INO + pindex * page_bits + bit;
37873+ return ino;
37874+}
37875+
37876+static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
37877+{
37878+ AuDebugOn(ino < AUFS_FIRST_INO);
37879+ ino -= AUFS_FIRST_INO;
37880+ *pindex = ino / page_bits;
37881+ *bit = ino % page_bits;
37882+}
37883+
37884+static int xib_pindex(struct super_block *sb, unsigned long pindex)
37885+{
37886+ int err;
37887+ loff_t pos;
37888+ ssize_t sz;
37889+ struct au_sbinfo *sbinfo;
37890+ struct file *xib;
37891+ unsigned long *p;
37892+
37893+ sbinfo = au_sbi(sb);
37894+ MtxMustLock(&sbinfo->si_xib_mtx);
37895+ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
37896+ || !au_opt_test(sbinfo->si_mntflags, XINO));
37897+
37898+ if (pindex == sbinfo->si_xib_last_pindex)
37899+ return 0;
37900+
37901+ xib = sbinfo->si_xib;
37902+ p = sbinfo->si_xib_buf;
37903+ pos = sbinfo->si_xib_last_pindex;
37904+ pos *= PAGE_SIZE;
37905+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
37906+ if (unlikely(sz != PAGE_SIZE))
37907+ goto out;
37908+
37909+ pos = pindex;
37910+ pos *= PAGE_SIZE;
37911+ if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE)
37912+ sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
37913+ else {
37914+ memset(p, 0, PAGE_SIZE);
37915+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
37916+ }
37917+ if (sz == PAGE_SIZE) {
37918+ sbinfo->si_xib_last_pindex = pindex;
37919+ return 0; /* success */
37920+ }
37921+
37922+out:
37923+ AuIOErr1("write failed (%zd)\n", sz);
37924+ err = sz;
37925+ if (sz >= 0)
37926+ err = -EIO;
37927+ return err;
37928+}
37929+
37930+static void au_xib_clear_bit(struct inode *inode)
37931+{
37932+ int err, bit;
37933+ unsigned long pindex;
37934+ struct super_block *sb;
37935+ struct au_sbinfo *sbinfo;
37936+
37937+ AuDebugOn(inode->i_nlink);
37938+
37939+ sb = inode->i_sb;
37940+ xib_calc_bit(inode->i_ino, &pindex, &bit);
37941+ AuDebugOn(page_bits <= bit);
37942+ sbinfo = au_sbi(sb);
37943+ mutex_lock(&sbinfo->si_xib_mtx);
37944+ err = xib_pindex(sb, pindex);
37945+ if (!err) {
37946+ clear_bit(bit, sbinfo->si_xib_buf);
37947+ sbinfo->si_xib_next_bit = bit;
37948+ }
37949+ mutex_unlock(&sbinfo->si_xib_mtx);
37950+}
37951+
37952+/* ---------------------------------------------------------------------- */
37953+
37954+/*
37955+ * truncate a xino bitmap file
37956+ */
37957+
37958+/* todo: slow */
37959+static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
37960+{
37961+ int err, bit;
37962+ ssize_t sz;
37963+ unsigned long pindex;
37964+ loff_t pos, pend;
37965+ struct au_sbinfo *sbinfo;
37966+ vfs_readf_t func;
37967+ ino_t *ino;
37968+ unsigned long *p;
37969+
37970+ err = 0;
37971+ sbinfo = au_sbi(sb);
37972+ MtxMustLock(&sbinfo->si_xib_mtx);
37973+ p = sbinfo->si_xib_buf;
37974+ func = sbinfo->si_xread;
37975+ pend = vfsub_f_size_read(file);
37976+ pos = 0;
37977+ while (pos < pend) {
37978+ sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
37979+ err = sz;
37980+ if (unlikely(sz <= 0))
37981+ goto out;
37982+
37983+ err = 0;
37984+ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
37985+ if (unlikely(*ino < AUFS_FIRST_INO))
37986+ continue;
37987+
37988+ xib_calc_bit(*ino, &pindex, &bit);
37989+ AuDebugOn(page_bits <= bit);
37990+ err = xib_pindex(sb, pindex);
37991+ if (!err)
37992+ set_bit(bit, p);
37993+ else
37994+ goto out;
37995+ }
37996+ }
37997+
37998+out:
37999+ return err;
38000+}
38001+
38002+static int xib_restore(struct super_block *sb)
38003+{
38004+ int err, i;
38005+ unsigned int nfile;
38006+ aufs_bindex_t bindex, bbot;
38007+ void *page;
38008+ struct au_branch *br;
38009+ struct au_xino *xi;
38010+ struct file *file;
38011+
38012+ err = -ENOMEM;
38013+ page = (void *)__get_free_page(GFP_NOFS);
38014+ if (unlikely(!page))
38015+ goto out;
38016+
38017+ err = 0;
38018+ bbot = au_sbbot(sb);
38019+ for (bindex = 0; !err && bindex <= bbot; bindex++)
38020+ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0) {
38021+ br = au_sbr(sb, bindex);
38022+ xi = br->br_xino;
38023+ nfile = xi->xi_nfile;
38024+ for (i = 0; i < nfile; i++) {
38025+ file = au_xino_file(xi, i);
38026+ if (file)
38027+ err = do_xib_restore(sb, file, page);
38028+ }
38029+ } else
38030+ AuDbg("skip shared b%d\n", bindex);
38031+ free_page((unsigned long)page);
38032+
38033+out:
38034+ return err;
38035+}
38036+
38037+int au_xib_trunc(struct super_block *sb)
38038+{
38039+ int err;
38040+ ssize_t sz;
38041+ loff_t pos;
38042+ struct au_sbinfo *sbinfo;
38043+ unsigned long *p;
38044+ struct file *file;
38045+
38046+ SiMustWriteLock(sb);
38047+
38048+ err = 0;
38049+ sbinfo = au_sbi(sb);
38050+ if (!au_opt_test(sbinfo->si_mntflags, XINO))
38051+ goto out;
38052+
38053+ file = sbinfo->si_xib;
38054+ if (vfsub_f_size_read(file) <= PAGE_SIZE)
38055+ goto out;
38056+
38057+ file = au_xino_create2(sb, &sbinfo->si_xib->f_path, NULL);
38058+ err = PTR_ERR(file);
38059+ if (IS_ERR(file))
38060+ goto out;
38061+ fput(sbinfo->si_xib);
38062+ sbinfo->si_xib = file;
38063+
38064+ p = sbinfo->si_xib_buf;
38065+ memset(p, 0, PAGE_SIZE);
38066+ pos = 0;
38067+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
38068+ if (unlikely(sz != PAGE_SIZE)) {
38069+ err = sz;
38070+ AuIOErr("err %d\n", err);
38071+ if (sz >= 0)
38072+ err = -EIO;
38073+ goto out;
38074+ }
38075+
38076+ mutex_lock(&sbinfo->si_xib_mtx);
38077+ /* mnt_want_write() is unnecessary here */
38078+ err = xib_restore(sb);
38079+ mutex_unlock(&sbinfo->si_xib_mtx);
38080+
38081+out:
38082+ return err;
38083+}
38084+
38085+/* ---------------------------------------------------------------------- */
38086+
38087+struct au_xino *au_xino_alloc(unsigned int nfile)
38088+{
38089+ struct au_xino *xi;
38090+
38091+ xi = kzalloc(sizeof(*xi), GFP_NOFS);
38092+ if (unlikely(!xi))
38093+ goto out;
38094+ xi->xi_nfile = nfile;
38095+ xi->xi_file = kcalloc(nfile, sizeof(*xi->xi_file), GFP_NOFS);
38096+ if (unlikely(!xi->xi_file))
38097+ goto out_free;
38098+
38099+ xi->xi_nondir.total = 8; /* initial size */
38100+ xi->xi_nondir.array = kcalloc(xi->xi_nondir.total, sizeof(ino_t),
38101+ GFP_NOFS);
38102+ if (unlikely(!xi->xi_nondir.array))
38103+ goto out_file;
38104+
38105+ spin_lock_init(&xi->xi_nondir.spin);
38106+ init_waitqueue_head(&xi->xi_nondir.wqh);
38107+ mutex_init(&xi->xi_mtx);
38108+ INIT_HLIST_BL_HEAD(&xi->xi_writing);
38109+ atomic_set(&xi->xi_truncating, 0);
38110+ kref_init(&xi->xi_kref);
38111+ goto out; /* success */
38112+
38113+out_file:
38114+ au_kfree_try_rcu(xi->xi_file);
38115+out_free:
38116+ au_kfree_rcu(xi);
38117+ xi = NULL;
38118+out:
38119+ return xi;
38120+}
38121+
38122+static int au_xino_init(struct au_branch *br, int idx, struct file *file)
38123+{
38124+ int err;
38125+ struct au_xino *xi;
38126+
38127+ err = 0;
38128+ xi = au_xino_alloc(idx + 1);
38129+ if (unlikely(!xi)) {
38130+ err = -ENOMEM;
38131+ goto out;
38132+ }
38133+
38134+ if (file)
38135+ get_file(file);
38136+ xi->xi_file[idx] = file;
38137+ AuDebugOn(br->br_xino);
38138+ br->br_xino = xi;
38139+
38140+out:
38141+ return err;
38142+}
38143+
38144+static void au_xino_release(struct kref *kref)
38145+{
38146+ struct au_xino *xi;
38147+ int i;
38148+ unsigned long ul;
38149+ struct hlist_bl_head *hbl;
38150+ struct hlist_bl_node *pos, *n;
38151+ struct au_xi_writing *p;
38152+
38153+ xi = container_of(kref, struct au_xino, xi_kref);
38154+ for (i = 0; i < xi->xi_nfile; i++)
38155+ if (xi->xi_file[i])
38156+ fput(xi->xi_file[i]);
38157+ for (i = xi->xi_nondir.total - 1; i >= 0; i--)
38158+ AuDebugOn(xi->xi_nondir.array[i]);
38159+ mutex_destroy(&xi->xi_mtx);
38160+ hbl = &xi->xi_writing;
38161+ ul = au_hbl_count(hbl);
38162+ if (unlikely(ul)) {
38163+ pr_warn("xi_writing %lu\n", ul);
38164+ hlist_bl_lock(hbl);
38165+ hlist_bl_for_each_entry_safe(p, pos, n, hbl, node) {
38166+ hlist_bl_del(&p->node);
38167+ /* kmemleak reported au_kfree_rcu() doesn't free it */
38168+ kfree(p);
38169+ }
38170+ hlist_bl_unlock(hbl);
38171+ }
38172+ au_kfree_try_rcu(xi->xi_file);
38173+ au_kfree_try_rcu(xi->xi_nondir.array);
38174+ au_kfree_rcu(xi);
38175+}
38176+
38177+int au_xino_put(struct au_branch *br)
38178+{
38179+ int ret;
38180+ struct au_xino *xi;
38181+
38182+ ret = 0;
38183+ xi = br->br_xino;
38184+ if (xi) {
38185+ br->br_xino = NULL;
38186+ ret = kref_put(&xi->xi_kref, au_xino_release);
38187+ }
38188+
38189+ return ret;
38190+}
38191+
38192+/* ---------------------------------------------------------------------- */
38193+
38194+/*
38195+ * xino mount option handlers
38196+ */
38197+
38198+/* xino bitmap */
38199+static void xino_clear_xib(struct super_block *sb)
38200+{
38201+ struct au_sbinfo *sbinfo;
38202+
38203+ SiMustWriteLock(sb);
38204+
38205+ sbinfo = au_sbi(sb);
38206+ /* unnecessary to clear sbinfo->si_xread and ->si_xwrite */
38207+ if (sbinfo->si_xib)
38208+ fput(sbinfo->si_xib);
38209+ sbinfo->si_xib = NULL;
38210+ if (sbinfo->si_xib_buf)
38211+ free_page((unsigned long)sbinfo->si_xib_buf);
38212+ sbinfo->si_xib_buf = NULL;
38213+}
38214+
38215+static int au_xino_set_xib(struct super_block *sb, struct path *path)
38216+{
38217+ int err;
38218+ loff_t pos;
38219+ struct au_sbinfo *sbinfo;
38220+ struct file *file;
38221+ struct super_block *xi_sb;
38222+
38223+ SiMustWriteLock(sb);
38224+
38225+ sbinfo = au_sbi(sb);
38226+ file = au_xino_create2(sb, path, sbinfo->si_xib);
38227+ err = PTR_ERR(file);
38228+ if (IS_ERR(file))
38229+ goto out;
38230+ if (sbinfo->si_xib)
38231+ fput(sbinfo->si_xib);
38232+ sbinfo->si_xib = file;
38233+ sbinfo->si_xread = vfs_readf(file);
38234+ sbinfo->si_xwrite = vfs_writef(file);
38235+ xi_sb = file_inode(file)->i_sb;
38236+ sbinfo->si_ximaxent = xi_sb->s_maxbytes;
38237+ if (unlikely(sbinfo->si_ximaxent < PAGE_SIZE)) {
38238+ err = -EIO;
38239+ pr_err("s_maxbytes(%llu) on %s is too small\n",
38240+ (u64)sbinfo->si_ximaxent, au_sbtype(xi_sb));
38241+ goto out_unset;
38242+ }
38243+ sbinfo->si_ximaxent /= sizeof(ino_t);
38244+
38245+ err = -ENOMEM;
38246+ if (!sbinfo->si_xib_buf)
38247+ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
38248+ if (unlikely(!sbinfo->si_xib_buf))
38249+ goto out_unset;
38250+
38251+ sbinfo->si_xib_last_pindex = 0;
38252+ sbinfo->si_xib_next_bit = 0;
38253+ if (vfsub_f_size_read(file) < PAGE_SIZE) {
38254+ pos = 0;
38255+ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
38256+ PAGE_SIZE, &pos);
38257+ if (unlikely(err != PAGE_SIZE))
38258+ goto out_free;
38259+ }
38260+ err = 0;
38261+ goto out; /* success */
38262+
38263+out_free:
38264+ if (sbinfo->si_xib_buf)
38265+ free_page((unsigned long)sbinfo->si_xib_buf);
38266+ sbinfo->si_xib_buf = NULL;
38267+ if (err >= 0)
38268+ err = -EIO;
38269+out_unset:
38270+ fput(sbinfo->si_xib);
38271+ sbinfo->si_xib = NULL;
38272+out:
38273+ AuTraceErr(err);
38274+ return err;
38275+}
38276+
38277+/* xino for each branch */
38278+static void xino_clear_br(struct super_block *sb)
38279+{
38280+ aufs_bindex_t bindex, bbot;
38281+ struct au_branch *br;
38282+
38283+ bbot = au_sbbot(sb);
38284+ for (bindex = 0; bindex <= bbot; bindex++) {
38285+ br = au_sbr(sb, bindex);
38286+ AuDebugOn(!br);
38287+ au_xino_put(br);
38288+ }
38289+}
38290+
38291+static void au_xino_set_br_shared(struct super_block *sb, struct au_branch *br,
38292+ aufs_bindex_t bshared)
38293+{
38294+ struct au_branch *brshared;
38295+
38296+ brshared = au_sbr(sb, bshared);
38297+ AuDebugOn(!brshared->br_xino);
38298+ AuDebugOn(!brshared->br_xino->xi_file);
38299+ if (br->br_xino != brshared->br_xino) {
38300+ au_xino_get(brshared);
38301+ au_xino_put(br);
38302+ br->br_xino = brshared->br_xino;
38303+ }
38304+}
38305+
38306+struct au_xino_do_set_br {
38307+ vfs_writef_t writef;
38308+ struct au_branch *br;
38309+ ino_t h_ino;
38310+ aufs_bindex_t bshared;
38311+};
38312+
38313+static int au_xino_do_set_br(struct super_block *sb, struct path *path,
38314+ struct au_xino_do_set_br *args)
38315+{
38316+ int err;
38317+ struct au_xi_calc calc;
38318+ struct file *file;
38319+ struct au_branch *br;
38320+ struct au_xi_new xinew = {
38321+ .base = path
38322+ };
38323+
38324+ br = args->br;
38325+ xinew.xi = br->br_xino;
38326+ au_xi_calc(sb, args->h_ino, &calc);
38327+ xinew.copy_src = au_xino_file(xinew.xi, calc.idx);
38328+ if (args->bshared >= 0)
38329+ /* shared xino */
38330+ au_xino_set_br_shared(sb, br, args->bshared);
38331+ else if (!xinew.xi) {
38332+ /* new xino */
38333+ err = au_xino_init(br, calc.idx, xinew.copy_src);
38334+ if (unlikely(err))
38335+ goto out;
38336+ }
38337+
38338+ /* force re-creating */
38339+ xinew.xi = br->br_xino;
38340+ xinew.idx = calc.idx;
38341+ mutex_lock(&xinew.xi->xi_mtx);
38342+ file = au_xi_new(sb, &xinew);
38343+ mutex_unlock(&xinew.xi->xi_mtx);
38344+ err = PTR_ERR(file);
38345+ if (IS_ERR(file))
38346+ goto out;
38347+ AuDebugOn(!file);
38348+
38349+ err = au_xino_do_write(args->writef, file, &calc, AUFS_ROOT_INO);
38350+ if (unlikely(err))
38351+ au_xino_put(br);
38352+
38353+out:
38354+ AuTraceErr(err);
38355+ return err;
38356+}
38357+
38358+static int au_xino_set_br(struct super_block *sb, struct path *path)
38359+{
38360+ int err;
38361+ aufs_bindex_t bindex, bbot;
38362+ struct au_xino_do_set_br args;
38363+ struct inode *inode;
38364+
38365+ SiMustWriteLock(sb);
38366+
38367+ bbot = au_sbbot(sb);
38368+ inode = d_inode(sb->s_root);
38369+ args.writef = au_sbi(sb)->si_xwrite;
38370+ for (bindex = 0; bindex <= bbot; bindex++) {
38371+ args.h_ino = au_h_iptr(inode, bindex)->i_ino;
38372+ args.br = au_sbr(sb, bindex);
38373+ args.bshared = is_sb_shared(sb, bindex, bindex - 1);
38374+ err = au_xino_do_set_br(sb, path, &args);
38375+ if (unlikely(err))
38376+ break;
38377+ }
38378+
38379+ AuTraceErr(err);
38380+ return err;
38381+}
38382+
38383+void au_xino_clr(struct super_block *sb)
38384+{
38385+ struct au_sbinfo *sbinfo;
38386+
38387+ au_xigen_clr(sb);
38388+ xino_clear_xib(sb);
38389+ xino_clear_br(sb);
38390+ dbgaufs_brs_del(sb, 0);
38391+ sbinfo = au_sbi(sb);
38392+ /* lvalue, do not call au_mntflags() */
38393+ au_opt_clr(sbinfo->si_mntflags, XINO);
38394+}
38395+
38396+int au_xino_set(struct super_block *sb, struct au_opt_xino *xiopt, int remount)
38397+{
38398+ int err, skip;
38399+ struct dentry *dentry, *parent, *cur_dentry, *cur_parent;
38400+ struct qstr *dname, *cur_name;
38401+ struct file *cur_xino;
38402+ struct au_sbinfo *sbinfo;
38403+ struct path *path, *cur_path;
38404+
38405+ SiMustWriteLock(sb);
38406+
38407+ err = 0;
38408+ sbinfo = au_sbi(sb);
38409+ path = &xiopt->file->f_path;
38410+ dentry = path->dentry;
38411+ parent = dget_parent(dentry);
38412+ if (remount) {
38413+ skip = 0;
38414+ cur_xino = sbinfo->si_xib;
38415+ if (cur_xino) {
38416+ cur_path = &cur_xino->f_path;
38417+ cur_dentry = cur_path->dentry;
38418+ cur_parent = dget_parent(cur_dentry);
38419+ cur_name = &cur_dentry->d_name;
38420+ dname = &dentry->d_name;
38421+ skip = (cur_parent == parent
38422+ && au_qstreq(dname, cur_name));
38423+ dput(cur_parent);
38424+ }
38425+ if (skip)
38426+ goto out;
38427+ }
38428+
38429+ au_opt_set(sbinfo->si_mntflags, XINO);
38430+ err = au_xino_set_xib(sb, path);
38431+ /* si_x{read,write} are set */
38432+ if (!err)
38433+ err = au_xigen_set(sb, path);
38434+ if (!err)
38435+ err = au_xino_set_br(sb, path);
38436+ if (!err) {
38437+ dbgaufs_brs_add(sb, 0, /*topdown*/1);
38438+ goto out; /* success */
38439+ }
38440+
38441+ /* reset all */
38442+ AuIOErr("failed setting xino(%d).\n", err);
38443+ au_xino_clr(sb);
38444+
38445+out:
38446+ dput(parent);
38447+ return err;
38448+}
38449+
38450+/*
38451+ * create a xinofile at the default place/path.
38452+ */
38453+struct file *au_xino_def(struct super_block *sb)
38454+{
38455+ struct file *file;
38456+ char *page, *p;
38457+ struct au_branch *br;
38458+ struct super_block *h_sb;
38459+ struct path path;
38460+ aufs_bindex_t bbot, bindex, bwr;
38461+
38462+ br = NULL;
38463+ bbot = au_sbbot(sb);
38464+ bwr = -1;
38465+ for (bindex = 0; bindex <= bbot; bindex++) {
38466+ br = au_sbr(sb, bindex);
38467+ if (au_br_writable(br->br_perm)
38468+ && !au_test_fs_bad_xino(au_br_sb(br))) {
38469+ bwr = bindex;
38470+ break;
38471+ }
38472+ }
38473+
38474+ if (bwr >= 0) {
38475+ file = ERR_PTR(-ENOMEM);
38476+ page = (void *)__get_free_page(GFP_NOFS);
38477+ if (unlikely(!page))
38478+ goto out;
38479+ path.mnt = au_br_mnt(br);
38480+ path.dentry = au_h_dptr(sb->s_root, bwr);
38481+ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
38482+ file = (void *)p;
38483+ if (!IS_ERR(p)) {
38484+ strcat(p, "/" AUFS_XINO_FNAME);
38485+ AuDbg("%s\n", p);
38486+ file = au_xino_create(sb, p, /*silent*/0, /*wbrtop*/1);
38487+ }
38488+ free_page((unsigned long)page);
38489+ } else {
38490+ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0,
38491+ /*wbrtop*/0);
38492+ if (IS_ERR(file))
38493+ goto out;
38494+ h_sb = file->f_path.dentry->d_sb;
38495+ if (unlikely(au_test_fs_bad_xino(h_sb))) {
38496+ pr_err("xino doesn't support %s(%s)\n",
38497+ AUFS_XINO_DEFPATH, au_sbtype(h_sb));
38498+ fput(file);
38499+ file = ERR_PTR(-EINVAL);
38500+ }
38501+ }
38502+
38503+out:
38504+ return file;
38505+}
38506+
38507+/* ---------------------------------------------------------------------- */
38508+
38509+/*
38510+ * initialize the xinofile for the specified branch @br
38511+ * at the place/path where @base_file indicates.
38512+ * test whether another branch is on the same filesystem or not,
38513+ * if found then share the xinofile with another branch.
38514+ */
38515+int au_xino_init_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
38516+ struct path *base)
38517+{
38518+ int err;
38519+ struct au_xino_do_set_br args = {
38520+ .h_ino = h_ino,
38521+ .br = br
38522+ };
38523+
38524+ args.writef = au_sbi(sb)->si_xwrite;
38525+ args.bshared = sbr_find_shared(sb, /*btop*/0, au_sbbot(sb),
38526+ au_br_sb(br));
38527+ err = au_xino_do_set_br(sb, base, &args);
38528+ if (unlikely(err))
38529+ au_xino_put(br);
38530+
38531+ return err;
38532+}
38533+
38534+/* ---------------------------------------------------------------------- */
38535+
38536+/*
38537+ * get an unused inode number from bitmap
38538+ */
38539+ino_t au_xino_new_ino(struct super_block *sb)
38540+{
38541+ ino_t ino;
38542+ unsigned long *p, pindex, ul, pend;
38543+ struct au_sbinfo *sbinfo;
38544+ struct file *file;
38545+ int free_bit, err;
38546+
38547+ if (!au_opt_test(au_mntflags(sb), XINO))
38548+ return iunique(sb, AUFS_FIRST_INO);
38549+
38550+ sbinfo = au_sbi(sb);
38551+ mutex_lock(&sbinfo->si_xib_mtx);
38552+ p = sbinfo->si_xib_buf;
38553+ free_bit = sbinfo->si_xib_next_bit;
38554+ if (free_bit < page_bits && !test_bit(free_bit, p))
38555+ goto out; /* success */
38556+ free_bit = find_first_zero_bit(p, page_bits);
38557+ if (free_bit < page_bits)
38558+ goto out; /* success */
38559+
38560+ pindex = sbinfo->si_xib_last_pindex;
38561+ for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
38562+ err = xib_pindex(sb, ul);
38563+ if (unlikely(err))
38564+ goto out_err;
38565+ free_bit = find_first_zero_bit(p, page_bits);
38566+ if (free_bit < page_bits)
38567+ goto out; /* success */
38568+ }
38569+
38570+ file = sbinfo->si_xib;
38571+ pend = vfsub_f_size_read(file) / PAGE_SIZE;
38572+ for (ul = pindex + 1; ul <= pend; ul++) {
38573+ err = xib_pindex(sb, ul);
38574+ if (unlikely(err))
38575+ goto out_err;
38576+ free_bit = find_first_zero_bit(p, page_bits);
38577+ if (free_bit < page_bits)
38578+ goto out; /* success */
38579+ }
38580+ BUG();
38581+
38582+out:
38583+ set_bit(free_bit, p);
38584+ sbinfo->si_xib_next_bit = free_bit + 1;
38585+ pindex = sbinfo->si_xib_last_pindex;
38586+ mutex_unlock(&sbinfo->si_xib_mtx);
38587+ ino = xib_calc_ino(pindex, free_bit);
38588+ AuDbg("i%lu\n", (unsigned long)ino);
38589+ return ino;
38590+out_err:
38591+ mutex_unlock(&sbinfo->si_xib_mtx);
38592+ AuDbg("i0\n");
38593+ return 0;
38594+}
38595+
38596+/* for s_op->delete_inode() */
38597+void au_xino_delete_inode(struct inode *inode, const int unlinked)
38598+{
38599+ int err;
38600+ unsigned int mnt_flags;
38601+ aufs_bindex_t bindex, bbot, bi;
38602+ unsigned char try_trunc;
38603+ struct au_iinfo *iinfo;
38604+ struct super_block *sb;
38605+ struct au_hinode *hi;
38606+ struct inode *h_inode;
38607+ struct au_branch *br;
38608+ vfs_writef_t xwrite;
38609+ struct au_xi_calc calc;
38610+ struct file *file;
38611+
38612+ AuDebugOn(au_is_bad_inode(inode));
38613+
38614+ sb = inode->i_sb;
38615+ mnt_flags = au_mntflags(sb);
38616+ if (!au_opt_test(mnt_flags, XINO)
38617+ || inode->i_ino == AUFS_ROOT_INO)
38618+ return;
38619+
38620+ if (unlinked) {
38621+ au_xigen_inc(inode);
38622+ au_xib_clear_bit(inode);
38623+ }
38624+
38625+ iinfo = au_ii(inode);
38626+ bindex = iinfo->ii_btop;
38627+ if (bindex < 0)
38628+ return;
38629+
38630+ xwrite = au_sbi(sb)->si_xwrite;
38631+ try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO);
38632+ hi = au_hinode(iinfo, bindex);
38633+ bbot = iinfo->ii_bbot;
38634+ for (; bindex <= bbot; bindex++, hi++) {
38635+ h_inode = hi->hi_inode;
38636+ if (!h_inode
38637+ || (!unlinked && h_inode->i_nlink))
38638+ continue;
38639+
38640+ /* inode may not be revalidated */
38641+ bi = au_br_index(sb, hi->hi_id);
38642+ if (bi < 0)
38643+ continue;
38644+
38645+ br = au_sbr(sb, bi);
38646+ au_xi_calc(sb, h_inode->i_ino, &calc);
38647+ file = au_xino_file(br->br_xino, calc.idx);
38648+ if (IS_ERR_OR_NULL(file))
38649+ continue;
38650+
38651+ err = au_xino_do_write(xwrite, file, &calc, /*ino*/0);
38652+ if (!err && try_trunc
38653+ && au_test_fs_trunc_xino(au_br_sb(br)))
38654+ xino_try_trunc(sb, br);
38655+ }
38656+}
38657+
38658+/* ---------------------------------------------------------------------- */
38659+
38660+static int au_xinondir_find(struct au_xino *xi, ino_t h_ino)
38661+{
38662+ int found, total, i;
38663+
38664+ found = -1;
38665+ total = xi->xi_nondir.total;
38666+ for (i = 0; i < total; i++) {
38667+ if (xi->xi_nondir.array[i] != h_ino)
38668+ continue;
38669+ found = i;
38670+ break;
38671+ }
38672+
38673+ return found;
38674+}
38675+
38676+static int au_xinondir_expand(struct au_xino *xi)
38677+{
38678+ int err, sz;
38679+ ino_t *p;
38680+
38681+ BUILD_BUG_ON(KMALLOC_MAX_SIZE > INT_MAX);
38682+
38683+ err = -ENOMEM;
38684+ sz = xi->xi_nondir.total * sizeof(ino_t);
38685+ if (unlikely(sz > KMALLOC_MAX_SIZE / 2))
38686+ goto out;
38687+ p = au_kzrealloc(xi->xi_nondir.array, sz, sz << 1, GFP_ATOMIC,
38688+ /*may_shrink*/0);
38689+ if (p) {
38690+ xi->xi_nondir.array = p;
38691+ xi->xi_nondir.total <<= 1;
38692+ AuDbg("xi_nondir.total %d\n", xi->xi_nondir.total);
38693+ err = 0;
38694+ }
38695+
38696+out:
38697+ return err;
38698+}
38699+
38700+void au_xinondir_leave(struct super_block *sb, aufs_bindex_t bindex,
38701+ ino_t h_ino, int idx)
38702+{
38703+ struct au_xino *xi;
38704+
38705+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
38706+ xi = au_sbr(sb, bindex)->br_xino;
38707+ AuDebugOn(idx < 0 || xi->xi_nondir.total <= idx);
38708+
38709+ spin_lock(&xi->xi_nondir.spin);
38710+ AuDebugOn(xi->xi_nondir.array[idx] != h_ino);
38711+ xi->xi_nondir.array[idx] = 0;
38712+ spin_unlock(&xi->xi_nondir.spin);
38713+ wake_up_all(&xi->xi_nondir.wqh);
38714+}
38715+
38716+int au_xinondir_enter(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
38717+ int *idx)
38718+{
38719+ int err, found, empty;
38720+ struct au_xino *xi;
38721+
38722+ err = 0;
38723+ *idx = -1;
38724+ if (!au_opt_test(au_mntflags(sb), XINO))
38725+ goto out; /* no xino */
38726+
38727+ xi = au_sbr(sb, bindex)->br_xino;
38728+
38729+again:
38730+ spin_lock(&xi->xi_nondir.spin);
38731+ found = au_xinondir_find(xi, h_ino);
38732+ if (found == -1) {
38733+ empty = au_xinondir_find(xi, /*h_ino*/0);
38734+ if (empty == -1) {
38735+ empty = xi->xi_nondir.total;
38736+ err = au_xinondir_expand(xi);
38737+ if (unlikely(err))
38738+ goto out_unlock;
38739+ }
38740+ xi->xi_nondir.array[empty] = h_ino;
38741+ *idx = empty;
38742+ } else {
38743+ spin_unlock(&xi->xi_nondir.spin);
38744+ wait_event(xi->xi_nondir.wqh,
38745+ xi->xi_nondir.array[found] != h_ino);
38746+ goto again;
38747+ }
38748+
38749+out_unlock:
38750+ spin_unlock(&xi->xi_nondir.spin);
38751+out:
38752+ return err;
38753+}
38754+
38755+/* ---------------------------------------------------------------------- */
38756+
38757+int au_xino_path(struct seq_file *seq, struct file *file)
38758+{
38759+ int err;
38760+
38761+ err = au_seq_path(seq, &file->f_path);
38762+ if (unlikely(err))
38763+ goto out;
38764+
38765+#define Deleted "\\040(deleted)"
38766+ seq->count -= sizeof(Deleted) - 1;
38767+ AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
38768+ sizeof(Deleted) - 1));
38769+#undef Deleted
38770+
38771+out:
38772+ return err;
38773+}
38774diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h
38775--- /usr/share/empty/include/uapi/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
38776+++ linux/include/uapi/linux/aufs_type.h 2020-04-03 08:16:49.834195677 +0200
38777@@ -0,0 +1,452 @@
38778+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
38779+/*
38780+ * Copyright (C) 2005-2020 Junjiro R. Okajima
38781+ *
38782+ * This program, aufs is free software; you can redistribute it and/or modify
38783+ * it under the terms of the GNU General Public License as published by
38784+ * the Free Software Foundation; either version 2 of the License, or
38785+ * (at your option) any later version.
38786+ *
38787+ * This program is distributed in the hope that it will be useful,
38788+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
38789+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38790+ * GNU General Public License for more details.
38791+ *
38792+ * You should have received a copy of the GNU General Public License
38793+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
38794+ */
38795+
38796+#ifndef __AUFS_TYPE_H__
38797+#define __AUFS_TYPE_H__
38798+
38799+#define AUFS_NAME "aufs"
38800+
38801+#ifdef __KERNEL__
38802+/*
38803+ * define it before including all other headers.
38804+ * sched.h may use pr_* macros before defining "current", so define the
38805+ * no-current version first, and re-define later.
38806+ */
38807+#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__
38808+#include <linux/sched.h>
38809+#undef pr_fmt
38810+#define pr_fmt(fmt) \
38811+ AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \
38812+ (int)sizeof(current->comm), current->comm, current->pid
38813+#include <linux/limits.h>
38814+#else
38815+#include <stdint.h>
38816+#include <sys/types.h>
38817+#include <limits.h>
38818+#endif /* __KERNEL__ */
38819+
38820+#define AUFS_VERSION "5.4-20200302"
38821+
38822+/* todo? move this to linux-2.6.19/include/magic.h */
38823+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
38824+
38825+/* ---------------------------------------------------------------------- */
38826+
38827+#ifdef __KERNEL__
38828+#ifdef CONFIG_AUFS_BRANCH_MAX_127
38829+typedef int8_t aufs_bindex_t;
38830+#define AUFS_BRANCH_MAX 127
38831+#else
38832+typedef int16_t aufs_bindex_t;
38833+#ifdef CONFIG_AUFS_BRANCH_MAX_511
38834+#define AUFS_BRANCH_MAX 511
38835+#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
38836+#define AUFS_BRANCH_MAX 1023
38837+#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
38838+#define AUFS_BRANCH_MAX 32767
38839+#endif
38840+#endif
38841+
38842+#ifndef AUFS_BRANCH_MAX
38843+#error unknown CONFIG_AUFS_BRANCH_MAX value
38844+#endif
38845+#endif /* __KERNEL__ */
38846+
38847+/* ---------------------------------------------------------------------- */
38848+
38849+#define AUFS_FSTYPE AUFS_NAME
38850+
38851+#define AUFS_ROOT_INO 2
38852+#define AUFS_FIRST_INO 11
38853+
38854+#define AUFS_WH_PFX ".wh."
38855+#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1)
38856+#define AUFS_WH_TMP_LEN 4
38857+/* a limit for rmdir/rename a dir and copyup */
38858+#define AUFS_MAX_NAMELEN (NAME_MAX \
38859+ - AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\
38860+ - 1 /* dot */\
38861+ - AUFS_WH_TMP_LEN) /* hex */
38862+#define AUFS_XINO_FNAME "." AUFS_NAME ".xino"
38863+#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME
38864+#define AUFS_XINO_DEF_SEC 30 /* seconds */
38865+#define AUFS_XINO_DEF_TRUNC 45 /* percentage */
38866+#define AUFS_DIRWH_DEF 3
38867+#define AUFS_RDCACHE_DEF 10 /* seconds */
38868+#define AUFS_RDCACHE_MAX 3600 /* seconds */
38869+#define AUFS_RDBLK_DEF 512 /* bytes */
38870+#define AUFS_RDHASH_DEF 32
38871+#define AUFS_WKQ_NAME AUFS_NAME "d"
38872+#define AUFS_MFS_DEF_SEC 30 /* seconds */
38873+#define AUFS_MFS_MAX_SEC 3600 /* seconds */
38874+#define AUFS_FHSM_CACHE_DEF_SEC 30 /* seconds */
38875+#define AUFS_PLINK_WARN 50 /* number of plinks in a single bucket */
38876+
38877+/* pseudo-link maintenace under /proc */
38878+#define AUFS_PLINK_MAINT_NAME "plink_maint"
38879+#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME
38880+#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME
38881+
38882+/* dirren, renamed dir */
38883+#define AUFS_DR_INFO_PFX AUFS_WH_PFX ".dr."
38884+#define AUFS_DR_BRHINO_NAME AUFS_WH_PFX "hino"
38885+/* whiteouted doubly */
38886+#define AUFS_WH_DR_INFO_PFX AUFS_WH_PFX AUFS_DR_INFO_PFX
38887+#define AUFS_WH_DR_BRHINO AUFS_WH_PFX AUFS_DR_BRHINO_NAME
38888+
38889+#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */
38890+#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME
38891+
38892+#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME
38893+#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk"
38894+#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph"
38895+
38896+/* doubly whiteouted */
38897+#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME
38898+#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME
38899+#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME
38900+
38901+/* branch permissions and attributes */
38902+#define AUFS_BRPERM_RW "rw"
38903+#define AUFS_BRPERM_RO "ro"
38904+#define AUFS_BRPERM_RR "rr"
38905+#define AUFS_BRATTR_COO_REG "coo_reg"
38906+#define AUFS_BRATTR_COO_ALL "coo_all"
38907+#define AUFS_BRATTR_FHSM "fhsm"
38908+#define AUFS_BRATTR_UNPIN "unpin"
38909+#define AUFS_BRATTR_ICEX "icex"
38910+#define AUFS_BRATTR_ICEX_SEC "icexsec"
38911+#define AUFS_BRATTR_ICEX_SYS "icexsys"
38912+#define AUFS_BRATTR_ICEX_TR "icextr"
38913+#define AUFS_BRATTR_ICEX_USR "icexusr"
38914+#define AUFS_BRATTR_ICEX_OTH "icexoth"
38915+#define AUFS_BRRATTR_WH "wh"
38916+#define AUFS_BRWATTR_NLWH "nolwh"
38917+#define AUFS_BRWATTR_MOO "moo"
38918+
38919+#define AuBrPerm_RW 1 /* writable, hardlinkable wh */
38920+#define AuBrPerm_RO (1 << 1) /* readonly */
38921+#define AuBrPerm_RR (1 << 2) /* natively readonly */
38922+#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
38923+
38924+#define AuBrAttr_COO_REG (1 << 3) /* copy-up on open */
38925+#define AuBrAttr_COO_ALL (1 << 4)
38926+#define AuBrAttr_COO_Mask (AuBrAttr_COO_REG | AuBrAttr_COO_ALL)
38927+
38928+#define AuBrAttr_FHSM (1 << 5) /* file-based hsm */
38929+#define AuBrAttr_UNPIN (1 << 6) /* rename-able top dir of
38930+ branch. meaningless since
38931+ linux-3.18-rc1 */
38932+
38933+/* ignore error in copying XATTR */
38934+#define AuBrAttr_ICEX_SEC (1 << 7)
38935+#define AuBrAttr_ICEX_SYS (1 << 8)
38936+#define AuBrAttr_ICEX_TR (1 << 9)
38937+#define AuBrAttr_ICEX_USR (1 << 10)
38938+#define AuBrAttr_ICEX_OTH (1 << 11)
38939+#define AuBrAttr_ICEX (AuBrAttr_ICEX_SEC \
38940+ | AuBrAttr_ICEX_SYS \
38941+ | AuBrAttr_ICEX_TR \
38942+ | AuBrAttr_ICEX_USR \
38943+ | AuBrAttr_ICEX_OTH)
38944+
38945+#define AuBrRAttr_WH (1 << 12) /* whiteout-able */
38946+#define AuBrRAttr_Mask AuBrRAttr_WH
38947+
38948+#define AuBrWAttr_NoLinkWH (1 << 13) /* un-hardlinkable whiteouts */
38949+#define AuBrWAttr_MOO (1 << 14) /* move-up on open */
38950+#define AuBrWAttr_Mask (AuBrWAttr_NoLinkWH | AuBrWAttr_MOO)
38951+
38952+#define AuBrAttr_CMOO_Mask (AuBrAttr_COO_Mask | AuBrWAttr_MOO)
38953+
38954+/* #warning test userspace */
38955+#ifdef __KERNEL__
38956+#ifndef CONFIG_AUFS_FHSM
38957+#undef AuBrAttr_FHSM
38958+#define AuBrAttr_FHSM 0
38959+#endif
38960+#ifndef CONFIG_AUFS_XATTR
38961+#undef AuBrAttr_ICEX
38962+#define AuBrAttr_ICEX 0
38963+#undef AuBrAttr_ICEX_SEC
38964+#define AuBrAttr_ICEX_SEC 0
38965+#undef AuBrAttr_ICEX_SYS
38966+#define AuBrAttr_ICEX_SYS 0
38967+#undef AuBrAttr_ICEX_TR
38968+#define AuBrAttr_ICEX_TR 0
38969+#undef AuBrAttr_ICEX_USR
38970+#define AuBrAttr_ICEX_USR 0
38971+#undef AuBrAttr_ICEX_OTH
38972+#define AuBrAttr_ICEX_OTH 0
38973+#endif
38974+#endif
38975+
38976+/* the longest combination */
38977+/* AUFS_BRATTR_ICEX and AUFS_BRATTR_ICEX_TR don't affect here */
38978+#define AuBrPermStrSz sizeof(AUFS_BRPERM_RW \
38979+ "+" AUFS_BRATTR_COO_REG \
38980+ "+" AUFS_BRATTR_FHSM \
38981+ "+" AUFS_BRATTR_UNPIN \
38982+ "+" AUFS_BRATTR_ICEX_SEC \
38983+ "+" AUFS_BRATTR_ICEX_SYS \
38984+ "+" AUFS_BRATTR_ICEX_USR \
38985+ "+" AUFS_BRATTR_ICEX_OTH \
38986+ "+" AUFS_BRWATTR_NLWH)
38987+
38988+typedef struct {
38989+ char a[AuBrPermStrSz];
38990+} au_br_perm_str_t;
38991+
38992+static inline int au_br_writable(int brperm)
38993+{
38994+ return brperm & AuBrPerm_RW;
38995+}
38996+
38997+static inline int au_br_whable(int brperm)
38998+{
38999+ return brperm & (AuBrPerm_RW | AuBrRAttr_WH);
39000+}
39001+
39002+static inline int au_br_wh_linkable(int brperm)
39003+{
39004+ return !(brperm & AuBrWAttr_NoLinkWH);
39005+}
39006+
39007+static inline int au_br_cmoo(int brperm)
39008+{
39009+ return brperm & AuBrAttr_CMOO_Mask;
39010+}
39011+
39012+static inline int au_br_fhsm(int brperm)
39013+{
39014+ return brperm & AuBrAttr_FHSM;
39015+}
39016+
39017+/* ---------------------------------------------------------------------- */
39018+
39019+/* ioctl */
39020+enum {
39021+ /* readdir in userspace */
39022+ AuCtl_RDU,
39023+ AuCtl_RDU_INO,
39024+
39025+ AuCtl_WBR_FD, /* pathconf wrapper */
39026+ AuCtl_IBUSY, /* busy inode */
39027+ AuCtl_MVDOWN, /* move-down */
39028+ AuCtl_BR, /* info about branches */
39029+ AuCtl_FHSM_FD /* connection for fhsm */
39030+};
39031+
39032+/* borrowed from linux/include/linux/kernel.h */
39033+#ifndef ALIGN
39034+#ifdef _GNU_SOURCE
39035+#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1)
39036+#else
39037+#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
39038+#endif
39039+#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
39040+#endif
39041+
39042+/* borrowed from linux/include/linux/compiler-gcc3.h */
39043+#ifndef __aligned
39044+#define __aligned(x) __attribute__((aligned(x)))
39045+#endif
39046+
39047+#ifdef __KERNEL__
39048+#ifndef __packed
39049+#define __packed __attribute__((packed))
39050+#endif
39051+#endif
39052+
39053+struct au_rdu_cookie {
39054+ uint64_t h_pos;
39055+ int16_t bindex;
39056+ uint8_t flags;
39057+ uint8_t pad;
39058+ uint32_t generation;
39059+} __aligned(8);
39060+
39061+struct au_rdu_ent {
39062+ uint64_t ino;
39063+ int16_t bindex;
39064+ uint8_t type;
39065+ uint8_t nlen;
39066+ uint8_t wh;
39067+ char name[0];
39068+} __aligned(8);
39069+
39070+static inline int au_rdu_len(int nlen)
39071+{
39072+ /* include the terminating NULL */
39073+ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1,
39074+ sizeof(uint64_t));
39075+}
39076+
39077+union au_rdu_ent_ul {
39078+ struct au_rdu_ent __user *e;
39079+ uint64_t ul;
39080+};
39081+
39082+enum {
39083+ AufsCtlRduV_SZ,
39084+ AufsCtlRduV_End
39085+};
39086+
39087+struct aufs_rdu {
39088+ /* input */
39089+ union {
39090+ uint64_t sz; /* AuCtl_RDU */
39091+ uint64_t nent; /* AuCtl_RDU_INO */
39092+ };
39093+ union au_rdu_ent_ul ent;
39094+ uint16_t verify[AufsCtlRduV_End];
39095+
39096+ /* input/output */
39097+ uint32_t blk;
39098+
39099+ /* output */
39100+ union au_rdu_ent_ul tail;
39101+ /* number of entries which were added in a single call */
39102+ uint64_t rent;
39103+ uint8_t full;
39104+ uint8_t shwh;
39105+
39106+ struct au_rdu_cookie cookie;
39107+} __aligned(8);
39108+
39109+/* ---------------------------------------------------------------------- */
39110+
39111+/* dirren. the branch is identified by the filename who contains this */
39112+struct au_drinfo {
39113+ uint64_t ino;
39114+ union {
39115+ uint8_t oldnamelen;
39116+ uint64_t _padding;
39117+ };
39118+ uint8_t oldname[0];
39119+} __aligned(8);
39120+
39121+struct au_drinfo_fdata {
39122+ uint32_t magic;
39123+ struct au_drinfo drinfo;
39124+} __aligned(8);
39125+
39126+#define AUFS_DRINFO_MAGIC_V1 ('a' << 24 | 'd' << 16 | 'r' << 8 | 0x01)
39127+/* future */
39128+#define AUFS_DRINFO_MAGIC_V2 ('a' << 24 | 'd' << 16 | 'r' << 8 | 0x02)
39129+
39130+/* ---------------------------------------------------------------------- */
39131+
39132+struct aufs_wbr_fd {
39133+ uint32_t oflags;
39134+ int16_t brid;
39135+} __aligned(8);
39136+
39137+/* ---------------------------------------------------------------------- */
39138+
39139+struct aufs_ibusy {
39140+ uint64_t ino, h_ino;
39141+ int16_t bindex;
39142+} __aligned(8);
39143+
39144+/* ---------------------------------------------------------------------- */
39145+
39146+/* error code for move-down */
39147+/* the actual message strings are implemented in aufs-util.git */
39148+enum {
39149+ EAU_MVDOWN_OPAQUE = 1,
39150+ EAU_MVDOWN_WHITEOUT,
39151+ EAU_MVDOWN_UPPER,
39152+ EAU_MVDOWN_BOTTOM,
39153+ EAU_MVDOWN_NOUPPER,
39154+ EAU_MVDOWN_NOLOWERBR,
39155+ EAU_Last
39156+};
39157+
39158+/* flags for move-down */
39159+#define AUFS_MVDOWN_DMSG 1
39160+#define AUFS_MVDOWN_OWLOWER (1 << 1) /* overwrite lower */
39161+#define AUFS_MVDOWN_KUPPER (1 << 2) /* keep upper */
39162+#define AUFS_MVDOWN_ROLOWER (1 << 3) /* do even if lower is RO */
39163+#define AUFS_MVDOWN_ROLOWER_R (1 << 4) /* did on lower RO */
39164+#define AUFS_MVDOWN_ROUPPER (1 << 5) /* do even if upper is RO */
39165+#define AUFS_MVDOWN_ROUPPER_R (1 << 6) /* did on upper RO */
39166+#define AUFS_MVDOWN_BRID_UPPER (1 << 7) /* upper brid */
39167+#define AUFS_MVDOWN_BRID_LOWER (1 << 8) /* lower brid */
39168+#define AUFS_MVDOWN_FHSM_LOWER (1 << 9) /* find fhsm attr for lower */
39169+#define AUFS_MVDOWN_STFS (1 << 10) /* req. stfs */
39170+#define AUFS_MVDOWN_STFS_FAILED (1 << 11) /* output: stfs is unusable */
39171+#define AUFS_MVDOWN_BOTTOM (1 << 12) /* output: no more lowers */
39172+
39173+/* index for move-down */
39174+enum {
39175+ AUFS_MVDOWN_UPPER,
39176+ AUFS_MVDOWN_LOWER,
39177+ AUFS_MVDOWN_NARRAY
39178+};
39179+
39180+/*
39181+ * additional info of move-down
39182+ * number of free blocks and inodes.
39183+ * subset of struct kstatfs, but smaller and always 64bit.
39184+ */
39185+struct aufs_stfs {
39186+ uint64_t f_blocks;
39187+ uint64_t f_bavail;
39188+ uint64_t f_files;
39189+ uint64_t f_ffree;
39190+};
39191+
39192+struct aufs_stbr {
39193+ int16_t brid; /* optional input */
39194+ int16_t bindex; /* output */
39195+ struct aufs_stfs stfs; /* output when AUFS_MVDOWN_STFS set */
39196+} __aligned(8);
39197+
39198+struct aufs_mvdown {
39199+ uint32_t flags; /* input/output */
39200+ struct aufs_stbr stbr[AUFS_MVDOWN_NARRAY]; /* input/output */
39201+ int8_t au_errno; /* output */
39202+} __aligned(8);
39203+
39204+/* ---------------------------------------------------------------------- */
39205+
39206+union aufs_brinfo {
39207+ /* PATH_MAX may differ between kernel-space and user-space */
39208+ char _spacer[4096];
39209+ struct {
39210+ int16_t id;
39211+ int perm;
39212+ char path[0];
39213+ };
39214+} __aligned(8);
39215+
39216+/* ---------------------------------------------------------------------- */
39217+
39218+#define AuCtlType 'A'
39219+#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu)
39220+#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu)
39221+#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \
39222+ struct aufs_wbr_fd)
39223+#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
39224+#define AUFS_CTL_MVDOWN _IOWR(AuCtlType, AuCtl_MVDOWN, \
39225+ struct aufs_mvdown)
39226+#define AUFS_CTL_BRINFO _IOW(AuCtlType, AuCtl_BR, union aufs_brinfo)
39227+#define AUFS_CTL_FHSM_FD _IOW(AuCtlType, AuCtl_FHSM_FD, int)
39228+
39229+#endif /* __AUFS_TYPE_H__ */
39230SPDX-License-Identifier: GPL-2.0
39231aufs5.4 loopback patch
39232
39233diff --git a/drivers/block/loop.c b/drivers/block/loop.c
39234index 5e094699215e..22b2ecb6cfe8 100644
39235--- a/drivers/block/loop.c
39236+++ b/drivers/block/loop.c
39237@@ -625,6 +625,15 @@ static inline void loop_update_dio(struct loop_device *lo)
39238 lo->use_dio);
39239 }
39240
39241+static struct file *loop_real_file(struct file *file)
39242+{
39243+ struct file *f = NULL;
39244+
39245+ if (file->f_path.dentry->d_sb->s_op->real_loop)
39246+ f = file->f_path.dentry->d_sb->s_op->real_loop(file);
39247+ return f;
39248+}
39249+
39250 static void loop_reread_partitions(struct loop_device *lo,
39251 struct block_device *bdev)
39252 {
39253@@ -678,6 +687,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
39254 unsigned int arg)
39255 {
39256 struct file *file = NULL, *old_file;
39257+ struct file *f, *virt_file = NULL, *old_virt_file;
39258 int error;
39259 bool partscan;
39260
39261@@ -697,12 +707,19 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
39262 file = fget(arg);
39263 if (!file)
39264 goto out_err;
39265+ f = loop_real_file(file);
39266+ if (f) {
39267+ virt_file = file;
39268+ file = f;
39269+ get_file(file);
39270+ }
39271
39272 error = loop_validate_file(file, bdev);
39273 if (error)
39274 goto out_err;
39275
39276 old_file = lo->lo_backing_file;
39277+ old_virt_file = lo->lo_backing_virt_file;
39278
39279 error = -EINVAL;
39280
39281@@ -714,6 +731,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
39282 blk_mq_freeze_queue(lo->lo_queue);
39283 mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
39284 lo->lo_backing_file = file;
39285+ lo->lo_backing_virt_file = virt_file;
39286 lo->old_gfp_mask = mapping_gfp_mask(file->f_mapping);
39287 mapping_set_gfp_mask(file->f_mapping,
39288 lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS));
39289@@ -727,6 +745,8 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
39290 * dependency.
39291 */
39292 fput(old_file);
39293+ if (old_virt_file)
39294+ fput(old_virt_file);
39295 if (partscan)
39296 loop_reread_partitions(lo, bdev);
39297 return 0;
39298@@ -735,6 +755,8 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
39299 mutex_unlock(&loop_ctl_mutex);
39300 if (file)
39301 fput(file);
39302+ if (virt_file)
39303+ fput(virt_file);
39304 return error;
39305 }
39306
39307@@ -939,7 +961,7 @@ static void loop_update_rotational(struct loop_device *lo)
39308 static int loop_set_fd(struct loop_device *lo, fmode_t mode,
39309 struct block_device *bdev, unsigned int arg)
39310 {
39311- struct file *file;
39312+ struct file *file, *f, *virt_file = NULL;
39313 struct inode *inode;
39314 struct address_space *mapping;
39315 struct block_device *claimed_bdev = NULL;
39316@@ -955,6 +977,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
39317 file = fget(arg);
39318 if (!file)
39319 goto out;
39320+ f = loop_real_file(file);
39321+ if (f) {
39322+ virt_file = file;
39323+ file = f;
39324+ get_file(file);
39325+ }
39326
39327 /*
39328 * If we don't hold exclusive handle for the device, upgrade to it
39329@@ -1003,6 +1031,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
39330 lo->lo_device = bdev;
39331 lo->lo_flags = lo_flags;
39332 lo->lo_backing_file = file;
39333+ lo->lo_backing_virt_file = virt_file;
39334 lo->transfer = NULL;
39335 lo->ioctl = NULL;
39336 lo->lo_sizelimit = 0;
39337@@ -1056,6 +1085,8 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
39338 bd_abort_claiming(bdev, claimed_bdev, loop_set_fd);
39339 out_putf:
39340 fput(file);
39341+ if (virt_file)
39342+ fput(virt_file);
39343 out:
39344 /* This is safe: open() is still holding a reference. */
39345 module_put(THIS_MODULE);
39346@@ -1102,6 +1133,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
39347 static int __loop_clr_fd(struct loop_device *lo, bool release)
39348 {
39349 struct file *filp = NULL;
39350+ struct file *virt_filp = lo->lo_backing_virt_file;
39351 gfp_t gfp = lo->old_gfp_mask;
39352 struct block_device *bdev = lo->lo_device;
39353 int err = 0;
39354@@ -1125,6 +1157,7 @@ static int __loop_clr_fd(struct loop_device *lo, bool release)
39355
39356 spin_lock_irq(&lo->lo_lock);
39357 lo->lo_backing_file = NULL;
39358+ lo->lo_backing_virt_file = NULL;
39359 spin_unlock_irq(&lo->lo_lock);
39360
39361 loop_release_xfer(lo);
39362@@ -1207,6 +1240,8 @@ static int __loop_clr_fd(struct loop_device *lo, bool release)
39363 */
39364 if (filp)
39365 fput(filp);
39366+ if (virt_filp)
39367+ fput(virt_filp);
39368 return err;
39369 }
39370
39371diff --git a/drivers/block/loop.h b/drivers/block/loop.h
39372index af75a5ee4094..1d847cb194ff 100644
39373--- a/drivers/block/loop.h
39374+++ b/drivers/block/loop.h
39375@@ -46,7 +46,7 @@ struct loop_device {
39376 int (*ioctl)(struct loop_device *, int cmd,
39377 unsigned long arg);
39378
39379- struct file * lo_backing_file;
39380+ struct file *lo_backing_file, *lo_backing_virt_file;
39381 struct block_device *lo_device;
39382 void *key_data;
39383
39384diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
39385index 6fb4a4ed8cc7..ba9a959f2db2 100644
39386--- a/fs/aufs/f_op.c
39387+++ b/fs/aufs/f_op.c
39388@@ -359,7 +359,7 @@ static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter)
39389 if (IS_ERR(h_file))
39390 goto out;
39391
39392- if (au_test_loopback_kthread()) {
39393+ if (0 && au_test_loopback_kthread()) {
39394 au_warn_loopback(h_file->f_path.dentry->d_sb);
39395 if (file->f_mapping != h_file->f_mapping) {
39396 file->f_mapping = h_file->f_mapping;
39397diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c
39398index a8b63acc6204..9d97c3af5686 100644
39399--- a/fs/aufs/loop.c
39400+++ b/fs/aufs/loop.c
39401@@ -133,3 +133,19 @@ void au_loopback_fin(void)
39402 symbol_put(loop_backing_file);
39403 au_kfree_try_rcu(au_warn_loopback_array);
39404 }
39405+
39406+/* ---------------------------------------------------------------------- */
39407+
39408+/* support the loopback block device insude aufs */
39409+
39410+struct file *aufs_real_loop(struct file *file)
39411+{
39412+ struct file *f;
39413+
39414+ BUG_ON(!au_test_aufs(file->f_path.dentry->d_sb));
39415+ fi_read_lock(file);
39416+ f = au_hf_top(file);
39417+ fi_read_unlock(file);
39418+ AuDebugOn(!f);
39419+ return f;
39420+}
39421diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h
39422index 94f4f80ae33b..ca1194354aff 100644
39423--- a/fs/aufs/loop.h
39424+++ b/fs/aufs/loop.h
39425@@ -26,6 +26,8 @@ void au_warn_loopback(struct super_block *h_sb);
39426
39427 int au_loopback_init(void);
39428 void au_loopback_fin(void);
39429+
39430+struct file *aufs_real_loop(struct file *file);
39431 #else
39432 AuStub(struct file *, loop_backing_file, return NULL, struct super_block *sb)
39433
39434@@ -36,6 +38,8 @@ AuStubVoid(au_warn_loopback, struct super_block *h_sb)
39435
39436 AuStubInt0(au_loopback_init, void)
39437 AuStubVoid(au_loopback_fin, void)
39438+
39439+AuStub(struct file *, aufs_real_loop, return NULL, struct file *file)
39440 #endif /* BLK_DEV_LOOP */
39441
39442 #endif /* __KERNEL__ */
39443diff --git a/fs/aufs/super.c b/fs/aufs/super.c
39444index 589dd0122020..801e0a7faec5 100644
39445--- a/fs/aufs/super.c
39446+++ b/fs/aufs/super.c
39447@@ -844,7 +844,10 @@ static const struct super_operations aufs_sop = {
39448 .statfs = aufs_statfs,
39449 .put_super = aufs_put_super,
39450 .sync_fs = aufs_sync_fs,
39451- .remount_fs = aufs_remount_fs
39452+ .remount_fs = aufs_remount_fs,
39453+#ifdef CONFIG_AUFS_BDEV_LOOP
39454+ .real_loop = aufs_real_loop
39455+#endif
39456 };
39457
39458 /* ---------------------------------------------------------------------- */
39459diff --git a/include/linux/fs.h b/include/linux/fs.h
39460index 381a13995011..215b76e0f9dc 100644
39461--- a/include/linux/fs.h
39462+++ b/include/linux/fs.h
39463@@ -1973,6 +1973,10 @@ struct super_operations {
39464 struct shrink_control *);
39465 long (*free_cached_objects)(struct super_block *,
39466 struct shrink_control *);
39467+#if IS_ENABLED(CONFIG_BLK_DEV_LOOP) || IS_ENABLED(CONFIG_BLK_DEV_LOOP_MODULE)
39468+ /* and aufs */
39469+ struct file *(*real_loop)(struct file *);
39470+#endif
39471 };
39472
39473 /*
This page took 0.650954 seconds and 4 git commands to generate.